Skip to contentSkip to conversation

Add board detection for Odroid XU3 / XU3Lite / XU4

PATCH New Przemyslaw Marczak 6 participants 106 messages Aug 28, 2015 – Nov 6, 2015

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover Add board detection for Odroid XU3 / XU3Lite / XU4

This patchset adds:
- define the CPU name for Chromebook Peach Pi as Exynos5800
- set the cpu id of Exynos5422 to 0x5422
- S2MPS11 PMIC I/O driver
- Exynos5420-compatible (9-channel, 12-bit) ADC driver
- board detection for Odroid XU3 / XU3lite / XU4

This was tested on Odroid XU3 and XU3 Lite, without the XU4, but I'm waiting for reply from the Odroid forum users.

Tested with buildman for samsung.

Available on github:
https://github.com/bobenstein/u-boot/tree/xu3-patchset-test

Przemyslaw Marczak (7):
s5p: cpu_info: use defined CPU name if available
peach-pi: define CPU name for SoC Exynos5800 Exynos5422/5800: set cpu id to 0x5422
dm: pmic: add s2mps11 PMIC I/O driver
odroid-xu3: enable s2mps11 PMIC support
Exynos: add internal ADC driver
exynos5-dt: add board detection for Odroid XU3/XU3L/XU4.

 arch/arm/cpu/armv7/s5p-common/cpu_info.c  |   5 ++
 arch/arm/dts/exynos5422-odroidxu3.dts     |   7 ++
 arch/arm/mach-exynos/Makefile             |   1 +
 arch/arm/mach-exynos/adc.c                |  83 ++++++++++++++++++++++
 arch/arm/mach-exynos/clock.c              |  16 ++---
 arch/arm/mach-exynos/clock_init_exynos5.c |   2 +-
 arch/arm/mach-exynos/common_setup.h       |   4 +-
 arch/arm/mach-exynos/include/mach/adc.h   |  45 ++++++++++++
 arch/arm/mach-exynos/include/mach/cpu.h   |  10 +--
 arch/arm/mach-exynos/include/mach/gpio.h  |   4 +-
 arch/arm/mach-exynos/pinmux.c             |   2 +-
 arch/arm/mach-exynos/power.c              |   2 +-
 board/samsung/common/exynos5-dt.c         | 114 ++++++++++++++++++++++++++++++
 configs/odroid-xu3_defconfig              |   3 +
 doc/device-tree-bindings/pmic/s2mps11.txt |  17 +++++
 drivers/power/pmic/Kconfig                |  14 ++++
 drivers/power/pmic/Makefile               |   1 +
 drivers/power/pmic/s2mps11.c              |  60 ++++++++++++++++
 include/configs/odroid_xu3.h              |  12 ++++
 include/configs/peach-pi.h                |   2 +
 include/power/s2mps11.h                   | 109 ++++++++++++++++++++++++++++
 21 files changed, 493 insertions(+), 20 deletions(-)
 create mode 100644 arch/arm/mach-exynos/adc.c
 create mode 100644 doc/device-tree-bindings/pmic/s2mps11.txt
 create mode 100644 drivers/power/pmic/s2mps11.c
 create mode 100644 include/power/s2mps11.h
Signature · 1 line
1.9.1
#1 lore raw

PATCH 1/7 s5p: cpu_info: use defined CPU name if available

The CPU name for Exynos was concatenated with cpu id, but for new Exynos platforms, like Chromebook Peach Pi based on Exynos5800, the name of SoC variant does not include the real SoC cpu id (0x5422).

For such case, the CPU name should be defined by the config file.

This commit introduces new config:
- CONFIG_CPU_NAME - with cpu name string

If defined, then the cpu id is not printed.

---
 arch/arm/cpu/armv7/s5p-common/cpu_info.c | 5 +++++
 1 file changed, 5 insertions(+)
arch/arm/cpu/armv7/s5p-common/cpu_info.c +5 -0
index 154d674..9b125a3 100644
@@ -30,7 +30,12 @@ u32 get_device_type(void)
 #ifdef CONFIG_DISPLAY_CPUINFO
 int print_cpuinfo(void)
 {
+/* For SoC with no real CPU ID in naming convention. */
+#ifdef CONFIG_CPU_NAME
+	printf("CPU:   %s @ ", CONFIG_CPU_NAME);
+#else
 	printf("CPU:   %s%X @ ", s5p_get_cpu_name(), s5p_cpu_id);
+#endif
 	print_freq(get_arm_clk(), "\n");
 
 	return 0;
Signature · 1 line
1.9.1
#2 lore raw

PATCH 1/7 s5p: cpu_info: use defined CPU name if available

Hi Przemyslaw,

Quoted 23 lines · Przemyslaw Marczak

The CPU name for Exynos was concatenated with cpu id, but for new Exynos platforms, like Chromebook Peach Pi based on Exynos5800, the name of SoC variant does not include the real SoC cpu id (0x5422).

For such case, the CPU name should be defined by the config file.

This commit introduces new config:
- CONFIG_CPU_NAME - with cpu name string

If defined, then the cpu id is not printed.

---
 arch/arm/cpu/armv7/s5p-common/cpu_info.c | 5 +++++
 1 file changed, 5 insertions(+)
arch/arm/cpu/armv7/s5p-common/cpu_info.c +0 -0
index 154d674..9b125a3 100644

arch/arm/cpu/armv7/s5p-common/cpu_info.c u32 get_device_type(void) · line 38

Quoted 9 lines
arch/arm/cpu/armv7/s5p-common/cpu_info.c +5 -0
@@ -30,7 +30,12 @@ u32 get_device_type(void)
 #ifdef CONFIG_DISPLAY_CPUINFO
 int print_cpuinfo(void)
 {
+/* For SoC with no real CPU ID in naming convention. */
+#ifdef CONFIG_CPU_NAME
+       printf("CPU:   %s @ ", CONFIG_CPU_NAME);
+#else
        printf("CPU:   %s%X @ ", s5p_get_cpu_name(), s5p_cpu_id);
+#endif

This adds a new CONFIG option - we should be trying to keep the code common. Does it print 5422 instead of 5800?

I'd suggest, either:

a) we don't care, 5422 is fine
b) we grab it from the device tree model or compatible string

Quoted 6 lines
arch/arm/cpu/armv7/s5p-common/cpu_info.c +0 -1
        print_freq(get_arm_clk(), "\n");
 
        return 0;
--

1.9.1

Regards,
Simon

#3 lore raw

PATCH 1/7 s5p: cpu_info: use defined CPU name if available

Hello Simon,

Quoted 30 lines · Simon Glass

Hi Przemyslaw,

Quoted 27 lines · Przemyslaw Marczak

The CPU name for Exynos was concatenated with cpu id, but for new Exynos platforms, like Chromebook Peach Pi based on Exynos5800, the name of SoC variant does not include the real SoC cpu id (0x5422).

For such case, the CPU name should be defined by the config file.

This commit introduces new config:
- CONFIG_CPU_NAME - with cpu name string

If defined, then the cpu id is not printed.

---
  arch/arm/cpu/armv7/s5p-common/cpu_info.c | 5 +++++
  1 file changed, 5 insertions(+)
arch/arm/cpu/armv7/s5p-common/cpu_info.c +1 -0
index 154d674..9b125a3 100644
@@ -30,7 +30,12 @@ u32 get_device_type(void)
  #ifdef CONFIG_DISPLAY_CPUINFO
  int print_cpuinfo(void)
  {
+/* For SoC with no real CPU ID in naming convention. */
Quoted 8 lines

arch/arm/cpu/armv7/s5p-common/cpu_info.c u32 get_device_type(void) · line 38

Quoted 5 lines
arch/arm/cpu/armv7/s5p-common/cpu_info.c +4 -0
+#ifdef CONFIG_CPU_NAME
+       printf("CPU:   %s @ ", CONFIG_CPU_NAME);
+#else
         printf("CPU:   %s%X @ ", s5p_get_cpu_name(), s5p_cpu_id);
+#endif

This adds a new CONFIG option - we should be trying to keep the code common. Does it print 5422 instead of 5800?

Yes, it does.

Quoted 6 lines

I'd suggest, either:

a) we don't care, 5422 is fine
b) we grab it from the device tree model or compatible string

Ok, the second one seem to be good.

Quoted 10 lines
Quoted 6 lines
arch/arm/cpu/armv7/s5p-common/cpu_info.c +0 -1
         print_freq(get_arm_clk(), "\n");
 
         return 0;
--

1.9.1

Regards,
Simon

Best regards,

Signature · 4 lines
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com
#4 lore raw

PATCH 2/7 peach-pi: define CPU name for SoC Exynos5800

In reply to Przemyslaw Marczak

This platform is based on Exynos5800 but the cpu id is 0x5422. This doesn't fit the common Exynos SoC name convention, so now, the CPU name is defined in config, to be printed properly.

---
 include/configs/peach-pi.h | 2 ++
 1 file changed, 2 insertions(+)
include/configs/peach-pi.h +2 -0
index 6c42aaa..0d7bc96 100644
@@ -9,6 +9,8 @@
 #ifndef __CONFIG_PEACH_PI_H
 #define __CONFIG_PEACH_PI_H
 
+#define CONFIG_CPU_NAME		"Exynos5800"
+
 #define MEM_LAYOUT_ENV_SETTINGS \
 	"bootm_size=0x10000000\0" \
 	"kernel_addr_r=0x22000000\0" \
Signature · 1 line
1.9.1
#5 lore raw

PATCH 3/7 Exynos5422/5800: set cpu id to 0x5422

In reply to Przemyslaw Marczak

The proper CPU ID for those Exynos variants is 0x5422, but before the 0x5800 was set. This commit fix this back.

Changes:
- set cpu id to 0x5422 instead of 0x5800
- remove macro proid_is_exynos5800()
- add macro proid_is_exynos5422()
- change the calls to proid_is_exynos5800() with new macro

---
 arch/arm/mach-exynos/clock.c              | 16 ++++++++--------
 arch/arm/mach-exynos/clock_init_exynos5.c |  2 +-
 arch/arm/mach-exynos/common_setup.h       |  4 ++--
 arch/arm/mach-exynos/include/mach/cpu.h   |  6 +++---
 arch/arm/mach-exynos/include/mach/gpio.h  |  4 ++--
 arch/arm/mach-exynos/pinmux.c             |  2 +-
 arch/arm/mach-exynos/power.c              |  2 +-
 7 files changed, 18 insertions(+), 18 deletions(-)
arch/arm/mach-exynos/clock.c +8 -8
index 1c6baa1..2d94851 100644
@@ -159,8 +159,8 @@ static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k)
 			div = PLL_DIV_1024;
 		else if (proid_is_exynos4412())
 			div = PLL_DIV_65535;
-		else if (proid_is_exynos5250() || proid_is_exynos5420()
-			 || proid_is_exynos5800())
+		else if (proid_is_exynos5250() || proid_is_exynos5420() ||
+			 proid_is_exynos5422())
 			div = PLL_DIV_65536;
 		else
 			return 0;
@@ -346,7 +346,7 @@ static struct clk_bit_info *get_clk_bit_info(int peripheral)
 	int i;
 	struct clk_bit_info *info;
 
-	if (proid_is_exynos5420() || proid_is_exynos5800())
+	if (proid_is_exynos5420() || proid_is_exynos5422())
 		info = exynos542x_bit_info;
 	else
 		info = exynos5_bit_info;
@@ -558,7 +558,7 @@ static unsigned long exynos542x_get_periph_rate(int peripheral)
 unsigned long clock_get_periph_rate(int peripheral)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return exynos542x_get_periph_rate(peripheral);
 		return exynos5_get_periph_rate(peripheral);
 	} else {
@@ -1576,7 +1576,7 @@ static unsigned long exynos4_get_i2c_clk(void)
 unsigned long get_pll_clk(int pllreg)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return exynos542x_get_pll_clk(pllreg);
 		return exynos5_get_pll_clk(pllreg);
 	} else if (cpu_is_exynos4()) {
@@ -1694,7 +1694,7 @@ void set_mmc_clk(int dev_index, unsigned int div)
 		div -= 1;
 
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			exynos5420_set_mmc_clk(dev_index, div);
 		else
 			exynos5_set_mmc_clk(dev_index, div);
@@ -1710,7 +1710,7 @@ unsigned long get_lcd_clk(void)
 	} else if (cpu_is_exynos5()) {
 		if (proid_is_exynos5420())
 			return exynos5420_get_lcd_clk();
-		else if (proid_is_exynos5800())
+		else if (proid_is_exynos5422())
 			return exynos5800_get_lcd_clk();
 		else
 			return exynos5_get_lcd_clk();
@@ -1742,7 +1742,7 @@ void set_mipi_clk(void)
 int set_spi_clk(int periph_id, unsigned int rate)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return exynos5420_set_spi_clk(periph_id, rate);
 		return exynos5_set_spi_clk(periph_id, rate);
 	}
arch/arm/mach-exynos/clock_init_exynos5.c +1 -1
index 0200fd1..1b7498d 100644
@@ -971,7 +971,7 @@ static void exynos5420_system_clock_init(void)
 
 void system_clock_init(void)
 {
-	if (proid_is_exynos5420() || proid_is_exynos5800())
+	if (proid_is_exynos5420() || proid_is_exynos5422())
 		exynos5420_system_clock_init();
 	else
 		exynos5250_system_clock_init();
arch/arm/mach-exynos/common_setup.h +2 -2
index 67aac2d..2829fb2 100644
@@ -78,7 +78,7 @@ static inline void configure_l2_ctlr(void)
 		CACHE_TAG_RAM_LATENCY_2_CYCLES |
 		CACHE_DATA_RAM_LATENCY_2_CYCLES;
 
-	if (proid_is_exynos5420() || proid_is_exynos5800()) {
+	if (proid_is_exynos5420() || proid_is_exynos5422()) {
 		val |= CACHE_ECC_AND_PARITY |
 			CACHE_TAG_RAM_LATENCY_3_CYCLES |
 			CACHE_DATA_RAM_LATENCY_3_CYCLES;
@@ -97,7 +97,7 @@ static inline void configure_l2_actlr(void)
 {
 	uint32_t val;
 
-	if (proid_is_exynos5420() || proid_is_exynos5800()) {
+	if (proid_is_exynos5420() || proid_is_exynos5422()) {
 		mrc_l2_aux_ctlr(val);
 		val |= CACHE_ENABLE_FORCE_L2_LOGIC |
 			CACHE_DISABLE_CLEAN_EVICT;
arch/arm/mach-exynos/include/mach/cpu.h +3 -3
index cb3d2cc..14a1692 100644
@@ -237,7 +237,7 @@ static inline void s5p_set_cpu_id(void)
 		 * Exynos5800 is a variant of Exynos5420
 		 * and has product id 0x5422
 		 */
-		s5p_cpu_id = 0x5800;
+		s5p_cpu_id = 0x5422;
 		break;
 	}
 }
@@ -267,7 +267,7 @@ IS_EXYNOS_TYPE(exynos4210, 0x4210)
 IS_EXYNOS_TYPE(exynos4412, 0x4412)
 IS_EXYNOS_TYPE(exynos5250, 0x5250)
 IS_EXYNOS_TYPE(exynos5420, 0x5420)
-IS_EXYNOS_TYPE(exynos5800, 0x5800)
+IS_EXYNOS_TYPE(exynos5422, 0x5422)
 
 #define SAMSUNG_BASE(device, base)				\
 static inline unsigned int __attribute__((no_instrument_function)) \
@@ -278,7 +278,7 @@ static inline unsigned int __attribute__((no_instrument_function)) \
 			return EXYNOS4X12_##base;		\
 		return EXYNOS4_##base;				\
 	} else if (cpu_is_exynos5()) {				\
-		if (proid_is_exynos5420() || proid_is_exynos5800())	\
+		if (proid_is_exynos5420() || proid_is_exynos5422())	\
 			return EXYNOS5420_##base;		\
 		return EXYNOS5_##base;				\
 	}							\
arch/arm/mach-exynos/include/mach/gpio.h +2 -2
index 9699954..7fc8e61 100644
@@ -1398,7 +1398,7 @@ static struct gpio_info exynos5420_gpio_data[EXYNOS5420_GPIO_NUM_PARTS] = {
 static inline struct gpio_info *get_gpio_data(void)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return exynos5420_gpio_data;
 		else
 			return exynos5_gpio_data;
@@ -1415,7 +1415,7 @@ static inline struct gpio_info *get_gpio_data(void)
 static inline unsigned int get_bank_num(void)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return EXYNOS5420_GPIO_NUM_PARTS;
 		else
 			return EXYNOS5_GPIO_NUM_PARTS;
arch/arm/mach-exynos/pinmux.c +1 -1
index 179b294..a556e4a 100644
@@ -858,7 +858,7 @@ static int exynos4x12_pinmux_config(int peripheral, int flags)
 int exynos_pinmux_config(int peripheral, int flags)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return exynos5420_pinmux_config(peripheral, flags);
 		else if (proid_is_exynos5250())
 			return exynos5_pinmux_config(peripheral, flags);
arch/arm/mach-exynos/power.c +1 -1
index 1b12051..cd2d661 100644
@@ -125,7 +125,7 @@ static void exynos5420_set_usbdev_phy_ctrl(unsigned int enable)
 void set_usbdrd_phy_ctrl(unsigned int enable)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			exynos5420_set_usbdev_phy_ctrl(enable);
 		else
 			exynos5_set_usbdrd_phy_ctrl(enable);
Signature · 1 line
1.9.1
#6 lore raw

PATCH 3/7 Exynos5422/5800: set cpu id to 0x5422

Quoted 10 lines · Przemyslaw Marczak

The proper CPU ID for those Exynos variants is 0x5422, but before the 0x5800 was set. This commit fix this back.

Changes:
- set cpu id to 0x5422 instead of 0x5800
- remove macro proid_is_exynos5800()
- add macro proid_is_exynos5422()
- change the calls to proid_is_exynos5800() with new macro

Quoted 9 lines
---
 arch/arm/mach-exynos/clock.c              | 16 ++++++++--------
 arch/arm/mach-exynos/clock_init_exynos5.c |  2 +-
 arch/arm/mach-exynos/common_setup.h       |  4 ++--
 arch/arm/mach-exynos/include/mach/cpu.h   |  6 +++---
 arch/arm/mach-exynos/include/mach/gpio.h  |  4 ++--
 arch/arm/mach-exynos/pinmux.c             |  2 +-
 arch/arm/mach-exynos/power.c              |  2 +-
 7 files changed, 18 insertions(+), 18 deletions(-)
#7 lore raw

PATCH 4/7 dm: pmic: add s2mps11 PMIC I/O driver

In reply to Przemyslaw Marczak

This driver allows I/O operations on the Samsung S2MPS11 PMIC, which provides lots of LDO/BUCK outputs.

To enable it, update defconfig with:
- CONFIG_DM_PMIC_S2MPS11
and additional, if were not defined:
- CONFIG_CMD_PMIC
- CONFIG_ERRNO_STR

The binding info: doc/device-tree-bindings/pmic/s2mps11.txt

---
 doc/device-tree-bindings/pmic/s2mps11.txt |  17 +++++
 drivers/power/pmic/Kconfig                |  14 ++++
 drivers/power/pmic/Makefile               |   1 +
 drivers/power/pmic/s2mps11.c              |  60 ++++++++++++++++
 include/power/s2mps11.h                   | 109 ++++++++++++++++++++++++++++++
 5 files changed, 201 insertions(+)
 create mode 100644 doc/device-tree-bindings/pmic/s2mps11.txt
 create mode 100644 drivers/power/pmic/s2mps11.c
 create mode 100644 include/power/s2mps11.h
doc/device-tree-bindings/pmic/s2mps11.txt new file +17 -0
new file mode 100644
index 0000000..db8d624
@@ -0,0 +1,17 @@
+SAMSUBNG, S2MPS11 PMIC
+
+This file describes the binding info for the PMIC driver:
+- drivers/power/pmic/s2mps11.c
+
+Required properties:
+- compatible: "samsung,s2mps11-pmic"
+- reg = 0x66
+
+With those two properties, the pmic device can be used for read/write only.
+
+Example:
+
+s2mps11 at 66 {
+	compatible = "samsung,s2mps11-pmic";
+	reg = <0x66>;
+};
drivers/power/pmic/Kconfig +14 -0
index fc6a374..c66b352 100644
@@ -24,6 +24,20 @@ config DM_PMIC_MAX77686
 	This config enables implementation of driver-model pmic uclass features
 	for PMIC MAX77686. The driver implements read/write operations.
 
+config DM_PMIC_S2MPS11
+	bool "Enable Driver Model for PMIC Samsung S2MPS11"
+	depends on DM_PMIC
+	---help---
+	The Samsung S2MPS11 PMIC provides:
+	 - 38 adjustable LDO regulators
+	 - 9 High-Efficiency Buck Converters
+	 - 1 BuckBoost Converter
+	 - RTC with two alarms
+	 - Backup battery charger
+	 - I2C Configuration Interface
+	This driver provides access to I/O interface only.
+	Binding info: doc/device-tree-bindings/pmic/s2mps11.txt
+
 config DM_PMIC_SANDBOX
 	bool "Enable Driver Model for emulated Sandbox PMIC "
 	depends on DM_PMIC
drivers/power/pmic/Makefile +1 -0
index 99c5778..1b58d98 100644
@@ -8,6 +8,7 @@
 obj-$(CONFIG_DM_PMIC) += pmic-uclass.o
 obj-$(CONFIG_DM_PMIC_MAX77686) += max77686.o
 obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze100.o
+obj-$(CONFIG_DM_PMIC_S2MPS11) += s2mps11.o
 obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o
 obj-$(CONFIG_PMIC_TPS65090) += tps65090.o
 obj-$(CONFIG_PMIC_S5M8767) += s5m8767.o
drivers/power/pmic/s2mps11.c new file +60 -0

60 lines not on this page · raw message

include/power/s2mps11.h new file +109 -0

109 lines not on this page · raw message

Signature · 1 line
1.9.1
#8 lore raw

PATCH 4/7 dm: pmic: add s2mps11 PMIC I/O driver

Quoted 12 lines · Przemyslaw Marczak

This driver allows I/O operations on the Samsung S2MPS11 PMIC, which provides lots of LDO/BUCK outputs.

To enable it, update defconfig with:
- CONFIG_DM_PMIC_S2MPS11
and additional, if were not defined:
- CONFIG_CMD_PMIC
- CONFIG_ERRNO_STR

The binding info: doc/device-tree-bindings/pmic/s2mps11.txt

Quoted 10 lines
---
 doc/device-tree-bindings/pmic/s2mps11.txt |  17 +++++
 drivers/power/pmic/Kconfig                |  14 ++++
 drivers/power/pmic/Makefile               |   1 +
 drivers/power/pmic/s2mps11.c              |  60 ++++++++++++++++
 include/power/s2mps11.h                   | 109 ++++++++++++++++++++++++++++++
 5 files changed, 201 insertions(+)
 create mode 100644 doc/device-tree-bindings/pmic/s2mps11.txt
 create mode 100644 drivers/power/pmic/s2mps11.c
 create mode 100644 include/power/s2mps11.h

(2 nits below)

Quoted 29 lines
doc/device-tree-bindings/pmic/s2mps11.txt new file +17 -0
new file mode 100644
index 0000000..db8d624
@@ -0,0 +1,17 @@
+SAMSUBNG, S2MPS11 PMIC
+
+This file describes the binding info for the PMIC driver:
+- drivers/power/pmic/s2mps11.c
+
+Required properties:
+- compatible: "samsung,s2mps11-pmic"
+- reg = 0x66
+
+With those two properties, the pmic device can be used for read/write only.
+
+Example:
+
+s2mps11 at 66 {
+       compatible = "samsung,s2mps11-pmic";
+       reg = <0x66>;
+};
drivers/power/pmic/Kconfig +0 -0
index fc6a374..c66b352 100644

drivers/power/pmic/Kconfig config DM_PMIC_MAX77686 · line 27

Quoted 4 lines
drivers/power/pmic/Kconfig +1 -0
@@ -24,6 +24,20 @@ config DM_PMIC_MAX77686
        This config enables implementation of driver-model pmic uclass features
        for PMIC MAX77686. The driver implements read/write operations.
 
+config DM_PMIC_S2MPS11

nit: I don't think this should have a DM_ prefix. Remember that all the CONFIG_DM_... options are going to be removed one day. It is intended to select the DM version of a subsystem. In your case you only have a DM version of the driver, so just CONFIG_PMIC_S2MPS11 seems fine.

Quoted 100 lines
drivers/power/pmic/Kconfig +13 -0
+       bool "Enable Driver Model for PMIC Samsung S2MPS11"
+       depends on DM_PMIC
+       ---help---
+       The Samsung S2MPS11 PMIC provides:
+        - 38 adjustable LDO regulators
+        - 9 High-Efficiency Buck Converters
+        - 1 BuckBoost Converter
+        - RTC with two alarms
+        - Backup battery charger
+        - I2C Configuration Interface
+       This driver provides access to I/O interface only.
+       Binding info: doc/device-tree-bindings/pmic/s2mps11.txt
+
 config DM_PMIC_SANDBOX
        bool "Enable Driver Model for emulated Sandbox PMIC "
        depends on DM_PMIC
drivers/power/pmic/Makefile +1 -0
index 99c5778..1b58d98 100644
@@ -8,6 +8,7 @@
 obj-$(CONFIG_DM_PMIC) += pmic-uclass.o
 obj-$(CONFIG_DM_PMIC_MAX77686) += max77686.o
 obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze100.o
+obj-$(CONFIG_DM_PMIC_S2MPS11) += s2mps11.o
 obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o
 obj-$(CONFIG_PMIC_TPS65090) += tps65090.o
 obj-$(CONFIG_PMIC_S5M8767) += s5m8767.o
drivers/power/pmic/s2mps11.c new file +60 -0
new file mode 100644
index 0000000..7e28402
@@ -0,0 +1,60 @@
+/*
+ *  Copyright (C) 2015 Samsung Electronics
+ *  Przemyslaw Marczak  <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <errno.h>
+#include <dm.h>
+#include <i2c.h>
+#include <power/pmic.h>
+#include <power/s2mps11.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int s2mps11_reg_count(struct udevice *dev)
+{
+       return S2MPS11_REG_COUNT;
+}
+
+static int s2mps11_write(struct udevice *dev, uint reg, const uint8_t *buff,
+                        int len)
+{
+       if (dm_i2c_write(dev, reg, buff, len)) {
+               error("write error to device: %p register: %#x!", dev, reg);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int s2mps11_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
+{
+       if (dm_i2c_read(dev, reg, buff, len)) {
+               error("read error from device: %p register: %#x!", dev, reg);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static struct dm_pmic_ops s2mps11_ops = {
+       .reg_count = s2mps11_reg_count,
+       .read = s2mps11_read,
+       .write = s2mps11_write,
+};
+
+static const struct udevice_id s2mps11_ids[] = {
+       { .compatible = "samsung,s2mps11-pmic" },
+       { }
+};
+
+U_BOOT_DRIVER(pmic_s2mps11) = {
+       .name = "s2mps11_pmic",
+       .id = UCLASS_PMIC,
+       .of_match = s2mps11_ids,
+       .ops = &s2mps11_ops,
+};
include/power/s2mps11.h new file +0 -0
new file mode 100644
index 0000000..885a816

include/power/s2mps11.h line 1

Quoted 1 line
include/power/s2mps11.h new file +1 -0
@@ -0,0 +1,109 @@
+#ifndef __INCLUDE__S2MPS11__H__

nit: I don't think you need __INCLUDE__ here

Quoted 109 lines
include/power/s2mps11.h new file +108 -1
+#define __INCLUDE__S2MPS11__H__
+
+enum s2mps11_reg {
+       S2MPS11_REG_ID = 0,
+       S2MPS11_REG_INT1,
+       S2MPS11_REG_INT2,
+       S2MPS11_REG_INT3,
+       S2MPS11_REG_INT1M,
+       S2MPS11_REG_INT2M,
+       S2MPS11_REG_INT3M,
+       S2MPS11_REG_STATUS1,
+       S2MPS11_REG_STATUS2,
+       S2MPS11_REG_OFFSRC,
+       S2MPS11_REG_PWRONSRC,
+       S2MPS11_REG_RTC_CTRL,
+       S2MPS11_REG_CTRL1,
+       S2MPS11_REG_ETC_TEST,
+       S2MPS11_REG_RSVD3,
+       S2MPS11_REG_BU_CHG,
+       S2MPS11_REG_RAMP,
+       S2MPS11_REG_RAMP_BUCK,
+       S2MPS11_REG_LDO1_8,
+       S2MPS11_REG_LDO9_16,
+       S2MPS11_REG_LDO17_24,
+       S2MPS11_REG_LDO25_32,
+       S2MPS11_REG_LDO33_38,
+       S2MPS11_REG_LDO1_8_OVC,
+       S2MPS11_REG_LDO9_16_OVC,
+       S2MPS11_REG_LDO17_24_OVC,
+       S2MPS11_REG_LDO25_32_OVC,
+       S2MPS11_REG_LDO33_38_OVC,
+       S2MPS11_REG_RESERVED1,
+       S2MPS11_REG_RESERVED2,
+       S2MPS11_REG_RESERVED3,
+       S2MPS11_REG_RESERVED4,
+       S2MPS11_REG_RESERVED5,
+       S2MPS11_REG_RESERVED6,
+       S2MPS11_REG_RESERVED7,
+       S2MPS11_REG_RESERVED8,
+       S2MPS11_REG_WDRSTEN_CTRL,
+       S2MPS11_REG_B1CTRL1,
+       S2MPS11_REG_B1CTRL2,
+       S2MPS11_REG_B2CTRL1,
+       S2MPS11_REG_B2CTRL2,
+       S2MPS11_REG_B3CTRL1,
+       S2MPS11_REG_B3CTRL2,
+       S2MPS11_REG_B4CTRL1,
+       S2MPS11_REG_B4CTRL2,
+       S2MPS11_REG_B5CTRL1,
+       S2MPS11_REG_BUCK5_SW,
+       S2MPS11_REG_B5CTRL2,
+       S2MPS11_REG_B5CTRL3,
+       S2MPS11_REG_B5CTRL4,
+       S2MPS11_REG_B5CTRL5,
+       S2MPS11_REG_B6CTRL1,
+       S2MPS11_REG_B6CTRL2,
+       S2MPS11_REG_B7CTRL1,
+       S2MPS11_REG_B7CTRL2,
+       S2MPS11_REG_B8CTRL1,
+       S2MPS11_REG_B8CTRL2,
+       S2MPS11_REG_B9CTRL1,
+       S2MPS11_REG_B9CTRL2,
+       S2MPS11_REG_B10CTRL1,
+       S2MPS11_REG_B10CTRL2,
+       S2MPS11_REG_L1CTRL,
+       S2MPS11_REG_L2CTRL,
+       S2MPS11_REG_L3CTRL,
+       S2MPS11_REG_L4CTRL,
+       S2MPS11_REG_L5CTRL,
+       S2MPS11_REG_L6CTRL,
+       S2MPS11_REG_L7CTRL,
+       S2MPS11_REG_L8CTRL,
+       S2MPS11_REG_L9CTRL,
+       S2MPS11_REG_L10CTRL,
+       S2MPS11_REG_L11CTRL,
+       S2MPS11_REG_L12CTRL,
+       S2MPS11_REG_L13CTRL,
+       S2MPS11_REG_L14CTRL,
+       S2MPS11_REG_L15CTRL,
+       S2MPS11_REG_L16CTRL,
+       S2MPS11_REG_L17CTRL,
+       S2MPS11_REG_L18CTRL,
+       S2MPS11_REG_L19CTRL,
+       S2MPS11_REG_L20CTRL,
+       S2MPS11_REG_L21CTRL,
+       S2MPS11_REG_L22CTRL,
+       S2MPS11_REG_L23CTRL,
+       S2MPS11_REG_L24CTRL,
+       S2MPS11_REG_L25CTRL,
+       S2MPS11_REG_L26CTRL,
+       S2MPS11_REG_L27CTRL,
+       S2MPS11_REG_L28CTRL,
+       S2MPS11_REG_L29CTRL,
+       S2MPS11_REG_L30CTRL,
+       S2MPS11_REG_L31CTRL,
+       S2MPS11_REG_L32CTRL,
+       S2MPS11_REG_L33CTRL,
+       S2MPS11_REG_L34CTRL,
+       S2MPS11_REG_L35CTRL,
+       S2MPS11_REG_L36CTRL,
+       S2MPS11_REG_L37CTRL,
+       S2MPS11_REG_L38CTRL,
+       S2MPS11_REG_COUNT,
+};
+
+#define S2MPS11_LDO26_ENABLE   0xec
+
+#endif
--
Quoted 2 lines

1.9.1

Regards,
Simon

#9 lore raw

PATCH 4/7 dm: pmic: add s2mps11 PMIC I/O driver

Hello,

Quoted 60 lines · Simon Glass
Quoted 19 lines · Przemyslaw Marczak

This driver allows I/O operations on the Samsung S2MPS11 PMIC, which provides lots of LDO/BUCK outputs.

To enable it, update defconfig with:
- CONFIG_DM_PMIC_S2MPS11
and additional, if were not defined:
- CONFIG_CMD_PMIC
- CONFIG_ERRNO_STR

The binding info: doc/device-tree-bindings/pmic/s2mps11.txt

---
  doc/device-tree-bindings/pmic/s2mps11.txt |  17 +++++
  drivers/power/pmic/Kconfig                |  14 ++++
  drivers/power/pmic/Makefile               |   1 +
  drivers/power/pmic/s2mps11.c              |  60 ++++++++++++++++
  include/power/s2mps11.h                   | 109 ++++++++++++++++++++++++++++++
  5 files changed, 201 insertions(+)
Quoted 3 lines

create mode 100644 doc/device-tree-bindings/pmic/s2mps11.txt create mode 100644 drivers/power/pmic/s2mps11.c create mode 100644 include/power/s2mps11.h

(2 nits below)

Quoted 32 lines
doc/device-tree-bindings/pmic/s2mps11.txt new file +17 -0
new file mode 100644
index 0000000..db8d624
@@ -0,0 +1,17 @@
+SAMSUBNG, S2MPS11 PMIC
+
+This file describes the binding info for the PMIC driver:
+- drivers/power/pmic/s2mps11.c
+
+Required properties:
+- compatible: "samsung,s2mps11-pmic"
+- reg = 0x66
+
+With those two properties, the pmic device can be used for read/write only.
+
+Example:
+
+s2mps11 at 66 {
+       compatible = "samsung,s2mps11-pmic";
+       reg = <0x66>;
+};
drivers/power/pmic/Kconfig +0 -0
index fc6a374..c66b352 100644
@@ -24,6 +24,20 @@ config DM_PMIC_MAX77686
         This config enables implementation of driver-model pmic uclass features
         for PMIC MAX77686. The driver implements read/write operations.
 
Quoted 8 lines

drivers/power/pmic/Kconfig config DM_PMIC_MAX77686 · line 27

Quoted 1 line
drivers/power/pmic/Kconfig +1 -0
+config DM_PMIC_S2MPS11

nit: I don't think this should have a DM_ prefix. Remember that all the CONFIG_DM_... options are going to be removed one day. It is intended to select the DM version of a subsystem. In your case you only have a DM version of the driver, so just CONFIG_PMIC_S2MPS11 seems fine.

Ah, ok. I will update this.

Quoted 95 lines
Quoted 95 lines
drivers/power/pmic/Kconfig +13 -0
+       bool "Enable Driver Model for PMIC Samsung S2MPS11"
+       depends on DM_PMIC
+       ---help---
+       The Samsung S2MPS11 PMIC provides:
+        - 38 adjustable LDO regulators
+        - 9 High-Efficiency Buck Converters
+        - 1 BuckBoost Converter
+        - RTC with two alarms
+        - Backup battery charger
+        - I2C Configuration Interface
+       This driver provides access to I/O interface only.
+       Binding info: doc/device-tree-bindings/pmic/s2mps11.txt
+
  config DM_PMIC_SANDBOX
         bool "Enable Driver Model for emulated Sandbox PMIC "
         depends on DM_PMIC
drivers/power/pmic/Makefile +1 -0
index 99c5778..1b58d98 100644
@@ -8,6 +8,7 @@
  obj-$(CONFIG_DM_PMIC) += pmic-uclass.o
  obj-$(CONFIG_DM_PMIC_MAX77686) += max77686.o
  obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze100.o
+obj-$(CONFIG_DM_PMIC_S2MPS11) += s2mps11.o
  obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o
  obj-$(CONFIG_PMIC_TPS65090) += tps65090.o
  obj-$(CONFIG_PMIC_S5M8767) += s5m8767.o
drivers/power/pmic/s2mps11.c new file +60 -0
new file mode 100644
index 0000000..7e28402
@@ -0,0 +1,60 @@
+/*
+ *  Copyright (C) 2015 Samsung Electronics
+ *  Przemyslaw Marczak  <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <errno.h>
+#include <dm.h>
+#include <i2c.h>
+#include <power/pmic.h>
+#include <power/s2mps11.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int s2mps11_reg_count(struct udevice *dev)
+{
+       return S2MPS11_REG_COUNT;
+}
+
+static int s2mps11_write(struct udevice *dev, uint reg, const uint8_t *buff,
+                        int len)
+{
+       if (dm_i2c_write(dev, reg, buff, len)) {
+               error("write error to device: %p register: %#x!", dev, reg);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int s2mps11_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
+{
+       if (dm_i2c_read(dev, reg, buff, len)) {
+               error("read error from device: %p register: %#x!", dev, reg);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static struct dm_pmic_ops s2mps11_ops = {
+       .reg_count = s2mps11_reg_count,
+       .read = s2mps11_read,
+       .write = s2mps11_write,
+};
+
+static const struct udevice_id s2mps11_ids[] = {
+       { .compatible = "samsung,s2mps11-pmic" },
+       { }
+};
+
+U_BOOT_DRIVER(pmic_s2mps11) = {
+       .name = "s2mps11_pmic",
+       .id = UCLASS_PMIC,
+       .of_match = s2mps11_ids,
+       .ops = &s2mps11_ops,
+};
include/power/s2mps11.h +0 -0
Quoted 9 lines

include/power/s2mps11.h line 1

Quoted 6 lines

new file mode 100644
index 0000000..885a816

include/power/s2mps11.h new file +1 -0
@@ -0,0 +1,109 @@
+#ifndef __INCLUDE__S2MPS11__H__

nit: I don't think you need __INCLUDE__ here

ok, will remove.

Quoted 106 lines
Quoted 106 lines
include/power/s2mps11.h new file +106 -0
+#define __INCLUDE__S2MPS11__H__
+
+enum s2mps11_reg {
+       S2MPS11_REG_ID = 0,
+       S2MPS11_REG_INT1,
+       S2MPS11_REG_INT2,
+       S2MPS11_REG_INT3,
+       S2MPS11_REG_INT1M,
+       S2MPS11_REG_INT2M,
+       S2MPS11_REG_INT3M,
+       S2MPS11_REG_STATUS1,
+       S2MPS11_REG_STATUS2,
+       S2MPS11_REG_OFFSRC,
+       S2MPS11_REG_PWRONSRC,
+       S2MPS11_REG_RTC_CTRL,
+       S2MPS11_REG_CTRL1,
+       S2MPS11_REG_ETC_TEST,
+       S2MPS11_REG_RSVD3,
+       S2MPS11_REG_BU_CHG,
+       S2MPS11_REG_RAMP,
+       S2MPS11_REG_RAMP_BUCK,
+       S2MPS11_REG_LDO1_8,
+       S2MPS11_REG_LDO9_16,
+       S2MPS11_REG_LDO17_24,
+       S2MPS11_REG_LDO25_32,
+       S2MPS11_REG_LDO33_38,
+       S2MPS11_REG_LDO1_8_OVC,
+       S2MPS11_REG_LDO9_16_OVC,
+       S2MPS11_REG_LDO17_24_OVC,
+       S2MPS11_REG_LDO25_32_OVC,
+       S2MPS11_REG_LDO33_38_OVC,
+       S2MPS11_REG_RESERVED1,
+       S2MPS11_REG_RESERVED2,
+       S2MPS11_REG_RESERVED3,
+       S2MPS11_REG_RESERVED4,
+       S2MPS11_REG_RESERVED5,
+       S2MPS11_REG_RESERVED6,
+       S2MPS11_REG_RESERVED7,
+       S2MPS11_REG_RESERVED8,
+       S2MPS11_REG_WDRSTEN_CTRL,
+       S2MPS11_REG_B1CTRL1,
+       S2MPS11_REG_B1CTRL2,
+       S2MPS11_REG_B2CTRL1,
+       S2MPS11_REG_B2CTRL2,
+       S2MPS11_REG_B3CTRL1,
+       S2MPS11_REG_B3CTRL2,
+       S2MPS11_REG_B4CTRL1,
+       S2MPS11_REG_B4CTRL2,
+       S2MPS11_REG_B5CTRL1,
+       S2MPS11_REG_BUCK5_SW,
+       S2MPS11_REG_B5CTRL2,
+       S2MPS11_REG_B5CTRL3,
+       S2MPS11_REG_B5CTRL4,
+       S2MPS11_REG_B5CTRL5,
+       S2MPS11_REG_B6CTRL1,
+       S2MPS11_REG_B6CTRL2,
+       S2MPS11_REG_B7CTRL1,
+       S2MPS11_REG_B7CTRL2,
+       S2MPS11_REG_B8CTRL1,
+       S2MPS11_REG_B8CTRL2,
+       S2MPS11_REG_B9CTRL1,
+       S2MPS11_REG_B9CTRL2,
+       S2MPS11_REG_B10CTRL1,
+       S2MPS11_REG_B10CTRL2,
+       S2MPS11_REG_L1CTRL,
+       S2MPS11_REG_L2CTRL,
+       S2MPS11_REG_L3CTRL,
+       S2MPS11_REG_L4CTRL,
+       S2MPS11_REG_L5CTRL,
+       S2MPS11_REG_L6CTRL,
+       S2MPS11_REG_L7CTRL,
+       S2MPS11_REG_L8CTRL,
+       S2MPS11_REG_L9CTRL,
+       S2MPS11_REG_L10CTRL,
+       S2MPS11_REG_L11CTRL,
+       S2MPS11_REG_L12CTRL,
+       S2MPS11_REG_L13CTRL,
+       S2MPS11_REG_L14CTRL,
+       S2MPS11_REG_L15CTRL,
+       S2MPS11_REG_L16CTRL,
+       S2MPS11_REG_L17CTRL,
+       S2MPS11_REG_L18CTRL,
+       S2MPS11_REG_L19CTRL,
+       S2MPS11_REG_L20CTRL,
+       S2MPS11_REG_L21CTRL,
+       S2MPS11_REG_L22CTRL,
+       S2MPS11_REG_L23CTRL,
+       S2MPS11_REG_L24CTRL,
+       S2MPS11_REG_L25CTRL,
+       S2MPS11_REG_L26CTRL,
+       S2MPS11_REG_L27CTRL,
+       S2MPS11_REG_L28CTRL,
+       S2MPS11_REG_L29CTRL,
+       S2MPS11_REG_L30CTRL,
+       S2MPS11_REG_L31CTRL,
+       S2MPS11_REG_L32CTRL,
+       S2MPS11_REG_L33CTRL,
+       S2MPS11_REG_L34CTRL,
+       S2MPS11_REG_L35CTRL,
+       S2MPS11_REG_L36CTRL,
+       S2MPS11_REG_L37CTRL,
+       S2MPS11_REG_L38CTRL,
+       S2MPS11_REG_COUNT,
+};
+
+#define S2MPS11_LDO26_ENABLE   0xec
Quoted 9 lines
Quoted 5 lines
include/power/s2mps11.h new file +2 -1
+
+#endif
--

1.9.1

Regards,
Simon

Thanks,

Signature · 4 lines
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com
#10 lore raw

PATCH 4/7 dm: pmic: add s2mps11 PMIC I/O driver

In reply to Przemyslaw Marczak

Dear Przemyslaw Marczak,

Just some minor comment,

Quoted 29 lines · Przemyslaw Marczak

This driver allows I/O operations on the Samsung S2MPS11 PMIC, which provides lots of LDO/BUCK outputs.

To enable it, update defconfig with:
- CONFIG_DM_PMIC_S2MPS11
and additional, if were not defined:
- CONFIG_CMD_PMIC
- CONFIG_ERRNO_STR

The binding info: doc/device-tree-bindings/pmic/s2mps11.txt

---
 doc/device-tree-bindings/pmic/s2mps11.txt |  17 +++++
 drivers/power/pmic/Kconfig                |  14 ++++
 drivers/power/pmic/Makefile               |   1 +
 drivers/power/pmic/s2mps11.c              |  60 ++++++++++++++++
 include/power/s2mps11.h                   | 109 ++++++++++++++++++++++++++++++
 5 files changed, 201 insertions(+)
 create mode 100644 doc/device-tree-bindings/pmic/s2mps11.txt
 create mode 100644 drivers/power/pmic/s2mps11.c
 create mode 100644 include/power/s2mps11.h
doc/device-tree-bindings/pmic/s2mps11.txt new file +0 -0
new file mode 100644
index 0000000..db8d624

doc/device-tree-bindings/pmic/s2mps11.txt line 1

Quoted 1 line
doc/device-tree-bindings/pmic/s2mps11.txt new file +1 -0
@@ -0,0 +1,17 @@
+SAMSUBNG, S2MPS11 PMIC

SAMSUNG?

Quoted 225 lines
doc/device-tree-bindings/pmic/s2mps11.txt new file +16 -0
+
+This file describes the binding info for the PMIC driver:
+- drivers/power/pmic/s2mps11.c
+
+Required properties:
+- compatible: "samsung,s2mps11-pmic"
+- reg = 0x66
+
+With those two properties, the pmic device can be used for read/write only.
+
+Example:
+
+s2mps11 at 66 {
+	compatible = "samsung,s2mps11-pmic";
+	reg = <0x66>;
+};
drivers/power/pmic/Kconfig +14 -0
index fc6a374..c66b352 100644
@@ -24,6 +24,20 @@ config DM_PMIC_MAX77686
 	This config enables implementation of driver-model pmic uclass features
 	for PMIC MAX77686. The driver implements read/write operations.
 
+config DM_PMIC_S2MPS11
+	bool "Enable Driver Model for PMIC Samsung S2MPS11"
+	depends on DM_PMIC
+	---help---
+	The Samsung S2MPS11 PMIC provides:
+	 - 38 adjustable LDO regulators
+	 - 9 High-Efficiency Buck Converters
+	 - 1 BuckBoost Converter
+	 - RTC with two alarms
+	 - Backup battery charger
+	 - I2C Configuration Interface
+	This driver provides access to I/O interface only.
+	Binding info: doc/device-tree-bindings/pmic/s2mps11.txt
+
 config DM_PMIC_SANDBOX
 	bool "Enable Driver Model for emulated Sandbox PMIC "
 	depends on DM_PMIC
drivers/power/pmic/Makefile +1 -0
index 99c5778..1b58d98 100644
@@ -8,6 +8,7 @@
 obj-$(CONFIG_DM_PMIC) += pmic-uclass.o
 obj-$(CONFIG_DM_PMIC_MAX77686) += max77686.o
 obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze100.o
+obj-$(CONFIG_DM_PMIC_S2MPS11) += s2mps11.o
 obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o
 obj-$(CONFIG_PMIC_TPS65090) += tps65090.o
 obj-$(CONFIG_PMIC_S5M8767) += s5m8767.o
drivers/power/pmic/s2mps11.c new file +60 -0
new file mode 100644
index 0000000..7e28402
@@ -0,0 +1,60 @@
+/*
+ *  Copyright (C) 2015 Samsung Electronics
+ *  Przemyslaw Marczak  <[email protected]>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <errno.h>
+#include <dm.h>
+#include <i2c.h>
+#include <power/pmic.h>
+#include <power/s2mps11.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int s2mps11_reg_count(struct udevice *dev)
+{
+	return S2MPS11_REG_COUNT;
+}
+
+static int s2mps11_write(struct udevice *dev, uint reg, const uint8_t *buff,
+			 int len)
+{
+	if (dm_i2c_write(dev, reg, buff, len)) {
+		error("write error to device: %p register: %#x!", dev, reg);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int s2mps11_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
+{
+	if (dm_i2c_read(dev, reg, buff, len)) {
+		error("read error from device: %p register: %#x!", dev, reg);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static struct dm_pmic_ops s2mps11_ops = {
+	.reg_count = s2mps11_reg_count,
+	.read = s2mps11_read,
+	.write = s2mps11_write,
+};
+
+static const struct udevice_id s2mps11_ids[] = {
+	{ .compatible = "samsung,s2mps11-pmic" },
+	{ }
+};
+
+U_BOOT_DRIVER(pmic_s2mps11) = {
+	.name = "s2mps11_pmic",
+	.id = UCLASS_PMIC,
+	.of_match = s2mps11_ids,
+	.ops = &s2mps11_ops,
+};
include/power/s2mps11.h new file +99 -0
new file mode 100644
index 0000000..885a816
@@ -0,0 +1,109 @@
+#ifndef __INCLUDE__S2MPS11__H__
+#define __INCLUDE__S2MPS11__H__
+
+enum s2mps11_reg {
+	S2MPS11_REG_ID = 0,
+	S2MPS11_REG_INT1,
+	S2MPS11_REG_INT2,
+	S2MPS11_REG_INT3,
+	S2MPS11_REG_INT1M,
+	S2MPS11_REG_INT2M,
+	S2MPS11_REG_INT3M,
+	S2MPS11_REG_STATUS1,
+	S2MPS11_REG_STATUS2,
+	S2MPS11_REG_OFFSRC,
+	S2MPS11_REG_PWRONSRC,
+	S2MPS11_REG_RTC_CTRL,
+	S2MPS11_REG_CTRL1,
+	S2MPS11_REG_ETC_TEST,
+	S2MPS11_REG_RSVD3,
+	S2MPS11_REG_BU_CHG,
+	S2MPS11_REG_RAMP,
+	S2MPS11_REG_RAMP_BUCK,
+	S2MPS11_REG_LDO1_8,
+	S2MPS11_REG_LDO9_16,
+	S2MPS11_REG_LDO17_24,
+	S2MPS11_REG_LDO25_32,
+	S2MPS11_REG_LDO33_38,
+	S2MPS11_REG_LDO1_8_OVC,
+	S2MPS11_REG_LDO9_16_OVC,
+	S2MPS11_REG_LDO17_24_OVC,
+	S2MPS11_REG_LDO25_32_OVC,
+	S2MPS11_REG_LDO33_38_OVC,
+	S2MPS11_REG_RESERVED1,
+	S2MPS11_REG_RESERVED2,
+	S2MPS11_REG_RESERVED3,
+	S2MPS11_REG_RESERVED4,
+	S2MPS11_REG_RESERVED5,
+	S2MPS11_REG_RESERVED6,
+	S2MPS11_REG_RESERVED7,
+	S2MPS11_REG_RESERVED8,
+	S2MPS11_REG_WDRSTEN_CTRL,
+	S2MPS11_REG_B1CTRL1,
+	S2MPS11_REG_B1CTRL2,
+	S2MPS11_REG_B2CTRL1,
+	S2MPS11_REG_B2CTRL2,
+	S2MPS11_REG_B3CTRL1,
+	S2MPS11_REG_B3CTRL2,
+	S2MPS11_REG_B4CTRL1,
+	S2MPS11_REG_B4CTRL2,
+	S2MPS11_REG_B5CTRL1,
+	S2MPS11_REG_BUCK5_SW,
+	S2MPS11_REG_B5CTRL2,
+	S2MPS11_REG_B5CTRL3,
+	S2MPS11_REG_B5CTRL4,
+	S2MPS11_REG_B5CTRL5,
+	S2MPS11_REG_B6CTRL1,
+	S2MPS11_REG_B6CTRL2,
+	S2MPS11_REG_B7CTRL1,
+	S2MPS11_REG_B7CTRL2,
+	S2MPS11_REG_B8CTRL1,
+	S2MPS11_REG_B8CTRL2,
+	S2MPS11_REG_B9CTRL1,
+	S2MPS11_REG_B9CTRL2,
+	S2MPS11_REG_B10CTRL1,
+	S2MPS11_REG_B10CTRL2,
+	S2MPS11_REG_L1CTRL,
+	S2MPS11_REG_L2CTRL,
+	S2MPS11_REG_L3CTRL,
+	S2MPS11_REG_L4CTRL,
+	S2MPS11_REG_L5CTRL,
+	S2MPS11_REG_L6CTRL,
+	S2MPS11_REG_L7CTRL,
+	S2MPS11_REG_L8CTRL,
+	S2MPS11_REG_L9CTRL,
+	S2MPS11_REG_L10CTRL,
+	S2MPS11_REG_L11CTRL,
+	S2MPS11_REG_L12CTRL,
+	S2MPS11_REG_L13CTRL,
+	S2MPS11_REG_L14CTRL,
+	S2MPS11_REG_L15CTRL,
+	S2MPS11_REG_L16CTRL,
+	S2MPS11_REG_L17CTRL,
+	S2MPS11_REG_L18CTRL,
+	S2MPS11_REG_L19CTRL,
+	S2MPS11_REG_L20CTRL,
+	S2MPS11_REG_L21CTRL,
+	S2MPS11_REG_L22CTRL,
+	S2MPS11_REG_L23CTRL,
+	S2MPS11_REG_L24CTRL,
+	S2MPS11_REG_L25CTRL,
+	S2MPS11_REG_L26CTRL,
+	S2MPS11_REG_L27CTRL,
+	S2MPS11_REG_L28CTRL,
+	S2MPS11_REG_L29CTRL,
+	S2MPS11_REG_L30CTRL,
+	S2MPS11_REG_L31CTRL,
+	S2MPS11_REG_L32CTRL,
+	S2MPS11_REG_L33CTRL,
+	S2MPS11_REG_L34CTRL,

include/power/s2mps11.h line 109

Quoted 10 lines
include/power/s2mps11.h new file +10 -0
+	S2MPS11_REG_L35CTRL,
+	S2MPS11_REG_L36CTRL,
+	S2MPS11_REG_L37CTRL,
+	S2MPS11_REG_L38CTRL,
+	S2MPS11_REG_COUNT,
+};
+
+#define S2MPS11_LDO26_ENABLE	0xec
+
+#endif

Thanks,
Minkyu Kang.

#11 lore raw

PATCH 4/7 dm: pmic: add s2mps11 PMIC I/O driver

Hello Minkyu,

Quoted 28 lines · Minkyu Kang

Dear Przemyslaw Marczak,

Just some minor comment,

Quoted 23 lines · Przemyslaw Marczak

This driver allows I/O operations on the Samsung S2MPS11 PMIC, which provides lots of LDO/BUCK outputs.

To enable it, update defconfig with:
- CONFIG_DM_PMIC_S2MPS11
and additional, if were not defined:
- CONFIG_CMD_PMIC
- CONFIG_ERRNO_STR

The binding info: doc/device-tree-bindings/pmic/s2mps11.txt

---
  doc/device-tree-bindings/pmic/s2mps11.txt |  17 +++++
  drivers/power/pmic/Kconfig                |  14 ++++
  drivers/power/pmic/Makefile               |   1 +
  drivers/power/pmic/s2mps11.c              |  60 ++++++++++++++++
  include/power/s2mps11.h                   | 109 ++++++++++++++++++++++++++++++
  5 files changed, 201 insertions(+)

create mode 100644 doc/device-tree-bindings/pmic/s2mps11.txt create mode 100644 drivers/power/pmic/s2mps11.c create mode 100644 include/power/s2mps11.h

Quoted 10 lines

doc/device-tree-bindings/pmic/s2mps11.txt line 1

Quoted 7 lines
doc/device-tree-bindings/pmic/s2mps11.txt new file +1 -0
new file mode 100644
index 0000000..db8d624
@@ -0,0 +1,17 @@
+SAMSUBNG, S2MPS11 PMIC

SAMSUNG?

Right, will fix.

Quoted 230 lines
Quoted 230 lines
doc/device-tree-bindings/pmic/s2mps11.txt new file +16 -0
+
+This file describes the binding info for the PMIC driver:
+- drivers/power/pmic/s2mps11.c
+
+Required properties:
+- compatible: "samsung,s2mps11-pmic"
+- reg = 0x66
+
+With those two properties, the pmic device can be used for read/write only.
+
+Example:
+
+s2mps11 at 66 {
+	compatible = "samsung,s2mps11-pmic";
+	reg = <0x66>;
+};
drivers/power/pmic/Kconfig +14 -0
index fc6a374..c66b352 100644
@@ -24,6 +24,20 @@ config DM_PMIC_MAX77686
  	This config enables implementation of driver-model pmic uclass features
  	for PMIC MAX77686. The driver implements read/write operations.
 
+config DM_PMIC_S2MPS11
+	bool "Enable Driver Model for PMIC Samsung S2MPS11"
+	depends on DM_PMIC
+	---help---
+	The Samsung S2MPS11 PMIC provides:
+	 - 38 adjustable LDO regulators
+	 - 9 High-Efficiency Buck Converters
+	 - 1 BuckBoost Converter
+	 - RTC with two alarms
+	 - Backup battery charger
+	 - I2C Configuration Interface
+	This driver provides access to I/O interface only.
+	Binding info: doc/device-tree-bindings/pmic/s2mps11.txt
+
  config DM_PMIC_SANDBOX
  	bool "Enable Driver Model for emulated Sandbox PMIC "
  	depends on DM_PMIC
drivers/power/pmic/Makefile +1 -0
index 99c5778..1b58d98 100644
@@ -8,6 +8,7 @@
  obj-$(CONFIG_DM_PMIC) += pmic-uclass.o
  obj-$(CONFIG_DM_PMIC_MAX77686) += max77686.o
  obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze100.o
+obj-$(CONFIG_DM_PMIC_S2MPS11) += s2mps11.o
  obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o
  obj-$(CONFIG_PMIC_TPS65090) += tps65090.o
  obj-$(CONFIG_PMIC_S5M8767) += s5m8767.o
drivers/power/pmic/s2mps11.c new file +60 -0
new file mode 100644
index 0000000..7e28402
@@ -0,0 +1,60 @@
+/*
+ *  Copyright (C) 2015 Samsung Electronics
+ *  Przemyslaw Marczak  <[email protected]>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <errno.h>
+#include <dm.h>
+#include <i2c.h>
+#include <power/pmic.h>
+#include <power/s2mps11.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int s2mps11_reg_count(struct udevice *dev)
+{
+	return S2MPS11_REG_COUNT;
+}
+
+static int s2mps11_write(struct udevice *dev, uint reg, const uint8_t *buff,
+			 int len)
+{
+	if (dm_i2c_write(dev, reg, buff, len)) {
+		error("write error to device: %p register: %#x!", dev, reg);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int s2mps11_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
+{
+	if (dm_i2c_read(dev, reg, buff, len)) {
+		error("read error from device: %p register: %#x!", dev, reg);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static struct dm_pmic_ops s2mps11_ops = {
+	.reg_count = s2mps11_reg_count,
+	.read = s2mps11_read,
+	.write = s2mps11_write,
+};
+
+static const struct udevice_id s2mps11_ids[] = {
+	{ .compatible = "samsung,s2mps11-pmic" },
+	{ }
+};
+
+U_BOOT_DRIVER(pmic_s2mps11) = {
+	.name = "s2mps11_pmic",
+	.id = UCLASS_PMIC,
+	.of_match = s2mps11_ids,
+	.ops = &s2mps11_ops,
+};
include/power/s2mps11.h new file +105 -0
new file mode 100644
index 0000000..885a816
@@ -0,0 +1,109 @@
+#ifndef __INCLUDE__S2MPS11__H__
+#define __INCLUDE__S2MPS11__H__
+
+enum s2mps11_reg {
+	S2MPS11_REG_ID = 0,
+	S2MPS11_REG_INT1,
+	S2MPS11_REG_INT2,
+	S2MPS11_REG_INT3,
+	S2MPS11_REG_INT1M,
+	S2MPS11_REG_INT2M,
+	S2MPS11_REG_INT3M,
+	S2MPS11_REG_STATUS1,
+	S2MPS11_REG_STATUS2,
+	S2MPS11_REG_OFFSRC,
+	S2MPS11_REG_PWRONSRC,
+	S2MPS11_REG_RTC_CTRL,
+	S2MPS11_REG_CTRL1,
+	S2MPS11_REG_ETC_TEST,
+	S2MPS11_REG_RSVD3,
+	S2MPS11_REG_BU_CHG,
+	S2MPS11_REG_RAMP,
+	S2MPS11_REG_RAMP_BUCK,
+	S2MPS11_REG_LDO1_8,
+	S2MPS11_REG_LDO9_16,
+	S2MPS11_REG_LDO17_24,
+	S2MPS11_REG_LDO25_32,
+	S2MPS11_REG_LDO33_38,
+	S2MPS11_REG_LDO1_8_OVC,
+	S2MPS11_REG_LDO9_16_OVC,
+	S2MPS11_REG_LDO17_24_OVC,
+	S2MPS11_REG_LDO25_32_OVC,
+	S2MPS11_REG_LDO33_38_OVC,
+	S2MPS11_REG_RESERVED1,
+	S2MPS11_REG_RESERVED2,
+	S2MPS11_REG_RESERVED3,
+	S2MPS11_REG_RESERVED4,
+	S2MPS11_REG_RESERVED5,
+	S2MPS11_REG_RESERVED6,
+	S2MPS11_REG_RESERVED7,
+	S2MPS11_REG_RESERVED8,
+	S2MPS11_REG_WDRSTEN_CTRL,
+	S2MPS11_REG_B1CTRL1,
+	S2MPS11_REG_B1CTRL2,
+	S2MPS11_REG_B2CTRL1,
+	S2MPS11_REG_B2CTRL2,
+	S2MPS11_REG_B3CTRL1,
+	S2MPS11_REG_B3CTRL2,
+	S2MPS11_REG_B4CTRL1,
+	S2MPS11_REG_B4CTRL2,
+	S2MPS11_REG_B5CTRL1,
+	S2MPS11_REG_BUCK5_SW,
+	S2MPS11_REG_B5CTRL2,
+	S2MPS11_REG_B5CTRL3,
+	S2MPS11_REG_B5CTRL4,
+	S2MPS11_REG_B5CTRL5,
+	S2MPS11_REG_B6CTRL1,
+	S2MPS11_REG_B6CTRL2,
+	S2MPS11_REG_B7CTRL1,
+	S2MPS11_REG_B7CTRL2,
+	S2MPS11_REG_B8CTRL1,
+	S2MPS11_REG_B8CTRL2,
+	S2MPS11_REG_B9CTRL1,
+	S2MPS11_REG_B9CTRL2,
+	S2MPS11_REG_B10CTRL1,
+	S2MPS11_REG_B10CTRL2,
+	S2MPS11_REG_L1CTRL,
+	S2MPS11_REG_L2CTRL,
+	S2MPS11_REG_L3CTRL,
+	S2MPS11_REG_L4CTRL,
+	S2MPS11_REG_L5CTRL,
+	S2MPS11_REG_L6CTRL,
+	S2MPS11_REG_L7CTRL,
+	S2MPS11_REG_L8CTRL,
+	S2MPS11_REG_L9CTRL,
+	S2MPS11_REG_L10CTRL,
+	S2MPS11_REG_L11CTRL,
+	S2MPS11_REG_L12CTRL,
+	S2MPS11_REG_L13CTRL,
+	S2MPS11_REG_L14CTRL,
+	S2MPS11_REG_L15CTRL,
+	S2MPS11_REG_L16CTRL,
+	S2MPS11_REG_L17CTRL,
+	S2MPS11_REG_L18CTRL,
+	S2MPS11_REG_L19CTRL,
+	S2MPS11_REG_L20CTRL,
+	S2MPS11_REG_L21CTRL,
+	S2MPS11_REG_L22CTRL,
+	S2MPS11_REG_L23CTRL,
+	S2MPS11_REG_L24CTRL,
+	S2MPS11_REG_L25CTRL,
+	S2MPS11_REG_L26CTRL,
+	S2MPS11_REG_L27CTRL,
+	S2MPS11_REG_L28CTRL,
+	S2MPS11_REG_L29CTRL,
+	S2MPS11_REG_L30CTRL,
+	S2MPS11_REG_L31CTRL,
+	S2MPS11_REG_L32CTRL,
+	S2MPS11_REG_L33CTRL,
+	S2MPS11_REG_L34CTRL,
+	S2MPS11_REG_L35CTRL,
+	S2MPS11_REG_L36CTRL,
+	S2MPS11_REG_L37CTRL,
+	S2MPS11_REG_L38CTRL,
+	S2MPS11_REG_COUNT,
+};
Quoted 9 lines

include/power/s2mps11.h line 109

Quoted 5 lines
include/power/s2mps11.h new file +4 -0
+
+#define S2MPS11_LDO26_ENABLE	0xec
+
+#endif

Thanks,
Minkyu Kang.

Best regards,

Signature · 4 lines
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com
#12 lore raw

PATCH 5/7 odroid-xu3: enable s2mps11 PMIC support

In reply to Przemyslaw Marczak
---
 arch/arm/dts/exynos5422-odroidxu3.dts | 7 +++++++
 configs/odroid-xu3_defconfig          | 3 +++
 2 files changed, 10 insertions(+)
arch/arm/dts/exynos5422-odroidxu3.dts +7 -0
index d0a8621..9dec679 100644
@@ -31,6 +31,13 @@
 			0xb0000000 0xea00000>;
 	};
 
+	i2c at 12CA0000 {
+		s2mps11_pmic at 66 {
+			compatible = "samsung,s2mps11-pmic";
+			reg = <0x66>;
+		};
+	};
+
 	ehci at 12110000 {
 		samsung,vbus-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>;
 	};
configs/odroid-xu3_defconfig +3 -0
index 9c3b6d6..ae6270b 100644
@@ -8,7 +8,10 @@ CONFIG_DEFAULT_DEVICE_TREE="exynos5422-odroidxu3"
 CONFIG_DM_I2C=y
 CONFIG_DM_I2C_COMPAT=y
 CONFIG_DM_PMIC=y
+CONFIG_CMD_PMIC=y
+CONFIG_ERRNO_STR=y
 CONFIG_DM_REGULATOR=y
+CONFIG_DM_PMIC_S2MPS11=y
 CONFIG_VIDEO_BRIDGE=y
 CONFIG_SYS_PROMPT="ODROID-XU3 # "
 CONFIG_USB=y
Signature · 1 line
1.9.1
#14 lore raw

PATCH 6/7 Exynos: add internal ADC driver

In reply to Przemyslaw Marczak

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.

---
 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
arch/arm/mach-exynos/Makefile +1 -0
index 8542f89..4b7f91f 100644
@@ -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
arch/arm/mach-exynos/adc.c new file +83 -0

83 lines not on this page · raw message

arch/arm/mach-exynos/include/mach/adc.h +45 -0

57 lines not on this page · raw message

arch/arm/mach-exynos/include/mach/cpu.h +2 -2
index 14a1692..75933e7 100644
@@ -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
 #define EXYNOS5420_UART_BASE		0x12C00000
 #define EXYNOS5420_I2C_BASE		0x12C60000
 #define EXYNOS5420_I2C_8910_BASE	0x12E00000
+#define EXYNOS5420_ADC_BASE		0x12D10000
 #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
 
Signature · 1 line
1.9.1
#15 lore raw

PATCH 6/7 Exynos: add internal ADC driver

Hi Przemyslaw,

Quoted 8 lines · Przemyslaw Marczak

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.

Quoted 8 lines
---
 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?

Quoted 170 lines
arch/arm/mach-exynos/Makefile +1 -0
index 8542f89..4b7f91f 100644
@@ -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
arch/arm/mach-exynos/adc.c new file +83 -0
new file mode 100644
index 0000000..e8dd619
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics
+ * Przemyslaw Marczak <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#include <common.h>
+#include <errno.h>
+#include <asm/arch/adc.h>
+#include <asm/arch/power.h>
+
+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;
+}
arch/arm/mach-exynos/include/mach/adc.h +45 -0
index a0e26d7..228acf4 100644
@@ -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_ */
arch/arm/mach-exynos/include/mach/cpu.h +0 -0
index 14a1692..75933e7 100644

arch/arm/mach-exynos/include/mach/cpu.h line 170

Quoted 5 lines
arch/arm/mach-exynos/include/mach/cpu.h +1 -1
@@ -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?

arch/arm/mach-exynos/include/mach/cpu.h line 174

Quoted 4 lines
arch/arm/mach-exynos/include/mach/cpu.h +1 -0
 #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.

Quoted 12 lines
arch/arm/mach-exynos/include/mach/cpu.h +0 -2
 #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
 
--
Quoted 2 lines

1.9.1

Regards,
Simon

#16 lore raw

PATCH 6/7 Exynos: add internal ADC driver

Hello,

Quoted 20 lines · Simon Glass

Hi Przemyslaw,

Quoted 8 lines · Przemyslaw Marczak

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.

Quoted 8 lines
---
  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

Quoted 3 lines

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.

Quoted 164 lines
Quoted 164 lines
arch/arm/mach-exynos/Makefile +1 -0
index 8542f89..4b7f91f 100644
@@ -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
arch/arm/mach-exynos/adc.c new file +83 -0
new file mode 100644
index 0000000..e8dd619
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics
+ * Przemyslaw Marczak <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#include <common.h>
+#include <errno.h>
+#include <asm/arch/adc.h>
+#include <asm/arch/power.h>
+
+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;
+}
arch/arm/mach-exynos/include/mach/adc.h +45 -0
index a0e26d7..228acf4 100644
@@ -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
 
Quoted 14 lines

arch/arm/mach-exynos/include/mach/cpu.h line 170

Quoted 11 lines
arch/arm/mach-exynos/include/mach/adc.h +0 -0
  #endif /* __ASM_ARM_ARCH_ADC_H_ */
arch/arm/mach-exynos/include/mach/cpu.h +1 -1
index 14a1692..75933e7 100644
@@ -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.

Quoted 7 lines

arch/arm/mach-exynos/include/mach/cpu.h line 174

Quoted 4 lines
arch/arm/mach-exynos/include/mach/cpu.h +1 -0
  #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

Quoted 11 lines
Quoted 11 lines
arch/arm/mach-exynos/include/mach/cpu.h +0 -1
  #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
 
Quoted 7 lines
Quoted 3 lines

--
1.9.1

Regards,
Simon

Thanks,

Signature · 4 lines
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com
#17 lore raw

PATCH 7/7 exynos5-dt: add board detection for Odroid XU3/XU3L/XU4.

In reply to Przemyslaw Marczak

There are few revisions of Odroid XU3/XU4:

 Rev   ADC   Board
 0.1     0   XU3 0.1
 0.2   372   XU3 0.2 | XU3L - no DISPLAYPORT
 0.3   739   XU4 0.1

This commit adds implementation of functions:
- set_board_type() - read ADC and set type
- get_board_rev() - returns board revision: 1..3
- board_is_odroidxu3() - returns bool
- board_is_odroidxu4() - returns bool
- get_board_type() - returns board type string

After I2C controller init, the last function can check if the board is "Lite" variant for XU3, by probing chip 0x40 on I2C0 (INA231 - exists only on non-lite). This is useful for setting fdt file name at misc_init_r().

The enabled configs:
- CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
- CONFIG_ODROID_REV_AIN
- CONFIG_REVISION_TAG
- CONFIG_MISC_INIT_R
- CONFIG_BOARD_TYPES

This also redefines CONFIG_SYS_BOARD to "odroid".

---
 board/samsung/common/exynos5-dt.c | 114 ++++++++++++++++++++++++++++++++++++++
 include/configs/odroid_xu3.h      |  12 ++++
 2 files changed, 126 insertions(+)
board/samsung/common/exynos5-dt.c +114 -0
index 7d1b88a..41141df 100644
@@ -18,6 +18,7 @@
 #include <usb.h>
 #include <video_bridge.h>
 #include <asm/gpio.h>
+#include <asm/arch/adc.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/dwmmc.h>
 #include <asm/arch/mmc.h>
@@ -28,6 +29,7 @@
 #include <power/max77686_pmic.h>
 #include <power/regulator.h>
 #include <power/s5m8767.h>
+#include <power/s2mps11.h>
 #include <tmu.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -360,3 +362,115 @@ char *get_dfu_alt_boot(char *interface, char *devstr)
 	return alt_boot;
 }
 #endif
+
+#ifdef CONFIG_REVISION_TAG
+/**
+ * Odroix XU3/4 board revisions:
+ * Rev   ADC   Board
+ * 0.1     0   XU3 0.1
+ * 0.2   372   XU3 0.2 | XU3L - no DISPLAYPORT (probe I2C0:0x40 / INA231)
+ * 0.3   739   XU4 0.1
+ * Use +/-20 for ADC value tolerance.
+ */
+enum {
+	ODROID_XU3_REV01,
+	ODROID_XU3_REV02,
+	ODROID_XU4_REV01,
+	ODROID_UNKNOWN_REV,
+	ODROID_REV_COUNT,
+};
+
+struct odroid_type {
+	int board_type;
+	int rev;
+	int adc_val;
+	const char *name;
+};
+
+struct odroid_type odroid_type[] = {
+	{ ODROID_XU3_REV01, 1, 0, "xu3" },
+	{ ODROID_XU3_REV02, 2, 372, "xu3" },
+	{ ODROID_XU4_REV01, 1, 739, "xu4" },
+	{ ODROID_UNKNOWN_REV, 0, 4095, "unknown" },
+};
+
+bool board_is_odroidxu3(void)
+{
+	if (gd->board_type < ODROID_XU4_REV01)
+		return true;
+
+	return false;
+}
+
+bool board_is_odroidxu4(void)
+{
+	if (gd->board_type > ODROID_XU3_REV02)
+		return true;
+
+	return false;
+}
+
+int set_board_type(void)
+{
+	int adcval, i;
+
+	adcval = exynos_adc_read_channel(CONFIG_ODROID_REV_AIN);
+	if (adcval < 0)
+		return adcval;
+
+	for (i = 0; i < ODROID_REV_COUNT; i++) {
+		/* ADC tolerance: +20 */
+		if (adcval < odroid_type[i].adc_val + 20) {
+			gd->board_type = i;
+			return i;
+		}
+	}
+
+	return ODROID_UNKNOWN_REV;
+}
+
+int get_board_rev(void)
+{
+	return odroid_type[gd->board_type].rev;
+}
+
+/**
+ * get_board_type - returns pointer to one of the board type string.
+ * Board types: "xu3", "xu3-lite", "xu4". However the "xu3itel" can be
+ * detected only when the i2c controller is ready to use. Fortunately,
+ * XU3 and XU3L are compatible, and the information about board lite
+ * revision is needed before boot linux, to set proper environment
+ * variable: $fdtfile.
+ */
+const char *get_board_type(void)
+{
+	const char *type_xu3l = "xu3-lite";
+	struct udevice *dev, *chip;
+	int ret;
+
+	if (gd->board_type != ODROID_XU3_REV02)
+		goto exit;
+
+	ret = pmic_get("s2mps11", &dev);
+	if (ret)
+		goto exit;
+
+	/* Enable LDO26: 3.0V */
+	ret = pmic_reg_write(dev, S2MPS11_REG_L26CTRL,
+			     S2MPS11_LDO26_ENABLE);
+	if (ret)
+		goto exit;
+
+	/* Check XU3Lite by probe INA231 I2C0:0x40 */
+	ret = uclass_get_device(UCLASS_I2C, 0, &dev);
+	if (ret)
+		goto exit;
+
+	ret = dm_i2c_probe(dev, 0x40, 0x0, &chip);
+	if (ret)
+		return type_xu3l;
+
+exit:
+	return odroid_type[gd->board_type].name;
+}
+#endif
include/configs/odroid_xu3.h +12 -0
index 3c70158..648e48b 100644
@@ -94,6 +94,8 @@
 	"boot.scr fat 0 1;"                 \
 	"boot.cmd fat 0 1;"                 \
 	"exynos5422-odroidxu3.dtb fat 0 1;" \
+	"exynos5422-odroidxu3-lite.dtb fat 0 1;" \
+	"exynos5422-odroidxu4.dtb fat 0 1;" \
 	"boot part 0 1;"                    \
 	"root part 0 2\0"
 
@@ -113,9 +115,19 @@
 
 /* Enable: board/samsung/common/misc.c to use set_dfu_alt_info() */
 #define CONFIG_MISC_COMMON
+#define CONFIG_MISC_INIT_R
 #define CONFIG_SET_DFU_ALT_INFO
 #define CONFIG_SET_DFU_ALT_BUF_LEN	(SZ_1K)
 
+/* Set soc_rev, soc_id, board_rev, boardname, fdtfile */
+#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
+#define CONFIG_ODROID_REV_AIN			9
+#define CONFIG_REVISION_TAG
+#define CONFIG_BOARD_TYPES
+
+#undef CONFIG_SYS_BOARD
+#define CONFIG_SYS_BOARD	"odroid"
+
 /* Define new extra env settings, including DFU settings */
 #undef CONFIG_EXTRA_ENV_SETTINGS
 #define CONFIG_EXTRA_ENV_SETTINGS \
Signature · 1 line
1.9.1
#18 lore raw

PATCH 7/7 exynos5-dt: add board detection for Odroid XU3/XU3L/XU4.

Hi Przemyslaw,

Quoted 54 lines · Przemyslaw Marczak

There are few revisions of Odroid XU3/XU4:

 Rev   ADC   Board
 0.1     0   XU3 0.1
 0.2   372   XU3 0.2 | XU3L - no DISPLAYPORT
 0.3   739   XU4 0.1

This commit adds implementation of functions:
- set_board_type() - read ADC and set type
- get_board_rev() - returns board revision: 1..3
- board_is_odroidxu3() - returns bool
- board_is_odroidxu4() - returns bool
- get_board_type() - returns board type string

After I2C controller init, the last function can check if the board is "Lite" variant for XU3, by probing chip 0x40 on I2C0 (INA231 - exists only on non-lite). This is useful for setting fdt file name at misc_init_r().

The enabled configs:
- CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
- CONFIG_ODROID_REV_AIN
- CONFIG_REVISION_TAG
- CONFIG_MISC_INIT_R
- CONFIG_BOARD_TYPES

This also redefines CONFIG_SYS_BOARD to "odroid".

---
 board/samsung/common/exynos5-dt.c | 114 ++++++++++++++++++++++++++++++++++++++
 include/configs/odroid_xu3.h      |  12 ++++
 2 files changed, 126 insertions(+)
board/samsung/common/exynos5-dt.c +2 -0
index 7d1b88a..41141df 100644
@@ -18,6 +18,7 @@
 #include <usb.h>
 #include <video_bridge.h>
 #include <asm/gpio.h>
+#include <asm/arch/adc.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/dwmmc.h>
 #include <asm/arch/mmc.h>
@@ -28,6 +29,7 @@
 #include <power/max77686_pmic.h>
 #include <power/regulator.h>
 #include <power/s5m8767.h>
+#include <power/s2mps11.h>
 #include <tmu.h>
 
 DECLARE_GLOBAL_DATA_PTR;

board/samsung/common/exynos5-dt.c char *get_dfu_alt_boot(char *interface, char *devstr) · line 366

Quoted 5 lines
board/samsung/common/exynos5-dt.c +2 -0
@@ -360,3 +362,115 @@ char *get_dfu_alt_boot(char *interface, char *devstr)
        return alt_boot;
 }
 #endif
+
+#ifdef CONFIG_REVISION_TAG

Can we check the compatible string instead? It would be good to avoid #ifdef in common code.

Quoted 144 lines
board/samsung/common/exynos5-dt.c +110 -0
+/**
+ * Odroix XU3/4 board revisions:
+ * Rev   ADC   Board
+ * 0.1     0   XU3 0.1
+ * 0.2   372   XU3 0.2 | XU3L - no DISPLAYPORT (probe I2C0:0x40 / INA231)
+ * 0.3   739   XU4 0.1
+ * Use +/-20 for ADC value tolerance.
+ */
+enum {
+       ODROID_XU3_REV01,
+       ODROID_XU3_REV02,
+       ODROID_XU4_REV01,
+       ODROID_UNKNOWN_REV,
+       ODROID_REV_COUNT,
+};
+
+struct odroid_type {
+       int board_type;
+       int rev;
+       int adc_val;
+       const char *name;
+};
+
+struct odroid_type odroid_type[] = {
+       { ODROID_XU3_REV01, 1, 0, "xu3" },
+       { ODROID_XU3_REV02, 2, 372, "xu3" },
+       { ODROID_XU4_REV01, 1, 739, "xu4" },
+       { ODROID_UNKNOWN_REV, 0, 4095, "unknown" },
+};
+
+bool board_is_odroidxu3(void)
+{
+       if (gd->board_type < ODROID_XU4_REV01)
+               return true;
+
+       return false;
+}
+
+bool board_is_odroidxu4(void)
+{
+       if (gd->board_type > ODROID_XU3_REV02)
+               return true;
+
+       return false;
+}
+
+int set_board_type(void)
+{
+       int adcval, i;
+
+       adcval = exynos_adc_read_channel(CONFIG_ODROID_REV_AIN);
+       if (adcval < 0)
+               return adcval;
+
+       for (i = 0; i < ODROID_REV_COUNT; i++) {
+               /* ADC tolerance: +20 */
+               if (adcval < odroid_type[i].adc_val + 20) {
+                       gd->board_type = i;
+                       return i;
+               }
+       }
+
+       return ODROID_UNKNOWN_REV;
+}
+
+int get_board_rev(void)
+{
+       return odroid_type[gd->board_type].rev;
+}
+
+/**
+ * get_board_type - returns pointer to one of the board type string.
+ * Board types: "xu3", "xu3-lite", "xu4". However the "xu3itel" can be
+ * detected only when the i2c controller is ready to use. Fortunately,
+ * XU3 and XU3L are compatible, and the information about board lite
+ * revision is needed before boot linux, to set proper environment
+ * variable: $fdtfile.
+ */
+const char *get_board_type(void)
+{
+       const char *type_xu3l = "xu3-lite";
+       struct udevice *dev, *chip;
+       int ret;
+
+       if (gd->board_type != ODROID_XU3_REV02)
+               goto exit;
+
+       ret = pmic_get("s2mps11", &dev);
+       if (ret)
+               goto exit;
+
+       /* Enable LDO26: 3.0V */
+       ret = pmic_reg_write(dev, S2MPS11_REG_L26CTRL,
+                            S2MPS11_LDO26_ENABLE);
+       if (ret)
+               goto exit;
+
+       /* Check XU3Lite by probe INA231 I2C0:0x40 */
+       ret = uclass_get_device(UCLASS_I2C, 0, &dev);
+       if (ret)
+               goto exit;
+
+       ret = dm_i2c_probe(dev, 0x40, 0x0, &chip);
+       if (ret)
+               return type_xu3l;
+
+exit:
+       return odroid_type[gd->board_type].name;
+}
+#endif
include/configs/odroid_xu3.h +12 -1
index 3c70158..648e48b 100644
@@ -94,6 +94,8 @@
        "boot.scr fat 0 1;"                 \
        "boot.cmd fat 0 1;"                 \
        "exynos5422-odroidxu3.dtb fat 0 1;" \
+       "exynos5422-odroidxu3-lite.dtb fat 0 1;" \
+       "exynos5422-odroidxu4.dtb fat 0 1;" \
        "boot part 0 1;"                    \
        "root part 0 2\0"
 
@@ -113,9 +115,19 @@
 
 /* Enable: board/samsung/common/misc.c to use set_dfu_alt_info() */
 #define CONFIG_MISC_COMMON
+#define CONFIG_MISC_INIT_R
 #define CONFIG_SET_DFU_ALT_INFO
 #define CONFIG_SET_DFU_ALT_BUF_LEN     (SZ_1K)
 
+/* Set soc_rev, soc_id, board_rev, boardname, fdtfile */
+#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
+#define CONFIG_ODROID_REV_AIN                  9
+#define CONFIG_REVISION_TAG
+#define CONFIG_BOARD_TYPES
+
+#undef CONFIG_SYS_BOARD
+#define CONFIG_SYS_BOARD       "odroid"
+
 /* Define new extra env settings, including DFU settings */
 #undef CONFIG_EXTRA_ENV_SETTINGS
 #define CONFIG_EXTRA_ENV_SETTINGS \
--
Quoted 2 lines

1.9.1

Regards,
Simon

#19 lore raw

PATCH 7/7 exynos5-dt: add board detection for Odroid XU3/XU3L/XU4.

Hello,

Quoted 55 lines · Simon Glass

Hi Przemyslaw,

Quoted 52 lines · Przemyslaw Marczak

There are few revisions of Odroid XU3/XU4:

  Rev   ADC   Board
  0.1     0   XU3 0.1
  0.2   372   XU3 0.2 | XU3L - no DISPLAYPORT
  0.3   739   XU4 0.1

This commit adds implementation of functions:
- set_board_type() - read ADC and set type
- get_board_rev() - returns board revision: 1..3
- board_is_odroidxu3() - returns bool
- board_is_odroidxu4() - returns bool
- get_board_type() - returns board type string

After I2C controller init, the last function can check if the board is "Lite" variant for XU3, by probing chip 0x40 on I2C0 (INA231 - exists only on non-lite). This is useful for setting fdt file name at misc_init_r().

The enabled configs:
- CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
- CONFIG_ODROID_REV_AIN
- CONFIG_REVISION_TAG
- CONFIG_MISC_INIT_R
- CONFIG_BOARD_TYPES

This also redefines CONFIG_SYS_BOARD to "odroid".

---
  board/samsung/common/exynos5-dt.c | 114 ++++++++++++++++++++++++++++++++++++++
  include/configs/odroid_xu3.h      |  12 ++++
  2 files changed, 126 insertions(+)
board/samsung/common/exynos5-dt.c +2 -0
index 7d1b88a..41141df 100644
@@ -18,6 +18,7 @@
  #include <usb.h>
  #include <video_bridge.h>
  #include <asm/gpio.h>
+#include <asm/arch/adc.h>
  #include <asm/arch/cpu.h>
  #include <asm/arch/dwmmc.h>
  #include <asm/arch/mmc.h>
@@ -28,6 +29,7 @@
  #include <power/max77686_pmic.h>
  #include <power/regulator.h>
  #include <power/s5m8767.h>
+#include <power/s2mps11.h>
  #include <tmu.h>
 
Quoted 11 lines

board/samsung/common/exynos5-dt.c char *get_dfu_alt_boot(char *interface, char *devstr) · line 366

Quoted 7 lines
board/samsung/common/exynos5-dt.c +2 -0
  DECLARE_GLOBAL_DATA_PTR;
@@ -360,3 +362,115 @@ char *get_dfu_alt_boot(char *interface, char *devstr)
         return alt_boot;
  }
  #endif
+
+#ifdef CONFIG_REVISION_TAG

Can we check the compatible string instead? It would be good to avoid #ifdef in common code.

Ok, I will add some lines to check it.

Quoted 141 lines
Quoted 141 lines
board/samsung/common/exynos5-dt.c +110 -0
+/**
+ * Odroix XU3/4 board revisions:
+ * Rev   ADC   Board
+ * 0.1     0   XU3 0.1
+ * 0.2   372   XU3 0.2 | XU3L - no DISPLAYPORT (probe I2C0:0x40 / INA231)
+ * 0.3   739   XU4 0.1
+ * Use +/-20 for ADC value tolerance.
+ */
+enum {
+       ODROID_XU3_REV01,
+       ODROID_XU3_REV02,
+       ODROID_XU4_REV01,
+       ODROID_UNKNOWN_REV,
+       ODROID_REV_COUNT,
+};
+
+struct odroid_type {
+       int board_type;
+       int rev;
+       int adc_val;
+       const char *name;
+};
+
+struct odroid_type odroid_type[] = {
+       { ODROID_XU3_REV01, 1, 0, "xu3" },
+       { ODROID_XU3_REV02, 2, 372, "xu3" },
+       { ODROID_XU4_REV01, 1, 739, "xu4" },
+       { ODROID_UNKNOWN_REV, 0, 4095, "unknown" },
+};
+
+bool board_is_odroidxu3(void)
+{
+       if (gd->board_type < ODROID_XU4_REV01)
+               return true;
+
+       return false;
+}
+
+bool board_is_odroidxu4(void)
+{
+       if (gd->board_type > ODROID_XU3_REV02)
+               return true;
+
+       return false;
+}
+
+int set_board_type(void)
+{
+       int adcval, i;
+
+       adcval = exynos_adc_read_channel(CONFIG_ODROID_REV_AIN);
+       if (adcval < 0)
+               return adcval;
+
+       for (i = 0; i < ODROID_REV_COUNT; i++) {
+               /* ADC tolerance: +20 */
+               if (adcval < odroid_type[i].adc_val + 20) {
+                       gd->board_type = i;
+                       return i;
+               }
+       }
+
+       return ODROID_UNKNOWN_REV;
+}
+
+int get_board_rev(void)
+{
+       return odroid_type[gd->board_type].rev;
+}
+
+/**
+ * get_board_type - returns pointer to one of the board type string.
+ * Board types: "xu3", "xu3-lite", "xu4". However the "xu3itel" can be
+ * detected only when the i2c controller is ready to use. Fortunately,
+ * XU3 and XU3L are compatible, and the information about board lite
+ * revision is needed before boot linux, to set proper environment
+ * variable: $fdtfile.
+ */
+const char *get_board_type(void)
+{
+       const char *type_xu3l = "xu3-lite";
+       struct udevice *dev, *chip;
+       int ret;
+
+       if (gd->board_type != ODROID_XU3_REV02)
+               goto exit;
+
+       ret = pmic_get("s2mps11", &dev);
+       if (ret)
+               goto exit;
+
+       /* Enable LDO26: 3.0V */
+       ret = pmic_reg_write(dev, S2MPS11_REG_L26CTRL,
+                            S2MPS11_LDO26_ENABLE);
+       if (ret)
+               goto exit;
+
+       /* Check XU3Lite by probe INA231 I2C0:0x40 */
+       ret = uclass_get_device(UCLASS_I2C, 0, &dev);
+       if (ret)
+               goto exit;
+
+       ret = dm_i2c_probe(dev, 0x40, 0x0, &chip);
+       if (ret)
+               return type_xu3l;
+
+exit:
+       return odroid_type[gd->board_type].name;
+}
+#endif
include/configs/odroid_xu3.h +12 -0
index 3c70158..648e48b 100644
@@ -94,6 +94,8 @@
         "boot.scr fat 0 1;"                 \
         "boot.cmd fat 0 1;"                 \
         "exynos5422-odroidxu3.dtb fat 0 1;" \
+       "exynos5422-odroidxu3-lite.dtb fat 0 1;" \
+       "exynos5422-odroidxu4.dtb fat 0 1;" \
         "boot part 0 1;"                    \
         "root part 0 2\0"
 
@@ -113,9 +115,19 @@
 
  /* Enable: board/samsung/common/misc.c to use set_dfu_alt_info() */
  #define CONFIG_MISC_COMMON
+#define CONFIG_MISC_INIT_R
  #define CONFIG_SET_DFU_ALT_INFO
  #define CONFIG_SET_DFU_ALT_BUF_LEN     (SZ_1K)
 
+/* Set soc_rev, soc_id, board_rev, boardname, fdtfile */
+#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
+#define CONFIG_ODROID_REV_AIN                  9
+#define CONFIG_REVISION_TAG
+#define CONFIG_BOARD_TYPES
+
+#undef CONFIG_SYS_BOARD
+#define CONFIG_SYS_BOARD       "odroid"
+
  /* Define new extra env settings, including DFU settings */
Quoted 9 lines
Quoted 5 lines
include/configs/odroid_xu3.h +0 -1
  #undef CONFIG_EXTRA_ENV_SETTINGS
  #define CONFIG_EXTRA_ENV_SETTINGS \
--

1.9.1

Regards,
Simon

Thanks,

Signature · 4 lines
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com
#20 lore raw

cover Add board detection for Odroid XU3 / XU3Lite / XU4

In reply to Przemyslaw Marczak

hi Przemyslaw,

Quoted 24 lines · Przemyslaw Marczak

This patchset adds:
- define the CPU name for Chromebook Peach Pi as Exynos5800
- set the cpu id of Exynos5422 to 0x5422
- S2MPS11 PMIC I/O driver
- Exynos5420-compatible (9-channel, 12-bit) ADC driver
- board detection for Odroid XU3 / XU3lite / XU4

This was tested on Odroid XU3 and XU3 Lite, without the XU4, but I'm waiting for reply from the Odroid forum users.

Tested with buildman for samsung.

Available on github:
https://github.com/bobenstein/u-boot/tree/xu3-patchset-test

Przemyslaw Marczak (7):
s5p: cpu_info: use defined CPU name if available
peach-pi: define CPU name for SoC Exynos5800 Exynos5422/5800: set cpu id to 0x5422
dm: pmic: add s2mps11 PMIC I/O driver
odroid-xu3: enable s2mps11 PMIC support
Exynos: add internal ADC driver
exynos5-dt: add board detection for Odroid XU3/XU3L/XU4.

Quoted 13 lines
 arch/arm/cpu/armv7/s5p-common/cpu_info.c  |   5 ++
 arch/arm/dts/exynos5422-odroidxu3.dts     |   7 ++
 arch/arm/mach-exynos/Makefile             |   1 +
 arch/arm/mach-exynos/adc.c                |  83 ++++++++++++++++++++++
 arch/arm/mach-exynos/clock.c              |  16 ++---
 arch/arm/mach-exynos/clock_init_exynos5.c |   2 +-
 arch/arm/mach-exynos/common_setup.h       |   4 +-
 arch/arm/mach-exynos/include/mach/adc.h   |  45 ++++++++++++
 arch/arm/mach-exynos/include/mach/cpu.h   |  10 +--
 arch/arm/mach-exynos/include/mach/gpio.h  |   4 +-
 arch/arm/mach-exynos/pinmux.c             |   2 +-
 arch/arm/mach-exynos/power.c              |   2 +-
 board/samsung/common/exynos5-dt.c         | 114

++++++++++++++++++++++++++++++

Quoted 8 lines
 configs/odroid-xu3_defconfig              |   3 +
 doc/device-tree-bindings/pmic/s2mps11.txt |  17 +++++
 drivers/power/pmic/Kconfig                |  14 ++++
 drivers/power/pmic/Makefile               |   1 +
 drivers/power/pmic/s2mps11.c              |  60 ++++++++++++++++
 include/configs/odroid_xu3.h              |  12 ++++
 include/configs/peach-pi.h                |   2 +
 include/power/s2mps11.h                   | 109

++++++++++++++++++++++++++++

Quoted 6 lines
 21 files changed, 493 insertions(+), 20 deletions(-)
 create mode 100644 arch/arm/mach-exynos/adc.c
 create mode 100644 doc/device-tree-bindings/pmic/s2mps11.txt
 create mode 100644 drivers/power/pmic/s2mps11.c
 create mode 100644 include/power/s2mps11.h

Thanks for these patches.
? ??

At the last moment I got this to work on my odroidxu3 board.

One problem I would like to address out is usb smsc95xx ethernet is not getting started at the boot.

# usb start                   /* command failed at the start */
------------------------------------------------------------------------------------------------------
U-Boot 2015.10-rc2-00226-g7dbe336 (Aug 30 2015 - 23:41:27 +0530) for
ODROID-XU3
CPU:   Exynos5422 @ 800 MHz
Model: Odroid XU3 based on EXYNOS5422
Board: Odroid XU3 based on EXYNOS5422
Model: xu3
DRAM:  2 GiB
MMC:   EXYNOS DWMMC: 0, EXYNOS DWMMC: 1

*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   No ethernet found.
Hit any key to stop autoboot:  0

switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
starting USB...

USB0:   USB EHCI 1.00
USB1:   Register 2000140 NbrPorts 2

Starting the controller
USB XHCI 1.00
USB2: Register 2000140 NbrPorts 2
Starting the controller
USB XHCI 1.00
scanning bus 0 for devices... 1 USB Device(s) found scanning bus 1 for devices... 1 USB Device(s) found scanning bus 2 for devices... 1 USB Device(s) found
scanning usb for ethernet devices... 0 Ethernet Device(s) found
No ethernet found.
missing environment variable: pxeuuid
missing environment variable: bootfile
-----------------------------------------------------------------------------------------

I will give it a try with latest kernel and let you know how it worked on Odroid-XU4 / XU4.

-Anand Moon

Quoted 3 lines

--
1.9.1

#21 lore raw

cover Add board detection for Odroid XU3 / XU3Lite / XU4

Hello Anand,

Quoted 105 lines · Anand Moon

hi Przemyslaw,

Quoted 24 lines · On 28 August 2015 at 19:29, Przemyslaw Marczak <[email protected]…

This patchset adds:
- define the CPU name for Chromebook Peach Pi as Exynos5800
- set the cpu id of Exynos5422 to 0x5422
- S2MPS11 PMIC I/O driver
- Exynos5420-compatible (9-channel, 12-bit) ADC driver
- board detection for Odroid XU3 / XU3lite / XU4

This was tested on Odroid XU3 and XU3 Lite, without the XU4, but I'm waiting for reply from the Odroid forum users.

Tested with buildman for samsung.

Available on github:
https://github.com/bobenstein/u-boot/tree/xu3-patchset-test

Przemyslaw Marczak (7):
s5p: cpu_info: use defined CPU name if available
peach-pi: define CPU name for SoC Exynos5800 Exynos5422/5800: set cpu id to 0x5422
dm: pmic: add s2mps11 PMIC I/O driver
odroid-xu3: enable s2mps11 PMIC support
Exynos: add internal ADC driver
exynos5-dt: add board detection for Odroid XU3/XU3L/XU4.

Quoted 13 lines
 arch/arm/cpu/armv7/s5p-common/cpu_info.c  |   5 ++
 arch/arm/dts/exynos5422-odroidxu3.dts     |   7 ++
 arch/arm/mach-exynos/Makefile             |   1 +
 arch/arm/mach-exynos/adc.c                |  83 ++++++++++++++++++++++
 arch/arm/mach-exynos/clock.c              |  16 ++---
 arch/arm/mach-exynos/clock_init_exynos5.c |   2 +-
 arch/arm/mach-exynos/common_setup.h       |   4 +-
 arch/arm/mach-exynos/include/mach/adc.h   |  45 ++++++++++++
 arch/arm/mach-exynos/include/mach/cpu.h   |  10 +--
 arch/arm/mach-exynos/include/mach/gpio.h  |   4 +-
 arch/arm/mach-exynos/pinmux.c             |   2 +-
 arch/arm/mach-exynos/power.c              |   2 +-
 board/samsung/common/exynos5-dt.c         | 114

++++++++++++++++++++++++++++++

Quoted 8 lines
 configs/odroid-xu3_defconfig              |   3 +
 doc/device-tree-bindings/pmic/s2mps11.txt |  17 +++++
 drivers/power/pmic/Kconfig                |  14 ++++
 drivers/power/pmic/Makefile               |   1 +
 drivers/power/pmic/s2mps11.c              |  60 ++++++++++++++++
 include/configs/odroid_xu3.h              |  12 ++++
 include/configs/peach-pi.h                |   2 +
 include/power/s2mps11.h                   | 109

++++++++++++++++++++++++++++

Quoted 6 lines
 21 files changed, 493 insertions(+), 20 deletions(-)
 create mode 100644 arch/arm/mach-exynos/adc.c
 create mode 100644 doc/device-tree-bindings/pmic/s2mps11.txt
 create mode 100644 drivers/power/pmic/s2mps11.c
 create mode 100644 include/power/s2mps11.h

Thanks for these patches.
? ??

At the last moment I got this to work on my odroidxu3 board.

One problem I would like to address out is usb smsc95xx ethernet is not getting started at the boot.

# usb start                   /* command failed at the start */
------------------------------------------------------------------------------------------------------
U-Boot 2015.10-rc2-00226-g7dbe336 (Aug 30 2015 - 23:41:27 +0530) for
ODROID-XU3
CPU:   Exynos5422 @ 800 MHz
Model: Odroid XU3 based on EXYNOS5422
Board: Odroid XU3 based on EXYNOS5422
Model: xu3
DRAM:  2 GiB
MMC:   EXYNOS DWMMC: 0, EXYNOS DWMMC: 1

*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   No ethernet found.
Hit any key to stop autoboot:  0

switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
starting USB...

USB0:   USB EHCI 1.00
USB1:   Register 2000140 NbrPorts 2

Starting the controller
USB XHCI 1.00
USB2: Register 2000140 NbrPorts 2
Starting the controller
USB XHCI 1.00
scanning bus 0 for devices... 1 USB Device(s) found
scanning bus 1 for devices... 1 USB Device(s) found
scanning bus 2 for devices... 1 USB Device(s) found
scanning usb for ethernet devices... 0 Ethernet Device(s) found
No ethernet found.
missing environment variable: pxeuuid
missing environment variable: bootfile
-----------------------------------------------------------------------------------------

Quoted 8 lines

I will give it a try with latest kernel and let you know how it worked on Odroid-XU4 / XU4.

-Anand Moon

Quoted 3 lines

--
1.9.1

Thank you for pointing this, but at present I'm busy with some other work and I don't have too much time for it. Maybe in the next week.

Best regards,

Signature · 4 lines
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com
#22 lore raw

cover Add board detection for Odroid XU3 / XU3Lite / XU4

In reply to Anand Moon
Quoted 29 lines · On Mon, 31 Aug 2015 00:33:16 +0530 Anand Moon <[email protected]> wrote:

At the last moment I got this to work on my odroidxu3 board.

One problem I would like to address out is usb smsc95xx ethernet is not getting started at the boot.

# usb start                   /* command failed at the start */
------------------------------------------------------------------------------------------------------
U-Boot 2015.10-rc2-00226-g7dbe336 (Aug 30 2015 - 23:41:27 +0530) for
ODROID-XU3
CPU:   Exynos5422 @ 800 MHz
Model: Odroid XU3 based on EXYNOS5422
Board: Odroid XU3 based on EXYNOS5422
Model: xu3
DRAM:  2 GiB
MMC:   EXYNOS DWMMC: 0, EXYNOS DWMMC: 1

*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   No ethernet found.
Hit any key to stop autoboot:  0

switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
starting USB...

USB0:   USB EHCI 1.00
USB1:   Register 2000140 NbrPorts 2
Quoted 13 lines

Starting the controller
USB XHCI 1.00
USB2: Register 2000140 NbrPorts 2
Starting the controller
USB XHCI 1.00
scanning bus 0 for devices... 1 USB Device(s) found scanning bus 1 for devices... 1 USB Device(s) found scanning bus 2 for devices... 1 USB Device(s) found
scanning usb for ethernet devices... 0 Ethernet Device(s) found
No ethernet found.
missing environment variable: pxeuuid
missing environment variable: bootfile
-----------------------------------------------------------------------------------------

Hi Anand,

This looks like it might be the same problem as

    http://lists.denx.de/pipermail/u-boot/2015-October/230827.html

Simon Glass asked if this also happens on XU3, so maybe you could test the same workaround on your board and provide feedback?

Signature · 2 lines
Best regards,
Siarhei Siamashka
#23 lore raw

cover Add board detection for Odroid XU3 / XU3Lite / XU4

Hi Siarhei

Quoted 46 lines · Siarhei Siamashka
Quoted 29 lines · On Mon, 31 Aug 2015 00:33:16 +0530 Anand Moon <[email protected]> wrote:

At the last moment I got this to work on my odroidxu3 board.

One problem I would like to address out is usb smsc95xx ethernet is not getting started at the boot.

# usb start                   /* command failed at the start */
------------------------------------------------------------------------------------------------------
U-Boot 2015.10-rc2-00226-g7dbe336 (Aug 30 2015 - 23:41:27 +0530) for
ODROID-XU3
CPU:   Exynos5422 @ 800 MHz
Model: Odroid XU3 based on EXYNOS5422
Board: Odroid XU3 based on EXYNOS5422
Model: xu3
DRAM:  2 GiB
MMC:   EXYNOS DWMMC: 0, EXYNOS DWMMC: 1

*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   No ethernet found.
Hit any key to stop autoboot:  0

switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
starting USB...

USB0:   USB EHCI 1.00
USB1:   Register 2000140 NbrPorts 2
Quoted 13 lines

Starting the controller
USB XHCI 1.00
USB2: Register 2000140 NbrPorts 2
Starting the controller
USB XHCI 1.00
scanning bus 0 for devices... 1 USB Device(s) found scanning bus 1 for devices... 1 USB Device(s) found scanning bus 2 for devices... 1 USB Device(s) found
scanning usb for ethernet devices... 0 Ethernet Device(s) found
No ethernet found.
missing environment variable: pxeuuid
missing environment variable: bootfile
-----------------------------------------------------------------------------------------

Quoted 8 lines

Hi Anand,

This looks like it might be the same problem as

    http://lists.denx.de/pipermail/u-boot/2015-October/230827.html

Simon Glass asked if this also happens on XU3, so maybe you could test the same workaround on your board and provide feedback?

Yes I see the same problem.
----------------------------------------------------------------------------------------------------
U-Boot 2015.10-rc3-00227-g94fa041-dirty (Sep 27 2015 - 15:37:17 +0930) for ODROI

CPU:   Exynos5422 @ 800 MHz
Model: Odroid XU3 based on EXYNOS5422
Board: Odroid XU3 based on EXYNOS5422
Type:  xu3
DRAM:  2 GiB
MMC:   EXYNOS DWMMC: 0, EXYNOS DWMMC: 1

*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   No ethernet found.
Hit any key to stop autoboot:  0

ODROID-XU3 #
ODROID-XU3 #
ODROID-XU3 #
ODROID-XU3 # setenv usbethaddr 02:DE:AD:BE:EF:FF ODROID-XU3 # usb start
starting USB...

USB0:   USB EHCI 1.00
USB1:   Register 2000140 NbrPorts 2

Starting the controller
USB XHCI 1.00
USB2: Register 2000140 NbrPorts 2
Starting the controller
USB XHCI 1.00
scanning bus 0 for devices... 1 USB Device(s) found scanning bus 1 for devices... 1 USB Device(s) found scanning bus 2 for devices... 1 USB Device(s) found
scanning usb for ethernet devices... 0 Ethernet Device(s) found
ODROID-XU3 #
----------------------------------------------------------------------------------------------------

-Anand Moon

Quoted 3 lines

--
Best regards,
Siarhei Siamashka

#24 lore raw

cover Add board detection for Odroid XU3 / XU3Lite / XU4

In reply to Siarhei Siamashka

Hi Siarhei ,

Quoted 48 lines · Siarhei Siamashka
Quoted 29 lines · On Mon, 31 Aug 2015 00:33:16 +0530 Anand Moon <[email protected]> wrote:

At the last moment I got this to work on my odroidxu3 board.

One problem I would like to address out is usb smsc95xx ethernet is not getting started at the boot.

# usb start                   /* command failed at the start */
------------------------------------------------------------------------------------------------------
U-Boot 2015.10-rc2-00226-g7dbe336 (Aug 30 2015 - 23:41:27 +0530) for
ODROID-XU3
CPU:   Exynos5422 @ 800 MHz
Model: Odroid XU3 based on EXYNOS5422
Board: Odroid XU3 based on EXYNOS5422
Model: xu3
DRAM:  2 GiB
MMC:   EXYNOS DWMMC: 0, EXYNOS DWMMC: 1

*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   No ethernet found.
Hit any key to stop autoboot:  0

switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
starting USB...

USB0:   USB EHCI 1.00
USB1:   Register 2000140 NbrPorts 2
Quoted 13 lines

Starting the controller
USB XHCI 1.00
USB2: Register 2000140 NbrPorts 2
Starting the controller
USB XHCI 1.00
scanning bus 0 for devices... 1 USB Device(s) found scanning bus 1 for devices... 1 USB Device(s) found scanning bus 2 for devices... 1 USB Device(s) found
scanning usb for ethernet devices... 0 Ethernet Device(s) found
No ethernet found.
missing environment variable: pxeuuid
missing environment variable: bootfile
-----------------------------------------------------------------------------------------

Hi Anand,

Quoted 7 lines

This looks like it might be the same problem as

    http://lists.denx.de/pipermail/u-boot/2015-October/230827.html

Simon Glass asked if this also happens on XU3, so maybe you could test the same workaround on your board and provide feedback?

--

Odroid u3 also has the same problem
---------------------------------------------------------
U-Boot 2015.10-rc5-00030-gac6a532-dirty (Oct 20 2015 - 01:37:27 +1030)

CPU:   Exynos4412 @ 1 GHz
Model: Odroid based on Exynos4412
Board: Odroid based on Exynos4412
Model: u3
DRAM:  2 GiB
LDO20 at VDDQ_EMMC_1.8V: set 1800000 uV; enabling
LDO22 at VDDQ_EMMC_2.8V: set 2800000 uV; enabling
LDO21 at TFLASH_2.8V: set 2800000 uV; enabling
MMC:   SAMSUNG SDHCI: 0, EXYNOS DWMMC: 1

*** Warning - bad CRC, using default environment

Net:   No ethernet found.
Hit any key to stop autoboot:  0

Odroid # setenv usbethaddr 02:DE:AD:BE:EF:FF
Odroid # usb start
starting USB...
USB0: USB EHCI 1.00
scanning bus 0 for devices... 1 USB Device(s) found
scanning usb for ethernet devices... 0 Ethernet Device(s) found
Odroid #
---------------------------------------------------------

-Anand Moon

Quoted 2 lines

Best regards,
Siarhei Siamashka

#25 lore raw

cover Add board detection for Odroid XU3 / XU3Lite / XU4

Hello Siarhei, Anand,

Quoted 86 lines · Anand Moon

Hi Siarhei ,

Quoted 48 lines · Siarhei Siamashka
Quoted 29 lines · On Mon, 31 Aug 2015 00:33:16 +0530 Anand Moon <[email protected]> wrote:

At the last moment I got this to work on my odroidxu3 board.

One problem I would like to address out is usb smsc95xx ethernet is not getting started at the boot.

# usb start                   /* command failed at the start */
------------------------------------------------------------------------------------------------------
U-Boot 2015.10-rc2-00226-g7dbe336 (Aug 30 2015 - 23:41:27 +0530) for
ODROID-XU3
CPU:   Exynos5422 @ 800 MHz
Model: Odroid XU3 based on EXYNOS5422
Board: Odroid XU3 based on EXYNOS5422
Model: xu3
DRAM:  2 GiB
MMC:   EXYNOS DWMMC: 0, EXYNOS DWMMC: 1

*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   No ethernet found.
Hit any key to stop autoboot:  0

switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
starting USB...

USB0:   USB EHCI 1.00
USB1:   Register 2000140 NbrPorts 2
Quoted 13 lines

Starting the controller
USB XHCI 1.00
USB2: Register 2000140 NbrPorts 2
Starting the controller
USB XHCI 1.00
scanning bus 0 for devices... 1 USB Device(s) found
scanning bus 1 for devices... 1 USB Device(s) found
scanning bus 2 for devices... 1 USB Device(s) found
scanning usb for ethernet devices... 0 Ethernet Device(s) found
No ethernet found.
missing environment variable: pxeuuid
missing environment variable: bootfile
-----------------------------------------------------------------------------------------

Hi Anand,

Quoted 7 lines

This looks like it might be the same problem as

     http://lists.denx.de/pipermail/u-boot/2015-October/230827.html

Simon Glass asked if this also happens on XU3, so maybe you could test the same workaround on your board and provide feedback?

--

Odroid u3 also has the same problem
---------------------------------------------------------
U-Boot 2015.10-rc5-00030-gac6a532-dirty (Oct 20 2015 - 01:37:27 +1030)

CPU:   Exynos4412 @ 1 GHz
Model: Odroid based on Exynos4412
Board: Odroid based on Exynos4412
Model: u3
DRAM:  2 GiB
LDO20 at VDDQ_EMMC_1.8V: set 1800000 uV; enabling
LDO22 at VDDQ_EMMC_2.8V: set 2800000 uV; enabling
LDO21 at TFLASH_2.8V: set 2800000 uV; enabling
MMC:   SAMSUNG SDHCI: 0, EXYNOS DWMMC: 1

*** Warning - bad CRC, using default environment

Net:   No ethernet found.
Hit any key to stop autoboot:  0

Odroid # setenv usbethaddr 02:DE:AD:BE:EF:FF
Odroid # usb start
starting USB...
USB0: USB EHCI 1.00
scanning bus 0 for devices... 1 USB Device(s) found
scanning usb for ethernet devices... 0 Ethernet Device(s) found
Odroid #
---------------------------------------------------------

Quoted 4 lines

-Anand Moon

Quoted 2 lines

Best regards,
Siarhei Siamashka

Lukasz is working on that issue, and he discovered that the sequence of usb start/reset works for this and the Ethernet is detected then.

-----------------------------------------------------------------------
ODROID-XU3 # usb start
starting USB...

USB0:   USB EHCI 1.00
USB1:   Register 2000140 NbrPorts 2

Starting the controller
USB XHCI 1.00
USB2: Register 2000140 NbrPorts 2
Starting the controller
USB XHCI 1.00
scanning bus 0 for devices... 1 USB Device(s) found
scanning bus 1 for devices... 1 USB Device(s) found
scanning bus 2 for devices... 1 USB Device(s) found
scanning usb for ethernet devices... 0 Ethernet Device(s) found
ODROID-XU3 # usb reset
resetting USB...

USB0:   USB EHCI 1.00
USB1:   Register 2000140 NbrPorts 2

Starting the controller
USB XHCI 1.00
USB2: Register 2000140 NbrPorts 2
Starting the controller
USB XHCI 1.00
scanning bus 0 for devices... 3 USB Device(s) found scanning bus 1 for devices... 1 USB Device(s) found scanning bus 2 for devices... 1 USB Device(s) found
scanning usb for ethernet devices...
Error: sms0 address not set.
Warning: failed to set MAC address
1 Ethernet Device(s) found
ODROID-XU3 #
-----------------------------------------------------------------------

Best regards,

Signature · 4 lines
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com
#26 lore raw

cover Add board detection for Odroid XU3 / XU3Lite / XU4

In reply to Przemyslaw Marczak

Hi Przemyslaw,

Quoted 15 lines · Przemyslaw Marczak

This patchset adds:
- define the CPU name for Chromebook Peach Pi as Exynos5800
- set the cpu id of Exynos5422 to 0x5422
- S2MPS11 PMIC I/O driver
- Exynos5420-compatible (9-channel, 12-bit) ADC driver
- board detection for Odroid XU3 / XU3lite / XU4

This was tested on Odroid XU3 and XU3 Lite, without the XU4, but I'm waiting for reply from the Odroid forum users.

Tested with buildman for samsung.

Available on github:
https://github.com/bobenstein/u-boot/tree/xu3-patchset-test

Quoted 8 lines

Przemyslaw Marczak (7):
s5p: cpu_info: use defined CPU name if available
peach-pi: define CPU name for SoC Exynos5800 Exynos5422/5800: set cpu id to 0x5422
dm: pmic: add s2mps11 PMIC I/O driver
odroid-xu3: enable s2mps11 PMIC support
Exynos: add internal ADC driver
exynos5-dt: add board detection for Odroid XU3/XU3L/XU4.

It's nice to have things automatic. Is this easier than having a separate device tree for each board?

Regards
Simon

#27 lore raw

cover Add board detection for Odroid XU3 / XU3Lite / XU4

Hello Simon,

Quoted 27 lines · Simon Glass

Hi Przemyslaw,

Quoted 15 lines · Przemyslaw Marczak

This patchset adds:
- define the CPU name for Chromebook Peach Pi as Exynos5800
- set the cpu id of Exynos5422 to 0x5422
- S2MPS11 PMIC I/O driver
- Exynos5420-compatible (9-channel, 12-bit) ADC driver
- board detection for Odroid XU3 / XU3lite / XU4

This was tested on Odroid XU3 and XU3 Lite, without the XU4, but I'm waiting for reply from the Odroid forum users.

Tested with buildman for samsung.

Available on github:
https://github.com/bobenstein/u-boot/tree/xu3-patchset-test

Quoted 8 lines

Przemyslaw Marczak (7):
s5p: cpu_info: use defined CPU name if available
peach-pi: define CPU name for SoC Exynos5800 Exynos5422/5800: set cpu id to 0x5422
dm: pmic: add s2mps11 PMIC I/O driver
odroid-xu3: enable s2mps11 PMIC support
Exynos: add internal ADC driver
exynos5-dt: add board detection for Odroid XU3/XU3L/XU4.

Quoted 6 lines

It's nice to have things automatic. Is this easier than having a separate device tree for each board?

Regards
Simon

In my intention was using a single U-Boot binary (u-boot-dtb.bin) with the three almost full compatible boards.
This is also easier for other developers, who don't need care about few configs and few dtb's.

And finally this code can load proper dtb for Linux Kernel for each supported board. So in the next part (Linux boot), things are done clean.

The common board file is quite messy because of this code, so if you don't like it, then I can move it to independent file.

Best regards,

Signature · 4 lines
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com
#28 lore raw

cover Add board detection for Odroid XU3 / XU3Lite / XU4

Hi Przemyslaw,

Quoted 42 lines · Przemyslaw Marczak

Hello Simon,

Quoted 30 lines · Simon Glass

Hi Przemyslaw,

Quoted 16 lines · Przemyslaw Marczak

This patchset adds:
- define the CPU name for Chromebook Peach Pi as Exynos5800
- set the cpu id of Exynos5422 to 0x5422
- S2MPS11 PMIC I/O driver
- Exynos5420-compatible (9-channel, 12-bit) ADC driver
- board detection for Odroid XU3 / XU3lite / XU4

This was tested on Odroid XU3 and XU3 Lite, without the XU4, but I'm waiting for reply from the Odroid forum users.

Tested with buildman for samsung.

Available on github:
https://github.com/bobenstein/u-boot/tree/xu3-patchset-test

Quoted 8 lines

Przemyslaw Marczak (7):
s5p: cpu_info: use defined CPU name if available
peach-pi: define CPU name for SoC Exynos5800 Exynos5422/5800: set cpu id to 0x5422
dm: pmic: add s2mps11 PMIC I/O driver
odroid-xu3: enable s2mps11 PMIC support
Exynos: add internal ADC driver
exynos5-dt: add board detection for Odroid XU3/XU3L/XU4.

Quoted 6 lines

It's nice to have things automatic. Is this easier than having a separate device tree for each board?

Regards
Simon

Quoted 6 lines

In my intention was using a single U-Boot binary (u-boot-dtb.bin) with the three almost full compatible boards. This is also easier for other developers, who don't need care about few configs and few dtb's.

And finally this code can load proper dtb for Linux Kernel for each supported board. So in the next part (Linux boot), things are done clean.

The common board file is quite messy because of this code, so if you don't like it, then I can move it to independent file.

I don't think it matters that much. I'm not keen on the #ifdef CONFIG_REVISION_TAG - can you instead check the board compatible string? The code should be generic to exynos5.

Regards,
Simon

#29 lore raw

cover Add board detection for Odroid XU3 / XU3Lite / XU4

Hello,

Quoted 50 lines · Simon Glass

Hi Przemyslaw,

Quoted 47 lines · Przemyslaw Marczak

Hello Simon,

Quoted 30 lines · Simon Glass

Hi Przemyslaw,

Quoted 16 lines · Przemyslaw Marczak

This patchset adds:
- define the CPU name for Chromebook Peach Pi as Exynos5800
- set the cpu id of Exynos5422 to 0x5422
- S2MPS11 PMIC I/O driver
- Exynos5420-compatible (9-channel, 12-bit) ADC driver
- board detection for Odroid XU3 / XU3lite / XU4

This was tested on Odroid XU3 and XU3 Lite, without the XU4, but I'm waiting for reply from the Odroid forum users.

Tested with buildman for samsung.

Available on github:
https://github.com/bobenstein/u-boot/tree/xu3-patchset-test

Quoted 8 lines

Przemyslaw Marczak (7):
s5p: cpu_info: use defined CPU name if available
peach-pi: define CPU name for SoC Exynos5800 Exynos5422/5800: set cpu id to 0x5422
dm: pmic: add s2mps11 PMIC I/O driver
odroid-xu3: enable s2mps11 PMIC support
Exynos: add internal ADC driver
exynos5-dt: add board detection for Odroid XU3/XU3L/XU4.

Quoted 6 lines

It's nice to have things automatic. Is this easier than having a separate device tree for each board?

Regards
Simon

In my intention was using a single U-Boot binary (u-boot-dtb.bin) with the three almost full compatible boards. This is also easier for other developers, who don't need care about few configs and few dtb's.

And finally this code can load proper dtb for Linux Kernel for each supported board. So in the next part (Linux boot), things are done clean.

Quoted 9 lines
Quoted 1 line

The common board file is quite messy because of this code, so if you don't like it, then I can move it to independent file.

I don't think it matters that much. I'm not keen on the #ifdef CONFIG_REVISION_TAG - can you instead check the board compatible string? The code should be generic to exynos5.

Regards,
Simon

Thanks for review, I will send the next version in the next week. And will try to keep things common.

Best regards

Signature · 4 lines
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com
#30 lore raw

v2 cover Add board detection for Odroid XU3 / XU3Lite / XU4

In reply to Przemyslaw Marczak

This patchset adds:
- CPU model in dts for Chromebook Peach Pi as Exynos5800
- set the cpu id of Exynos5422 to 0x5422
- S2MPS11 PMIC I/O driver
- Exynos5420-compatible (9-channel, 12-bit) ADC driver
- new file for Exynos5: exynos5-dt-types.c
- board detection for Odroid XU3 / XU3lite / XU4
- fixed ADC val for XU4

This was tested on Odroid XU3 and XU3 Lite, without the XU4, but I'm waiting for reply from the Odroid forum users.

Tested with buildman for samsung.

Available on github:
https://github.com/bobenstein/u-boot/tree/xu3-detect-patchset-v1
https://github.com/bobenstein/u-boot/tree/xu3-detect-patchset-v2

Przemyslaw Marczak (11):
samsung: board/misc: check returned pointer for get_board_type() calls
s5p: cpu_info: print "cpu-model" if exists in dts
Peach-Pi: dts: add cpu-model string
Exynos5422/5800: set cpu id to 0x5422
dm: pmic: add s2mps11 PMIC I/O driver
dm: adc: add simple ADC uclass implementation
dm: adc: add Exynos54xx compatible ADC driver
Odroid-XU3: enable s2mps11 PMIC support
Exynos54xx: dts: add ADC node
Odroid-XU3: dts: enable ADC, with request for pre-reloc bind
exynos5-dt-types: add board detection for Odroid XU3/XU3L/XU4.

 arch/arm/cpu/armv7/s5p-common/cpu_info.c  |  14 ++-
 arch/arm/dts/exynos5422-odroidxu3.dts     |  12 ++
 arch/arm/dts/exynos54xx.dtsi              |   7 ++
 arch/arm/dts/exynos5800-peach-pi.dts      |   1 +
 arch/arm/mach-exynos/clock.c              |  16 +--
 arch/arm/mach-exynos/clock_init_exynos5.c |   2 +-
 arch/arm/mach-exynos/common_setup.h       |   4 +-
 arch/arm/mach-exynos/include/mach/adc.h   |  45 +++++++
 arch/arm/mach-exynos/include/mach/cpu.h   |   6 +-
 arch/arm/mach-exynos/include/mach/gpio.h  |   4 +-
 arch/arm/mach-exynos/pinmux.c             |   2 +-
 arch/arm/mach-exynos/power.c              |   2 +-
 board/samsung/common/Makefile             |   5 +-
 board/samsung/common/board.c              |   4 +-
 board/samsung/common/exynos5-dt-types.c   | 196 ++++++++++++++++++++++++++++++
 board/samsung/common/exynos5-dt.c         |  12 ++
 board/samsung/common/misc.c               |   3 +
 configs/odroid-xu3_defconfig              |   5 +
 doc/device-tree-bindings/pmic/s2mps11.txt |  17 +++
 drivers/Kconfig                           |   2 +
 drivers/Makefile                          |   1 +
 drivers/adc/Kconfig                       |  17 +++
 drivers/adc/Makefile                      |   9 ++
 drivers/adc/adc-uclass.c                  |  76 ++++++++++++
 drivers/adc/exynos-adc.c                  | 102 ++++++++++++++++
 drivers/power/pmic/Kconfig                |  14 +++
 drivers/power/pmic/Makefile               |   1 +
 drivers/power/pmic/s2mps11.c              |  60 +++++++++
 include/adc.h                             |  88 ++++++++++++++
 include/configs/odroid_xu3.h              |  12 ++
 include/dm/uclass-id.h                    |   1 +
 include/power/s2mps11.h                   | 109 +++++++++++++++++
 include/samsung/exynos5-dt-types.h        |  27 ++++
 33 files changed, 854 insertions(+), 22 deletions(-)
 create mode 100644 board/samsung/common/exynos5-dt-types.c
 create mode 100644 doc/device-tree-bindings/pmic/s2mps11.txt
 create mode 100644 drivers/adc/Kconfig
 create mode 100644 drivers/adc/Makefile
 create mode 100644 drivers/adc/adc-uclass.c
 create mode 100644 drivers/adc/exynos-adc.c
 create mode 100644 drivers/power/pmic/s2mps11.c
 create mode 100644 include/adc.h
 create mode 100644 include/power/s2mps11.h
 create mode 100644 include/samsung/exynos5-dt-types.h
Signature · 1 line
1.9.1
#31 lore raw

PATCH v2 1/11 samsung: board/misc: check returned pointer for get_board_type() calls

The function get_board_type() is called in two places by common code, but the returned pointer was never check.

This commit adds checking the returned pointer, before use it.

---
Changes V2:
- new commit

---
 board/samsung/common/board.c | 4 ++--
 board/samsung/common/misc.c  | 3 +++
 2 files changed, 5 insertions(+), 2 deletions(-)
board/samsung/common/board.c +2 -2
index d32c75d..1334c22 100644
@@ -304,8 +304,8 @@ int checkboard(void)
 	printf("Board: %s\n", board_info ? board_info : "unknown");
 #ifdef CONFIG_BOARD_TYPES
 	board_info = get_board_type();
-
-	printf("Model: %s\n", board_info ? board_info : "unknown");
+	if (board_info)
+		printf("Type:  %s\n", board_info);
 #endif
 	return 0;
 }
board/samsung/common/misc.c +3 -0
index e0e2c48..c8316d8 100644
@@ -85,6 +85,9 @@ void set_board_info(void)
 
 #ifdef CONFIG_BOARD_TYPES
 	bdtype = get_board_type();
+	if (!bdtype)
+		bdtype = "";
+
 	sprintf(info, "%s%s", bdname, bdtype);
 	setenv("boardname", info);
 #endif
Signature · 1 line
1.9.1
#32 lore raw

PATCH v2 1/11 samsung: board/misc: check returned pointer for get_board_type() calls

Quoted 5 lines · Przemyslaw Marczak

The function get_board_type() is called in two places by common code, but the returned pointer was never check.

This commit adds checking the returned pointer, before use it.

Quoted 8 lines

---
Changes V2:
- new commit

---
 board/samsung/common/board.c | 4 ++--
 board/samsung/common/misc.c  | 3 +++
 2 files changed, 5 insertions(+), 2 deletions(-)
#33 lore raw

PATCH v2 2/11 s5p: cpu_info: print "cpu-model" if exists in dts

In reply to Przemyslaw Marczak

The CPU name for Exynos was concatenated with cpu id, but for new Exynos platforms, like Chromebook Peach Pi based on Exynos5800, the name of SoC variant does not include the real SoC cpu id (0x5422).

For such case, the CPU name should be defined in device tree.

This commit introduces new device-tree property for Exynos:
- "cpu-model" - with cpu name string
If defined, then the cpu id is not printed.

---
Changes V2:
- new commit

---
 arch/arm/cpu/armv7/s5p-common/cpu_info.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)
arch/arm/cpu/armv7/s5p-common/cpu_info.c +13 -1
index 154d674..97d611f 100644
@@ -5,9 +5,12 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 #include <common.h>
+#include <fdtdec.h>
 #include <asm/io.h>
 #include <asm/arch/clk.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 /* Default is s5pc100 */
 unsigned int s5p_cpu_id = 0xC100;
 /* Default is EVT1 */
@@ -30,7 +33,16 @@ u32 get_device_type(void)
 #ifdef CONFIG_DISPLAY_CPUINFO
 int print_cpuinfo(void)
 {
-	printf("CPU:   %s%X @ ", s5p_get_cpu_name(), s5p_cpu_id);
+	const char *cpu_model = NULL;
+	int len = 0;
+
+	/* For SoC with no real CPU ID in naming convention. */
+	cpu_model = fdt_getprop(gd->fdt_blob, 0, "cpu-model", &len);
+	if (cpu_model)
+		printf("CPU:   %.*s @ ", len, cpu_model);
+	else
+		printf("CPU:   %s%X @ ", s5p_get_cpu_name(), s5p_cpu_id);
+
 	print_freq(get_arm_clk(), "\n");
 
 	return 0;
Signature · 1 line
1.9.1
#34 lore raw

PATCH v2 2/11 s5p: cpu_info: print "cpu-model" if exists in dts

Quoted 11 lines · Przemyslaw Marczak

The CPU name for Exynos was concatenated with cpu id, but for new Exynos platforms, like Chromebook Peach Pi based on Exynos5800, the name of SoC variant does not include the real SoC cpu id (0x5422).

For such case, the CPU name should be defined in device tree.

This commit introduces new device-tree property for Exynos:
- "cpu-model" - with cpu name string
If defined, then the cpu id is not printed.

Quoted 8 lines

---
Changes V2:
- new commit

---
 arch/arm/cpu/armv7/s5p-common/cpu_info.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

Please see nit below.

Quoted 18 lines
arch/arm/cpu/armv7/s5p-common/cpu_info.c +3 -0
index 154d674..97d611f 100644
@@ -5,9 +5,12 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 #include <common.h>
+#include <fdtdec.h>
 #include <asm/io.h>
 #include <asm/arch/clk.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 /* Default is s5pc100 */
 unsigned int s5p_cpu_id = 0xC100;
 /* Default is EVT1 */

arch/arm/cpu/armv7/s5p-common/cpu_info.c u32 get_device_type(void) · line 37

Quoted 6 lines
arch/arm/cpu/armv7/s5p-common/cpu_info.c +2 -1
@@ -30,7 +33,16 @@ u32 get_device_type(void)
 #ifdef CONFIG_DISPLAY_CPUINFO
 int print_cpuinfo(void)
 {
-       printf("CPU:   %s%X @ ", s5p_get_cpu_name(), s5p_cpu_id);
+       const char *cpu_model = NULL;
+       int len = 0;

No need to init these two variables.

Quoted 14 lines
arch/arm/cpu/armv7/s5p-common/cpu_info.c +8 -1
+
+       /* For SoC with no real CPU ID in naming convention. */
+       cpu_model = fdt_getprop(gd->fdt_blob, 0, "cpu-model", &len);
+       if (cpu_model)
+               printf("CPU:   %.*s @ ", len, cpu_model);
+       else
+               printf("CPU:   %s%X @ ", s5p_get_cpu_name(), s5p_cpu_id);
+
        print_freq(get_arm_clk(), "\n");
 
        return 0;
--

1.9.1

#35 lore raw

PATCH v2 2/11 s5p: cpu_info: print "cpu-model" if exists in dts

Hello Simon,

Quoted 37 lines · Simon Glass
Quoted 11 lines · Przemyslaw Marczak

The CPU name for Exynos was concatenated with cpu id, but for new Exynos platforms, like Chromebook Peach Pi based on Exynos5800, the name of SoC variant does not include the real SoC cpu id (0x5422).

For such case, the CPU name should be defined in device tree.

This commit introduces new device-tree property for Exynos:
- "cpu-model" - with cpu name string
If defined, then the cpu id is not printed.

Quoted 8 lines

---
Changes V2:
- new commit

---
  arch/arm/cpu/armv7/s5p-common/cpu_info.c | 14 +++++++++++++-
  1 file changed, 13 insertions(+), 1 deletion(-)

Please see nit below.

Quoted 12 lines
arch/arm/cpu/armv7/s5p-common/cpu_info.c +1 -0
index 154d674..97d611f 100644
@@ -5,9 +5,12 @@
   * SPDX-License-Identifier:    GPL-2.0+
   */
  #include <common.h>
+#include <fdtdec.h>
  #include <asm/io.h>
  #include <asm/arch/clk.h>
 
Quoted 15 lines

arch/arm/cpu/armv7/s5p-common/cpu_info.c u32 get_device_type(void) · line 37

Quoted 12 lines
arch/arm/cpu/armv7/s5p-common/cpu_info.c +4 -1
+DECLARE_GLOBAL_DATA_PTR;
+
  /* Default is s5pc100 */
  unsigned int s5p_cpu_id = 0xC100;
  /* Default is EVT1 */
@@ -30,7 +33,16 @@ u32 get_device_type(void)
  #ifdef CONFIG_DISPLAY_CPUINFO
  int print_cpuinfo(void)
  {
-       printf("CPU:   %s%X @ ", s5p_get_cpu_name(), s5p_cpu_id);
+       const char *cpu_model = NULL;
+       int len = 0;

No need to init these two variables.

Ok, will correct this.

Quoted 10 lines
Quoted 10 lines
arch/arm/cpu/armv7/s5p-common/cpu_info.c +8 -0
+
+       /* For SoC with no real CPU ID in naming convention. */
+       cpu_model = fdt_getprop(gd->fdt_blob, 0, "cpu-model", &len);
+       if (cpu_model)
+               printf("CPU:   %.*s @ ", len, cpu_model);
+       else
+               printf("CPU:   %s%X @ ", s5p_get_cpu_name(), s5p_cpu_id);
+
         print_freq(get_arm_clk(), "\n");
 
Quoted 5 lines
Quoted 4 lines
arch/arm/cpu/armv7/s5p-common/cpu_info.c +0 -1
         return 0;
--

1.9.1

Best regards,

Signature · 4 lines
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com
#36 lore raw

PATCH v2 3/11 Peach-Pi: dts: add cpu-model string

In reply to Przemyslaw Marczak

This platform is based on Exynos5800 but the cpu id is 0x5422. This doesn't fit the common Exynos SoC name convention, so now, the CPU name is defined by device tree string, to be printed properly.

---
Changes V2:
- move cpu name from config to dts

---
 arch/arm/dts/exynos5800-peach-pi.dts | 1 +
 1 file changed, 1 insertion(+)
arch/arm/dts/exynos5800-peach-pi.dts +1 -0
index 1d7ff23..76826dc 100644
@@ -12,6 +12,7 @@
 
 / {
 	model = "Samsung/Google Peach Pi board based on Exynos5800";
+	cpu-model = "Exynos5800";
 
 	compatible = "google,pit-rev#", "google,pit",
 		"google,peach", "samsung,exynos5800", "samsung,exynos5";
Signature · 1 line
1.9.1
#37 lore raw

PATCH v2 3/11 Peach-Pi: dts: add cpu-model string

Hi Przemyslaw,

Quoted 26 lines · Przemyslaw Marczak

This platform is based on Exynos5800 but the cpu id is 0x5422. This doesn't fit the common Exynos SoC name convention, so now, the CPU name is defined by device tree string, to be printed properly.

---
Changes V2:
- move cpu name from config to dts

---
 arch/arm/dts/exynos5800-peach-pi.dts | 1 +
 1 file changed, 1 insertion(+)
arch/arm/dts/exynos5800-peach-pi.dts +1 -1
index 1d7ff23..76826dc 100644
@@ -12,6 +12,7 @@
 
 / {
        model = "Samsung/Google Peach Pi board based on Exynos5800";
+       cpu-model = "Exynos5800";
 
        compatible = "google,pit-rev#", "google,pit",
                "google,peach", "samsung,exynos5800", "samsung,exynos5";
--
Quoted 2 lines

1.9.1

Is this defined by the standard binding? If not, can you add or change the binding file?

Regards,
Simon

#38 lore raw

PATCH v2 3/11 Peach-Pi: dts: add cpu-model string

Hello Simon,

Quoted 35 lines · Simon Glass

Hi Przemyslaw,

Quoted 26 lines · Przemyslaw Marczak

This platform is based on Exynos5800 but the cpu id is 0x5422. This doesn't fit the common Exynos SoC name convention, so now, the CPU name is defined by device tree string, to be printed properly.

---
Changes V2:
- move cpu name from config to dts

---
  arch/arm/dts/exynos5800-peach-pi.dts | 1 +
  1 file changed, 1 insertion(+)
arch/arm/dts/exynos5800-peach-pi.dts +1 -1
index 1d7ff23..76826dc 100644
@@ -12,6 +12,7 @@
 
  / {
         model = "Samsung/Google Peach Pi board based on Exynos5800";
+       cpu-model = "Exynos5800";
 
         compatible = "google,pit-rev#", "google,pit",
                 "google,peach", "samsung,exynos5800", "samsung,exynos5";
--
Quoted 2 lines

1.9.1

Is this defined by the standard binding? If not, can you add or change the binding file?

Quoted 3 lines

Regards,
Simon

No, it's not standard. I will add binding info.

Best regards

Signature · 4 lines
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com
#39 lore raw

PATCH v2 4/11 Exynos5422/5800: set cpu id to 0x5422

In reply to Przemyslaw Marczak

The proper CPU ID for those Exynos variants is 0x5422, but before the 0x5800 was set. This commit fix this back.

Changes:
- set cpu id to 0x5422 instead of 0x5800
- remove macro proid_is_exynos5800()
- add macro proid_is_exynos5422()
- change the calls to proid_is_exynos5800() with new macro

---
Changes V2:
- none

---
 arch/arm/mach-exynos/clock.c              | 16 ++++++++--------
 arch/arm/mach-exynos/clock_init_exynos5.c |  2 +-
 arch/arm/mach-exynos/common_setup.h       |  4 ++--
 arch/arm/mach-exynos/include/mach/cpu.h   |  6 +++---
 arch/arm/mach-exynos/include/mach/gpio.h  |  4 ++--
 arch/arm/mach-exynos/pinmux.c             |  2 +-
 arch/arm/mach-exynos/power.c              |  2 +-
 7 files changed, 18 insertions(+), 18 deletions(-)
arch/arm/mach-exynos/clock.c +8 -8
index 1c6baa1..2d94851 100644
@@ -159,8 +159,8 @@ static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k)
 			div = PLL_DIV_1024;
 		else if (proid_is_exynos4412())
 			div = PLL_DIV_65535;
-		else if (proid_is_exynos5250() || proid_is_exynos5420()
-			 || proid_is_exynos5800())
+		else if (proid_is_exynos5250() || proid_is_exynos5420() ||
+			 proid_is_exynos5422())
 			div = PLL_DIV_65536;
 		else
 			return 0;
@@ -346,7 +346,7 @@ static struct clk_bit_info *get_clk_bit_info(int peripheral)
 	int i;
 	struct clk_bit_info *info;
 
-	if (proid_is_exynos5420() || proid_is_exynos5800())
+	if (proid_is_exynos5420() || proid_is_exynos5422())
 		info = exynos542x_bit_info;
 	else
 		info = exynos5_bit_info;
@@ -558,7 +558,7 @@ static unsigned long exynos542x_get_periph_rate(int peripheral)
 unsigned long clock_get_periph_rate(int peripheral)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return exynos542x_get_periph_rate(peripheral);
 		return exynos5_get_periph_rate(peripheral);
 	} else {
@@ -1576,7 +1576,7 @@ static unsigned long exynos4_get_i2c_clk(void)
 unsigned long get_pll_clk(int pllreg)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return exynos542x_get_pll_clk(pllreg);
 		return exynos5_get_pll_clk(pllreg);
 	} else if (cpu_is_exynos4()) {
@@ -1694,7 +1694,7 @@ void set_mmc_clk(int dev_index, unsigned int div)
 		div -= 1;
 
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			exynos5420_set_mmc_clk(dev_index, div);
 		else
 			exynos5_set_mmc_clk(dev_index, div);
@@ -1710,7 +1710,7 @@ unsigned long get_lcd_clk(void)
 	} else if (cpu_is_exynos5()) {
 		if (proid_is_exynos5420())
 			return exynos5420_get_lcd_clk();
-		else if (proid_is_exynos5800())
+		else if (proid_is_exynos5422())
 			return exynos5800_get_lcd_clk();
 		else
 			return exynos5_get_lcd_clk();
@@ -1742,7 +1742,7 @@ void set_mipi_clk(void)
 int set_spi_clk(int periph_id, unsigned int rate)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return exynos5420_set_spi_clk(periph_id, rate);
 		return exynos5_set_spi_clk(periph_id, rate);
 	}
arch/arm/mach-exynos/clock_init_exynos5.c +1 -1
index 0200fd1..1b7498d 100644
@@ -971,7 +971,7 @@ static void exynos5420_system_clock_init(void)
 
 void system_clock_init(void)
 {
-	if (proid_is_exynos5420() || proid_is_exynos5800())
+	if (proid_is_exynos5420() || proid_is_exynos5422())
 		exynos5420_system_clock_init();
 	else
 		exynos5250_system_clock_init();
arch/arm/mach-exynos/common_setup.h +2 -2
index 67aac2d..2829fb2 100644
@@ -78,7 +78,7 @@ static inline void configure_l2_ctlr(void)
 		CACHE_TAG_RAM_LATENCY_2_CYCLES |
 		CACHE_DATA_RAM_LATENCY_2_CYCLES;
 
-	if (proid_is_exynos5420() || proid_is_exynos5800()) {
+	if (proid_is_exynos5420() || proid_is_exynos5422()) {
 		val |= CACHE_ECC_AND_PARITY |
 			CACHE_TAG_RAM_LATENCY_3_CYCLES |
 			CACHE_DATA_RAM_LATENCY_3_CYCLES;
@@ -97,7 +97,7 @@ static inline void configure_l2_actlr(void)
 {
 	uint32_t val;
 
-	if (proid_is_exynos5420() || proid_is_exynos5800()) {
+	if (proid_is_exynos5420() || proid_is_exynos5422()) {
 		mrc_l2_aux_ctlr(val);
 		val |= CACHE_ENABLE_FORCE_L2_LOGIC |
 			CACHE_DISABLE_CLEAN_EVICT;
arch/arm/mach-exynos/include/mach/cpu.h +3 -3
index cb3d2cc..14a1692 100644
@@ -237,7 +237,7 @@ static inline void s5p_set_cpu_id(void)
 		 * Exynos5800 is a variant of Exynos5420
 		 * and has product id 0x5422
 		 */
-		s5p_cpu_id = 0x5800;
+		s5p_cpu_id = 0x5422;
 		break;
 	}
 }
@@ -267,7 +267,7 @@ IS_EXYNOS_TYPE(exynos4210, 0x4210)
 IS_EXYNOS_TYPE(exynos4412, 0x4412)
 IS_EXYNOS_TYPE(exynos5250, 0x5250)
 IS_EXYNOS_TYPE(exynos5420, 0x5420)
-IS_EXYNOS_TYPE(exynos5800, 0x5800)
+IS_EXYNOS_TYPE(exynos5422, 0x5422)
 
 #define SAMSUNG_BASE(device, base)				\
 static inline unsigned int __attribute__((no_instrument_function)) \
@@ -278,7 +278,7 @@ static inline unsigned int __attribute__((no_instrument_function)) \
 			return EXYNOS4X12_##base;		\
 		return EXYNOS4_##base;				\
 	} else if (cpu_is_exynos5()) {				\
-		if (proid_is_exynos5420() || proid_is_exynos5800())	\
+		if (proid_is_exynos5420() || proid_is_exynos5422())	\
 			return EXYNOS5420_##base;		\
 		return EXYNOS5_##base;				\
 	}							\
arch/arm/mach-exynos/include/mach/gpio.h +2 -2
index 9699954..7fc8e61 100644
@@ -1398,7 +1398,7 @@ static struct gpio_info exynos5420_gpio_data[EXYNOS5420_GPIO_NUM_PARTS] = {
 static inline struct gpio_info *get_gpio_data(void)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return exynos5420_gpio_data;
 		else
 			return exynos5_gpio_data;
@@ -1415,7 +1415,7 @@ static inline struct gpio_info *get_gpio_data(void)
 static inline unsigned int get_bank_num(void)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return EXYNOS5420_GPIO_NUM_PARTS;
 		else
 			return EXYNOS5_GPIO_NUM_PARTS;
arch/arm/mach-exynos/pinmux.c +1 -1
index 179b294..a556e4a 100644
@@ -858,7 +858,7 @@ static int exynos4x12_pinmux_config(int peripheral, int flags)
 int exynos_pinmux_config(int peripheral, int flags)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return exynos5420_pinmux_config(peripheral, flags);
 		else if (proid_is_exynos5250())
 			return exynos5_pinmux_config(peripheral, flags);
arch/arm/mach-exynos/power.c +1 -1
index 1b12051..cd2d661 100644
@@ -125,7 +125,7 @@ static void exynos5420_set_usbdev_phy_ctrl(unsigned int enable)
 void set_usbdrd_phy_ctrl(unsigned int enable)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			exynos5420_set_usbdev_phy_ctrl(enable);
 		else
 			exynos5_set_usbdrd_phy_ctrl(enable);
Signature · 1 line
1.9.1
#40 lore raw

PATCH v2 4/11 Exynos5422/5800: set cpu id to 0x5422

Hi, Przemyslaw.

Quoted 132 lines · Przemyslaw Marczak

The proper CPU ID for those Exynos variants is 0x5422, but before the 0x5800 was set. This commit fix this back.

Changes:
- set cpu id to 0x5422 instead of 0x5800
- remove macro proid_is_exynos5800()
- add macro proid_is_exynos5422()
- change the calls to proid_is_exynos5800() with new macro

---
Changes V2:
- none

---
 arch/arm/mach-exynos/clock.c              | 16 ++++++++--------
 arch/arm/mach-exynos/clock_init_exynos5.c |  2 +-
 arch/arm/mach-exynos/common_setup.h       |  4 ++--
 arch/arm/mach-exynos/include/mach/cpu.h   |  6 +++---
 arch/arm/mach-exynos/include/mach/gpio.h  |  4 ++--
 arch/arm/mach-exynos/pinmux.c             |  2 +-
 arch/arm/mach-exynos/power.c              |  2 +-
 7 files changed, 18 insertions(+), 18 deletions(-)
arch/arm/mach-exynos/clock.c +8 -8
index 1c6baa1..2d94851 100644
@@ -159,8 +159,8 @@ static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k)
 			div = PLL_DIV_1024;
 		else if (proid_is_exynos4412())
 			div = PLL_DIV_65535;
-		else if (proid_is_exynos5250() || proid_is_exynos5420()
-			 || proid_is_exynos5800())
+		else if (proid_is_exynos5250() || proid_is_exynos5420() ||
+			 proid_is_exynos5422())
 			div = PLL_DIV_65536;
 		else
 			return 0;
@@ -346,7 +346,7 @@ static struct clk_bit_info *get_clk_bit_info(int peripheral)
 	int i;
 	struct clk_bit_info *info;
 
-	if (proid_is_exynos5420() || proid_is_exynos5800())
+	if (proid_is_exynos5420() || proid_is_exynos5422())
 		info = exynos542x_bit_info;
 	else
 		info = exynos5_bit_info;
@@ -558,7 +558,7 @@ static unsigned long exynos542x_get_periph_rate(int peripheral)
 unsigned long clock_get_periph_rate(int peripheral)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return exynos542x_get_periph_rate(peripheral);
 		return exynos5_get_periph_rate(peripheral);
 	} else {
@@ -1576,7 +1576,7 @@ static unsigned long exynos4_get_i2c_clk(void)
 unsigned long get_pll_clk(int pllreg)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return exynos542x_get_pll_clk(pllreg);
 		return exynos5_get_pll_clk(pllreg);
 	} else if (cpu_is_exynos4()) {
@@ -1694,7 +1694,7 @@ void set_mmc_clk(int dev_index, unsigned int div)
 		div -= 1;
 
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			exynos5420_set_mmc_clk(dev_index, div);
 		else
 			exynos5_set_mmc_clk(dev_index, div);
@@ -1710,7 +1710,7 @@ unsigned long get_lcd_clk(void)
 	} else if (cpu_is_exynos5()) {
 		if (proid_is_exynos5420())
 			return exynos5420_get_lcd_clk();
-		else if (proid_is_exynos5800())
+		else if (proid_is_exynos5422())
 			return exynos5800_get_lcd_clk();
 		else
 			return exynos5_get_lcd_clk();
@@ -1742,7 +1742,7 @@ void set_mipi_clk(void)
 int set_spi_clk(int periph_id, unsigned int rate)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return exynos5420_set_spi_clk(periph_id, rate);
 		return exynos5_set_spi_clk(periph_id, rate);
 	}
arch/arm/mach-exynos/clock_init_exynos5.c +1 -1
index 0200fd1..1b7498d 100644
@@ -971,7 +971,7 @@ static void exynos5420_system_clock_init(void)
 
 void system_clock_init(void)
 {
-	if (proid_is_exynos5420() || proid_is_exynos5800())
+	if (proid_is_exynos5420() || proid_is_exynos5422())
 		exynos5420_system_clock_init();
 	else
 		exynos5250_system_clock_init();
arch/arm/mach-exynos/common_setup.h +2 -2
index 67aac2d..2829fb2 100644
@@ -78,7 +78,7 @@ static inline void configure_l2_ctlr(void)
 		CACHE_TAG_RAM_LATENCY_2_CYCLES |
 		CACHE_DATA_RAM_LATENCY_2_CYCLES;
 
-	if (proid_is_exynos5420() || proid_is_exynos5800()) {
+	if (proid_is_exynos5420() || proid_is_exynos5422()) {
 		val |= CACHE_ECC_AND_PARITY |
 			CACHE_TAG_RAM_LATENCY_3_CYCLES |
 			CACHE_DATA_RAM_LATENCY_3_CYCLES;
@@ -97,7 +97,7 @@ static inline void configure_l2_actlr(void)
 {
 	uint32_t val;
 
-	if (proid_is_exynos5420() || proid_is_exynos5800()) {
+	if (proid_is_exynos5420() || proid_is_exynos5422()) {
 		mrc_l2_aux_ctlr(val);
 		val |= CACHE_ENABLE_FORCE_L2_LOGIC |
 			CACHE_DISABLE_CLEAN_EVICT;
arch/arm/mach-exynos/include/mach/cpu.h +0 -0
index cb3d2cc..14a1692 100644

arch/arm/mach-exynos/include/mach/cpu.h static inline void s5p_set_cpu_id(void) · line 239

Quoted 3 lines
arch/arm/mach-exynos/include/mach/cpu.h +0 -0
@@ -237,7 +237,7 @@ static inline void s5p_set_cpu_id(void)
 		 * Exynos5800 is a variant of Exynos5420
 		 * and has product id 0x5422
 		 */

Needs to modify the above comment?

Best Regards,
Jaehoon Chung

Quoted 72 lines
arch/arm/mach-exynos/include/mach/cpu.h +3 -3
-		s5p_cpu_id = 0x5800;
+		s5p_cpu_id = 0x5422;
 		break;
 	}
 }
@@ -267,7 +267,7 @@ IS_EXYNOS_TYPE(exynos4210, 0x4210)
 IS_EXYNOS_TYPE(exynos4412, 0x4412)
 IS_EXYNOS_TYPE(exynos5250, 0x5250)
 IS_EXYNOS_TYPE(exynos5420, 0x5420)
-IS_EXYNOS_TYPE(exynos5800, 0x5800)
+IS_EXYNOS_TYPE(exynos5422, 0x5422)
 
 #define SAMSUNG_BASE(device, base)				\
 static inline unsigned int __attribute__((no_instrument_function)) \
@@ -278,7 +278,7 @@ static inline unsigned int __attribute__((no_instrument_function)) \
 			return EXYNOS4X12_##base;		\
 		return EXYNOS4_##base;				\
 	} else if (cpu_is_exynos5()) {				\
-		if (proid_is_exynos5420() || proid_is_exynos5800())	\
+		if (proid_is_exynos5420() || proid_is_exynos5422())	\
 			return EXYNOS5420_##base;		\
 		return EXYNOS5_##base;				\
 	}							\
arch/arm/mach-exynos/include/mach/gpio.h +2 -2
index 9699954..7fc8e61 100644
@@ -1398,7 +1398,7 @@ static struct gpio_info exynos5420_gpio_data[EXYNOS5420_GPIO_NUM_PARTS] = {
 static inline struct gpio_info *get_gpio_data(void)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return exynos5420_gpio_data;
 		else
 			return exynos5_gpio_data;
@@ -1415,7 +1415,7 @@ static inline struct gpio_info *get_gpio_data(void)
 static inline unsigned int get_bank_num(void)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return EXYNOS5420_GPIO_NUM_PARTS;
 		else
 			return EXYNOS5_GPIO_NUM_PARTS;
arch/arm/mach-exynos/pinmux.c +1 -1
index 179b294..a556e4a 100644
@@ -858,7 +858,7 @@ static int exynos4x12_pinmux_config(int peripheral, int flags)
 int exynos_pinmux_config(int peripheral, int flags)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return exynos5420_pinmux_config(peripheral, flags);
 		else if (proid_is_exynos5250())
 			return exynos5_pinmux_config(peripheral, flags);
arch/arm/mach-exynos/power.c +1 -1
index 1b12051..cd2d661 100644
@@ -125,7 +125,7 @@ static void exynos5420_set_usbdev_phy_ctrl(unsigned int enable)
 void set_usbdrd_phy_ctrl(unsigned int enable)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			exynos5420_set_usbdev_phy_ctrl(enable);
 		else
 			exynos5_set_usbdrd_phy_ctrl(enable);
#41 lore raw

PATCH v2 4/11 Exynos5422/5800: set cpu id to 0x5422

Hello Jaehoon,

Quoted 141 lines · Jaehoon Chung

Hi, Przemyslaw.

Quoted 132 lines · Przemyslaw Marczak

The proper CPU ID for those Exynos variants is 0x5422, but before the 0x5800 was set. This commit fix this back.

Changes:
- set cpu id to 0x5422 instead of 0x5800
- remove macro proid_is_exynos5800()
- add macro proid_is_exynos5422()
- change the calls to proid_is_exynos5800() with new macro

---
Changes V2:
- none

---
  arch/arm/mach-exynos/clock.c              | 16 ++++++++--------
  arch/arm/mach-exynos/clock_init_exynos5.c |  2 +-
  arch/arm/mach-exynos/common_setup.h       |  4 ++--
  arch/arm/mach-exynos/include/mach/cpu.h   |  6 +++---
  arch/arm/mach-exynos/include/mach/gpio.h  |  4 ++--
  arch/arm/mach-exynos/pinmux.c             |  2 +-
  arch/arm/mach-exynos/power.c              |  2 +-
  7 files changed, 18 insertions(+), 18 deletions(-)
arch/arm/mach-exynos/clock.c +8 -8
index 1c6baa1..2d94851 100644
@@ -159,8 +159,8 @@ static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k)
  			div = PLL_DIV_1024;
  		else if (proid_is_exynos4412())
  			div = PLL_DIV_65535;
-		else if (proid_is_exynos5250() || proid_is_exynos5420()
-			 || proid_is_exynos5800())
+		else if (proid_is_exynos5250() || proid_is_exynos5420() ||
+			 proid_is_exynos5422())
  			div = PLL_DIV_65536;
  		else
  			return 0;
@@ -346,7 +346,7 @@ static struct clk_bit_info *get_clk_bit_info(int peripheral)
  	int i;
  	struct clk_bit_info *info;
 
-	if (proid_is_exynos5420() || proid_is_exynos5800())
+	if (proid_is_exynos5420() || proid_is_exynos5422())
  		info = exynos542x_bit_info;
  	else
  		info = exynos5_bit_info;
@@ -558,7 +558,7 @@ static unsigned long exynos542x_get_periph_rate(int peripheral)
  unsigned long clock_get_periph_rate(int peripheral)
  {
  	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
  			return exynos542x_get_periph_rate(peripheral);
  		return exynos5_get_periph_rate(peripheral);
  	} else {
@@ -1576,7 +1576,7 @@ static unsigned long exynos4_get_i2c_clk(void)
  unsigned long get_pll_clk(int pllreg)
  {
  	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
  			return exynos542x_get_pll_clk(pllreg);
  		return exynos5_get_pll_clk(pllreg);
  	} else if (cpu_is_exynos4()) {
@@ -1694,7 +1694,7 @@ void set_mmc_clk(int dev_index, unsigned int div)
  		div -= 1;
 
  	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
  			exynos5420_set_mmc_clk(dev_index, div);
  		else
  			exynos5_set_mmc_clk(dev_index, div);
@@ -1710,7 +1710,7 @@ unsigned long get_lcd_clk(void)
  	} else if (cpu_is_exynos5()) {
  		if (proid_is_exynos5420())
  			return exynos5420_get_lcd_clk();
-		else if (proid_is_exynos5800())
+		else if (proid_is_exynos5422())
  			return exynos5800_get_lcd_clk();
  		else
  			return exynos5_get_lcd_clk();
@@ -1742,7 +1742,7 @@ void set_mipi_clk(void)
  int set_spi_clk(int periph_id, unsigned int rate)
  {
  	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
  			return exynos5420_set_spi_clk(periph_id, rate);
  		return exynos5_set_spi_clk(periph_id, rate);
  	}
arch/arm/mach-exynos/clock_init_exynos5.c +1 -1
index 0200fd1..1b7498d 100644
@@ -971,7 +971,7 @@ static void exynos5420_system_clock_init(void)
 
  void system_clock_init(void)
  {
-	if (proid_is_exynos5420() || proid_is_exynos5800())
+	if (proid_is_exynos5420() || proid_is_exynos5422())
  		exynos5420_system_clock_init();
  	else
  		exynos5250_system_clock_init();
arch/arm/mach-exynos/common_setup.h +2 -2
index 67aac2d..2829fb2 100644
@@ -78,7 +78,7 @@ static inline void configure_l2_ctlr(void)
  		CACHE_TAG_RAM_LATENCY_2_CYCLES |
  		CACHE_DATA_RAM_LATENCY_2_CYCLES;
 
-	if (proid_is_exynos5420() || proid_is_exynos5800()) {
+	if (proid_is_exynos5420() || proid_is_exynos5422()) {
  		val |= CACHE_ECC_AND_PARITY |
  			CACHE_TAG_RAM_LATENCY_3_CYCLES |
  			CACHE_DATA_RAM_LATENCY_3_CYCLES;
@@ -97,7 +97,7 @@ static inline void configure_l2_actlr(void)
  {
  	uint32_t val;
 
-	if (proid_is_exynos5420() || proid_is_exynos5800()) {
+	if (proid_is_exynos5420() || proid_is_exynos5422()) {
  		mrc_l2_aux_ctlr(val);
  		val |= CACHE_ENABLE_FORCE_L2_LOGIC |
  			CACHE_DISABLE_CLEAN_EVICT;
arch/arm/mach-exynos/include/mach/cpu.h +0 -0
index cb3d2cc..14a1692 100644

arch/arm/mach-exynos/include/mach/cpu.h static inline void s5p_set_cpu_id(void) · line 239

Quoted 3 lines
arch/arm/mach-exynos/include/mach/cpu.h +0 -0
@@ -237,7 +237,7 @@ static inline void s5p_set_cpu_id(void)
  		 * Exynos5800 is a variant of Exynos5420
  		 * and has product id 0x5422
  		 */

Needs to modify the above comment?

Quoted 3 lines

Best Regards,
Jaehoon Chung

Thanks! Will fix in next version.

Best regards,

Signature · 4 lines
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com
#42 lore raw

PATCH v2 5/11 dm: pmic: add s2mps11 PMIC I/O driver

In reply to Przemyslaw Marczak

This driver allows I/O operations on the Samsung S2MPS11 PMIC, which provides lots of LDO/BUCK outputs.

To enable it, update defconfig with:
- CONFIG_PMIC_S2MPS11
and additional, if were not defined:
- CONFIG_CMD_PMIC
- CONFIG_ERRNO_STR

The binding info: doc/device-tree-bindings/pmic/s2mps11.txt

---
Changes V2:
- remove "DM" prefix from config name
- fix word mistake in binding description

---
 doc/device-tree-bindings/pmic/s2mps11.txt |  17 +++++
 drivers/power/pmic/Kconfig                |  14 ++++
 drivers/power/pmic/Makefile               |   1 +
 drivers/power/pmic/s2mps11.c              |  60 ++++++++++++++++
 include/power/s2mps11.h                   | 109 ++++++++++++++++++++++++++++++
 5 files changed, 201 insertions(+)
 create mode 100644 doc/device-tree-bindings/pmic/s2mps11.txt
 create mode 100644 drivers/power/pmic/s2mps11.c
 create mode 100644 include/power/s2mps11.h
doc/device-tree-bindings/pmic/s2mps11.txt new file +17 -0
new file mode 100644
index 0000000..422f14f
@@ -0,0 +1,17 @@
+SAMSUNG, S2MPS11 PMIC
+
+This file describes the binding info for the PMIC driver:
+- drivers/power/pmic/s2mps11.c
+
+Required properties:
+- compatible: "samsung,s2mps11-pmic"
+- reg = 0x66
+
+With those two properties, the pmic device can be used for read/write only.
+
+Example:
+
+s2mps11 at 66 {
+	compatible = "samsung,s2mps11-pmic";
+	reg = <0x66>;
+};
drivers/power/pmic/Kconfig +14 -0
index 547fd1a..fb29843 100644
@@ -33,6 +33,20 @@ config DM_PMIC_MAX77686
 	This config enables implementation of driver-model pmic uclass features
 	for PMIC MAX77686. The driver implements read/write operations.
 
+config PMIC_S2MPS11
+	bool "Enable Driver Model for PMIC Samsung S2MPS11"
+	depends on DM_PMIC
+	---help---
+	The Samsung S2MPS11 PMIC provides:
+	 - 38 adjustable LDO regulators
+	 - 9 High-Efficiency Buck Converters
+	 - 1 BuckBoost Converter
+	 - RTC with two alarms
+	 - Backup battery charger
+	 - I2C Configuration Interface
+	This driver provides access to I/O interface only.
+	Binding info: doc/device-tree-bindings/pmic/s2mps11.txt
+
 config DM_PMIC_SANDBOX
 	bool "Enable Driver Model for emulated Sandbox PMIC "
 	depends on DM_PMIC
drivers/power/pmic/Makefile +1 -0
index 00fde71..91e78f8 100644
@@ -8,6 +8,7 @@
 obj-$(CONFIG_DM_PMIC) += pmic-uclass.o
 obj-$(CONFIG_DM_PMIC_MAX77686) += max77686.o
 obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze100.o
+obj-$(CONFIG_PMIC_S2MPS11) += s2mps11.o
 obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o
 obj-$(CONFIG_PMIC_ACT8846) += act8846.o
 obj-$(CONFIG_PMIC_TPS65090) += tps65090.o
drivers/power/pmic/s2mps11.c new file +60 -0

60 lines not on this page · raw message

include/power/s2mps11.h new file +109 -0

109 lines not on this page · raw message

Signature · 1 line
1.9.1
#43 lore raw

PATCH v2 5/11 dm: pmic: add s2mps11 PMIC I/O driver

Hi Przemyslaw,

Quoted 16 lines · Przemyslaw Marczak

This driver allows I/O operations on the Samsung S2MPS11 PMIC, which provides lots of LDO/BUCK outputs.

To enable it, update defconfig with:
- CONFIG_PMIC_S2MPS11
and additional, if were not defined:
- CONFIG_CMD_PMIC
- CONFIG_ERRNO_STR

The binding info: doc/device-tree-bindings/pmic/s2mps11.txt

---
Changes V2:
- remove "DM" prefix from config name
- fix word mistake in binding description

Quoted 10 lines
---
 doc/device-tree-bindings/pmic/s2mps11.txt |  17 +++++
 drivers/power/pmic/Kconfig                |  14 ++++
 drivers/power/pmic/Makefile               |   1 +
 drivers/power/pmic/s2mps11.c              |  60 ++++++++++++++++
 include/power/s2mps11.h                   | 109 ++++++++++++++++++++++++++++++
 5 files changed, 201 insertions(+)
 create mode 100644 doc/device-tree-bindings/pmic/s2mps11.txt
 create mode 100644 drivers/power/pmic/s2mps11.c
 create mode 100644 include/power/s2mps11.h

But please see nit below.

Quoted 85 lines
doc/device-tree-bindings/pmic/s2mps11.txt new file +17 -0
new file mode 100644
index 0000000..422f14f
@@ -0,0 +1,17 @@
+SAMSUNG, S2MPS11 PMIC
+
+This file describes the binding info for the PMIC driver:
+- drivers/power/pmic/s2mps11.c
+
+Required properties:
+- compatible: "samsung,s2mps11-pmic"
+- reg = 0x66
+
+With those two properties, the pmic device can be used for read/write only.
+
+Example:
+
+s2mps11 at 66 {
+       compatible = "samsung,s2mps11-pmic";
+       reg = <0x66>;
+};
drivers/power/pmic/Kconfig +14 -0
index 547fd1a..fb29843 100644
@@ -33,6 +33,20 @@ config DM_PMIC_MAX77686
        This config enables implementation of driver-model pmic uclass features
        for PMIC MAX77686. The driver implements read/write operations.
 
+config PMIC_S2MPS11
+       bool "Enable Driver Model for PMIC Samsung S2MPS11"
+       depends on DM_PMIC
+       ---help---
+       The Samsung S2MPS11 PMIC provides:
+        - 38 adjustable LDO regulators
+        - 9 High-Efficiency Buck Converters
+        - 1 BuckBoost Converter
+        - RTC with two alarms
+        - Backup battery charger
+        - I2C Configuration Interface
+       This driver provides access to I/O interface only.
+       Binding info: doc/device-tree-bindings/pmic/s2mps11.txt
+
 config DM_PMIC_SANDBOX
        bool "Enable Driver Model for emulated Sandbox PMIC "
        depends on DM_PMIC
drivers/power/pmic/Makefile +1 -0
index 00fde71..91e78f8 100644
@@ -8,6 +8,7 @@
 obj-$(CONFIG_DM_PMIC) += pmic-uclass.o
 obj-$(CONFIG_DM_PMIC_MAX77686) += max77686.o
 obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze100.o
+obj-$(CONFIG_PMIC_S2MPS11) += s2mps11.o
 obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o
 obj-$(CONFIG_PMIC_ACT8846) += act8846.o
 obj-$(CONFIG_PMIC_TPS65090) += tps65090.o
drivers/power/pmic/s2mps11.c new file +18 -0
new file mode 100644
index 0000000..7e28402
@@ -0,0 +1,60 @@
+/*
+ *  Copyright (C) 2015 Samsung Electronics
+ *  Przemyslaw Marczak  <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <errno.h>
+#include <dm.h>
+#include <i2c.h>
+#include <power/pmic.h>
+#include <power/s2mps11.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int s2mps11_reg_count(struct udevice *dev)

drivers/power/pmic/s2mps11.c line 28

Quoted 10 lines
drivers/power/pmic/s2mps11.c new file +10 -0
+{
+       return S2MPS11_REG_COUNT;
+}
+
+static int s2mps11_write(struct udevice *dev, uint reg, const uint8_t *buff,
+                        int len)
+{
+       if (dm_i2c_write(dev, reg, buff, len)) {
+               error("write error to device: %p register: %#x!", dev, reg);
+               return -EIO;

Should return the value of dm_i2c_write(). Also below.

Quoted 148 lines
drivers/power/pmic/s2mps11.c new file +32 -0
+       }
+
+       return 0;
+}
+
+static int s2mps11_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
+{
+       if (dm_i2c_read(dev, reg, buff, len)) {
+               error("read error from device: %p register: %#x!", dev, reg);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static struct dm_pmic_ops s2mps11_ops = {
+       .reg_count = s2mps11_reg_count,
+       .read = s2mps11_read,
+       .write = s2mps11_write,
+};
+
+static const struct udevice_id s2mps11_ids[] = {
+       { .compatible = "samsung,s2mps11-pmic" },
+       { }
+};
+
+U_BOOT_DRIVER(pmic_s2mps11) = {
+       .name = "s2mps11_pmic",
+       .id = UCLASS_PMIC,
+       .of_match = s2mps11_ids,
+       .ops = &s2mps11_ops,
+};
include/power/s2mps11.h new file +109 -1
new file mode 100644
index 0000000..5da4719
@@ -0,0 +1,109 @@
+#ifndef __S2MPS11__H__
+#define __S2MPS11__H__
+
+enum s2mps11_reg {
+       S2MPS11_REG_ID = 0,
+       S2MPS11_REG_INT1,
+       S2MPS11_REG_INT2,
+       S2MPS11_REG_INT3,
+       S2MPS11_REG_INT1M,
+       S2MPS11_REG_INT2M,
+       S2MPS11_REG_INT3M,
+       S2MPS11_REG_STATUS1,
+       S2MPS11_REG_STATUS2,
+       S2MPS11_REG_OFFSRC,
+       S2MPS11_REG_PWRONSRC,
+       S2MPS11_REG_RTC_CTRL,
+       S2MPS11_REG_CTRL1,
+       S2MPS11_REG_ETC_TEST,
+       S2MPS11_REG_RSVD3,
+       S2MPS11_REG_BU_CHG,
+       S2MPS11_REG_RAMP,
+       S2MPS11_REG_RAMP_BUCK,
+       S2MPS11_REG_LDO1_8,
+       S2MPS11_REG_LDO9_16,
+       S2MPS11_REG_LDO17_24,
+       S2MPS11_REG_LDO25_32,
+       S2MPS11_REG_LDO33_38,
+       S2MPS11_REG_LDO1_8_OVC,
+       S2MPS11_REG_LDO9_16_OVC,
+       S2MPS11_REG_LDO17_24_OVC,
+       S2MPS11_REG_LDO25_32_OVC,
+       S2MPS11_REG_LDO33_38_OVC,
+       S2MPS11_REG_RESERVED1,
+       S2MPS11_REG_RESERVED2,
+       S2MPS11_REG_RESERVED3,
+       S2MPS11_REG_RESERVED4,
+       S2MPS11_REG_RESERVED5,
+       S2MPS11_REG_RESERVED6,
+       S2MPS11_REG_RESERVED7,
+       S2MPS11_REG_RESERVED8,
+       S2MPS11_REG_WDRSTEN_CTRL,
+       S2MPS11_REG_B1CTRL1,
+       S2MPS11_REG_B1CTRL2,
+       S2MPS11_REG_B2CTRL1,
+       S2MPS11_REG_B2CTRL2,
+       S2MPS11_REG_B3CTRL1,
+       S2MPS11_REG_B3CTRL2,
+       S2MPS11_REG_B4CTRL1,
+       S2MPS11_REG_B4CTRL2,
+       S2MPS11_REG_B5CTRL1,
+       S2MPS11_REG_BUCK5_SW,
+       S2MPS11_REG_B5CTRL2,
+       S2MPS11_REG_B5CTRL3,
+       S2MPS11_REG_B5CTRL4,
+       S2MPS11_REG_B5CTRL5,
+       S2MPS11_REG_B6CTRL1,
+       S2MPS11_REG_B6CTRL2,
+       S2MPS11_REG_B7CTRL1,
+       S2MPS11_REG_B7CTRL2,
+       S2MPS11_REG_B8CTRL1,
+       S2MPS11_REG_B8CTRL2,
+       S2MPS11_REG_B9CTRL1,
+       S2MPS11_REG_B9CTRL2,
+       S2MPS11_REG_B10CTRL1,
+       S2MPS11_REG_B10CTRL2,
+       S2MPS11_REG_L1CTRL,
+       S2MPS11_REG_L2CTRL,
+       S2MPS11_REG_L3CTRL,
+       S2MPS11_REG_L4CTRL,
+       S2MPS11_REG_L5CTRL,
+       S2MPS11_REG_L6CTRL,
+       S2MPS11_REG_L7CTRL,
+       S2MPS11_REG_L8CTRL,
+       S2MPS11_REG_L9CTRL,
+       S2MPS11_REG_L10CTRL,
+       S2MPS11_REG_L11CTRL,
+       S2MPS11_REG_L12CTRL,
+       S2MPS11_REG_L13CTRL,
+       S2MPS11_REG_L14CTRL,
+       S2MPS11_REG_L15CTRL,
+       S2MPS11_REG_L16CTRL,
+       S2MPS11_REG_L17CTRL,
+       S2MPS11_REG_L18CTRL,
+       S2MPS11_REG_L19CTRL,
+       S2MPS11_REG_L20CTRL,
+       S2MPS11_REG_L21CTRL,
+       S2MPS11_REG_L22CTRL,
+       S2MPS11_REG_L23CTRL,
+       S2MPS11_REG_L24CTRL,
+       S2MPS11_REG_L25CTRL,
+       S2MPS11_REG_L26CTRL,
+       S2MPS11_REG_L27CTRL,
+       S2MPS11_REG_L28CTRL,
+       S2MPS11_REG_L29CTRL,
+       S2MPS11_REG_L30CTRL,
+       S2MPS11_REG_L31CTRL,
+       S2MPS11_REG_L32CTRL,
+       S2MPS11_REG_L33CTRL,
+       S2MPS11_REG_L34CTRL,
+       S2MPS11_REG_L35CTRL,
+       S2MPS11_REG_L36CTRL,
+       S2MPS11_REG_L37CTRL,
+       S2MPS11_REG_L38CTRL,
+       S2MPS11_REG_COUNT,
+};
+
+#define S2MPS11_LDO26_ENABLE   0xec
+
+#endif
--
Quoted 2 lines

1.9.1

Regards,
Simon

#44 lore raw

PATCH v2 5/11 dm: pmic: add s2mps11 PMIC I/O driver

Hi Simon,

Quoted 123 lines · Simon Glass

Hi Przemyslaw,

Quoted 23 lines · Przemyslaw Marczak

This driver allows I/O operations on the Samsung S2MPS11 PMIC, which provides lots of LDO/BUCK outputs.

To enable it, update defconfig with:
- CONFIG_PMIC_S2MPS11
and additional, if were not defined:
- CONFIG_CMD_PMIC
- CONFIG_ERRNO_STR

The binding info: doc/device-tree-bindings/pmic/s2mps11.txt

---
Changes V2:
- remove "DM" prefix from config name
- fix word mistake in binding description

---
  doc/device-tree-bindings/pmic/s2mps11.txt |  17 +++++
  drivers/power/pmic/Kconfig                |  14 ++++
  drivers/power/pmic/Makefile               |   1 +
  drivers/power/pmic/s2mps11.c              |  60 ++++++++++++++++
  include/power/s2mps11.h                   | 109 ++++++++++++++++++++++++++++++
  5 files changed, 201 insertions(+)
Quoted 3 lines

create mode 100644 doc/device-tree-bindings/pmic/s2mps11.txt create mode 100644 drivers/power/pmic/s2mps11.c create mode 100644 include/power/s2mps11.h

But please see nit below.

Quoted 89 lines
doc/device-tree-bindings/pmic/s2mps11.txt new file +17 -0
new file mode 100644
index 0000000..422f14f
@@ -0,0 +1,17 @@
+SAMSUNG, S2MPS11 PMIC
+
+This file describes the binding info for the PMIC driver:
+- drivers/power/pmic/s2mps11.c
+
+Required properties:
+- compatible: "samsung,s2mps11-pmic"
+- reg = 0x66
+
+With those two properties, the pmic device can be used for read/write only.
+
+Example:
+
+s2mps11 at 66 {
+       compatible = "samsung,s2mps11-pmic";
+       reg = <0x66>;
+};
drivers/power/pmic/Kconfig +14 -0
index 547fd1a..fb29843 100644
@@ -33,6 +33,20 @@ config DM_PMIC_MAX77686
         This config enables implementation of driver-model pmic uclass features
         for PMIC MAX77686. The driver implements read/write operations.
 
+config PMIC_S2MPS11
+       bool "Enable Driver Model for PMIC Samsung S2MPS11"
+       depends on DM_PMIC
+       ---help---
+       The Samsung S2MPS11 PMIC provides:
+        - 38 adjustable LDO regulators
+        - 9 High-Efficiency Buck Converters
+        - 1 BuckBoost Converter
+        - RTC with two alarms
+        - Backup battery charger
+        - I2C Configuration Interface
+       This driver provides access to I/O interface only.
+       Binding info: doc/device-tree-bindings/pmic/s2mps11.txt
+
  config DM_PMIC_SANDBOX
         bool "Enable Driver Model for emulated Sandbox PMIC "
         depends on DM_PMIC
drivers/power/pmic/Makefile +1 -0
index 00fde71..91e78f8 100644
@@ -8,6 +8,7 @@
  obj-$(CONFIG_DM_PMIC) += pmic-uclass.o
  obj-$(CONFIG_DM_PMIC_MAX77686) += max77686.o
  obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze100.o
+obj-$(CONFIG_PMIC_S2MPS11) += s2mps11.o
  obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o
  obj-$(CONFIG_PMIC_ACT8846) += act8846.o
  obj-$(CONFIG_PMIC_TPS65090) += tps65090.o
drivers/power/pmic/s2mps11.c new file +22 -0
new file mode 100644
index 0000000..7e28402
@@ -0,0 +1,60 @@
+/*
+ *  Copyright (C) 2015 Samsung Electronics
+ *  Przemyslaw Marczak  <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <errno.h>
+#include <dm.h>
+#include <i2c.h>
+#include <power/pmic.h>
+#include <power/s2mps11.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int s2mps11_reg_count(struct udevice *dev)
+{
+       return S2MPS11_REG_COUNT;
+}
+
Quoted 9 lines

drivers/power/pmic/s2mps11.c line 28

Quoted 6 lines
drivers/power/pmic/s2mps11.c new file +6 -0
+static int s2mps11_write(struct udevice *dev, uint reg, const uint8_t *buff,
+                        int len)
+{
+       if (dm_i2c_write(dev, reg, buff, len)) {
+               error("write error to device: %p register: %#x!", dev, reg);
+               return -EIO;

Should return the value of dm_i2c_write(). Also below.

Right, will fix.

Quoted 145 lines
Quoted 145 lines
drivers/power/pmic/s2mps11.c new file +32 -0
+       }
+
+       return 0;
+}
+
+static int s2mps11_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
+{
+       if (dm_i2c_read(dev, reg, buff, len)) {
+               error("read error from device: %p register: %#x!", dev, reg);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static struct dm_pmic_ops s2mps11_ops = {
+       .reg_count = s2mps11_reg_count,
+       .read = s2mps11_read,
+       .write = s2mps11_write,
+};
+
+static const struct udevice_id s2mps11_ids[] = {
+       { .compatible = "samsung,s2mps11-pmic" },
+       { }
+};
+
+U_BOOT_DRIVER(pmic_s2mps11) = {
+       .name = "s2mps11_pmic",
+       .id = UCLASS_PMIC,
+       .of_match = s2mps11_ids,
+       .ops = &s2mps11_ops,
+};
include/power/s2mps11.h new file +107 -0
new file mode 100644
index 0000000..5da4719
@@ -0,0 +1,109 @@
+#ifndef __S2MPS11__H__
+#define __S2MPS11__H__
+
+enum s2mps11_reg {
+       S2MPS11_REG_ID = 0,
+       S2MPS11_REG_INT1,
+       S2MPS11_REG_INT2,
+       S2MPS11_REG_INT3,
+       S2MPS11_REG_INT1M,
+       S2MPS11_REG_INT2M,
+       S2MPS11_REG_INT3M,
+       S2MPS11_REG_STATUS1,
+       S2MPS11_REG_STATUS2,
+       S2MPS11_REG_OFFSRC,
+       S2MPS11_REG_PWRONSRC,
+       S2MPS11_REG_RTC_CTRL,
+       S2MPS11_REG_CTRL1,
+       S2MPS11_REG_ETC_TEST,
+       S2MPS11_REG_RSVD3,
+       S2MPS11_REG_BU_CHG,
+       S2MPS11_REG_RAMP,
+       S2MPS11_REG_RAMP_BUCK,
+       S2MPS11_REG_LDO1_8,
+       S2MPS11_REG_LDO9_16,
+       S2MPS11_REG_LDO17_24,
+       S2MPS11_REG_LDO25_32,
+       S2MPS11_REG_LDO33_38,
+       S2MPS11_REG_LDO1_8_OVC,
+       S2MPS11_REG_LDO9_16_OVC,
+       S2MPS11_REG_LDO17_24_OVC,
+       S2MPS11_REG_LDO25_32_OVC,
+       S2MPS11_REG_LDO33_38_OVC,
+       S2MPS11_REG_RESERVED1,
+       S2MPS11_REG_RESERVED2,
+       S2MPS11_REG_RESERVED3,
+       S2MPS11_REG_RESERVED4,
+       S2MPS11_REG_RESERVED5,
+       S2MPS11_REG_RESERVED6,
+       S2MPS11_REG_RESERVED7,
+       S2MPS11_REG_RESERVED8,
+       S2MPS11_REG_WDRSTEN_CTRL,
+       S2MPS11_REG_B1CTRL1,
+       S2MPS11_REG_B1CTRL2,
+       S2MPS11_REG_B2CTRL1,
+       S2MPS11_REG_B2CTRL2,
+       S2MPS11_REG_B3CTRL1,
+       S2MPS11_REG_B3CTRL2,
+       S2MPS11_REG_B4CTRL1,
+       S2MPS11_REG_B4CTRL2,
+       S2MPS11_REG_B5CTRL1,
+       S2MPS11_REG_BUCK5_SW,
+       S2MPS11_REG_B5CTRL2,
+       S2MPS11_REG_B5CTRL3,
+       S2MPS11_REG_B5CTRL4,
+       S2MPS11_REG_B5CTRL5,
+       S2MPS11_REG_B6CTRL1,
+       S2MPS11_REG_B6CTRL2,
+       S2MPS11_REG_B7CTRL1,
+       S2MPS11_REG_B7CTRL2,
+       S2MPS11_REG_B8CTRL1,
+       S2MPS11_REG_B8CTRL2,
+       S2MPS11_REG_B9CTRL1,
+       S2MPS11_REG_B9CTRL2,
+       S2MPS11_REG_B10CTRL1,
+       S2MPS11_REG_B10CTRL2,
+       S2MPS11_REG_L1CTRL,
+       S2MPS11_REG_L2CTRL,
+       S2MPS11_REG_L3CTRL,
+       S2MPS11_REG_L4CTRL,
+       S2MPS11_REG_L5CTRL,
+       S2MPS11_REG_L6CTRL,
+       S2MPS11_REG_L7CTRL,
+       S2MPS11_REG_L8CTRL,
+       S2MPS11_REG_L9CTRL,
+       S2MPS11_REG_L10CTRL,
+       S2MPS11_REG_L11CTRL,
+       S2MPS11_REG_L12CTRL,
+       S2MPS11_REG_L13CTRL,
+       S2MPS11_REG_L14CTRL,
+       S2MPS11_REG_L15CTRL,
+       S2MPS11_REG_L16CTRL,
+       S2MPS11_REG_L17CTRL,
+       S2MPS11_REG_L18CTRL,
+       S2MPS11_REG_L19CTRL,
+       S2MPS11_REG_L20CTRL,
+       S2MPS11_REG_L21CTRL,
+       S2MPS11_REG_L22CTRL,
+       S2MPS11_REG_L23CTRL,
+       S2MPS11_REG_L24CTRL,
+       S2MPS11_REG_L25CTRL,
+       S2MPS11_REG_L26CTRL,
+       S2MPS11_REG_L27CTRL,
+       S2MPS11_REG_L28CTRL,
+       S2MPS11_REG_L29CTRL,
+       S2MPS11_REG_L30CTRL,
+       S2MPS11_REG_L31CTRL,
+       S2MPS11_REG_L32CTRL,
+       S2MPS11_REG_L33CTRL,
+       S2MPS11_REG_L34CTRL,
+       S2MPS11_REG_L35CTRL,
+       S2MPS11_REG_L36CTRL,
+       S2MPS11_REG_L37CTRL,
+       S2MPS11_REG_L38CTRL,
+       S2MPS11_REG_COUNT,
+};
+
+#define S2MPS11_LDO26_ENABLE   0xec
Quoted 9 lines
Quoted 5 lines
include/power/s2mps11.h new file +2 -1
+
+#endif
--

1.9.1

Regards,
Simon

Best regards,

Signature · 4 lines
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com
#45 lore raw

PATCH v2 6/11 dm: adc: add simple ADC uclass implementation

In reply to Przemyslaw Marczak

This commit adds:
- new uclass id: UCLASS_ADC
- new uclass driver: drivers/adc/adc-uclass.c

The uclass's implementation is as simple as needed and provides functions:
- adc_init() - init ADC conversion
- adc_data() - convert and return data
- adc_data_mask() - return ADC data mask
- adc_channel_single_shot() - function for single ADC convertion

---
Changes V2:
- new commit - introduce ADC uclass driver

---
 drivers/Kconfig          |  2 ++
 drivers/Makefile         |  1 +
 drivers/adc/Kconfig      |  8 +++++
 drivers/adc/Makefile     |  8 +++++
 drivers/adc/adc-uclass.c | 76 +++++++++++++++++++++++++++++++++++++++++
 include/adc.h            | 88 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/dm/uclass-id.h   |  1 +
 7 files changed, 184 insertions(+)
 create mode 100644 drivers/adc/Kconfig
 create mode 100644 drivers/adc/Makefile
 create mode 100644 drivers/adc/adc-uclass.c
 create mode 100644 include/adc.h
drivers/Kconfig +2 -0
index 63c92c5..ad9ae3a 100644
@@ -4,6 +4,8 @@ source "drivers/core/Kconfig"
 
 # types of drivers sorted in alphabetical order
 
+source "drivers/adc/Kconfig"
+
 source "drivers/block/Kconfig"
 
 source "drivers/clk/Kconfig"
drivers/Makefile +1 -0
index 9d0a595..d7d5e9f 100644
@@ -35,6 +35,7 @@ obj-$(CONFIG_SPL_SATA_SUPPORT) += block/
 
 else
 
+obj-y += adc/
 obj-$(CONFIG_DM_DEMO) += demo/
 obj-$(CONFIG_BIOSEMU) += bios_emulator/
 obj-y += block/
drivers/adc/Kconfig new file +8 -0
new file mode 100644
index 0000000..1cb1a8d
@@ -0,0 +1,8 @@
+config ADC
+	bool "Enable ADC drivers using Driver Model"
+	help
+	  This allows drivers to be provided for ADCs to drive their features,
+	  trough simple ADC uclass driver interface, with operations:
+	  - device enable
+	  - conversion init
+	  - conversion start and return data with data mask
drivers/adc/Makefile new file +8 -0
new file mode 100644
index 0000000..c4d9618
@@ -0,0 +1,8 @@
+#
+# Copyright (C) 2015 Samsung Electronics
+# Przemyslaw Marczak <[email protected]>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-$(CONFIG_ADC) += adc-uclass.o
drivers/adc/adc-uclass.c new file +76 -0

76 lines not on this page · raw message

include/adc.h new file +88 -0

88 lines not on this page · raw message

include/dm/uclass-id.h +1 -0
index 1eeec74..0f7e7da 100644
@@ -25,6 +25,7 @@ enum uclass_id {
 	UCLASS_SIMPLE_BUS,	/* bus with child devices */
 
 	/* U-Boot uclasses start here - in alphabetical order */
+	UCLASS_ADC,		/* Analog-to-digital converter */
 	UCLASS_CLK,		/* Clock source, e.g. used by peripherals */
 	UCLASS_CPU,		/* CPU, typically part of an SoC */
 	UCLASS_CROS_EC,		/* Chrome OS EC */
Signature · 1 line
1.9.1
#46 lore raw

PATCH v2 6/11 dm: adc: add simple ADC uclass implementation

Hi Przemyslaw,

Quoted 14 lines · Przemyslaw Marczak

This commit adds:
- new uclass id: UCLASS_ADC
- new uclass driver: drivers/adc/adc-uclass.c

The uclass's implementation is as simple as needed and provides functions:
- adc_init() - init ADC conversion
- adc_data() - convert and return data
- adc_data_mask() - return ADC data mask
- adc_channel_single_shot() - function for single ADC convertion

---
Changes V2:
- new commit - introduce ADC uclass driver

Quoted 13 lines
---
 drivers/Kconfig          |  2 ++
 drivers/Makefile         |  1 +
 drivers/adc/Kconfig      |  8 +++++
 drivers/adc/Makefile     |  8 +++++
 drivers/adc/adc-uclass.c | 76 +++++++++++++++++++++++++++++++++++++++++
 include/adc.h            | 88 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/dm/uclass-id.h   |  1 +
 7 files changed, 184 insertions(+)
 create mode 100644 drivers/adc/Kconfig
 create mode 100644 drivers/adc/Makefile
 create mode 100644 drivers/adc/adc-uclass.c
 create mode 100644 include/adc.h

Sorry I have quite a lot of questions and comments on this.

Quoted 32 lines
drivers/Kconfig +2 -0
index 63c92c5..ad9ae3a 100644
@@ -4,6 +4,8 @@ source "drivers/core/Kconfig"
 
 # types of drivers sorted in alphabetical order
 
+source "drivers/adc/Kconfig"
+
 source "drivers/block/Kconfig"
 
 source "drivers/clk/Kconfig"
drivers/Makefile +1 -0
index 9d0a595..d7d5e9f 100644
@@ -35,6 +35,7 @@ obj-$(CONFIG_SPL_SATA_SUPPORT) += block/
 
 else
 
+obj-y += adc/
 obj-$(CONFIG_DM_DEMO) += demo/
 obj-$(CONFIG_BIOSEMU) += bios_emulator/
 obj-y += block/
drivers/adc/Kconfig new file +0 -0
new file mode 100644
index 0000000..1cb1a8d

drivers/adc/Kconfig line 5

Quoted 5 lines
drivers/adc/Kconfig new file +5 -0
@@ -0,0 +1,8 @@
+config ADC
+       bool "Enable ADC drivers using Driver Model"
+       help
+         This allows drivers to be provided for ADCs to drive their features,
+         trough simple ADC uclass driver interface, with operations:

through a simple

Quoted 29 lines
drivers/adc/Kconfig new file +3 -0
+         - device enable
+         - conversion init
+         - conversion start and return data with data mask
drivers/adc/Makefile new file +8 -0
new file mode 100644
index 0000000..c4d9618
@@ -0,0 +1,8 @@
+#
+# Copyright (C) 2015 Samsung Electronics
+# Przemyslaw Marczak <[email protected]>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-$(CONFIG_ADC) += adc-uclass.o
drivers/adc/adc-uclass.c new file +6 -0
new file mode 100644
index 0000000..bb71b6e
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics
+ * Przemyslaw Marczak <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */

drivers/adc/adc-uclass.c line 16

Quoted 10 lines
drivers/adc/adc-uclass.c new file +10 -0
+
+#include <common.h>
+#include <errno.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <dm/device-internal.h>
+#include <dm/uclass-internal.h>
+#include <adc.h>
+
+#define ADC_UCLASS_PLATDATA_SIZE       sizeof(struct adc_uclass_platdata)

Can we drop #define?

drivers/adc/adc-uclass.c line 25

Quoted 9 lines
drivers/adc/adc-uclass.c new file +9 -0
+
+int adc_init(struct udevice *dev, int channel)
+{
+       const struct adc_ops *ops = dev_get_driver_ops(dev);
+
+       if (ops->adc_init)
+               return ops->adc_init(dev, channel);
+
+       return -ENOSYS;

Let's turn each of these around so that errors are the exception, not the normal path.

if (!ops->adc_init)
return -ENOSYS;

return ops->...

Quoted 20 lines
drivers/adc/adc-uclass.c new file +20 -0
+}
+
+int adc_data(struct udevice *dev, unsigned int *data)
+{
+       const struct adc_ops *ops = dev_get_driver_ops(dev);
+
+       *data = 0;
+
+       if (ops->adc_data)
+               return ops->adc_data(dev, data);
+
+       return -ENOSYS;
+}
+
+int adc_data_mask(struct udevice *dev)
+{
+       struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
+
+       if (uc_pdata)
+               return uc_pdata->data_mask;

drivers/adc/adc-uclass.c line 55

Quoted 10 lines
drivers/adc/adc-uclass.c new file +10 -0
+
+       return -ENOSYS;
+}
+
+int adc_channel_single_shot(const char *name, int channel, unsigned int *data)
+{
+       struct udevice *dev;
+       int ret;
+
+       *data = 0;

I don't think we need this assignment. This can be undefined if an error is returned.

Quoted 54 lines
drivers/adc/adc-uclass.c new file +21 -0
+
+       ret = uclass_get_device_by_name(UCLASS_ADC, name, &dev);
+       if (ret)
+               return ret;
+
+       ret = adc_init(dev, channel);
+       if (ret)
+               return ret;
+
+       ret = adc_data(dev, data);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+UCLASS_DRIVER(adc) = {
+       .id     = UCLASS_ADC,
+       .name   = "adc",
+       .per_device_platdata_auto_alloc_size = ADC_UCLASS_PLATDATA_SIZE,
+};
include/adc.h new file +27 -0
new file mode 100644
index 0000000..57b9281
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics
+ * Przemyslaw Marczak <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _ADC_H_
+#define _ADC_H_
+
+/**
+ * struct adc_uclass_platdata - ADC power supply and reference Voltage info
+ *
+ * @data_mask     - conversion output data mask
+ * @channels_num  - number of analog channels input
+ * @vdd_supply    - positive reference voltage supply
+ * @vss_supply    - negative reference voltage supply
+ */
+struct adc_uclass_platdata {
+       unsigned int data_mask;
+       unsigned int channels_num;
+       struct udevice *vdd_supply;
+       struct udevice *vss_supply;
+};
+
+/**
+ * struct adc_ops - ADC device operations

include/adc.h line 37

Quoted 10 lines
include/adc.h new file +10 -0
+ */
+struct adc_ops {
+       /**
+        * conversion_init() - init device's default conversion parameters
+        *
+        * @dev:     ADC device to init
+        * @channel: analog channel number
+        * @return:  0 if OK, -ve on error
+        */
+       int (*adc_init)(struct udevice *dev, int channel);

s/adc_init/init/

Same below. Also it seems like this starts the conversion, so how about using the name start().

Quoted 10 lines
include/adc.h new file +10 -0
+
+       /**
+        * conversion_data() - get output data of given channel conversion
+        *
+        * @dev:          ADC device to trigger
+        * @channel_data: pointer to returned channel's data
+        * @return:       0 if OK, -ve on error
+        */
+       int (*adc_data)(struct udevice *dev, unsigned int *channel_data);
+};

include/adc.h line 57

Quoted 10 lines
include/adc.h new file +10 -0
+
+/**
+ * adc_init() - init device's default conversion parameters for the given
+ * analog input channel.
+ *
+ * @dev:     ADC device to init
+ * @channel: analog channel number
+ * @return:  0 if OK, -ve on error
+ */
+int adc_init(struct udevice *dev, int channel);

adc_start()?

include/adc.h line 66

Quoted 9 lines
include/adc.h new file +9 -0
+
+/**
+ * adc_data() - get conversion data for the channel inited by adc_init().
+ *
+ * @dev:    ADC device to trigger
+ * @data:   pointer to returned channel's data
+ * @return: 0 if OK, -ve on error
+ */
+int adc_data(struct udevice *dev, unsigned int *data);

This seems a bit wonky. Why not pass in the channel with this call? What if I want to start conversions on multiple channels at the same time?

include/adc.h line 73

Quoted 7 lines
include/adc.h new file +7 -0
+
+/**
+ * adc_data_mask() - get data mask (ADC resolution mask) for given ADC device.
+ * This can be used if adc uclass platform data is filled.
+ *
+ * @dev:    ADC device to check
+ * @return: 0 if OK, -ve on error

If it always returns 0 unless there is an error, what is the point? Or is this comment incorrect?

include/adc.h line 80

Quoted 7 lines
include/adc.h new file +7 -0
+ */
+int adc_data_mask(struct udevice *dev);
+
+/**
+ * adc_channel_single_shot() - get output data of convertion for the ADC
+ * device's channel. This function search for the device with the given name,
+ * init the given channel and returns the convertion data.

It also inits the device.

I would prefer a function that finds a device by name and inits it.

include/adc.h line 84

Quoted 4 lines
include/adc.h new file +4 -0
+ *
+ * @name:    device's name to search
+ * @channel: device's input channel to init
+ * @data:    pointer to convertion output data

conversion

Quoted 17 lines
include/adc.h new file +4 -0
+ */
+int adc_channel_single_shot(const char *name, int channel, unsigned int *data);
+
+#endif
include/dm/uclass-id.h +1 -1
index 1eeec74..0f7e7da 100644
@@ -25,6 +25,7 @@ enum uclass_id {
        UCLASS_SIMPLE_BUS,      /* bus with child devices */
 
        /* U-Boot uclasses start here - in alphabetical order */
+       UCLASS_ADC,             /* Analog-to-digital converter */
        UCLASS_CLK,             /* Clock source, e.g. used by peripherals */
        UCLASS_CPU,             /* CPU, typically part of an SoC */
        UCLASS_CROS_EC,         /* Chrome OS EC */
--
Quoted 2 lines

1.9.1

Regards,
Simon

#47 lore raw

PATCH v2 6/11 dm: adc: add simple ADC uclass implementation

Hello Simon,

Quoted 31 lines · Simon Glass

Hi Przemyslaw,

Quoted 23 lines · Przemyslaw Marczak

This commit adds:
- new uclass id: UCLASS_ADC
- new uclass driver: drivers/adc/adc-uclass.c

The uclass's implementation is as simple as needed and provides functions:
- adc_init() - init ADC conversion
- adc_data() - convert and return data
- adc_data_mask() - return ADC data mask
- adc_channel_single_shot() - function for single ADC convertion

---
Changes V2:
- new commit - introduce ADC uclass driver

---
  drivers/Kconfig          |  2 ++
  drivers/Makefile         |  1 +
  drivers/adc/Kconfig      |  8 +++++
  drivers/adc/Makefile     |  8 +++++
  drivers/adc/adc-uclass.c | 76 +++++++++++++++++++++++++++++++++++++++++
  include/adc.h            | 88 ++++++++++++++++++++++++++++++++++++++++++++++++
  include/dm/uclass-id.h   |  1 +
  7 files changed, 184 insertions(+)
Quoted 4 lines

create mode 100644 drivers/adc/Kconfig
create mode 100644 drivers/adc/Makefile
create mode 100644 drivers/adc/adc-uclass.c
create mode 100644 include/adc.h

Quoted 2 lines

Sorry I have quite a lot of questions and comments on this.

Yes, ok.

Quoted 31 lines
Quoted 31 lines
drivers/Kconfig +2 -0
index 63c92c5..ad9ae3a 100644
@@ -4,6 +4,8 @@ source "drivers/core/Kconfig"
 
  # types of drivers sorted in alphabetical order
 
+source "drivers/adc/Kconfig"
+
  source "drivers/block/Kconfig"
 
  source "drivers/clk/Kconfig"
drivers/Makefile +1 -0
index 9d0a595..d7d5e9f 100644
@@ -35,6 +35,7 @@ obj-$(CONFIG_SPL_SATA_SUPPORT) += block/
 
  else
 
+obj-y += adc/
  obj-$(CONFIG_DM_DEMO) += demo/
  obj-$(CONFIG_BIOSEMU) += bios_emulator/
  obj-y += block/
drivers/adc/Kconfig new file +0 -0
new file mode 100644
index 0000000..1cb1a8d
Quoted 9 lines

drivers/adc/Kconfig line 5

Quoted 6 lines
drivers/adc/Kconfig new file +5 -0
@@ -0,0 +1,8 @@
+config ADC
+       bool "Enable ADC drivers using Driver Model"
+       help
+         This allows drivers to be provided for ADCs to drive their features,
+         trough simple ADC uclass driver interface, with operations:

through a simple

Ok.

Quoted 33 lines
Quoted 33 lines
drivers/adc/Kconfig new file +3 -0
+         - device enable
+         - conversion init
+         - conversion start and return data with data mask
drivers/adc/Makefile new file +8 -0
new file mode 100644
index 0000000..c4d9618
@@ -0,0 +1,8 @@
+#
+# Copyright (C) 2015 Samsung Electronics
+# Przemyslaw Marczak <[email protected]>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-$(CONFIG_ADC) += adc-uclass.o
drivers/adc/adc-uclass.c new file +10 -0
new file mode 100644
index 0000000..bb71b6e
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics
+ * Przemyslaw Marczak <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <dm.h>
Quoted 9 lines

drivers/adc/adc-uclass.c line 16

Quoted 6 lines
drivers/adc/adc-uclass.c new file +6 -0
+#include <dm/lists.h>
+#include <dm/device-internal.h>
+#include <dm/uclass-internal.h>
+#include <adc.h>
+
+#define ADC_UCLASS_PLATDATA_SIZE       sizeof(struct adc_uclass_platdata)

Can we drop #define?

Don't you think, that single line initialization looks better than those with line breaks? This is the purpose of that define.

Quoted 13 lines

drivers/adc/adc-uclass.c line 25

Quoted 9 lines
drivers/adc/adc-uclass.c new file +9 -0
+
+int adc_init(struct udevice *dev, int channel)
+{
+       const struct adc_ops *ops = dev_get_driver_ops(dev);
+
+       if (ops->adc_init)
+               return ops->adc_init(dev, channel);
+
+       return -ENOSYS;

Let's turn each of these around so that errors are the exception, not the normal path.

Quoted 5 lines

if (!ops->adc_init)

    return -ENOSYS;

return ops->...

Ok, I will turn it.

Quoted 25 lines
Quoted 25 lines
drivers/adc/adc-uclass.c new file +25 -0
+}
+
+int adc_data(struct udevice *dev, unsigned int *data)
+{
+       const struct adc_ops *ops = dev_get_driver_ops(dev);
+
+       *data = 0;
+
+       if (ops->adc_data)
+               return ops->adc_data(dev, data);
+
+       return -ENOSYS;
+}
+
+int adc_data_mask(struct udevice *dev)
+{
+       struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
+
+       if (uc_pdata)
+               return uc_pdata->data_mask;
+
+       return -ENOSYS;
+}
+
+int adc_channel_single_shot(const char *name, int channel, unsigned int *data)
Quoted 9 lines

drivers/adc/adc-uclass.c line 55

Quoted 5 lines
drivers/adc/adc-uclass.c new file +5 -0
+{
+       struct udevice *dev;
+       int ret;
+
+       *data = 0;

I don't think we need this assignment. This can be undefined if an error is returned.

Ok.

Quoted 67 lines
Quoted 54 lines
drivers/adc/adc-uclass.c new file +21 -0
+
+       ret = uclass_get_device_by_name(UCLASS_ADC, name, &dev);
+       if (ret)
+               return ret;
+
+       ret = adc_init(dev, channel);
+       if (ret)
+               return ret;
+
+       ret = adc_data(dev, data);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+UCLASS_DRIVER(adc) = {
+       .id     = UCLASS_ADC,
+       .name   = "adc",
+       .per_device_platdata_auto_alloc_size = ADC_UCLASS_PLATDATA_SIZE,
+};
include/adc.h new file +27 -0
new file mode 100644
index 0000000..57b9281
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics
+ * Przemyslaw Marczak <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _ADC_H_
+#define _ADC_H_
+
+/**
+ * struct adc_uclass_platdata - ADC power supply and reference Voltage info
+ *
+ * @data_mask     - conversion output data mask
+ * @channels_num  - number of analog channels input
+ * @vdd_supply    - positive reference voltage supply
+ * @vss_supply    - negative reference voltage supply
+ */
+struct adc_uclass_platdata {
+       unsigned int data_mask;
+       unsigned int channels_num;
+       struct udevice *vdd_supply;
+       struct udevice *vss_supply;
+};
+
+/**
+ * struct adc_ops - ADC device operations

include/adc.h line 37

Quoted 10 lines
include/adc.h new file +10 -0
+ */
+struct adc_ops {
+       /**
+        * conversion_init() - init device's default conversion parameters
+        *
+        * @dev:     ADC device to init
+        * @channel: analog channel number
+        * @return:  0 if OK, -ve on error
+        */
+       int (*adc_init)(struct udevice *dev, int channel);

s/adc_init/init/

Quoted 3 lines

Same below. Also it seems like this starts the conversion, so how about using the name start().

Ok, I will modify the API.

Quoted 23 lines
Quoted 10 lines
include/adc.h new file +10 -0
+
+       /**
+        * conversion_data() - get output data of given channel conversion
+        *
+        * @dev:          ADC device to trigger
+        * @channel_data: pointer to returned channel's data
+        * @return:       0 if OK, -ve on error
+        */
+       int (*adc_data)(struct udevice *dev, unsigned int *channel_data);
+};

include/adc.h line 57

Quoted 10 lines
include/adc.h new file +10 -0
+
+/**
+ * adc_init() - init device's default conversion parameters for the given
+ * analog input channel.
+ *
+ * @dev:     ADC device to init
+ * @channel: analog channel number
+ * @return:  0 if OK, -ve on error
+ */
+int adc_init(struct udevice *dev, int channel);

adc_start()?

Quoted 14 lines

include/adc.h line 66

Quoted 9 lines
include/adc.h new file +9 -0
+
+/**
+ * adc_data() - get conversion data for the channel inited by adc_init().
+ *
+ * @dev:    ADC device to trigger
+ * @data:   pointer to returned channel's data
+ * @return: 0 if OK, -ve on error
+ */
+int adc_data(struct udevice *dev, unsigned int *data);

This seems a bit wonky. Why not pass in the channel with this call? What if I want to start conversions on multiple channels at the same time?

Right, this could be more flexible. I will modify it.

Quoted 11 lines

include/adc.h line 73

Quoted 7 lines
include/adc.h new file +7 -0
+
+/**
+ * adc_data_mask() - get data mask (ADC resolution mask) for given ADC device.
+ * This can be used if adc uclass platform data is filled.
+ *
+ * @dev:    ADC device to check
+ * @return: 0 if OK, -ve on error

If it always returns 0 unless there is an error, what is the point? Or is this comment incorrect?

Yes, that is a mistake.

Quoted 10 lines

include/adc.h line 80

Quoted 7 lines
include/adc.h new file +7 -0
+ */
+int adc_data_mask(struct udevice *dev);
+
+/**
+ * adc_channel_single_shot() - get output data of convertion for the ADC
+ * device's channel. This function search for the device with the given name,
+ * init the given channel and returns the convertion data.

It also inits the device.

Quoted 2 lines

I would prefer a function that finds a device by name and inits it.

Ah, ok.

Quoted 7 lines

include/adc.h line 84

Quoted 4 lines
include/adc.h new file +4 -0
+ *
+ * @name:    device's name to search
+ * @channel: device's input channel to init
+ * @data:    pointer to convertion output data

conversion

Okay.

Quoted 11 lines
Quoted 11 lines
include/adc.h new file +4 -0
+ */
+int adc_channel_single_shot(const char *name, int channel, unsigned int *data);
+
+#endif
include/dm/uclass-id.h +0 -0
index 1eeec74..0f7e7da 100644
@@ -25,6 +25,7 @@ enum uclass_id {
         UCLASS_SIMPLE_BUS,      /* bus with child devices */
 
Quoted 12 lines
Quoted 8 lines
include/dm/uclass-id.h +1 -1
         /* U-Boot uclasses start here - in alphabetical order */
+       UCLASS_ADC,             /* Analog-to-digital converter */
         UCLASS_CLK,             /* Clock source, e.g. used by peripherals */
         UCLASS_CPU,             /* CPU, typically part of an SoC */
         UCLASS_CROS_EC,         /* Chrome OS EC */
--

1.9.1

Regards,
Simon

Thanks for comments. The ADC API is not ideal, however it fits my needs. Also it looks like nobody was using ADC before in U-Boot, so I can suppose it can be as simple as possible. I will clean this :)

Best regards

Signature · 4 lines
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com
#48 lore raw

PATCH v2 7/11 dm: adc: add Exynos54xx compatible ADC driver

In reply to Przemyslaw Marczak

This commit adds driver for Exynos54xx ADC subsystem.

The driver is implemented using driver model,
amd provides ADC uclass's operations:
- adc_init()
- adc_data()

This driver uses sdelay() function on pooling, so it can be used before the delay timer is inited.
The basic parameters of ADC conversion, are:
- sample rate: 600KSPS
- output the data as average of 8 time conversion

ADC features:
- sample rate: 600KSPS
- resolution: 12-bit
- channels: 10 (analog multiplexer)

---
Changes V2:
- new commit - move previous adc driver from SoC directory to drivers/adc

---
 arch/arm/mach-exynos/include/mach/adc.h |  45 ++++++++++++++
 drivers/adc/Kconfig                     |   9 +++
 drivers/adc/Makefile                    |   1 +
 drivers/adc/exynos-adc.c                | 102 ++++++++++++++++++++++++++++++++
 4 files changed, 157 insertions(+)
 create mode 100644 drivers/adc/exynos-adc.c
arch/arm/mach-exynos/include/mach/adc.h +45 -0
index a0e26d7..228acf4 100644
@@ -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_ */
drivers/adc/Kconfig +9 -0
index 1cb1a8d..8ee6531 100644
@@ -6,3 +6,12 @@ config ADC
 	  - device enable
 	  - conversion init
 	  - conversion start and return data with data mask
+
+config ADC_EXYNOS
+	bool "Enable Exynos 54xx ADC driver"
+	help
+	  This enables basic driver for Exynos ADC compatible with Exynos54xx.
+	  It provides:
+	  - 10 analog input channels
+	  - 12-bit resolution
+	  - 600 KSPS of sample rate
drivers/adc/Makefile +1 -0
index c4d9618..eb85b8b 100644
@@ -6,3 +6,4 @@
 #
 
 obj-$(CONFIG_ADC) += adc-uclass.o
+obj-$(CONFIG_ADC_EXYNOS) += exynos-adc.o
drivers/adc/exynos-adc.c new file +102 -0

102 lines not on this page · raw message

Signature · 1 line
1.9.1
#49 lore raw

PATCH v2 7/11 dm: adc: add Exynos54xx compatible ADC driver

Hi Przemyslaw,

Quoted 35 lines · Przemyslaw Marczak

This commit adds driver for Exynos54xx ADC subsystem.

The driver is implemented using driver model,
amd provides ADC uclass's operations:
- adc_init()
- adc_data()

This driver uses sdelay() function on pooling, so it can be used before the delay timer is inited.
The basic parameters of ADC conversion, are:
- sample rate: 600KSPS
- output the data as average of 8 time conversion

ADC features:
- sample rate: 600KSPS
- resolution: 12-bit
- channels: 10 (analog multiplexer)

---
Changes V2:
- new commit - move previous adc driver from SoC directory to drivers/adc

---
 arch/arm/mach-exynos/include/mach/adc.h |  45 ++++++++++++++
 drivers/adc/Kconfig                     |   9 +++
 drivers/adc/Makefile                    |   1 +
 drivers/adc/exynos-adc.c                | 102 ++++++++++++++++++++++++++++++++
 4 files changed, 157 insertions(+)
 create mode 100644 drivers/adc/exynos-adc.c
arch/arm/mach-exynos/include/mach/adc.h +0 -0
index a0e26d7..228acf4 100644

arch/arm/mach-exynos/include/mach/adc.h line 13

Quoted 5 lines
arch/arm/mach-exynos/include/mach/adc.h +2 -0
@@ -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)

No need for brackets on these simple ones

Quoted 60 lines
arch/arm/mach-exynos/include/mach/adc.h +43 -0
+
+#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_ */
drivers/adc/Kconfig +0 -0
index 1cb1a8d..8ee6531 100644
@@ -6,3 +6,12 @@ config ADC
          - device enable
          - conversion init

drivers/adc/Kconfig config ADC · line 17

Quoted 10 lines
drivers/adc/Kconfig +9 -0
          - conversion start and return data with data mask
+
+config ADC_EXYNOS
+       bool "Enable Exynos 54xx ADC driver"
+       help
+         This enables basic driver for Exynos ADC compatible with Exynos54xx.
+         It provides:
+         - 10 analog input channels
+         - 12-bit resolution
+         - 600 KSPS of sample rate

Great help!

Quoted 22 lines
drivers/adc/Makefile +1 -0
index c4d9618..eb85b8b 100644
@@ -6,3 +6,4 @@
 #
 
 obj-$(CONFIG_ADC) += adc-uclass.o
+obj-$(CONFIG_ADC_EXYNOS) += exynos-adc.o
drivers/adc/exynos-adc.c new file +7 -0
new file mode 100644
index 0000000..fdffea0
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics
+ * Przemyslaw Marczak <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#include <common.h>

drivers/adc/exynos-adc.c line 17

Quoted 10 lines
drivers/adc/exynos-adc.c new file +10 -0
+#include <errno.h>
+#include <dm.h>
+#include <adc.h>
+#include <asm/arch/adc.h>
+
+struct exynos_adc_priv {
+       struct exynos_adc_v2 *regs;
+};
+
+extern void sdelay(unsigned long loops);

Can you put this include system.h for exynos, or similar? Also, I think the problem is that timer_init() is called after initf_dm(). There is a patch to add timer support to driver model so perhaps that will help?

Quoted 8 lines
drivers/adc/exynos-adc.c new file +8 -0
+
+int exynos_adc_data(struct udevice *dev, unsigned int *data)
+{
+       struct exynos_adc_priv *priv = dev_get_priv(dev);
+       struct exynos_adc_v2 *regs = priv->regs;
+       unsigned int cfg, timeout_us = ADC_V2_CONV_TIMEOUT_US;
+
+       /* Start conversion */

drivers/adc/exynos-adc.c line 35

Quoted 10 lines
drivers/adc/exynos-adc.c new file +10 -0
+       cfg = readl(&regs->con1);
+       writel(cfg | ADC_V2_CON1_STC_EN, &regs->con1);
+
+       while (ADC_V2_GET_STATUS_FLAG(readl(&regs->status)) != FLAG_CONV_END) {
+               sdelay(4);
+               if (!timeout_us--) {
+                       error("ADC conversion timeout!");
+                       return -ETIME;
+               }
+       }

Hmm, we don't want to put delays in drivers. I though that the init() method was used to start the conversion, but now I see that it is not. I think the uclass is going to have to know how long to wait for the conversion to be ready.

How about this for an interface:

adc_start(dev, channel)
adc_read(dev, channel)

which waits until the conversion is ready on that channel. The driver can set up the time that the conversion will be ready (and store it in the uclass) when the conversion starts.

Can we support conversions on several channels at once?

Quoted 21 lines
drivers/adc/exynos-adc.c new file +21 -0
+
+       *data = readl(&regs->dat) & ADC_V2_DAT_MASK;
+
+       return 0;
+}
+
+int exynos_adc_init(struct udevice *dev, int channel)
+{
+       struct exynos_adc_priv *priv = dev_get_priv(dev);
+       struct exynos_adc_v2 *regs = priv->regs;
+       unsigned int cfg;
+
+       /* Check HW version */
+       if (readl(&regs->version) != ADC_V2_VERSION) {
+               error("This driver supports only ADC v2!");
+               return -ENXIO;
+       }
+
+       /* ADC Reset */
+       writel(ADC_V2_CON1_SOFT_RESET, &regs->con1);
+

drivers/adc/exynos-adc.c line 66

Quoted 10 lines
drivers/adc/exynos-adc.c new file +10 -0
+       /* Disable INT - will read status only */
+       writel(0x0, &regs->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, &regs->con2);

Can this function go in probe() instead? The only thing that can't is 'channel'. Is that setting which channel does the conversion? If so, perhaps that particular setting could move to the start function?

Quoted 37 lines
drivers/adc/exynos-adc.c new file +36 -1
+
+       return 0;
+}
+
+int exynos_adc_ofdata_to_platdata(struct udevice *dev)
+{
+       struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
+       struct exynos_adc_priv *priv = dev_get_priv(dev);
+
+       priv->regs = (struct exynos_adc_v2 *)dev_get_addr(dev);
+
+       uc_pdata->data_mask = ADC_V2_DAT_MASK;
+       /* Channel count starts from 0 */
+       uc_pdata->channels_num = ADC_V2_MAX_CHANNEL + 1;
+
+       return 0;
+}
+
+static const struct adc_ops exynos_adc_ops = {
+       .adc_init = exynos_adc_init,
+       .adc_data = exynos_adc_data,
+};
+
+static const struct udevice_id exynos_adc_ids[] = {
+       { .compatible = "samsung,exynos-adc-v2" },
+       { }
+};
+
+U_BOOT_DRIVER(exynos_adc) = {
+       .name           = "exynos-adc",
+       .id             = UCLASS_ADC,
+       .of_match       = exynos_adc_ids,
+       .ops            = &exynos_adc_ops,
+       .ofdata_to_platdata = exynos_adc_ofdata_to_platdata,
+       .priv_auto_alloc_size = sizeof(struct exynos_adc_priv),
+};
--
Quoted 2 lines

1.9.1

Regards,
Simon

#50 lore raw

PATCH v2 7/11 dm: adc: add Exynos54xx compatible ADC driver

Hello Simon,

Quoted 41 lines · Simon Glass

Hi Przemyslaw,

Quoted 38 lines · Przemyslaw Marczak

This commit adds driver for Exynos54xx ADC subsystem.

The driver is implemented using driver model,
amd provides ADC uclass's operations:
- adc_init()
- adc_data()

This driver uses sdelay() function on pooling, so it can be used before the delay timer is inited.
The basic parameters of ADC conversion, are:
- sample rate: 600KSPS
- output the data as average of 8 time conversion

ADC features:
- sample rate: 600KSPS
- resolution: 12-bit
- channels: 10 (analog multiplexer)

---
Changes V2:
- new commit - move previous adc driver from SoC directory to drivers/adc

---
  arch/arm/mach-exynos/include/mach/adc.h |  45 ++++++++++++++
  drivers/adc/Kconfig                     |   9 +++
  drivers/adc/Makefile                    |   1 +
  drivers/adc/exynos-adc.c                | 102 ++++++++++++++++++++++++++++++++
  4 files changed, 157 insertions(+)

create mode 100644 drivers/adc/exynos-adc.c

arch/arm/mach-exynos/include/mach/adc.h +0 -0
index a0e26d7..228acf4 100644
@@ -9,6 +9,38 @@
  #ifndef __ASM_ARM_ARCH_ADC_H_
  #define __ASM_ARM_ARCH_ADC_H_
 
Quoted 5 lines

arch/arm/mach-exynos/include/mach/adc.h line 13

Quoted 2 lines
arch/arm/mach-exynos/include/mach/adc.h +2 -0
+#define ADC_V2_CON1_SOFT_RESET         (0x2 << 1)
+#define ADC_V2_CON1_STC_EN             (0x1)

No need for brackets on these simple ones

Okay, I will remove them.

Quoted 64 lines
Quoted 64 lines
arch/arm/mach-exynos/include/mach/adc.h +43 -0
+
+#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_ */
drivers/adc/Kconfig +3 -0
index 1cb1a8d..8ee6531 100644
@@ -6,3 +6,12 @@ config ADC
           - device enable
           - conversion init
           - conversion start and return data with data mask
+
+config ADC_EXYNOS
+       bool "Enable Exynos 54xx ADC driver"
Quoted 9 lines

drivers/adc/Kconfig config ADC · line 17

Quoted 6 lines
drivers/adc/Kconfig +6 -0
+       help
+         This enables basic driver for Exynos ADC compatible with Exynos54xx.
+         It provides:
+         - 10 analog input channels
+         - 12-bit resolution
+         - 600 KSPS of sample rate

Great help!

Thanks:)

Quoted 29 lines
Quoted 29 lines
drivers/adc/Makefile +1 -0
index c4d9618..eb85b8b 100644
@@ -6,3 +6,4 @@
  #
 
  obj-$(CONFIG_ADC) += adc-uclass.o
+obj-$(CONFIG_ADC_EXYNOS) += exynos-adc.o
drivers/adc/exynos-adc.c new file +14 -0
new file mode 100644
index 0000000..fdffea0
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics
+ * Przemyslaw Marczak <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#include <common.h>
+#include <errno.h>
+#include <dm.h>
+#include <adc.h>
+#include <asm/arch/adc.h>
+
+struct exynos_adc_priv {
+       struct exynos_adc_v2 *regs;
Quoted 9 lines

drivers/adc/exynos-adc.c line 17

Quoted 3 lines
drivers/adc/exynos-adc.c new file +3 -0
+};
+
+extern void sdelay(unsigned long loops);

Can you put this include system.h for exynos, or similar? Also, I think the problem is that timer_init() is called after initf_dm(). There is a patch to add timer support to driver model so perhaps that will help?

Ok, will move this. And yes, the problem is with too late timer init. I saw the work for timer uclass, however I would prefer just use this function. It can be moved in the future.

I'm trying add simple functionality, move everything to driver model is not related to this patch set.

We can add the timer driver later, and then fix each timer call.

Quoted 15 lines
Quoted 15 lines
drivers/adc/exynos-adc.c new file +15 -0
+
+int exynos_adc_data(struct udevice *dev, unsigned int *data)
+{
+       struct exynos_adc_priv *priv = dev_get_priv(dev);
+       struct exynos_adc_v2 *regs = priv->regs;
+       unsigned int cfg, timeout_us = ADC_V2_CONV_TIMEOUT_US;
+
+       /* Start conversion */
+       cfg = readl(&regs->con1);
+       writel(cfg | ADC_V2_CON1_STC_EN, &regs->con1);
+
+       while (ADC_V2_GET_STATUS_FLAG(readl(&regs->status)) != FLAG_CONV_END) {
+               sdelay(4);
+               if (!timeout_us--) {
+                       error("ADC conversion timeout!");
Quoted 8 lines

drivers/adc/exynos-adc.c line 35

Quoted 3 lines
drivers/adc/exynos-adc.c new file +3 -0
+                       return -ETIME;
+               }
+       }

Hmm, we don't want to put delays in drivers. I though that the init() method was used to start the conversion, but now I see that it is not. I think the uclass is going to have to know how long to wait for the conversion to be ready.

Good point, I will move the delay to uclass driver.

Quoted 9 lines

How about this for an interface:

adc_start(dev, channel)
adc_read(dev, channel)

which waits until the conversion is ready on that channel. The driver can set up the time that the conversion will be ready (and store it in the uclass) when the conversion starts.

Ok, that sounds good.

Quoted 3 lines

Can we support conversions on several channels at once?

Some hardware can do this, but the Exynos internal ADC is simple and allows only for a single channel conversion at a time.

I can add an uclass operation function call, e.g. adc_channels_data(), and if it's not implemented by the device driver, then it can get the data for each channel in a loop.

Is that good to you?

Quoted 27 lines
Quoted 27 lines
drivers/adc/exynos-adc.c new file +27 -0
+
+       *data = readl(&regs->dat) & ADC_V2_DAT_MASK;
+
+       return 0;
+}
+
+int exynos_adc_init(struct udevice *dev, int channel)
+{
+       struct exynos_adc_priv *priv = dev_get_priv(dev);
+       struct exynos_adc_v2 *regs = priv->regs;
+       unsigned int cfg;
+
+       /* Check HW version */
+       if (readl(&regs->version) != ADC_V2_VERSION) {
+               error("This driver supports only ADC v2!");
+               return -ENXIO;
+       }
+
+       /* ADC Reset */
+       writel(ADC_V2_CON1_SOFT_RESET, &regs->con1);
+
+       /* Disable INT - will read status only */
+       writel(0x0, &regs->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);
Quoted 9 lines

drivers/adc/exynos-adc.c line 66

Quoted 4 lines
drivers/adc/exynos-adc.c new file +4 -0
+       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, &regs->con2);

Can this function go in probe() instead? The only thing that can't is 'channel'. Is that setting which channel does the conversion? If so, perhaps that particular setting could move to the start function?

Yes, those settings should be done before each conversion.

Quoted 34 lines
Quoted 34 lines
drivers/adc/exynos-adc.c new file +34 -0
+
+       return 0;
+}
+
+int exynos_adc_ofdata_to_platdata(struct udevice *dev)
+{
+       struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
+       struct exynos_adc_priv *priv = dev_get_priv(dev);
+
+       priv->regs = (struct exynos_adc_v2 *)dev_get_addr(dev);
+
+       uc_pdata->data_mask = ADC_V2_DAT_MASK;
+       /* Channel count starts from 0 */
+       uc_pdata->channels_num = ADC_V2_MAX_CHANNEL + 1;
+
+       return 0;
+}
+
+static const struct adc_ops exynos_adc_ops = {
+       .adc_init = exynos_adc_init,
+       .adc_data = exynos_adc_data,
+};
+
+static const struct udevice_id exynos_adc_ids[] = {
+       { .compatible = "samsung,exynos-adc-v2" },
+       { }
+};
+
+U_BOOT_DRIVER(exynos_adc) = {
+       .name           = "exynos-adc",
+       .id             = UCLASS_ADC,
+       .of_match       = exynos_adc_ids,
+       .ops            = &exynos_adc_ops,
+       .ofdata_to_platdata = exynos_adc_ofdata_to_platdata,
Quoted 9 lines
Quoted 5 lines
drivers/adc/exynos-adc.c new file +2 -1
+       .priv_auto_alloc_size = sizeof(struct exynos_adc_priv),
+};
--

1.9.1

Regards,
Simon

Best regards

Signature · 4 lines
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com
#51 lore raw

PATCH v2 7/11 dm: adc: add Exynos54xx compatible ADC driver

Hi Przemyslaw,

Quoted 235 lines · Przemyslaw Marczak

Hello Simon,

Quoted 46 lines · Simon Glass

Hi Przemyslaw,

Quoted 41 lines · Przemyslaw Marczak

This commit adds driver for Exynos54xx ADC subsystem.

The driver is implemented using driver model,
amd provides ADC uclass's operations:
- adc_init()
- adc_data()

This driver uses sdelay() function on pooling, so it can be used before the delay timer is inited.
The basic parameters of ADC conversion, are:
- sample rate: 600KSPS
- output the data as average of 8 time conversion

ADC features:
- sample rate: 600KSPS
- resolution: 12-bit
- channels: 10 (analog multiplexer)

---
Changes V2:
- new commit - move previous adc driver from SoC directory to drivers/adc

---
  arch/arm/mach-exynos/include/mach/adc.h |  45 ++++++++++++++
  drivers/adc/Kconfig                     |   9 +++
  drivers/adc/Makefile                    |   1 +
  drivers/adc/exynos-adc.c                | 102
++++++++++++++++++++++++++++++++
  4 files changed, 157 insertions(+)

create mode 100644 drivers/adc/exynos-adc.c

arch/arm/mach-exynos/include/mach/adc.h +0 -0
index a0e26d7..228acf4 100644
@@ -9,6 +9,38 @@
  #ifndef __ASM_ARM_ARCH_ADC_H_
  #define __ASM_ARM_ARCH_ADC_H_
 
Quoted 6 lines

arch/arm/mach-exynos/include/mach/adc.h line 13

Quoted 2 lines
arch/arm/mach-exynos/include/mach/adc.h +2 -0
+#define ADC_V2_CON1_SOFT_RESET         (0x2 << 1)
+#define ADC_V2_CON1_STC_EN             (0x1)

No need for brackets on these simple ones

Okay, I will remove them.

Quoted 67 lines
Quoted 67 lines
arch/arm/mach-exynos/include/mach/adc.h +26 -0
+
+#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 */

arch/arm/mach-exynos/include/mach/adc.h +17 -0
+#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_ */
drivers/adc/Kconfig +5 -0
index 1cb1a8d..8ee6531 100644
@@ -6,3 +6,12 @@ config ADC
           - device enable
           - conversion init
           - conversion start and return data with data mask
+
+config ADC_EXYNOS
+       bool "Enable Exynos 54xx ADC driver"
+       help
+         This enables basic driver for Exynos ADC compatible with
Quoted 9 lines

drivers/adc/Kconfig config ADC · line 17

Quoted 5 lines

Exynos54xx.

drivers/adc/Kconfig +4 -0
+         It provides:
+         - 10 analog input channels
+         - 12-bit resolution
+         - 600 KSPS of sample rate

Great help!

Thanks:)

Quoted 30 lines
Quoted 30 lines
drivers/adc/Makefile +1 -0
index c4d9618..eb85b8b 100644
@@ -6,3 +6,4 @@
  #
 
  obj-$(CONFIG_ADC) += adc-uclass.o
+obj-$(CONFIG_ADC_EXYNOS) += exynos-adc.o
drivers/adc/exynos-adc.c new file +15 -0
new file mode 100644
index 0000000..fdffea0
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics
+ * Przemyslaw Marczak <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#include <common.h>
+#include <errno.h>
+#include <dm.h>
+#include <adc.h>
+#include <asm/arch/adc.h>
+
+struct exynos_adc_priv {
+       struct exynos_adc_v2 *regs;
+};
Quoted 9 lines

drivers/adc/exynos-adc.c line 17

Quoted 2 lines
drivers/adc/exynos-adc.c new file +2 -0
+
+extern void sdelay(unsigned long loops);

Can you put this include system.h for exynos, or similar? Also, I think the problem is that timer_init() is called after initf_dm(). There is a patch to add timer support to driver model so perhaps that will help?

Ok, will move this. And yes, the problem is with too late timer init. I saw the work for timer uclass, however I would prefer just use this function. It can be moved in the future.

I'm trying add simple functionality, move everything to driver model is not related to this patch set.

We can add the timer driver later, and then fix each timer call.

Quoted 17 lines
Quoted 17 lines
drivers/adc/exynos-adc.c new file +12 -0
+
+int exynos_adc_data(struct udevice *dev, unsigned int *data)
+{
+       struct exynos_adc_priv *priv = dev_get_priv(dev);
+       struct exynos_adc_v2 *regs = priv->regs;
+       unsigned int cfg, timeout_us = ADC_V2_CONV_TIMEOUT_US;
+
+       /* Start conversion */
+       cfg = readl(&regs->con1);
+       writel(cfg | ADC_V2_CON1_STC_EN, &regs->con1);
+
+       while (ADC_V2_GET_STATUS_FLAG(readl(&regs->status)) !=

FLAG_CONV_END) {

drivers/adc/exynos-adc.c new file +4 -0
+               sdelay(4);
+               if (!timeout_us--) {
+                       error("ADC conversion timeout!");
+                       return -ETIME;
Quoted 8 lines

drivers/adc/exynos-adc.c

Quoted 2 lines
drivers/adc/exynos-adc.c new file +2 -0
+               }
+       }

Hmm, we don't want to put delays in drivers. I though that the init() method was used to start the conversion, but now I see that it is not. I think the uclass is going to have to know how long to wait for the conversion to be ready.

Good point, I will move the delay to uclass driver.

Quoted 9 lines

How about this for an interface:

adc_start(dev, channel)
adc_read(dev, channel)

which waits until the conversion is ready on that channel. The driver can set up the time that the conversion will be ready (and store it in the uclass) when the conversion starts.

Ok, that sounds good.

Quoted 3 lines

Can we support conversions on several channels at once?

Quoted 8 lines

Some hardware can do this, but the Exynos internal ADC is simple and allows only for a single channel conversion at a time.

I can add an uclass operation function call, e.g. adc_channels_data(), and if it's not implemented by the device driver, then it can get the data for each channel in a loop.

Is that good to you?

Yes - so long as the loop is not in the driver it is good.

Quoted 88 lines
Quoted 30 lines
Quoted 30 lines
drivers/adc/exynos-adc.c new file +28 -0
+
+       *data = readl(&regs->dat) & ADC_V2_DAT_MASK;
+
+       return 0;
+}
+
+int exynos_adc_init(struct udevice *dev, int channel)
+{
+       struct exynos_adc_priv *priv = dev_get_priv(dev);
+       struct exynos_adc_v2 *regs = priv->regs;
+       unsigned int cfg;
+
+       /* Check HW version */
+       if (readl(&regs->version) != ADC_V2_VERSION) {
+               error("This driver supports only ADC v2!");
+               return -ENXIO;
+       }
+
+       /* ADC Reset */
+       writel(ADC_V2_CON1_SOFT_RESET, &regs->con1);
+
+       /* Disable INT - will read status only */
+       writel(0x0, &regs->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);
Quoted 9 lines

drivers/adc/exynos-adc.c line 66

Quoted 3 lines
drivers/adc/exynos-adc.c new file +3 -0
+       cfg |= ADC_V2_CON2_ESEL(ESEL_ADC_EVAL_TIME_20CLK);
+       cfg |= ADC_V2_CON2_HIGHF(HIGHF_CONV_RATE_600KSPS);
+       writel(cfg, &regs->con2);

Can this function go in probe() instead? The only thing that can't is 'channel'. Is that setting which channel does the conversion? If so, perhaps that particular setting could move to the start function?

Yes, those settings should be done before each conversion.

Quoted 35 lines
Quoted 35 lines
drivers/adc/exynos-adc.c new file +7 -0
+
+       return 0;
+}
+
+int exynos_adc_ofdata_to_platdata(struct udevice *dev)
+{
+       struct adc_uclass_platdata *uc_pdata =

dev_get_uclass_platdata(dev);

drivers/adc/exynos-adc.c new file +27 -0
+       struct exynos_adc_priv *priv = dev_get_priv(dev);
+
+       priv->regs = (struct exynos_adc_v2 *)dev_get_addr(dev);
+
+       uc_pdata->data_mask = ADC_V2_DAT_MASK;
+       /* Channel count starts from 0 */
+       uc_pdata->channels_num = ADC_V2_MAX_CHANNEL + 1;
+
+       return 0;
+}
+
+static const struct adc_ops exynos_adc_ops = {
+       .adc_init = exynos_adc_init,
+       .adc_data = exynos_adc_data,
+};
+
+static const struct udevice_id exynos_adc_ids[] = {
+       { .compatible = "samsung,exynos-adc-v2" },
+       { }
+};
+
+U_BOOT_DRIVER(exynos_adc) = {
+       .name           = "exynos-adc",
+       .id             = UCLASS_ADC,
+       .of_match       = exynos_adc_ids,
+       .ops            = &exynos_adc_ops,
+       .ofdata_to_platdata = exynos_adc_ofdata_to_platdata,
Quoted 9 lines
Quoted 5 lines
drivers/adc/exynos-adc.c new file +2 -1
+       .priv_auto_alloc_size = sizeof(struct exynos_adc_priv),
+};
--

1.9.1

Regards,
Simon

Quoted 6 lines

Best regards
--
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com

Regards,
Simon

#52 lore raw

PATCH v2 8/11 Odroid-XU3: enable s2mps11 PMIC support

In reply to Przemyslaw Marczak

---
Changes V2:
- none

---
 arch/arm/dts/exynos5422-odroidxu3.dts | 7 +++++++
 configs/odroid-xu3_defconfig          | 3 +++
 2 files changed, 10 insertions(+)
arch/arm/dts/exynos5422-odroidxu3.dts +7 -0
index d0a8621..9dec679 100644
@@ -31,6 +31,13 @@
 			0xb0000000 0xea00000>;
 	};
 
+	i2c at 12CA0000 {
+		s2mps11_pmic at 66 {
+			compatible = "samsung,s2mps11-pmic";
+			reg = <0x66>;
+		};
+	};
+
 	ehci at 12110000 {
 		samsung,vbus-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>;
 	};
configs/odroid-xu3_defconfig +3 -0
index 9c3b6d6..f38c37b 100644
@@ -8,7 +8,10 @@ CONFIG_DEFAULT_DEVICE_TREE="exynos5422-odroidxu3"
 CONFIG_DM_I2C=y
 CONFIG_DM_I2C_COMPAT=y
 CONFIG_DM_PMIC=y
+CONFIG_CMD_PMIC=y
+CONFIG_ERRNO_STR=y
 CONFIG_DM_REGULATOR=y
+CONFIG_PMIC_S2MPS11=y
 CONFIG_VIDEO_BRIDGE=y
 CONFIG_SYS_PROMPT="ODROID-XU3 # "
 CONFIG_USB=y
Signature · 1 line
1.9.1
#54 lore raw

PATCH v2 9/11 Exynos54xx: dts: add ADC node

In reply to Przemyslaw Marczak

This commit adds common ADC node, which is disabled as default.

---
Changes V2:
- new commit

---
 arch/arm/dts/exynos54xx.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)
arch/arm/dts/exynos54xx.dtsi +7 -0
index bd3619d..daa6a33 100644
@@ -42,6 +42,13 @@
 		xhci1 = "/xhci at 12400000";
 	};
 
+	adc at 12D10000 {
+		compatible = "samsung,exynos-adc-v2";
+		reg = <0x12D10000 0x100>;
+		interrupts = <0 106 0>;
+		status = "disabled";
+	};
+
 	i2c at 12CA0000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
Signature · 1 line
1.9.1
#55 lore raw

PATCH v2 9/11 Exynos54xx: dts: add ADC node

Quoted 15 lines · Przemyslaw Marczak

This commit adds common ADC node, which is disabled as default.

---
Changes V2:
- new commit

---
 arch/arm/dts/exynos54xx.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)
arch/arm/dts/exynos54xx.dtsi +0 -0
index bd3619d..daa6a33 100644

arch/arm/dts/exynos54xx.dtsi line 43

Quoted 2 lines
arch/arm/dts/exynos54xx.dtsi +0 -0
@@ -42,6 +42,13 @@
                xhci1 = "/xhci at 12400000";
        };
#56 lore raw

PATCH v2 10/11 Odroid-XU3: dts: enable ADC, with request for pre-reloc bind

In reply to Przemyslaw Marczak

This ADC is required for Odroid's board revision detection. The pre-reloc request is enabled, since board detection will be done in one of early function call.

---
Changes V2:
- new commit

---
 arch/arm/dts/exynos5422-odroidxu3.dts | 5 +++++
 1 file changed, 5 insertions(+)
arch/arm/dts/exynos5422-odroidxu3.dts +5 -0
index 9dec679..690c747 100644
@@ -31,6 +31,11 @@
 			0xb0000000 0xea00000>;
 	};
 
+	adc at 12D10000 {
+		u-boot,dm-pre-reloc;
+		status = "okay";
+	};
+
 	i2c at 12CA0000 {
 		s2mps11_pmic at 66 {
 			compatible = "samsung,s2mps11-pmic";
Signature · 1 line
1.9.1
#57 lore raw

PATCH v2 10/11 Odroid-XU3: dts: enable ADC, with request for pre-reloc bind

Quoted 11 lines · Przemyslaw Marczak

This ADC is required for Odroid's board revision detection. The pre-reloc request is enabled, since board detection will be done in one of early function call.

---
Changes V2:
- new commit

---
 arch/arm/dts/exynos5422-odroidxu3.dts | 5 +++++
 1 file changed, 5 insertions(+)
#58 lore raw

PATCH v2 11/11 exynos5-dt-types: add board detection for Odroid XU3/XU3L/XU4.

In reply to Przemyslaw Marczak

This commit adds additional file with implementation of board detection code for Odroid-XU3/XU4.

The detection depends on compatible found in fdt:
- "samsung,exynos5" - uses Exynos5 generic code
- "samsung,odroidxu3" - try detect XU3 revision

There are few revisions of Odroid XU3/XU4, each can be detected by checking the value of channel 9 of built-in ADC:

 Rev   ADC  Board
 0.1     0  XU3 0.1
 0.2   372  XU3 0.2 | XU3L - no DISPLAYPORT
 0.3  1280  XU4 0.1

The detection code depends on the ADC+10% value.

Implementation of functions:

- set_board_type()     - read ADC and set type
- get_board_rev()      - returns board revision: 1..3
- get_board_type()     - returns board type string

Additional functions with return values of bool:
- board_is_generic() - true if found compatible "samsung,exynos5"
but not "samsung,odroidxu3"
- board_is_odroidxu3() - true if found compatible "samsung,odroidxu3" and one of XU3 revision.
- board_is_odroidxu4() - true if found compatible "samsung,odroidxu3" and XU4 revision.

After I2C controller init, the get_board_type() can check if the XU3 board is a "Lite" variant, by probing chip 0x40 on I2C0 (INA231 - exists only on non-lite). This is useful for setting fdt file name at misc_init_r().

Enabled configs:
- CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
- CONFIG_ODROID_REV_AIN
- CONFIG_REVISION_TAG
- CONFIG_BOARD_TYPES

---
Changes V2:
- move detection code from exynos5-dt.c to exynos5-dt-types.c
- add header with board type function declarations
- check for compatible before do the detection
- update the ADC max values with 20% tolerance
- fix XU4 adc value, related to mistake from table in XU4 schematic
- return "Not supported" for XU4 when calls one of:
--dfu_get_alt_boot()
--dfu_get_alt_system()
- extend ${dfu_alt_system} by strings:
-- 'exynos5422-odroidxu3-lite.dtb'
-- 'exynos5422-odroidxu4.dtb' - allows prepare card on XU3

---
 board/samsung/common/Makefile           |   5 +-
 board/samsung/common/exynos5-dt-types.c | 196 ++++++++++++++++++++++++++++++++
 board/samsung/common/exynos5-dt.c       |  12 ++
 configs/odroid-xu3_defconfig            |   2 +
 include/configs/odroid_xu3.h            |  12 ++
 include/samsung/exynos5-dt-types.h      |  27 +++++
 6 files changed, 253 insertions(+), 1 deletion(-)
 create mode 100644 board/samsung/common/exynos5-dt-types.c
 create mode 100644 include/samsung/exynos5-dt-types.h
board/samsung/common/Makefile +4 -1
index 6cbd906..ef1a8f3 100644
@@ -11,5 +11,8 @@ obj-$(CONFIG_MISC_COMMON) += misc.o
 
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_BOARD_COMMON)	+= board.o
-obj-$(CONFIG_EXYNOS5_DT)	+= exynos5-dt.o
+ifdef CONFIG_EXYNOS5_DT
+obj-y += exynos5-dt.o
+obj-$(CONFIG_BOARD_TYPES) += exynos5-dt-types.o
+endif
 endif
board/samsung/common/exynos5-dt-types.c new file +196 -0

196 lines not on this page · raw message

board/samsung/common/exynos5-dt.c +12 -0
index 4250f72..4d9e151 100644
@@ -27,7 +27,10 @@
 #include <power/pmic.h>
 #include <power/max77686_pmic.h>
 #include <power/regulator.h>
+#include <power/s2mps11.h>
 #include <power/s5m8767.h>
+#include <samsung/exynos5-dt-types.h>
+#include <samsung/misc.h>
 #include <tmu.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -335,15 +338,24 @@ int board_usb_init(int index, enum usb_init_type init)
 #ifdef CONFIG_SET_DFU_ALT_INFO
 char *get_dfu_alt_system(char *interface, char *devstr)
 {
+	char *info = "Not supported!";
+
+	if (board_is_odroidxu4())
+		return info;
+
 	return getenv("dfu_alt_system");
 }
 
 char *get_dfu_alt_boot(char *interface, char *devstr)
 {
+	char *info = "Not supported!";
 	struct mmc *mmc;
 	char *alt_boot;
 	int dev_num;
 
+	if (board_is_odroidxu4())
+		return info;
+
 	dev_num = simple_strtoul(devstr, NULL, 10);
 
 	mmc = find_mmc_device(dev_num);
configs/odroid-xu3_defconfig +2 -0
index f38c37b..d7e5698 100644
@@ -16,3 +16,5 @@ CONFIG_VIDEO_BRIDGE=y
 CONFIG_SYS_PROMPT="ODROID-XU3 # "
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADC=y
+CONFIG_ADC_EXYNOS=y
include/configs/odroid_xu3.h +12 -0
index 3c70158..648e48b 100644
@@ -94,6 +94,8 @@
 	"boot.scr fat 0 1;"                 \
 	"boot.cmd fat 0 1;"                 \
 	"exynos5422-odroidxu3.dtb fat 0 1;" \
+	"exynos5422-odroidxu3-lite.dtb fat 0 1;" \
+	"exynos5422-odroidxu4.dtb fat 0 1;" \
 	"boot part 0 1;"                    \
 	"root part 0 2\0"
 
@@ -113,9 +115,19 @@
 
 /* Enable: board/samsung/common/misc.c to use set_dfu_alt_info() */
 #define CONFIG_MISC_COMMON
+#define CONFIG_MISC_INIT_R
 #define CONFIG_SET_DFU_ALT_INFO
 #define CONFIG_SET_DFU_ALT_BUF_LEN	(SZ_1K)
 
+/* Set soc_rev, soc_id, board_rev, boardname, fdtfile */
+#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
+#define CONFIG_ODROID_REV_AIN			9
+#define CONFIG_REVISION_TAG
+#define CONFIG_BOARD_TYPES
+
+#undef CONFIG_SYS_BOARD
+#define CONFIG_SYS_BOARD	"odroid"
+
 /* Define new extra env settings, including DFU settings */
 #undef CONFIG_EXTRA_ENV_SETTINGS
 #define CONFIG_EXTRA_ENV_SETTINGS \
include/samsung/exynos5-dt-types.h new file +27 -0
new file mode 100644
index 0000000..479e2e7
@@ -0,0 +1,27 @@
+#ifndef _EXYNOS5_DT_H_
+#define _EXYNOS5_DT_H_
+
+enum {
+	EXYNOS5_BOARD_GENERIC,
+
+	EXYNOS5_BOARD_ODROID_XU3,
+	EXYNOS5_BOARD_ODROID_XU3_REV01,
+	EXYNOS5_BOARD_ODROID_XU3_REV02,
+	EXYNOS5_BOARD_ODROID_XU4_REV01,
+	EXYNOS5_BOARD_ODROID_UNKNOWN,
+
+	EXYNOS5_BOARD_COUNT,
+};
+
+struct odroid_rev_info {
+	int board_type;
+	int board_rev;
+	int adc_val;
+	const char *name;
+};
+
+bool board_is_generic(void);
+bool board_is_odroidxu3(void);
+bool board_is_odroidxu4(void);
+
+#endif
Signature · 1 line
1.9.1
#59 lore raw

PATCH v2 11/11 exynos5-dt-types: add board detection for Odroid XU3/XU3L/XU4.

Hi Przemyslaw,

Quoted 54 lines · Przemyslaw Marczak

This commit adds additional file with implementation of board detection code for Odroid-XU3/XU4.

The detection depends on compatible found in fdt:
- "samsung,exynos5" - uses Exynos5 generic code
- "samsung,odroidxu3" - try detect XU3 revision

There are few revisions of Odroid XU3/XU4, each can be detected by checking the value of channel 9 of built-in ADC:

 Rev   ADC  Board
 0.1     0  XU3 0.1
 0.2   372  XU3 0.2 | XU3L - no DISPLAYPORT
 0.3  1280  XU4 0.1

The detection code depends on the ADC+10% value.

Implementation of functions:

- set_board_type()     - read ADC and set type
- get_board_rev()      - returns board revision: 1..3
- get_board_type()     - returns board type string

Additional functions with return values of bool:
- board_is_generic() - true if found compatible "samsung,exynos5"
but not "samsung,odroidxu3"
- board_is_odroidxu3() - true if found compatible "samsung,odroidxu3" and one of XU3 revision.
- board_is_odroidxu4() - true if found compatible "samsung,odroidxu3" and XU4 revision.

After I2C controller init, the get_board_type() can check if the XU3 board is a "Lite" variant, by probing chip 0x40 on I2C0 (INA231 - exists only on non-lite). This is useful for setting fdt file name at misc_init_r().

Enabled configs:
- CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
- CONFIG_ODROID_REV_AIN
- CONFIG_REVISION_TAG
- CONFIG_BOARD_TYPES

---
Changes V2:
- move detection code from exynos5-dt.c to exynos5-dt-types.c
- add header with board type function declarations
- check for compatible before do the detection
- update the ADC max values with 20% tolerance
- fix XU4 adc value, related to mistake from table in XU4 schematic
- return "Not supported" for XU4 when calls one of:
--dfu_get_alt_boot()
--dfu_get_alt_system()
- extend ${dfu_alt_system} by strings:
-- 'exynos5422-odroidxu3-lite.dtb'
-- 'exynos5422-odroidxu4.dtb' - allows prepare card on XU3

Quoted 10 lines
---
 board/samsung/common/Makefile           |   5 +-
 board/samsung/common/exynos5-dt-types.c | 196 ++++++++++++++++++++++++++++++++
 board/samsung/common/exynos5-dt.c       |  12 ++
 configs/odroid-xu3_defconfig            |   2 +
 include/configs/odroid_xu3.h            |  12 ++
 include/samsung/exynos5-dt-types.h      |  27 +++++
 6 files changed, 253 insertions(+), 1 deletion(-)
 create mode 100644 board/samsung/common/exynos5-dt-types.c
 create mode 100644 include/samsung/exynos5-dt-types.h

See nits below.

Quoted 112 lines
board/samsung/common/Makefile +4 -1
index 6cbd906..ef1a8f3 100644
@@ -11,5 +11,8 @@ obj-$(CONFIG_MISC_COMMON) += misc.o
 
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_BOARD_COMMON)     += board.o
-obj-$(CONFIG_EXYNOS5_DT)       += exynos5-dt.o
+ifdef CONFIG_EXYNOS5_DT
+obj-y += exynos5-dt.o
+obj-$(CONFIG_BOARD_TYPES) += exynos5-dt-types.o
+endif
 endif
board/samsung/common/exynos5-dt-types.c new file +91 -0
new file mode 100644
index 0000000..1364e98
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics
+ * Przemyslaw Marczak <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <adc.h>
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <power/pmic.h>
+#include <power/regulator.h>
+#include <power/s2mps11.h>
+#include <samsung/exynos5-dt-types.h>
+#include <samsung/misc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const struct udevice_id board_ids[] = {
+       { .compatible = "samsung,odroidxu3", .data = EXYNOS5_BOARD_ODROID_XU3 },
+       { .compatible = "samsung,exynos5", .data = EXYNOS5_BOARD_GENERIC },
+       { },
+};
+
+/**
+ * Odroix XU3/4 board revisions:
+ * Rev   ADCmax  Board
+ * 0.1     0     XU3 0.1
+ * 0.2   410     XU3 0.2 | XU3L - no DISPLAYPORT (probe I2C0:0x40 / INA231)
+ * 0.3  1408     XU4 0.1
+ * Use +10 % for ADC value tolerance.
+ */
+struct odroid_rev_info odroid_info[] = {
+       { EXYNOS5_BOARD_ODROID_XU3_REV01, 1, 10, "xu3" },
+       { EXYNOS5_BOARD_ODROID_XU3_REV02, 2, 410, "xu3" },
+       { EXYNOS5_BOARD_ODROID_XU4_REV01, 1, 1408, "xu4" },
+       { EXYNOS5_BOARD_ODROID_UNKNOWN, 0, 4095, "unknown" },
+};
+
+static unsigned int odroid_get_rev(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(odroid_info); i++) {
+               if (odroid_info[i].board_type == gd->board_type)
+                       return odroid_info[i].board_rev;
+       }
+
+       return 0;
+}
+
+static int odroid_get_board_type(void)
+{
+       unsigned int adcval;
+       int ret, i;
+
+       ret = adc_channel_single_shot("adc", CONFIG_ODROID_REV_AIN, &adcval);
+       if (ret)
+               goto rev_default;
+
+       for (i = 0; i < ARRAY_SIZE(odroid_info); i++) {
+               /* ADC tolerance: +20 % */
+               if (adcval < odroid_info[i].adc_val)
+                       return odroid_info[i].board_type;
+       }
+
+rev_default:
+       return EXYNOS5_BOARD_ODROID_XU3;
+}
+
+/**
+ * odroid_get_type_str - returns pointer to one of the board type string.
+ * Board types: "xu3", "xu3-lite", "xu4". However the "xu3lite" can be
+ * detected only when the i2c controller is ready to use. Fortunately,
+ * XU3 and XU3L are compatible, and the information about board lite
+ * revision is needed before booting the linux, to set proper environment
+ * variable: $fdtfile.
+ */
+static const char *odroid_get_type_str(void)
+{
+       const char *type_xu3l = "xu3-lite";
+       struct udevice *dev, *chip;
+       int i, ret;
+
+       if (gd->board_type != EXYNOS5_BOARD_ODROID_XU3_REV02)
+               goto exit;
+
+       ret = pmic_get("s2mps11", &dev);
+       if (ret)

board/samsung/common/exynos5-dt-types.c line 101

Quoted 10 lines
board/samsung/common/exynos5-dt-types.c new file +10 -0
+               goto exit;
+
+       /* Enable LDO26: 3.0V */
+       ret = pmic_reg_write(dev, S2MPS11_REG_L26CTRL,
+                            S2MPS11_LDO26_ENABLE);
+       if (ret)
+               goto exit;
+
+       /* Check XU3Lite by probe INA231 I2C0:0x40 */
+       ret = uclass_get_device(UCLASS_I2C, 0, &dev);

Yikes! What happens if you want to add a driver for this?

Quoted 63 lines
board/samsung/common/exynos5-dt-types.c new file +63 -0
+       if (ret)
+               goto exit;
+
+       ret = dm_i2c_probe(dev, 0x40, 0x0, &chip);
+       if (ret)
+               return type_xu3l;
+
+exit:
+       for (i = 0; i < ARRAY_SIZE(odroid_info); i++) {
+               if (odroid_info[i].board_type == gd->board_type)
+                       return odroid_info[i].name;
+       }
+
+       return NULL;
+}
+
+bool board_is_odroidxu3(void)
+{
+       if (gd->board_type >= EXYNOS5_BOARD_ODROID_XU3 &&
+           gd->board_type <= EXYNOS5_BOARD_ODROID_XU3_REV02)
+               return true;
+
+       return false;
+}
+
+bool board_is_odroidxu4(void)
+{
+       if (gd->board_type == EXYNOS5_BOARD_ODROID_XU4_REV01)
+               return true;
+
+       return false;
+}
+
+bool board_is_generic(void)
+{
+       if (gd->board_type == EXYNOS5_BOARD_GENERIC)
+               return true;
+
+       return false;
+}
+
+/**
+ * get_board_rev() - return detected board revision.
+ *
+ * @return:  return board revision number for XU3 or 0 for generic
+ */
+u32 get_board_rev(void)
+{
+       if (board_is_generic())
+               return 0;
+
+       return odroid_get_rev();
+}
+
+/**
+ * get_board_type() - returns board type string.
+ *
+ * @return:  return board type string for XU3 or empty string for generic
+ */
+const char *get_board_type(void)
+{
+       const char *generic = "";
+

board/samsung/common/exynos5-dt-types.c line 174

Quoted 10 lines
board/samsung/common/exynos5-dt-types.c new file +10 -0
+       if (board_is_generic())
+               return generic;
+
+       return odroid_get_type_str();
+}
+
+/**
+ * set_board_type() - set board type in gd->board_type.
+ * As default type set EXYNOS5_BOARD_GENERIC, if detect Odroid,
+ * then set it's proper type.

its

Quoted 9 lines
board/samsung/common/exynos5-dt-types.c new file +9 -0
+ */
+void set_board_type(void)
+{
+       const struct udevice_id *of_match = board_ids;
+       int ret;
+
+       gd->board_type = EXYNOS5_BOARD_GENERIC;
+
+       while (of_match->compatible) {

board/samsung/common/exynos5-dt-types.c line 193

Quoted 10 lines
board/samsung/common/exynos5-dt-types.c new file +10 -0
+               ret = fdt_node_check_compatible(gd->fdt_blob, 0,
+                                               of_match->compatible);
+               if (ret)
+                       of_match++;
+
+               gd->board_type = of_match->data;
+               break;
+       }
+
+       /* If Odroid, then check it's revision */

its

Quoted 120 lines
board/samsung/common/exynos5-dt-types.c new file +3 -0
+       if (board_is_odroidxu3())
+               gd->board_type = odroid_get_board_type();
+}
board/samsung/common/exynos5-dt.c +12 -0
index 4250f72..4d9e151 100644
@@ -27,7 +27,10 @@
 #include <power/pmic.h>
 #include <power/max77686_pmic.h>
 #include <power/regulator.h>
+#include <power/s2mps11.h>
 #include <power/s5m8767.h>
+#include <samsung/exynos5-dt-types.h>
+#include <samsung/misc.h>
 #include <tmu.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -335,15 +338,24 @@ int board_usb_init(int index, enum usb_init_type init)
 #ifdef CONFIG_SET_DFU_ALT_INFO
 char *get_dfu_alt_system(char *interface, char *devstr)
 {
+       char *info = "Not supported!";
+
+       if (board_is_odroidxu4())
+               return info;
+
        return getenv("dfu_alt_system");
 }
 
 char *get_dfu_alt_boot(char *interface, char *devstr)
 {
+       char *info = "Not supported!";
        struct mmc *mmc;
        char *alt_boot;
        int dev_num;
 
+       if (board_is_odroidxu4())
+               return info;
+
        dev_num = simple_strtoul(devstr, NULL, 10);
 
        mmc = find_mmc_device(dev_num);
configs/odroid-xu3_defconfig +2 -0
index f38c37b..d7e5698 100644
@@ -16,3 +16,5 @@ CONFIG_VIDEO_BRIDGE=y
 CONFIG_SYS_PROMPT="ODROID-XU3 # "
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_ADC=y
+CONFIG_ADC_EXYNOS=y
include/configs/odroid_xu3.h +12 -0
index 3c70158..648e48b 100644
@@ -94,6 +94,8 @@
        "boot.scr fat 0 1;"                 \
        "boot.cmd fat 0 1;"                 \
        "exynos5422-odroidxu3.dtb fat 0 1;" \
+       "exynos5422-odroidxu3-lite.dtb fat 0 1;" \
+       "exynos5422-odroidxu4.dtb fat 0 1;" \
        "boot part 0 1;"                    \
        "root part 0 2\0"
 
@@ -113,9 +115,19 @@
 
 /* Enable: board/samsung/common/misc.c to use set_dfu_alt_info() */
 #define CONFIG_MISC_COMMON
+#define CONFIG_MISC_INIT_R
 #define CONFIG_SET_DFU_ALT_INFO
 #define CONFIG_SET_DFU_ALT_BUF_LEN     (SZ_1K)
 
+/* Set soc_rev, soc_id, board_rev, boardname, fdtfile */
+#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
+#define CONFIG_ODROID_REV_AIN                  9
+#define CONFIG_REVISION_TAG
+#define CONFIG_BOARD_TYPES
+
+#undef CONFIG_SYS_BOARD
+#define CONFIG_SYS_BOARD       "odroid"
+
 /* Define new extra env settings, including DFU settings */
 #undef CONFIG_EXTRA_ENV_SETTINGS
 #define CONFIG_EXTRA_ENV_SETTINGS \
include/samsung/exynos5-dt-types.h new file +27 -1
new file mode 100644
index 0000000..479e2e7
@@ -0,0 +1,27 @@
+#ifndef _EXYNOS5_DT_H_
+#define _EXYNOS5_DT_H_
+
+enum {
+       EXYNOS5_BOARD_GENERIC,
+
+       EXYNOS5_BOARD_ODROID_XU3,
+       EXYNOS5_BOARD_ODROID_XU3_REV01,
+       EXYNOS5_BOARD_ODROID_XU3_REV02,
+       EXYNOS5_BOARD_ODROID_XU4_REV01,
+       EXYNOS5_BOARD_ODROID_UNKNOWN,
+
+       EXYNOS5_BOARD_COUNT,
+};
+
+struct odroid_rev_info {
+       int board_type;
+       int board_rev;
+       int adc_val;
+       const char *name;
+};
+
+bool board_is_generic(void);
+bool board_is_odroidxu3(void);
+bool board_is_odroidxu4(void);
+
+#endif
--
Quoted 2 lines

1.9.1

I can't help wondering why we don't just have separate device trees for these boards. It seems a pain to try to support them all with this auto-detection. Anyway, I think I already asked this and you're pretty sure this is what you want. I do understand the need to make it painless for users.

Regards,
Simon

#60 lore raw

PATCH v2 11/11 exynos5-dt-types: add board detection for Odroid XU3/XU3L/XU4.

Hello Simon,

Quoted 68 lines · Simon Glass

Hi Przemyslaw,

Quoted 62 lines · Przemyslaw Marczak

This commit adds additional file with implementation of board detection code for Odroid-XU3/XU4.

The detection depends on compatible found in fdt:
- "samsung,exynos5" - uses Exynos5 generic code
- "samsung,odroidxu3" - try detect XU3 revision

There are few revisions of Odroid XU3/XU4, each can be detected by checking the value of channel 9 of built-in ADC:

  Rev   ADC  Board
  0.1     0  XU3 0.1
  0.2   372  XU3 0.2 | XU3L - no DISPLAYPORT
  0.3  1280  XU4 0.1

The detection code depends on the ADC+10% value.

Implementation of functions:

- set_board_type()     - read ADC and set type
- get_board_rev()      - returns board revision: 1..3
- get_board_type()     - returns board type string

Additional functions with return values of bool:
- board_is_generic() - true if found compatible "samsung,exynos5"
but not "samsung,odroidxu3"
- board_is_odroidxu3() - true if found compatible "samsung,odroidxu3" and one of XU3 revision.
- board_is_odroidxu4() - true if found compatible "samsung,odroidxu3" and XU4 revision.

After I2C controller init, the get_board_type() can check if the XU3 board is a "Lite" variant, by probing chip 0x40 on I2C0 (INA231 - exists only on non-lite). This is useful for setting fdt file name at misc_init_r().

Enabled configs:
- CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
- CONFIG_ODROID_REV_AIN
- CONFIG_REVISION_TAG
- CONFIG_BOARD_TYPES

---
Changes V2:
- move detection code from exynos5-dt.c to exynos5-dt-types.c
- add header with board type function declarations
- check for compatible before do the detection
- update the ADC max values with 20% tolerance
- fix XU4 adc value, related to mistake from table in XU4 schematic
- return "Not supported" for XU4 when calls one of:

   --dfu_get_alt_boot()
   --dfu_get_alt_system()
- extend ${dfu_alt_system} by strings:
   -- 'exynos5422-odroidxu3-lite.dtb'
   -- 'exynos5422-odroidxu4.dtb' - allows prepare card on XU3
---
  board/samsung/common/Makefile           |   5 +-
  board/samsung/common/exynos5-dt-types.c | 196 ++++++++++++++++++++++++++++++++
  board/samsung/common/exynos5-dt.c       |  12 ++
  configs/odroid-xu3_defconfig            |   2 +
  include/configs/odroid_xu3.h            |  12 ++
  include/samsung/exynos5-dt-types.h      |  27 +++++
  6 files changed, 253 insertions(+), 1 deletion(-)
Quoted 2 lines

create mode 100644 board/samsung/common/exynos5-dt-types.c create mode 100644 include/samsung/exynos5-dt-types.h

Quoted 4 lines

See nits below.

Ok.

Quoted 116 lines
Quoted 116 lines
board/samsung/common/Makefile +4 -1
index 6cbd906..ef1a8f3 100644
@@ -11,5 +11,8 @@ obj-$(CONFIG_MISC_COMMON) += misc.o
 
  ifndef CONFIG_SPL_BUILD
  obj-$(CONFIG_BOARD_COMMON)     += board.o
-obj-$(CONFIG_EXYNOS5_DT)       += exynos5-dt.o
+ifdef CONFIG_EXYNOS5_DT
+obj-y += exynos5-dt.o
+obj-$(CONFIG_BOARD_TYPES) += exynos5-dt-types.o
+endif
  endif
board/samsung/common/exynos5-dt-types.c new file +95 -0
new file mode 100644
index 0000000..1364e98
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics
+ * Przemyslaw Marczak <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <adc.h>
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <power/pmic.h>
+#include <power/regulator.h>
+#include <power/s2mps11.h>
+#include <samsung/exynos5-dt-types.h>
+#include <samsung/misc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const struct udevice_id board_ids[] = {
+       { .compatible = "samsung,odroidxu3", .data = EXYNOS5_BOARD_ODROID_XU3 },
+       { .compatible = "samsung,exynos5", .data = EXYNOS5_BOARD_GENERIC },
+       { },
+};
+
+/**
+ * Odroix XU3/4 board revisions:
+ * Rev   ADCmax  Board
+ * 0.1     0     XU3 0.1
+ * 0.2   410     XU3 0.2 | XU3L - no DISPLAYPORT (probe I2C0:0x40 / INA231)
+ * 0.3  1408     XU4 0.1
+ * Use +10 % for ADC value tolerance.
+ */
+struct odroid_rev_info odroid_info[] = {
+       { EXYNOS5_BOARD_ODROID_XU3_REV01, 1, 10, "xu3" },
+       { EXYNOS5_BOARD_ODROID_XU3_REV02, 2, 410, "xu3" },
+       { EXYNOS5_BOARD_ODROID_XU4_REV01, 1, 1408, "xu4" },
+       { EXYNOS5_BOARD_ODROID_UNKNOWN, 0, 4095, "unknown" },
+};
+
+static unsigned int odroid_get_rev(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(odroid_info); i++) {
+               if (odroid_info[i].board_type == gd->board_type)
+                       return odroid_info[i].board_rev;
+       }
+
+       return 0;
+}
+
+static int odroid_get_board_type(void)
+{
+       unsigned int adcval;
+       int ret, i;
+
+       ret = adc_channel_single_shot("adc", CONFIG_ODROID_REV_AIN, &adcval);
+       if (ret)
+               goto rev_default;
+
+       for (i = 0; i < ARRAY_SIZE(odroid_info); i++) {
+               /* ADC tolerance: +20 % */
+               if (adcval < odroid_info[i].adc_val)
+                       return odroid_info[i].board_type;
+       }
+
+rev_default:
+       return EXYNOS5_BOARD_ODROID_XU3;
+}
+
+/**
+ * odroid_get_type_str - returns pointer to one of the board type string.
+ * Board types: "xu3", "xu3-lite", "xu4". However the "xu3lite" can be
+ * detected only when the i2c controller is ready to use. Fortunately,
+ * XU3 and XU3L are compatible, and the information about board lite
+ * revision is needed before booting the linux, to set proper environment
+ * variable: $fdtfile.
+ */
+static const char *odroid_get_type_str(void)
+{
+       const char *type_xu3l = "xu3-lite";
+       struct udevice *dev, *chip;
+       int i, ret;
+
+       if (gd->board_type != EXYNOS5_BOARD_ODROID_XU3_REV02)
+               goto exit;
+
+       ret = pmic_get("s2mps11", &dev);
+       if (ret)
+               goto exit;
+
+       /* Enable LDO26: 3.0V */
+       ret = pmic_reg_write(dev, S2MPS11_REG_L26CTRL,
Quoted 9 lines

board/samsung/common/exynos5-dt-types.c line 101

Quoted 6 lines
board/samsung/common/exynos5-dt-types.c new file +6 -0
+                            S2MPS11_LDO26_ENABLE);
+       if (ret)
+               goto exit;
+
+       /* Check XU3Lite by probe INA231 I2C0:0x40 */
+       ret = uclass_get_device(UCLASS_I2C, 0, &dev);

Yikes! What happens if you want to add a driver for this?

This may look much more pretty, but the INA's driver is not needed at U-Boot and also I don't like implement everything at once, since as you can see it takes some time to review and fixing again and again.

Quoted 67 lines
Quoted 67 lines
board/samsung/common/exynos5-dt-types.c new file +67 -0
+       if (ret)
+               goto exit;
+
+       ret = dm_i2c_probe(dev, 0x40, 0x0, &chip);
+       if (ret)
+               return type_xu3l;
+
+exit:
+       for (i = 0; i < ARRAY_SIZE(odroid_info); i++) {
+               if (odroid_info[i].board_type == gd->board_type)
+                       return odroid_info[i].name;
+       }
+
+       return NULL;
+}
+
+bool board_is_odroidxu3(void)
+{
+       if (gd->board_type >= EXYNOS5_BOARD_ODROID_XU3 &&
+           gd->board_type <= EXYNOS5_BOARD_ODROID_XU3_REV02)
+               return true;
+
+       return false;
+}
+
+bool board_is_odroidxu4(void)
+{
+       if (gd->board_type == EXYNOS5_BOARD_ODROID_XU4_REV01)
+               return true;
+
+       return false;
+}
+
+bool board_is_generic(void)
+{
+       if (gd->board_type == EXYNOS5_BOARD_GENERIC)
+               return true;
+
+       return false;
+}
+
+/**
+ * get_board_rev() - return detected board revision.
+ *
+ * @return:  return board revision number for XU3 or 0 for generic
+ */
+u32 get_board_rev(void)
+{
+       if (board_is_generic())
+               return 0;
+
+       return odroid_get_rev();
+}
+
+/**
+ * get_board_type() - returns board type string.
+ *
+ * @return:  return board type string for XU3 or empty string for generic
+ */
+const char *get_board_type(void)
+{
+       const char *generic = "";
+
+       if (board_is_generic())
+               return generic;
+
+       return odroid_get_type_str();
Quoted 9 lines

board/samsung/common/exynos5-dt-types.c line 174

Quoted 6 lines
board/samsung/common/exynos5-dt-types.c new file +6 -0
+}
+
+/**
+ * set_board_type() - set board type in gd->board_type.
+ * As default type set EXYNOS5_BOARD_GENERIC, if detect Odroid,
+ * then set it's proper type.

its

Right.

Quoted 13 lines
Quoted 13 lines
board/samsung/common/exynos5-dt-types.c new file +13 -0
+ */
+void set_board_type(void)
+{
+       const struct udevice_id *of_match = board_ids;
+       int ret;
+
+       gd->board_type = EXYNOS5_BOARD_GENERIC;
+
+       while (of_match->compatible) {
+               ret = fdt_node_check_compatible(gd->fdt_blob, 0,
+                                               of_match->compatible);
+               if (ret)
+                       of_match++;
Quoted 9 lines

board/samsung/common/exynos5-dt-types.c line 193

Quoted 6 lines
board/samsung/common/exynos5-dt-types.c new file +6 -0
+
+               gd->board_type = of_match->data;
+               break;
+       }
+
+       /* If Odroid, then check it's revision */

its

ok.

Quoted 129 lines
Quoted 120 lines
board/samsung/common/exynos5-dt-types.c new file +3 -0
+       if (board_is_odroidxu3())
+               gd->board_type = odroid_get_board_type();
+}
board/samsung/common/exynos5-dt.c +12 -0
index 4250f72..4d9e151 100644
@@ -27,7 +27,10 @@
  #include <power/pmic.h>
  #include <power/max77686_pmic.h>
  #include <power/regulator.h>
+#include <power/s2mps11.h>
  #include <power/s5m8767.h>
+#include <samsung/exynos5-dt-types.h>
+#include <samsung/misc.h>
  #include <tmu.h>
 
  DECLARE_GLOBAL_DATA_PTR;
@@ -335,15 +338,24 @@ int board_usb_init(int index, enum usb_init_type init)
  #ifdef CONFIG_SET_DFU_ALT_INFO
  char *get_dfu_alt_system(char *interface, char *devstr)
  {
+       char *info = "Not supported!";
+
+       if (board_is_odroidxu4())
+               return info;
+
         return getenv("dfu_alt_system");
  }
 
  char *get_dfu_alt_boot(char *interface, char *devstr)
  {
+       char *info = "Not supported!";
         struct mmc *mmc;
         char *alt_boot;
         int dev_num;
 
+       if (board_is_odroidxu4())
+               return info;
+
         dev_num = simple_strtoul(devstr, NULL, 10);
 
         mmc = find_mmc_device(dev_num);
configs/odroid-xu3_defconfig +2 -0
index f38c37b..d7e5698 100644
@@ -16,3 +16,5 @@ CONFIG_VIDEO_BRIDGE=y
  CONFIG_SYS_PROMPT="ODROID-XU3 # "
  CONFIG_USB=y
  CONFIG_DM_USB=y
+CONFIG_ADC=y
+CONFIG_ADC_EXYNOS=y
include/configs/odroid_xu3.h +12 -0
index 3c70158..648e48b 100644
@@ -94,6 +94,8 @@
         "boot.scr fat 0 1;"                 \
         "boot.cmd fat 0 1;"                 \
         "exynos5422-odroidxu3.dtb fat 0 1;" \
+       "exynos5422-odroidxu3-lite.dtb fat 0 1;" \
+       "exynos5422-odroidxu4.dtb fat 0 1;" \
         "boot part 0 1;"                    \
         "root part 0 2\0"
 
@@ -113,9 +115,19 @@
 
  /* Enable: board/samsung/common/misc.c to use set_dfu_alt_info() */
  #define CONFIG_MISC_COMMON
+#define CONFIG_MISC_INIT_R
  #define CONFIG_SET_DFU_ALT_INFO
  #define CONFIG_SET_DFU_ALT_BUF_LEN     (SZ_1K)
 
+/* Set soc_rev, soc_id, board_rev, boardname, fdtfile */
+#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
+#define CONFIG_ODROID_REV_AIN                  9
+#define CONFIG_REVISION_TAG
+#define CONFIG_BOARD_TYPES
+
+#undef CONFIG_SYS_BOARD
+#define CONFIG_SYS_BOARD       "odroid"
+
  /* Define new extra env settings, including DFU settings */
  #undef CONFIG_EXTRA_ENV_SETTINGS
  #define CONFIG_EXTRA_ENV_SETTINGS \
include/samsung/exynos5-dt-types.h new file +27 -1
new file mode 100644
index 0000000..479e2e7
@@ -0,0 +1,27 @@
+#ifndef _EXYNOS5_DT_H_
+#define _EXYNOS5_DT_H_
+
+enum {
+       EXYNOS5_BOARD_GENERIC,
+
+       EXYNOS5_BOARD_ODROID_XU3,
+       EXYNOS5_BOARD_ODROID_XU3_REV01,
+       EXYNOS5_BOARD_ODROID_XU3_REV02,
+       EXYNOS5_BOARD_ODROID_XU4_REV01,
+       EXYNOS5_BOARD_ODROID_UNKNOWN,
+
+       EXYNOS5_BOARD_COUNT,
+};
+
+struct odroid_rev_info {
+       int board_type;
+       int board_rev;
+       int adc_val;
+       const char *name;
+};
+
+bool board_is_generic(void);
+bool board_is_odroidxu3(void);
+bool board_is_odroidxu4(void);
+
+#endif
--
Quoted 2 lines

1.9.1

I can't help wondering why we don't just have separate device trees for these boards. It seems a pain to try to support them all with this auto-detection. Anyway, I think I already asked this and you're pretty sure this is what you want. I do understand the need to make it painless for users.

Quoted 3 lines

Regards,
Simon

It's much more easy for us, to support several Odroid revisions with the same SoC by the single U-Boot binary. It's also easy for the users, if they have a single binary for actually the same board variants.

And it's one less thing, that can be broken by the mistake :)

Thank you for your helpful comments, I will take them into account in V3.

Best regards,

Signature · 4 lines
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com
#61 lore raw

PATCH v2 11/11 exynos5-dt-types: add board detection for Odroid XU3/XU3L/XU4.

Hi Premyslaw,

Quoted 469 lines · Przemyslaw Marczak

Hello Simon,

Quoted 73 lines · Simon Glass

Hi Przemyslaw,

Quoted 64 lines · Przemyslaw Marczak

This commit adds additional file with implementation of board detection code for Odroid-XU3/XU4.

The detection depends on compatible found in fdt:
- "samsung,exynos5" - uses Exynos5 generic code
- "samsung,odroidxu3" - try detect XU3 revision

There are few revisions of Odroid XU3/XU4, each can be detected by checking the value of channel 9 of built-in ADC:

  Rev   ADC  Board
  0.1     0  XU3 0.1
  0.2   372  XU3 0.2 | XU3L - no DISPLAYPORT
  0.3  1280  XU4 0.1

The detection code depends on the ADC+10% value.

Implementation of functions:

- set_board_type()     - read ADC and set type
- get_board_rev()      - returns board revision: 1..3
- get_board_type()     - returns board type string

Additional functions with return values of bool:
- board_is_generic() - true if found compatible "samsung,exynos5"
but not "samsung,odroidxu3"
- board_is_odroidxu3() - true if found compatible "samsung,odroidxu3" and one of XU3 revision.
- board_is_odroidxu4() - true if found compatible "samsung,odroidxu3" and XU4 revision.

After I2C controller init, the get_board_type() can check if the XU3 board is a "Lite" variant, by probing chip 0x40 on I2C0 (INA231 - exists only on non-lite). This is useful for setting fdt file name at misc_init_r().

Enabled configs:
- CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
- CONFIG_ODROID_REV_AIN
- CONFIG_REVISION_TAG
- CONFIG_BOARD_TYPES

---
Changes V2:
- move detection code from exynos5-dt.c to exynos5-dt-types.c
- add header with board type function declarations
- check for compatible before do the detection
- update the ADC max values with 20% tolerance
- fix XU4 adc value, related to mistake from table in XU4 schematic
- return "Not supported" for XU4 when calls one of:

   --dfu_get_alt_boot()
   --dfu_get_alt_system()
- extend ${dfu_alt_system} by strings:
   -- 'exynos5422-odroidxu3-lite.dtb'
   -- 'exynos5422-odroidxu4.dtb' - allows prepare card on XU3
---
  board/samsung/common/Makefile           |   5 +-
  board/samsung/common/exynos5-dt-types.c | 196
++++++++++++++++++++++++++++++++
  board/samsung/common/exynos5-dt.c       |  12 ++
  configs/odroid-xu3_defconfig            |   2 +
  include/configs/odroid_xu3.h            |  12 ++
  include/samsung/exynos5-dt-types.h      |  27 +++++
  6 files changed, 253 insertions(+), 1 deletion(-)
Quoted 2 lines

create mode 100644 board/samsung/common/exynos5-dt-types.c create mode 100644 include/samsung/exynos5-dt-types.h

Quoted 4 lines

See nits below.

Ok.

Quoted 125 lines
Quoted 125 lines
board/samsung/common/Makefile +4 -1
index 6cbd906..ef1a8f3 100644
@@ -11,5 +11,8 @@ obj-$(CONFIG_MISC_COMMON) += misc.o
 
  ifndef CONFIG_SPL_BUILD
  obj-$(CONFIG_BOARD_COMMON)     += board.o
-obj-$(CONFIG_EXYNOS5_DT)       += exynos5-dt.o
+ifdef CONFIG_EXYNOS5_DT
+obj-y += exynos5-dt.o
+obj-$(CONFIG_BOARD_TYPES) += exynos5-dt-types.o
+endif
  endif
board/samsung/common/exynos5-dt-types.c new file +22 -0
new file mode 100644
index 0000000..1364e98
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics
+ * Przemyslaw Marczak <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <adc.h>
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <power/pmic.h>
+#include <power/regulator.h>
+#include <power/s2mps11.h>
+#include <samsung/exynos5-dt-types.h>
+#include <samsung/misc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const struct udevice_id board_ids[] = {
+       { .compatible = "samsung,odroidxu3", .data =

EXYNOS5_BOARD_ODROID_XU3 },
+ { .compatible = "samsung,exynos5", .data = EXYNOS5_BOARD_GENERIC
},

board/samsung/common/exynos5-dt-types.c new file +8 -0
+       { },
+};
+
+/**
+ * Odroix XU3/4 board revisions:
+ * Rev   ADCmax  Board
+ * 0.1     0     XU3 0.1
+ * 0.2   410     XU3 0.2 | XU3L - no DISPLAYPORT (probe I2C0:0x40 /

INA231)
+ * 0.3 1408 XU4 0.1
+ * Use +10 % for ADC value tolerance.
+ */

board/samsung/common/exynos5-dt-types.c new file +25 -0
+struct odroid_rev_info odroid_info[] = {
+       { EXYNOS5_BOARD_ODROID_XU3_REV01, 1, 10, "xu3" },
+       { EXYNOS5_BOARD_ODROID_XU3_REV02, 2, 410, "xu3" },
+       { EXYNOS5_BOARD_ODROID_XU4_REV01, 1, 1408, "xu4" },
+       { EXYNOS5_BOARD_ODROID_UNKNOWN, 0, 4095, "unknown" },
+};
+
+static unsigned int odroid_get_rev(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(odroid_info); i++) {
+               if (odroid_info[i].board_type == gd->board_type)
+                       return odroid_info[i].board_rev;
+       }
+
+       return 0;
+}
+
+static int odroid_get_board_type(void)
+{
+       unsigned int adcval;
+       int ret, i;
+
+       ret = adc_channel_single_shot("adc", CONFIG_ODROID_REV_AIN,

&adcval);

board/samsung/common/exynos5-dt-types.c new file +15 -0
+       if (ret)
+               goto rev_default;
+
+       for (i = 0; i < ARRAY_SIZE(odroid_info); i++) {
+               /* ADC tolerance: +20 % */
+               if (adcval < odroid_info[i].adc_val)
+                       return odroid_info[i].board_type;
+       }
+
+rev_default:
+       return EXYNOS5_BOARD_ODROID_XU3;
+}
+
+/**
+ * odroid_get_type_str - returns pointer to one of the board type

string.
+ * Board types: "xu3", "xu3-lite", "xu4". However the "xu3lite" can be
+ * detected only when the i2c controller is ready to use. Fortunately,
+ * XU3 and XU3L are compatible, and the information about board lite
+ * revision is needed before booting the linux, to set proper environment
+ * variable: $fdtfile.
+ */

board/samsung/common/exynos5-dt-types.c new file +16 -0
+static const char *odroid_get_type_str(void)
+{
+       const char *type_xu3l = "xu3-lite";
+       struct udevice *dev, *chip;
+       int i, ret;
+
+       if (gd->board_type != EXYNOS5_BOARD_ODROID_XU3_REV02)
+               goto exit;
+
+       ret = pmic_get("s2mps11", &dev);
+       if (ret)
+               goto exit;
+
+       /* Enable LDO26: 3.0V */
+       ret = pmic_reg_write(dev, S2MPS11_REG_L26CTRL,
+                            S2MPS11_LDO26_ENABLE);
Quoted 9 lines

board/samsung/common/exynos5-dt-types.c line 101

Quoted 5 lines
board/samsung/common/exynos5-dt-types.c new file +5 -0
+       if (ret)
+               goto exit;
+
+       /* Check XU3Lite by probe INA231 I2C0:0x40 */
+       ret = uclass_get_device(UCLASS_I2C, 0, &dev);

Yikes! What happens if you want to add a driver for this?

This may look much more pretty, but the INA's driver is not needed at U-Boot and also I don't like implement everything at once, since as you can see it takes some time to review and fixing again and again.

Quoted 69 lines
Quoted 69 lines
board/samsung/common/exynos5-dt-types.c new file +58 -0
+       if (ret)
+               goto exit;
+
+       ret = dm_i2c_probe(dev, 0x40, 0x0, &chip);
+       if (ret)
+               return type_xu3l;
+
+exit:
+       for (i = 0; i < ARRAY_SIZE(odroid_info); i++) {
+               if (odroid_info[i].board_type == gd->board_type)
+                       return odroid_info[i].name;
+       }
+
+       return NULL;
+}
+
+bool board_is_odroidxu3(void)
+{
+       if (gd->board_type >= EXYNOS5_BOARD_ODROID_XU3 &&
+           gd->board_type <= EXYNOS5_BOARD_ODROID_XU3_REV02)
+               return true;
+
+       return false;
+}
+
+bool board_is_odroidxu4(void)
+{
+       if (gd->board_type == EXYNOS5_BOARD_ODROID_XU4_REV01)
+               return true;
+
+       return false;
+}
+
+bool board_is_generic(void)
+{
+       if (gd->board_type == EXYNOS5_BOARD_GENERIC)
+               return true;
+
+       return false;
+}
+
+/**
+ * get_board_rev() - return detected board revision.
+ *
+ * @return:  return board revision number for XU3 or 0 for generic
+ */
+u32 get_board_rev(void)
+{
+       if (board_is_generic())
+               return 0;
+
+       return odroid_get_rev();
+}
+
+/**
+ * get_board_type() - returns board type string.
+ *
+ * @return:  return board type string for XU3 or empty string for

generic
+ */

board/samsung/common/exynos5-dt-types.c new file +9 -0
+const char *get_board_type(void)
+{
+       const char *generic = "";
+
+       if (board_is_generic())
+               return generic;
+
+       return odroid_get_type_str();
+}
Quoted 9 lines

board/samsung/common/exynos5-dt-types.c line 174

Quoted 5 lines
board/samsung/common/exynos5-dt-types.c new file +5 -0
+
+/**
+ * set_board_type() - set board type in gd->board_type.
+ * As default type set EXYNOS5_BOARD_GENERIC, if detect Odroid,
+ * then set it's proper type.

its

Right.

Quoted 14 lines
Quoted 14 lines

+ */

board/samsung/common/exynos5-dt-types.c new file +13 -0
+void set_board_type(void)
+{
+       const struct udevice_id *of_match = board_ids;
+       int ret;
+
+       gd->board_type = EXYNOS5_BOARD_GENERIC;
+
+       while (of_match->compatible) {
+               ret = fdt_node_check_compatible(gd->fdt_blob, 0,
+                                               of_match->compatible);
+               if (ret)
+                       of_match++;
+
Quoted 9 lines

board/samsung/common/exynos5-dt-types.c line 193

Quoted 5 lines
board/samsung/common/exynos5-dt-types.c new file +5 -0
+               gd->board_type = of_match->data;
+               break;
+       }
+
+       /* If Odroid, then check it's revision */

its

ok.

Quoted 132 lines
Quoted 123 lines
board/samsung/common/exynos5-dt-types.c new file +3 -0
+       if (board_is_odroidxu3())
+               gd->board_type = odroid_get_board_type();
+}
board/samsung/common/exynos5-dt.c +12 -0
index 4250f72..4d9e151 100644
@@ -27,7 +27,10 @@
  #include <power/pmic.h>
  #include <power/max77686_pmic.h>
  #include <power/regulator.h>
+#include <power/s2mps11.h>
  #include <power/s5m8767.h>
+#include <samsung/exynos5-dt-types.h>
+#include <samsung/misc.h>
  #include <tmu.h>
 
  DECLARE_GLOBAL_DATA_PTR;
@@ -335,15 +338,24 @@ int board_usb_init(int index, enum usb_init_type
 init)
  #ifdef CONFIG_SET_DFU_ALT_INFO
  char *get_dfu_alt_system(char *interface, char *devstr)
  {
+       char *info = "Not supported!";
+
+       if (board_is_odroidxu4())
+               return info;
+
         return getenv("dfu_alt_system");
  }
 
  char *get_dfu_alt_boot(char *interface, char *devstr)
  {
+       char *info = "Not supported!";
         struct mmc *mmc;
         char *alt_boot;
         int dev_num;
 
+       if (board_is_odroidxu4())
+               return info;
+
         dev_num = simple_strtoul(devstr, NULL, 10);
 
         mmc = find_mmc_device(dev_num);
configs/odroid-xu3_defconfig +2 -0
index f38c37b..d7e5698 100644
@@ -16,3 +16,5 @@ CONFIG_VIDEO_BRIDGE=y
  CONFIG_SYS_PROMPT="ODROID-XU3 # "
  CONFIG_USB=y
  CONFIG_DM_USB=y
+CONFIG_ADC=y
+CONFIG_ADC_EXYNOS=y
include/configs/odroid_xu3.h +12 -0
index 3c70158..648e48b 100644
@@ -94,6 +94,8 @@
         "boot.scr fat 0 1;"                 \
         "boot.cmd fat 0 1;"                 \
         "exynos5422-odroidxu3.dtb fat 0 1;" \
+       "exynos5422-odroidxu3-lite.dtb fat 0 1;" \
+       "exynos5422-odroidxu4.dtb fat 0 1;" \
         "boot part 0 1;"                    \
         "root part 0 2\0"
 
@@ -113,9 +115,19 @@
 
  /* Enable: board/samsung/common/misc.c to use set_dfu_alt_info() */
  #define CONFIG_MISC_COMMON
+#define CONFIG_MISC_INIT_R
  #define CONFIG_SET_DFU_ALT_INFO
  #define CONFIG_SET_DFU_ALT_BUF_LEN     (SZ_1K)
 
+/* Set soc_rev, soc_id, board_rev, boardname, fdtfile */
+#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
+#define CONFIG_ODROID_REV_AIN                  9
+#define CONFIG_REVISION_TAG
+#define CONFIG_BOARD_TYPES
+
+#undef CONFIG_SYS_BOARD
+#define CONFIG_SYS_BOARD       "odroid"
+
  /* Define new extra env settings, including DFU settings */
  #undef CONFIG_EXTRA_ENV_SETTINGS
  #define CONFIG_EXTRA_ENV_SETTINGS \
include/samsung/exynos5-dt-types.h new file +27 -1
new file mode 100644
index 0000000..479e2e7
@@ -0,0 +1,27 @@
+#ifndef _EXYNOS5_DT_H_
+#define _EXYNOS5_DT_H_
+
+enum {
+       EXYNOS5_BOARD_GENERIC,
+
+       EXYNOS5_BOARD_ODROID_XU3,
+       EXYNOS5_BOARD_ODROID_XU3_REV01,
+       EXYNOS5_BOARD_ODROID_XU3_REV02,
+       EXYNOS5_BOARD_ODROID_XU4_REV01,
+       EXYNOS5_BOARD_ODROID_UNKNOWN,
+
+       EXYNOS5_BOARD_COUNT,
+};
+
+struct odroid_rev_info {
+       int board_type;
+       int board_rev;
+       int adc_val;
+       const char *name;
+};
+
+bool board_is_generic(void);
+bool board_is_odroidxu3(void);
+bool board_is_odroidxu4(void);
+
+#endif
--
Quoted 2 lines

1.9.1

I can't help wondering why we don't just have separate device trees for these boards. It seems a pain to try to support them all with this auto-detection. Anyway, I think I already asked this and you're pretty sure this is what you want. I do understand the need to make it painless for users.

Quoted 3 lines

Regards,
Simon

Quoted 5 lines

It's much more easy for us, to support several Odroid revisions with the same SoC by the single U-Boot binary. It's also easy for the users, if they have a single binary for actually the same board variants.

And it's one less thing, that can be broken by the mistake :)

OK I see.

Regards,
Simon

#62 lore raw

v2 cover Add board detection for Odroid XU3 / XU3Lite / XU4

In reply to Przemyslaw Marczak

Hi Przemyslaw,

Quoted 67 lines · Przemyslaw Marczak

This patchset adds:
- CPU model in dts for Chromebook Peach Pi as Exynos5800
- set the cpu id of Exynos5422 to 0x5422
- S2MPS11 PMIC I/O driver
- Exynos5420-compatible (9-channel, 12-bit) ADC driver
- new file for Exynos5: exynos5-dt-types.c
- board detection for Odroid XU3 / XU3lite / XU4
- fixed ADC val for XU4

This was tested on Odroid XU3 and XU3 Lite, without the XU4, but I'm waiting for reply from the Odroid forum users.

Tested with buildman for samsung.

Available on github:
https://github.com/bobenstein/u-boot/tree/xu3-detect-patchset-v1
https://github.com/bobenstein/u-boot/tree/xu3-detect-patchset-v2

Przemyslaw Marczak (11):
samsung: board/misc: check returned pointer for get_board_type() calls
s5p: cpu_info: print "cpu-model" if exists in dts
Peach-Pi: dts: add cpu-model string
Exynos5422/5800: set cpu id to 0x5422
dm: pmic: add s2mps11 PMIC I/O driver
dm: adc: add simple ADC uclass implementation
dm: adc: add Exynos54xx compatible ADC driver
Odroid-XU3: enable s2mps11 PMIC support
Exynos54xx: dts: add ADC node
Odroid-XU3: dts: enable ADC, with request for pre-reloc bind
exynos5-dt-types: add board detection for Odroid XU3/XU3L/XU4.

 arch/arm/cpu/armv7/s5p-common/cpu_info.c  |  14 ++-
 arch/arm/dts/exynos5422-odroidxu3.dts     |  12 ++
 arch/arm/dts/exynos54xx.dtsi              |   7 ++
 arch/arm/dts/exynos5800-peach-pi.dts      |   1 +
 arch/arm/mach-exynos/clock.c              |  16 +--
 arch/arm/mach-exynos/clock_init_exynos5.c |   2 +-
 arch/arm/mach-exynos/common_setup.h       |   4 +-
 arch/arm/mach-exynos/include/mach/adc.h   |  45 +++++++
 arch/arm/mach-exynos/include/mach/cpu.h   |   6 +-
 arch/arm/mach-exynos/include/mach/gpio.h  |   4 +-
 arch/arm/mach-exynos/pinmux.c             |   2 +-
 arch/arm/mach-exynos/power.c              |   2 +-
 board/samsung/common/Makefile             |   5 +-
 board/samsung/common/board.c              |   4 +-
 board/samsung/common/exynos5-dt-types.c   | 196 ++++++++++++++++++++++++++++++
 board/samsung/common/exynos5-dt.c         |  12 ++
 board/samsung/common/misc.c               |   3 +
 configs/odroid-xu3_defconfig              |   5 +
 doc/device-tree-bindings/pmic/s2mps11.txt |  17 +++
 drivers/Kconfig                           |   2 +
 drivers/Makefile                          |   1 +
 drivers/adc/Kconfig                       |  17 +++
 drivers/adc/Makefile                      |   9 ++
 drivers/adc/adc-uclass.c                  |  76 ++++++++++++
 drivers/adc/exynos-adc.c                  | 102 ++++++++++++++++
 drivers/power/pmic/Kconfig                |  14 +++
 drivers/power/pmic/Makefile               |   1 +
 drivers/power/pmic/s2mps11.c              |  60 +++++++++
 include/adc.h                             |  88 ++++++++++++++
 include/configs/odroid_xu3.h              |  12 ++
 include/dm/uclass-id.h                    |   1 +
 include/power/s2mps11.h                   | 109 +++++++++++++++++
 include/samsung/exynos5-dt-types.h        |  27 ++++
 33 files changed, 854 insertions(+), 22 deletions(-)
 create mode 100644 board/samsung/common/exynos5-dt-types.c
 create mode 100644 doc/device-tree-bindings/pmic/s2mps11.txt
Quoted 9 lines
 create mode 100644 drivers/adc/Kconfig
 create mode 100644 drivers/adc/Makefile
 create mode 100644 drivers/adc/adc-uclass.c
 create mode 100644 drivers/adc/exynos-adc.c
 create mode 100644 drivers/power/pmic/s2mps11.c
 create mode 100644 include/adc.h
 create mode 100644 include/power/s2mps11.h
 create mode 100644 include/samsung/exynos5-dt-types.h

I have tested this patch on Odroid-XU3 and Odroid-XU4.

Both using micoSD and eMMC cards.

-Anand Moon

Quoted 3 lines

--
1.9.1

#63 lore raw

v2 cover Add board detection for Odroid XU3 / XU3Lite / XU4

Hello Anand,

Quoted 80 lines · Anand Moon

Hi Przemyslaw,

Quoted 65 lines · Przemyslaw Marczak

This patchset adds:
- CPU model in dts for Chromebook Peach Pi as Exynos5800
- set the cpu id of Exynos5422 to 0x5422
- S2MPS11 PMIC I/O driver
- Exynos5420-compatible (9-channel, 12-bit) ADC driver
- new file for Exynos5: exynos5-dt-types.c
- board detection for Odroid XU3 / XU3lite / XU4
- fixed ADC val for XU4

This was tested on Odroid XU3 and XU3 Lite, without the XU4, but I'm waiting for reply from the Odroid forum users.

Tested with buildman for samsung.

Available on github:
https://github.com/bobenstein/u-boot/tree/xu3-detect-patchset-v1
https://github.com/bobenstein/u-boot/tree/xu3-detect-patchset-v2

Przemyslaw Marczak (11):
samsung: board/misc: check returned pointer for get_board_type() calls
s5p: cpu_info: print "cpu-model" if exists in dts
Peach-Pi: dts: add cpu-model string
Exynos5422/5800: set cpu id to 0x5422
dm: pmic: add s2mps11 PMIC I/O driver
dm: adc: add simple ADC uclass implementation
dm: adc: add Exynos54xx compatible ADC driver
Odroid-XU3: enable s2mps11 PMIC support
Exynos54xx: dts: add ADC node
Odroid-XU3: dts: enable ADC, with request for pre-reloc bind
exynos5-dt-types: add board detection for Odroid XU3/XU3L/XU4.

  arch/arm/cpu/armv7/s5p-common/cpu_info.c  |  14 ++-
  arch/arm/dts/exynos5422-odroidxu3.dts     |  12 ++
  arch/arm/dts/exynos54xx.dtsi              |   7 ++
  arch/arm/dts/exynos5800-peach-pi.dts      |   1 +
  arch/arm/mach-exynos/clock.c              |  16 +--
  arch/arm/mach-exynos/clock_init_exynos5.c |   2 +-
  arch/arm/mach-exynos/common_setup.h       |   4 +-
  arch/arm/mach-exynos/include/mach/adc.h   |  45 +++++++
  arch/arm/mach-exynos/include/mach/cpu.h   |   6 +-
  arch/arm/mach-exynos/include/mach/gpio.h  |   4 +-
  arch/arm/mach-exynos/pinmux.c             |   2 +-
  arch/arm/mach-exynos/power.c              |   2 +-
  board/samsung/common/Makefile             |   5 +-
  board/samsung/common/board.c              |   4 +-
  board/samsung/common/exynos5-dt-types.c   | 196 ++++++++++++++++++++++++++++++
  board/samsung/common/exynos5-dt.c         |  12 ++
  board/samsung/common/misc.c               |   3 +
  configs/odroid-xu3_defconfig              |   5 +
  doc/device-tree-bindings/pmic/s2mps11.txt |  17 +++
  drivers/Kconfig                           |   2 +
  drivers/Makefile                          |   1 +
  drivers/adc/Kconfig                       |  17 +++
  drivers/adc/Makefile                      |   9 ++
  drivers/adc/adc-uclass.c                  |  76 ++++++++++++
  drivers/adc/exynos-adc.c                  | 102 ++++++++++++++++
  drivers/power/pmic/Kconfig                |  14 +++
  drivers/power/pmic/Makefile               |   1 +
  drivers/power/pmic/s2mps11.c              |  60 +++++++++
  include/adc.h                             |  88 ++++++++++++++
  include/configs/odroid_xu3.h              |  12 ++
  include/dm/uclass-id.h                    |   1 +
  include/power/s2mps11.h                   | 109 +++++++++++++++++
  include/samsung/exynos5-dt-types.h        |  27 ++++
  33 files changed, 854 insertions(+), 22 deletions(-)
Quoted 11 lines

create mode 100644 board/samsung/common/exynos5-dt-types.c create mode 100644 doc/device-tree-bindings/pmic/s2mps11.txt create mode 100644 drivers/adc/Kconfig
create mode 100644 drivers/adc/Makefile
create mode 100644 drivers/adc/adc-uclass.c
create mode 100644 drivers/adc/exynos-adc.c
create mode 100644 drivers/power/pmic/s2mps11.c create mode 100644 include/adc.h
create mode 100644 include/power/s2mps11.h
create mode 100644 include/samsung/exynos5-dt-types.h

Quoted 12 lines

I have tested this patch on Odroid-XU3 and Odroid-XU4.

Both using micoSD and eMMC cards.

-Anand Moon

Quoted 3 lines

--
1.9.1

Thank you for testing!

Best regards,

Signature · 4 lines
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com
#64 lore raw

v2 cover Add board detection for Odroid XU3 / XU3Lite / XU4

In reply to Przemyslaw Marczak

Hello,

Quoted 65 lines · Przemyslaw Marczak

This patchset adds:
- CPU model in dts for Chromebook Peach Pi as Exynos5800
- set the cpu id of Exynos5422 to 0x5422
- S2MPS11 PMIC I/O driver
- Exynos5420-compatible (9-channel, 12-bit) ADC driver
- new file for Exynos5: exynos5-dt-types.c
- board detection for Odroid XU3 / XU3lite / XU4
- fixed ADC val for XU4

This was tested on Odroid XU3 and XU3 Lite, without the XU4, but I'm waiting for reply from the Odroid forum users.

Tested with buildman for samsung.

Available on github:
https://github.com/bobenstein/u-boot/tree/xu3-detect-patchset-v1
https://github.com/bobenstein/u-boot/tree/xu3-detect-patchset-v2

Przemyslaw Marczak (11):
samsung: board/misc: check returned pointer for get_board_type() calls
s5p: cpu_info: print "cpu-model" if exists in dts
Peach-Pi: dts: add cpu-model string
Exynos5422/5800: set cpu id to 0x5422
dm: pmic: add s2mps11 PMIC I/O driver
dm: adc: add simple ADC uclass implementation
dm: adc: add Exynos54xx compatible ADC driver
Odroid-XU3: enable s2mps11 PMIC support
Exynos54xx: dts: add ADC node
Odroid-XU3: dts: enable ADC, with request for pre-reloc bind
exynos5-dt-types: add board detection for Odroid XU3/XU3L/XU4.

  arch/arm/cpu/armv7/s5p-common/cpu_info.c  |  14 ++-
  arch/arm/dts/exynos5422-odroidxu3.dts     |  12 ++
  arch/arm/dts/exynos54xx.dtsi              |   7 ++
  arch/arm/dts/exynos5800-peach-pi.dts      |   1 +
  arch/arm/mach-exynos/clock.c              |  16 +--
  arch/arm/mach-exynos/clock_init_exynos5.c |   2 +-
  arch/arm/mach-exynos/common_setup.h       |   4 +-
  arch/arm/mach-exynos/include/mach/adc.h   |  45 +++++++
  arch/arm/mach-exynos/include/mach/cpu.h   |   6 +-
  arch/arm/mach-exynos/include/mach/gpio.h  |   4 +-
  arch/arm/mach-exynos/pinmux.c             |   2 +-
  arch/arm/mach-exynos/power.c              |   2 +-
  board/samsung/common/Makefile             |   5 +-
  board/samsung/common/board.c              |   4 +-
  board/samsung/common/exynos5-dt-types.c   | 196 ++++++++++++++++++++++++++++++
  board/samsung/common/exynos5-dt.c         |  12 ++
  board/samsung/common/misc.c               |   3 +
  configs/odroid-xu3_defconfig              |   5 +
  doc/device-tree-bindings/pmic/s2mps11.txt |  17 +++
  drivers/Kconfig                           |   2 +
  drivers/Makefile                          |   1 +
  drivers/adc/Kconfig                       |  17 +++
  drivers/adc/Makefile                      |   9 ++
  drivers/adc/adc-uclass.c                  |  76 ++++++++++++
  drivers/adc/exynos-adc.c                  | 102 ++++++++++++++++
  drivers/power/pmic/Kconfig                |  14 +++
  drivers/power/pmic/Makefile               |   1 +
  drivers/power/pmic/s2mps11.c              |  60 +++++++++
  include/adc.h                             |  88 ++++++++++++++
  include/configs/odroid_xu3.h              |  12 ++
  include/dm/uclass-id.h                    |   1 +
  include/power/s2mps11.h                   | 109 +++++++++++++++++
  include/samsung/exynos5-dt-types.h        |  27 ++++
  33 files changed, 854 insertions(+), 22 deletions(-)
Quoted 11 lines

create mode 100644 board/samsung/common/exynos5-dt-types.c create mode 100644 doc/device-tree-bindings/pmic/s2mps11.txt create mode 100644 drivers/adc/Kconfig
create mode 100644 drivers/adc/Makefile
create mode 100644 drivers/adc/adc-uclass.c
create mode 100644 drivers/adc/exynos-adc.c
create mode 100644 drivers/power/pmic/s2mps11.c create mode 100644 include/adc.h
create mode 100644 include/power/s2mps11.h
create mode 100644 include/samsung/exynos5-dt-types.h

Simon,
Are you going to to review this patchset or can I update it and ask Minkyu for taking it?

Best regards,

Signature · 4 lines
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com
#65 lore raw

v2 cover Add board detection for Odroid XU3 / XU3Lite / XU4

Hi Przemyslaw,

Quoted 83 lines · Przemyslaw Marczak

Hello,

Quoted 67 lines · Przemyslaw Marczak

This patchset adds:
- CPU model in dts for Chromebook Peach Pi as Exynos5800
- set the cpu id of Exynos5422 to 0x5422
- S2MPS11 PMIC I/O driver
- Exynos5420-compatible (9-channel, 12-bit) ADC driver
- new file for Exynos5: exynos5-dt-types.c
- board detection for Odroid XU3 / XU3lite / XU4
- fixed ADC val for XU4

This was tested on Odroid XU3 and XU3 Lite, without the XU4, but I'm waiting for reply from the Odroid forum users.

Tested with buildman for samsung.

Available on github:
https://github.com/bobenstein/u-boot/tree/xu3-detect-patchset-v1
https://github.com/bobenstein/u-boot/tree/xu3-detect-patchset-v2

Przemyslaw Marczak (11):
samsung: board/misc: check returned pointer for get_board_type() calls
s5p: cpu_info: print "cpu-model" if exists in dts
Peach-Pi: dts: add cpu-model string
Exynos5422/5800: set cpu id to 0x5422
dm: pmic: add s2mps11 PMIC I/O driver
dm: adc: add simple ADC uclass implementation
dm: adc: add Exynos54xx compatible ADC driver
Odroid-XU3: enable s2mps11 PMIC support
Exynos54xx: dts: add ADC node
Odroid-XU3: dts: enable ADC, with request for pre-reloc bind
exynos5-dt-types: add board detection for Odroid XU3/XU3L/XU4.

  arch/arm/cpu/armv7/s5p-common/cpu_info.c  |  14 ++-
  arch/arm/dts/exynos5422-odroidxu3.dts     |  12 ++
  arch/arm/dts/exynos54xx.dtsi              |   7 ++
  arch/arm/dts/exynos5800-peach-pi.dts      |   1 +
  arch/arm/mach-exynos/clock.c              |  16 +--
  arch/arm/mach-exynos/clock_init_exynos5.c |   2 +-
  arch/arm/mach-exynos/common_setup.h       |   4 +-
  arch/arm/mach-exynos/include/mach/adc.h   |  45 +++++++
  arch/arm/mach-exynos/include/mach/cpu.h   |   6 +-
  arch/arm/mach-exynos/include/mach/gpio.h  |   4 +-
  arch/arm/mach-exynos/pinmux.c             |   2 +-
  arch/arm/mach-exynos/power.c              |   2 +-
  board/samsung/common/Makefile             |   5 +-
  board/samsung/common/board.c              |   4 +-
  board/samsung/common/exynos5-dt-types.c   | 196
++++++++++++++++++++++++++++++
  board/samsung/common/exynos5-dt.c         |  12 ++
  board/samsung/common/misc.c               |   3 +
  configs/odroid-xu3_defconfig              |   5 +
  doc/device-tree-bindings/pmic/s2mps11.txt |  17 +++
  drivers/Kconfig                           |   2 +
  drivers/Makefile                          |   1 +
  drivers/adc/Kconfig                       |  17 +++
  drivers/adc/Makefile                      |   9 ++
  drivers/adc/adc-uclass.c                  |  76 ++++++++++++
  drivers/adc/exynos-adc.c                  | 102 ++++++++++++++++
  drivers/power/pmic/Kconfig                |  14 +++
  drivers/power/pmic/Makefile               |   1 +
  drivers/power/pmic/s2mps11.c              |  60 +++++++++
  include/adc.h                             |  88 ++++++++++++++
  include/configs/odroid_xu3.h              |  12 ++
  include/dm/uclass-id.h                    |   1 +
  include/power/s2mps11.h                   | 109 +++++++++++++++++
  include/samsung/exynos5-dt-types.h        |  27 ++++
  33 files changed, 854 insertions(+), 22 deletions(-)
Quoted 11 lines

create mode 100644 board/samsung/common/exynos5-dt-types.c create mode 100644 doc/device-tree-bindings/pmic/s2mps11.txt create mode 100644 drivers/adc/Kconfig
create mode 100644 drivers/adc/Makefile
create mode 100644 drivers/adc/adc-uclass.c
create mode 100644 drivers/adc/exynos-adc.c
create mode 100644 drivers/power/pmic/s2mps11.c create mode 100644 include/adc.h
create mode 100644 include/power/s2mps11.h
create mode 100644 include/samsung/exynos5-dt-types.h

Quoted 3 lines

Simon,
Are you going to to review this patchset or can I update it and ask Minkyu for taking it?

I thought Minkyu would take it as it seems to be exynos-specific.

Regards,
Simon

#66 lore raw

v2 cover Add board detection for Odroid XU3 / XU3Lite / XU4

Hello,

Quoted 86 lines · Simon Glass

Hi Przemyslaw,

Quoted 83 lines · Przemyslaw Marczak

Hello,

Quoted 78 lines · Przemyslaw Marczak

This patchset adds:
- CPU model in dts for Chromebook Peach Pi as Exynos5800
- set the cpu id of Exynos5422 to 0x5422
- S2MPS11 PMIC I/O driver
- Exynos5420-compatible (9-channel, 12-bit) ADC driver
- new file for Exynos5: exynos5-dt-types.c
- board detection for Odroid XU3 / XU3lite / XU4
- fixed ADC val for XU4

This was tested on Odroid XU3 and XU3 Lite, without the XU4, but I'm waiting for reply from the Odroid forum users.

Tested with buildman for samsung.

Available on github:
https://github.com/bobenstein/u-boot/tree/xu3-detect-patchset-v1
https://github.com/bobenstein/u-boot/tree/xu3-detect-patchset-v2

Przemyslaw Marczak (11):
samsung: board/misc: check returned pointer for get_board_type() calls
s5p: cpu_info: print "cpu-model" if exists in dts
Peach-Pi: dts: add cpu-model string
Exynos5422/5800: set cpu id to 0x5422
dm: pmic: add s2mps11 PMIC I/O driver
dm: adc: add simple ADC uclass implementation
dm: adc: add Exynos54xx compatible ADC driver
Odroid-XU3: enable s2mps11 PMIC support
Exynos54xx: dts: add ADC node
Odroid-XU3: dts: enable ADC, with request for pre-reloc bind
exynos5-dt-types: add board detection for Odroid XU3/XU3L/XU4.

   arch/arm/cpu/armv7/s5p-common/cpu_info.c  |  14 ++-
   arch/arm/dts/exynos5422-odroidxu3.dts     |  12 ++
   arch/arm/dts/exynos54xx.dtsi              |   7 ++
   arch/arm/dts/exynos5800-peach-pi.dts      |   1 +
   arch/arm/mach-exynos/clock.c              |  16 +--
   arch/arm/mach-exynos/clock_init_exynos5.c |   2 +-
   arch/arm/mach-exynos/common_setup.h       |   4 +-
   arch/arm/mach-exynos/include/mach/adc.h   |  45 +++++++
   arch/arm/mach-exynos/include/mach/cpu.h   |   6 +-
   arch/arm/mach-exynos/include/mach/gpio.h  |   4 +-
   arch/arm/mach-exynos/pinmux.c             |   2 +-
   arch/arm/mach-exynos/power.c              |   2 +-
   board/samsung/common/Makefile             |   5 +-
   board/samsung/common/board.c              |   4 +-
   board/samsung/common/exynos5-dt-types.c   | 196
++++++++++++++++++++++++++++++
   board/samsung/common/exynos5-dt.c         |  12 ++
   board/samsung/common/misc.c               |   3 +
   configs/odroid-xu3_defconfig              |   5 +
   doc/device-tree-bindings/pmic/s2mps11.txt |  17 +++
   drivers/Kconfig                           |   2 +
   drivers/Makefile                          |   1 +
   drivers/adc/Kconfig                       |  17 +++
   drivers/adc/Makefile                      |   9 ++
   drivers/adc/adc-uclass.c                  |  76 ++++++++++++
   drivers/adc/exynos-adc.c                  | 102 ++++++++++++++++
   drivers/power/pmic/Kconfig                |  14 +++
   drivers/power/pmic/Makefile               |   1 +
   drivers/power/pmic/s2mps11.c              |  60 +++++++++
   include/adc.h                             |  88 ++++++++++++++
   include/configs/odroid_xu3.h              |  12 ++
   include/dm/uclass-id.h                    |   1 +
   include/power/s2mps11.h                   | 109 +++++++++++++++++
   include/samsung/exynos5-dt-types.h        |  27 ++++
   33 files changed, 854 insertions(+), 22 deletions(-)

create mode 100644 board/samsung/common/exynos5-dt-types.c create mode 100644 doc/device-tree-bindings/pmic/s2mps11.txt create mode 100644 drivers/adc/Kconfig
create mode 100644 drivers/adc/Makefile
create mode 100644 drivers/adc/adc-uclass.c
create mode 100644 drivers/adc/exynos-adc.c
create mode 100644 drivers/power/pmic/s2mps11.c create mode 100644 include/adc.h
create mode 100644 include/power/s2mps11.h
create mode 100644 include/samsung/exynos5-dt-types.h

Quoted 9 lines
Quoted 3 lines

Simon,
Are you going to to review this patchset or can I update it and ask Minkyu for taking it?

I thought Minkyu would take it as it seems to be exynos-specific.

Regards,
Simon

Ok. I will prepare the V3 and notify you.

Best regards,

Signature · 4 lines
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com
#67 lore raw

v3 cover Add board detection for Odroid XU3 / XU3Lite / XU4

In reply to Przemyslaw Marczak

This patchset adds:
- 'cpu-model' dts property for Chromebook Peach Pi as Exynos5800
- set the cpu id of Exynos5422 to 0x5422
- S2MPS11 PMIC I/O driver
- ADC uclass implementation
- Exynos5420-compatible (9-channel, 12-bit) ADC driver
- new file for Exynos5: exynos5-dt-types.c
- board detection for Odroid XU3 / XU3lite / XU4
- fixed ADC value for XU4 detection

This was tested on Odroid XU3/XU3 Lite/XU4 and sandbox.

Tested with buildman for samsung.

Available on github:
https://github.com/bobenstein/u-boot/tree/xu3-detect-patchset-v1
https://github.com/bobenstein/u-boot/tree/xu3-detect-patchset-v2
https://github.com/bobenstein/u-boot/tree/xu3-detect-patchset-v3

Przemyslaw Marczak (14):
samsung: board/misc: check returned pointer for get_board_type() calls
s5p: cpu_info: print "cpu-model" if exists in dts
Peach-Pi: dts: add cpu-model string
Exynos5422/5800: set cpu id to 0x5422
dm: pmic: add s2mps11 PMIC I/O driver
dm: regulator: add function device_get_supply_regulator()
dm: adc: add simple ADC uclass implementation
dm: adc: add Exynos54xx compatible ADC driver
Odroid-XU3: enable s2mps11 PMIC support
Exynos54xx: dts: add ADC node
Odroid-XU3: dts: enable ADC, with request for pre-reloc bind
exynos5-dt-types: add board detection for Odroid XU3/XU3L/XU4.
sandbox: add ADC driver
sandbox: add ADC unit tests

 arch/arm/cpu/armv7/s5p-common/cpu_info.c   |  14 +-
 arch/arm/dts/exynos5422-odroidxu3.dts      |  12 +
 arch/arm/dts/exynos54xx.dtsi               |   7 +
 arch/arm/dts/exynos5800-peach-pi.dts       |   1 +
 arch/arm/mach-exynos/clock.c               |  16 +-
 arch/arm/mach-exynos/clock_init_exynos5.c  |   2 +-
 arch/arm/mach-exynos/common_setup.h        |   4 +-
 arch/arm/mach-exynos/include/mach/adc.h    |  44 ++++
 arch/arm/mach-exynos/include/mach/cpu.h    |   6 +-
 arch/arm/mach-exynos/include/mach/gpio.h   |   4 +-
 arch/arm/mach-exynos/pinmux.c              |   2 +-
 arch/arm/mach-exynos/power.c               |   2 +-
 arch/sandbox/dts/sandbox_pmic.dtsi         |   2 +-
 arch/sandbox/dts/test.dts                  |   6 +
 board/samsung/common/Makefile              |   5 +-
 board/samsung/common/board.c               |   4 +-
 board/samsung/common/exynos5-dt-types.c    | 196 ++++++++++++++
 board/samsung/common/exynos5-dt.c          |  12 +
 board/samsung/common/misc.c                |   3 +
 configs/odroid-xu3_defconfig               |   5 +
 configs/sandbox_defconfig                  |   2 +
 doc/device-tree-bindings/adc/adc.txt       |  62 +++++
 doc/device-tree-bindings/exynos/soc.txt    |  21 ++
 doc/device-tree-bindings/pmic/s2mps11.txt  |  17 ++
 drivers/Kconfig                            |   2 +
 drivers/Makefile                           |   1 +
 drivers/adc/Kconfig                        |  30 +++
 drivers/adc/Makefile                       |  10 +
 drivers/adc/adc-uclass.c                   | 409 +++++++++++++++++++++++++++++
 drivers/adc/exynos-adc.c                   | 145 ++++++++++
 drivers/adc/sandbox.c                      | 174 ++++++++++++
 drivers/power/pmic/Kconfig                 |  14 +
 drivers/power/pmic/Makefile                |   1 +
 drivers/power/pmic/s2mps11.c               |  62 +++++
 drivers/power/regulator/regulator-uclass.c |   7 +
 include/adc.h                              | 288 ++++++++++++++++++++
 include/configs/odroid_xu3.h               |  12 +
 include/dm/uclass-id.h                     |   1 +
 include/power/regulator.h                  |  16 ++
 include/power/s2mps11.h                    | 109 ++++++++
 include/power/sandbox_pmic.h               |   4 +
 include/samsung/exynos5-dt-types.h         |  27 ++
 test/dm/Makefile                           |   1 +
 test/dm/adc.c                              | 165 ++++++++++++
 44 files changed, 1904 insertions(+), 23 deletions(-)
 create mode 100644 board/samsung/common/exynos5-dt-types.c
 create mode 100644 doc/device-tree-bindings/adc/adc.txt
 create mode 100644 doc/device-tree-bindings/exynos/soc.txt
 create mode 100644 doc/device-tree-bindings/pmic/s2mps11.txt
 create mode 100644 drivers/adc/Kconfig
 create mode 100644 drivers/adc/Makefile
 create mode 100644 drivers/adc/adc-uclass.c
 create mode 100644 drivers/adc/exynos-adc.c
 create mode 100644 drivers/adc/sandbox.c
 create mode 100644 drivers/power/pmic/s2mps11.c
 create mode 100644 include/adc.h
 create mode 100644 include/power/s2mps11.h
 create mode 100644 include/samsung/exynos5-dt-types.h
 create mode 100644 test/dm/adc.c
Signature · 1 line
1.9.1
#68 lore raw

PATCH v3 1/14 samsung: board/misc: check returned pointer for get_board_type() calls

The function get_board_type() is called in two places by common code, but the returned pointer was never check.

This commit adds checking the returned pointer, before use it.

---
Changes V2:
- new commit

---
 board/samsung/common/board.c | 4 ++--
 board/samsung/common/misc.c  | 3 +++
 2 files changed, 5 insertions(+), 2 deletions(-)
board/samsung/common/board.c +2 -2
index d32c75d..1334c22 100644
@@ -304,8 +304,8 @@ int checkboard(void)
 	printf("Board: %s\n", board_info ? board_info : "unknown");
 #ifdef CONFIG_BOARD_TYPES
 	board_info = get_board_type();
-
-	printf("Model: %s\n", board_info ? board_info : "unknown");
+	if (board_info)
+		printf("Type:  %s\n", board_info);
 #endif
 	return 0;
 }
board/samsung/common/misc.c +3 -0
index e0e2c48..c8316d8 100644
@@ -85,6 +85,9 @@ void set_board_info(void)
 
 #ifdef CONFIG_BOARD_TYPES
 	bdtype = get_board_type();
+	if (!bdtype)
+		bdtype = "";
+
 	sprintf(info, "%s%s", bdname, bdtype);
 	setenv("boardname", info);
 #endif
Signature · 1 line
1.9.1
#69 lore raw

PATCH v3 1/14 samsung: board/misc: check returned pointer for get_board_type() calls

Quoted 7 lines · Przemyslaw Marczak

The function get_board_type() is called in two places by common code, but the returned pointer was never check.

This commit adds checking the returned pointer, before use it.

Quoted 8 lines

---
Changes V2:
- new commit

---
 board/samsung/common/board.c | 4 ++--
 board/samsung/common/misc.c  | 3 +++
 2 files changed, 5 insertions(+), 2 deletions(-)
#70 lore raw

PATCH v3 1/14 samsung: board/misc: check returned pointer for get_board_type() calls

Quoted 17 lines · Simon Glass
Quoted 7 lines · Przemyslaw Marczak

The function get_board_type() is called in two places by common code, but the returned pointer was never check.

This commit adds checking the returned pointer, before use it.

Quoted 8 lines

---
Changes V2:
- new commit

---
 board/samsung/common/board.c | 4 ++--
 board/samsung/common/misc.c  | 3 +++
 2 files changed, 5 insertions(+), 2 deletions(-)
Quoted 1 line

-Anand Moon

#71 lore raw

PATCH v3 2/14 s5p: cpu_info: print "cpu-model" if exists in dts

In reply to Przemyslaw Marczak

The CPU name for Exynos was concatenated with cpu id, but for new Exynos platforms, like Chromebook Peach Pi based on Exynos5800, the name of SoC variant does not include the real SoC cpu id (0x5422).

For such case, the CPU name should be defined in device tree.

This commit introduces new device-tree property for Exynos:
- "cpu-model" - with cpu name string
If defined, then the cpu id is not printed.

---
Changes V2:
- new commit
Changes V3
- add cpu-model binding info

---
 arch/arm/cpu/armv7/s5p-common/cpu_info.c | 14 +++++++++++++-
 doc/device-tree-bindings/exynos/soc.txt  | 21 +++++++++++++++++++++
 2 files changed, 34 insertions(+), 1 deletion(-)
 create mode 100644 doc/device-tree-bindings/exynos/soc.txt
arch/arm/cpu/armv7/s5p-common/cpu_info.c +13 -1
index 154d674..764c661 100644
@@ -5,9 +5,12 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 #include <common.h>
+#include <fdtdec.h>
 #include <asm/io.h>
 #include <asm/arch/clk.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 /* Default is s5pc100 */
 unsigned int s5p_cpu_id = 0xC100;
 /* Default is EVT1 */
@@ -30,7 +33,16 @@ u32 get_device_type(void)
 #ifdef CONFIG_DISPLAY_CPUINFO
 int print_cpuinfo(void)
 {
-	printf("CPU:   %s%X @ ", s5p_get_cpu_name(), s5p_cpu_id);
+	const char *cpu_model;
+	int len;
+
+	/* For SoC with no real CPU ID in naming convention. */
+	cpu_model = fdt_getprop(gd->fdt_blob, 0, "cpu-model", &len);
+	if (cpu_model)
+		printf("CPU:   %.*s @ ", len, cpu_model);
+	else
+		printf("CPU:   %s%X @ ", s5p_get_cpu_name(), s5p_cpu_id);
+
 	print_freq(get_arm_clk(), "\n");
 
 	return 0;
doc/device-tree-bindings/exynos/soc.txt new file +21 -0
new file mode 100644
index 0000000..9ba6f3b
@@ -0,0 +1,21 @@
+Exynos SoC model
+
+The "cpu-model" property is a non-standard extension for the device tree root
+node. Since the cpu id of some Exynos variants does not correspond to product
+name, this property fills the gap.
+
+For almost all Exynos based boards in the kernel, the product name corresponds
+to the device tree file name. The same name is generated in U-Boot, so the new
+property allows doing it automatically.
+
+Required properties:
+ - cpu-model : Exynos product name
+
+Example:
+
+/ {
+	model = "Samsung/Google Peach Pi board based on Exynos5800";
+	cpu-model = "Exynos5800";
+
+	compatible = ...
+};
Signature · 1 line
1.9.1
#72 lore raw

PATCH v3 2/14 s5p: cpu_info: print "cpu-model" if exists in dts

Quoted 19 lines · Przemyslaw Marczak

The CPU name for Exynos was concatenated with cpu id, but for new Exynos platforms, like Chromebook Peach Pi based on Exynos5800, the name of SoC variant does not include the real SoC cpu id (0x5422).

For such case, the CPU name should be defined in device tree.

This commit introduces new device-tree property for Exynos:
- "cpu-model" - with cpu name string
If defined, then the cpu id is not printed.

---
Changes V2:
- new commit
Changes V3
- add cpu-model binding info

Quoted 5 lines
---
 arch/arm/cpu/armv7/s5p-common/cpu_info.c | 14 +++++++++++++-
 doc/device-tree-bindings/exynos/soc.txt  | 21 +++++++++++++++++++++
 2 files changed, 34 insertions(+), 1 deletion(-)
 create mode 100644 doc/device-tree-bindings/exynos/soc.txt
#73 lore raw

PATCH v3 2/14 s5p: cpu_info: print "cpu-model" if exists in dts

In reply to Przemyslaw Marczak

Hi

Quoted 88 lines · Przemyslaw Marczak

The CPU name for Exynos was concatenated with cpu id, but for new Exynos platforms, like Chromebook Peach Pi based on Exynos5800, the name of SoC variant does not include the real SoC cpu id (0x5422).

For such case, the CPU name should be defined in device tree.

This commit introduces new device-tree property for Exynos:
- "cpu-model" - with cpu name string
If defined, then the cpu id is not printed.

---
Changes V2:
- new commit
Changes V3
- add cpu-model binding info

---
 arch/arm/cpu/armv7/s5p-common/cpu_info.c | 14 +++++++++++++-
 doc/device-tree-bindings/exynos/soc.txt  | 21 +++++++++++++++++++++
 2 files changed, 34 insertions(+), 1 deletion(-)
 create mode 100644 doc/device-tree-bindings/exynos/soc.txt
arch/arm/cpu/armv7/s5p-common/cpu_info.c +13 -1
index 154d674..764c661 100644
@@ -5,9 +5,12 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 #include <common.h>
+#include <fdtdec.h>
 #include <asm/io.h>
 #include <asm/arch/clk.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 /* Default is s5pc100 */
 unsigned int s5p_cpu_id = 0xC100;
 /* Default is EVT1 */
@@ -30,7 +33,16 @@ u32 get_device_type(void)
 #ifdef CONFIG_DISPLAY_CPUINFO
 int print_cpuinfo(void)
 {
-       printf("CPU:   %s%X @ ", s5p_get_cpu_name(), s5p_cpu_id);
+       const char *cpu_model;
+       int len;
+
+       /* For SoC with no real CPU ID in naming convention. */
+       cpu_model = fdt_getprop(gd->fdt_blob, 0, "cpu-model", &len);
+       if (cpu_model)
+               printf("CPU:   %.*s @ ", len, cpu_model);
+       else
+               printf("CPU:   %s%X @ ", s5p_get_cpu_name(), s5p_cpu_id);
+
        print_freq(get_arm_clk(), "\n");
 
        return 0;
doc/device-tree-bindings/exynos/soc.txt new file +21 -1
new file mode 100644
index 0000000..9ba6f3b
@@ -0,0 +1,21 @@
+Exynos SoC model
+
+The "cpu-model" property is a non-standard extension for the device tree root
+node. Since the cpu id of some Exynos variants does not correspond to product
+name, this property fills the gap.
+
+For almost all Exynos based boards in the kernel, the product name corresponds
+to the device tree file name. The same name is generated in U-Boot, so the new
+property allows doing it automatically.
+
+Required properties:
+ - cpu-model : Exynos product name
+
+Example:
+
+/ {
+       model = "Samsung/Google Peach Pi board based on Exynos5800";
+       cpu-model = "Exynos5800";
+
+       compatible = ...
+};
--
Quoted 2 lines

1.9.1

-Anand Moon

#74 lore raw

PATCH v3 3/14 Peach-Pi: dts: add cpu-model string

In reply to Przemyslaw Marczak

This platform is based on Exynos5800 but the cpu id is 0x5422. This doesn't fit the common Exynos SoC name convention, so now, the CPU name is defined by device tree string, to be printed properly.

---
Changes V2:
- move cpu name from config to dts

---
 arch/arm/dts/exynos5800-peach-pi.dts | 1 +
 1 file changed, 1 insertion(+)
arch/arm/dts/exynos5800-peach-pi.dts +1 -0
index 1d7ff23..76826dc 100644
@@ -12,6 +12,7 @@
 
 / {
 	model = "Samsung/Google Peach Pi board based on Exynos5800";
+	cpu-model = "Exynos5800";
 
 	compatible = "google,pit-rev#", "google,pit",
 		"google,peach", "samsung,exynos5800", "samsung,exynos5";
Signature · 1 line
1.9.1
#75 lore raw

PATCH v3 3/14 Peach-Pi: dts: add cpu-model string

Quoted 8 lines · Przemyslaw Marczak

This platform is based on Exynos5800 but the cpu id is 0x5422. This doesn't fit the common Exynos SoC name convention, so now, the CPU name is defined by device tree string, to be printed properly.

Quoted 6 lines

---
Changes V2:
- move cpu name from config to dts

---
 arch/arm/dts/exynos5800-peach-pi.dts | 1 +
 1 file changed, 1 insertion(+)
#76 lore raw

PATCH v3 3/14 Peach-Pi: dts: add cpu-model string

In reply to Przemyslaw Marczak

Hi,

Quoted 28 lines · Przemyslaw Marczak

This platform is based on Exynos5800 but the cpu id is 0x5422. This doesn't fit the common Exynos SoC name convention, so now, the CPU name is defined by device tree string, to be printed properly.

---
Changes V2:
- move cpu name from config to dts

---
 arch/arm/dts/exynos5800-peach-pi.dts | 1 +
 1 file changed, 1 insertion(+)
arch/arm/dts/exynos5800-peach-pi.dts +1 -1
index 1d7ff23..76826dc 100644
@@ -12,6 +12,7 @@
 
 / {
        model = "Samsung/Google Peach Pi board based on Exynos5800";
+       cpu-model = "Exynos5800";
 
        compatible = "google,pit-rev#", "google,pit",
                "google,peach", "samsung,exynos5800", "samsung,exynos5";
--
Quoted 2 lines

1.9.1

-Anand Moon

#77 lore raw

PATCH v3 4/14 Exynos5422/5800: set cpu id to 0x5422

In reply to Przemyslaw Marczak

The proper CPU ID for those Exynos variants is 0x5422, but before the 0x5800 was set. This commit fix this back.

Changes:
- set cpu id to 0x5422 instead of 0x5800
- remove macro proid_is_exynos5800()
- add macro proid_is_exynos5422()
- change the calls to proid_is_exynos5800() with new macro

---
Changes V2:
- none

---
 arch/arm/mach-exynos/clock.c              | 16 ++++++++--------
 arch/arm/mach-exynos/clock_init_exynos5.c |  2 +-
 arch/arm/mach-exynos/common_setup.h       |  4 ++--
 arch/arm/mach-exynos/include/mach/cpu.h   |  6 +++---
 arch/arm/mach-exynos/include/mach/gpio.h  |  4 ++--
 arch/arm/mach-exynos/pinmux.c             |  2 +-
 arch/arm/mach-exynos/power.c              |  2 +-
 7 files changed, 18 insertions(+), 18 deletions(-)
arch/arm/mach-exynos/clock.c +8 -8
index 18eadf5..3d31f9d 100644
@@ -159,8 +159,8 @@ static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k)
 			div = PLL_DIV_1024;
 		else if (proid_is_exynos4412())
 			div = PLL_DIV_65535;
-		else if (proid_is_exynos5250() || proid_is_exynos5420()
-			 || proid_is_exynos5800())
+		else if (proid_is_exynos5250() || proid_is_exynos5420() ||
+			 proid_is_exynos5422())
 			div = PLL_DIV_65536;
 		else
 			return 0;
@@ -346,7 +346,7 @@ static struct clk_bit_info *get_clk_bit_info(int peripheral)
 	int i;
 	struct clk_bit_info *info;
 
-	if (proid_is_exynos5420() || proid_is_exynos5800())
+	if (proid_is_exynos5420() || proid_is_exynos5422())
 		info = exynos542x_bit_info;
 	else
 		info = exynos5_bit_info;
@@ -558,7 +558,7 @@ static unsigned long exynos542x_get_periph_rate(int peripheral)
 unsigned long clock_get_periph_rate(int peripheral)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return exynos542x_get_periph_rate(peripheral);
 		return exynos5_get_periph_rate(peripheral);
 	} else {
@@ -1576,7 +1576,7 @@ static unsigned long exynos4_get_i2c_clk(void)
 unsigned long get_pll_clk(int pllreg)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return exynos542x_get_pll_clk(pllreg);
 		return exynos5_get_pll_clk(pllreg);
 	} else if (cpu_is_exynos4()) {
@@ -1692,7 +1692,7 @@ void set_mmc_clk(int dev_index, unsigned int div)
 		div -= 1;
 
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			exynos5420_set_mmc_clk(dev_index, div);
 		else
 			exynos5_set_mmc_clk(dev_index, div);
@@ -1708,7 +1708,7 @@ unsigned long get_lcd_clk(void)
 	} else if (cpu_is_exynos5()) {
 		if (proid_is_exynos5420())
 			return exynos5420_get_lcd_clk();
-		else if (proid_is_exynos5800())
+		else if (proid_is_exynos5422())
 			return exynos5800_get_lcd_clk();
 		else
 			return exynos5_get_lcd_clk();
@@ -1740,7 +1740,7 @@ void set_mipi_clk(void)
 int set_spi_clk(int periph_id, unsigned int rate)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return exynos5420_set_spi_clk(periph_id, rate);
 		return exynos5_set_spi_clk(periph_id, rate);
 	}
arch/arm/mach-exynos/clock_init_exynos5.c +1 -1
index 0200fd1..1b7498d 100644
@@ -971,7 +971,7 @@ static void exynos5420_system_clock_init(void)
 
 void system_clock_init(void)
 {
-	if (proid_is_exynos5420() || proid_is_exynos5800())
+	if (proid_is_exynos5420() || proid_is_exynos5422())
 		exynos5420_system_clock_init();
 	else
 		exynos5250_system_clock_init();
arch/arm/mach-exynos/common_setup.h +2 -2
index 67aac2d..2829fb2 100644
@@ -78,7 +78,7 @@ static inline void configure_l2_ctlr(void)
 		CACHE_TAG_RAM_LATENCY_2_CYCLES |
 		CACHE_DATA_RAM_LATENCY_2_CYCLES;
 
-	if (proid_is_exynos5420() || proid_is_exynos5800()) {
+	if (proid_is_exynos5420() || proid_is_exynos5422()) {
 		val |= CACHE_ECC_AND_PARITY |
 			CACHE_TAG_RAM_LATENCY_3_CYCLES |
 			CACHE_DATA_RAM_LATENCY_3_CYCLES;
@@ -97,7 +97,7 @@ static inline void configure_l2_actlr(void)
 {
 	uint32_t val;
 
-	if (proid_is_exynos5420() || proid_is_exynos5800()) {
+	if (proid_is_exynos5420() || proid_is_exynos5422()) {
 		mrc_l2_aux_ctlr(val);
 		val |= CACHE_ENABLE_FORCE_L2_LOGIC |
 			CACHE_DISABLE_CLEAN_EVICT;
arch/arm/mach-exynos/include/mach/cpu.h +3 -3
index cb3d2cc..14a1692 100644
@@ -237,7 +237,7 @@ static inline void s5p_set_cpu_id(void)
 		 * Exynos5800 is a variant of Exynos5420
 		 * and has product id 0x5422
 		 */
-		s5p_cpu_id = 0x5800;
+		s5p_cpu_id = 0x5422;
 		break;
 	}
 }
@@ -267,7 +267,7 @@ IS_EXYNOS_TYPE(exynos4210, 0x4210)
 IS_EXYNOS_TYPE(exynos4412, 0x4412)
 IS_EXYNOS_TYPE(exynos5250, 0x5250)
 IS_EXYNOS_TYPE(exynos5420, 0x5420)
-IS_EXYNOS_TYPE(exynos5800, 0x5800)
+IS_EXYNOS_TYPE(exynos5422, 0x5422)
 
 #define SAMSUNG_BASE(device, base)				\
 static inline unsigned int __attribute__((no_instrument_function)) \
@@ -278,7 +278,7 @@ static inline unsigned int __attribute__((no_instrument_function)) \
 			return EXYNOS4X12_##base;		\
 		return EXYNOS4_##base;				\
 	} else if (cpu_is_exynos5()) {				\
-		if (proid_is_exynos5420() || proid_is_exynos5800())	\
+		if (proid_is_exynos5420() || proid_is_exynos5422())	\
 			return EXYNOS5420_##base;		\
 		return EXYNOS5_##base;				\
 	}							\
arch/arm/mach-exynos/include/mach/gpio.h +2 -2
index 9699954..7fc8e61 100644
@@ -1398,7 +1398,7 @@ static struct gpio_info exynos5420_gpio_data[EXYNOS5420_GPIO_NUM_PARTS] = {
 static inline struct gpio_info *get_gpio_data(void)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return exynos5420_gpio_data;
 		else
 			return exynos5_gpio_data;
@@ -1415,7 +1415,7 @@ static inline struct gpio_info *get_gpio_data(void)
 static inline unsigned int get_bank_num(void)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return EXYNOS5420_GPIO_NUM_PARTS;
 		else
 			return EXYNOS5_GPIO_NUM_PARTS;
arch/arm/mach-exynos/pinmux.c +1 -1
index 179b294..a556e4a 100644
@@ -858,7 +858,7 @@ static int exynos4x12_pinmux_config(int peripheral, int flags)
 int exynos_pinmux_config(int peripheral, int flags)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			return exynos5420_pinmux_config(peripheral, flags);
 		else if (proid_is_exynos5250())
 			return exynos5_pinmux_config(peripheral, flags);
arch/arm/mach-exynos/power.c +1 -1
index 1b12051..cd2d661 100644
@@ -125,7 +125,7 @@ static void exynos5420_set_usbdev_phy_ctrl(unsigned int enable)
 void set_usbdrd_phy_ctrl(unsigned int enable)
 {
 	if (cpu_is_exynos5()) {
-		if (proid_is_exynos5420() || proid_is_exynos5800())
+		if (proid_is_exynos5420() || proid_is_exynos5422())
 			exynos5420_set_usbdev_phy_ctrl(enable);
 		else
 			exynos5_set_usbdrd_phy_ctrl(enable);
Signature · 1 line
1.9.1
#78 lore raw

PATCH v3 4/14 Exynos5422/5800: set cpu id to 0x5422

hi,

Quoted 209 lines · Przemyslaw Marczak

The proper CPU ID for those Exynos variants is 0x5422, but before the 0x5800 was set. This commit fix this back.

Changes:
- set cpu id to 0x5422 instead of 0x5800
- remove macro proid_is_exynos5800()
- add macro proid_is_exynos5422()
- change the calls to proid_is_exynos5800() with new macro

---
Changes V2:
- none

---
 arch/arm/mach-exynos/clock.c              | 16 ++++++++--------
 arch/arm/mach-exynos/clock_init_exynos5.c |  2 +-
 arch/arm/mach-exynos/common_setup.h       |  4 ++--
 arch/arm/mach-exynos/include/mach/cpu.h   |  6 +++---
 arch/arm/mach-exynos/include/mach/gpio.h  |  4 ++--
 arch/arm/mach-exynos/pinmux.c             |  2 +-
 arch/arm/mach-exynos/power.c              |  2 +-
 7 files changed, 18 insertions(+), 18 deletions(-)
arch/arm/mach-exynos/clock.c +8 -8
index 18eadf5..3d31f9d 100644
@@ -159,8 +159,8 @@ static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k)
                        div = PLL_DIV_1024;
                else if (proid_is_exynos4412())
                        div = PLL_DIV_65535;
-               else if (proid_is_exynos5250() || proid_is_exynos5420()
-                        || proid_is_exynos5800())
+               else if (proid_is_exynos5250() || proid_is_exynos5420() ||
+                        proid_is_exynos5422())
                        div = PLL_DIV_65536;
                else
                        return 0;
@@ -346,7 +346,7 @@ static struct clk_bit_info *get_clk_bit_info(int peripheral)
        int i;
        struct clk_bit_info *info;
 
-       if (proid_is_exynos5420() || proid_is_exynos5800())
+       if (proid_is_exynos5420() || proid_is_exynos5422())
                info = exynos542x_bit_info;
        else
                info = exynos5_bit_info;
@@ -558,7 +558,7 @@ static unsigned long exynos542x_get_periph_rate(int peripheral)
 unsigned long clock_get_periph_rate(int peripheral)
 {
        if (cpu_is_exynos5()) {
-               if (proid_is_exynos5420() || proid_is_exynos5800())
+               if (proid_is_exynos5420() || proid_is_exynos5422())
                        return exynos542x_get_periph_rate(peripheral);
                return exynos5_get_periph_rate(peripheral);
        } else {
@@ -1576,7 +1576,7 @@ static unsigned long exynos4_get_i2c_clk(void)
 unsigned long get_pll_clk(int pllreg)
 {
        if (cpu_is_exynos5()) {
-               if (proid_is_exynos5420() || proid_is_exynos5800())
+               if (proid_is_exynos5420() || proid_is_exynos5422())
                        return exynos542x_get_pll_clk(pllreg);
                return exynos5_get_pll_clk(pllreg);
        } else if (cpu_is_exynos4()) {
@@ -1692,7 +1692,7 @@ void set_mmc_clk(int dev_index, unsigned int div)
                div -= 1;
 
        if (cpu_is_exynos5()) {
-               if (proid_is_exynos5420() || proid_is_exynos5800())
+               if (proid_is_exynos5420() || proid_is_exynos5422())
                        exynos5420_set_mmc_clk(dev_index, div);
                else
                        exynos5_set_mmc_clk(dev_index, div);
@@ -1708,7 +1708,7 @@ unsigned long get_lcd_clk(void)
        } else if (cpu_is_exynos5()) {
                if (proid_is_exynos5420())
                        return exynos5420_get_lcd_clk();
-               else if (proid_is_exynos5800())
+               else if (proid_is_exynos5422())
                        return exynos5800_get_lcd_clk();
                else
                        return exynos5_get_lcd_clk();
@@ -1740,7 +1740,7 @@ void set_mipi_clk(void)
 int set_spi_clk(int periph_id, unsigned int rate)
 {
        if (cpu_is_exynos5()) {
-               if (proid_is_exynos5420() || proid_is_exynos5800())
+               if (proid_is_exynos5420() || proid_is_exynos5422())
                        return exynos5420_set_spi_clk(periph_id, rate);
                return exynos5_set_spi_clk(periph_id, rate);
        }
arch/arm/mach-exynos/clock_init_exynos5.c +1 -1
index 0200fd1..1b7498d 100644
@@ -971,7 +971,7 @@ static void exynos5420_system_clock_init(void)
 
 void system_clock_init(void)
 {
-       if (proid_is_exynos5420() || proid_is_exynos5800())
+       if (proid_is_exynos5420() || proid_is_exynos5422())
                exynos5420_system_clock_init();
        else
                exynos5250_system_clock_init();
arch/arm/mach-exynos/common_setup.h +2 -2
index 67aac2d..2829fb2 100644
@@ -78,7 +78,7 @@ static inline void configure_l2_ctlr(void)
                CACHE_TAG_RAM_LATENCY_2_CYCLES |
                CACHE_DATA_RAM_LATENCY_2_CYCLES;
 
-       if (proid_is_exynos5420() || proid_is_exynos5800()) {
+       if (proid_is_exynos5420() || proid_is_exynos5422()) {
                val |= CACHE_ECC_AND_PARITY |
                        CACHE_TAG_RAM_LATENCY_3_CYCLES |
                        CACHE_DATA_RAM_LATENCY_3_CYCLES;
@@ -97,7 +97,7 @@ static inline void configure_l2_actlr(void)
 {
        uint32_t val;
 
-       if (proid_is_exynos5420() || proid_is_exynos5800()) {
+       if (proid_is_exynos5420() || proid_is_exynos5422()) {
                mrc_l2_aux_ctlr(val);
                val |= CACHE_ENABLE_FORCE_L2_LOGIC |
                        CACHE_DISABLE_CLEAN_EVICT;
arch/arm/mach-exynos/include/mach/cpu.h +3 -3
index cb3d2cc..14a1692 100644
@@ -237,7 +237,7 @@ static inline void s5p_set_cpu_id(void)
                 * Exynos5800 is a variant of Exynos5420
                 * and has product id 0x5422
                 */
-               s5p_cpu_id = 0x5800;
+               s5p_cpu_id = 0x5422;
                break;
        }
 }
@@ -267,7 +267,7 @@ IS_EXYNOS_TYPE(exynos4210, 0x4210)
 IS_EXYNOS_TYPE(exynos4412, 0x4412)
 IS_EXYNOS_TYPE(exynos5250, 0x5250)
 IS_EXYNOS_TYPE(exynos5420, 0x5420)
-IS_EXYNOS_TYPE(exynos5800, 0x5800)
+IS_EXYNOS_TYPE(exynos5422, 0x5422)
 
 #define SAMSUNG_BASE(device, base)                             \
 static inline unsigned int __attribute__((no_instrument_function)) \
@@ -278,7 +278,7 @@ static inline unsigned int __attribute__((no_instrument_function)) \
                        return EXYNOS4X12_##base;               \
                return EXYNOS4_##base;                          \
        } else if (cpu_is_exynos5()) {                          \
-               if (proid_is_exynos5420() || proid_is_exynos5800())     \
+               if (proid_is_exynos5420() || proid_is_exynos5422())     \
                        return EXYNOS5420_##base;               \
                return EXYNOS5_##base;                          \
        }                                                       \
arch/arm/mach-exynos/include/mach/gpio.h +2 -2
index 9699954..7fc8e61 100644
@@ -1398,7 +1398,7 @@ static struct gpio_info exynos5420_gpio_data[EXYNOS5420_GPIO_NUM_PARTS] = {
 static inline struct gpio_info *get_gpio_data(void)
 {
        if (cpu_is_exynos5()) {
-               if (proid_is_exynos5420() || proid_is_exynos5800())
+               if (proid_is_exynos5420() || proid_is_exynos5422())
                        return exynos5420_gpio_data;
                else
                        return exynos5_gpio_data;
@@ -1415,7 +1415,7 @@ static inline struct gpio_info *get_gpio_data(void)
 static inline unsigned int get_bank_num(void)
 {
        if (cpu_is_exynos5()) {
-               if (proid_is_exynos5420() || proid_is_exynos5800())
+               if (proid_is_exynos5420() || proid_is_exynos5422())
                        return EXYNOS5420_GPIO_NUM_PARTS;
                else
                        return EXYNOS5_GPIO_NUM_PARTS;
arch/arm/mach-exynos/pinmux.c +1 -1
index 179b294..a556e4a 100644
@@ -858,7 +858,7 @@ static int exynos4x12_pinmux_config(int peripheral, int flags)
 int exynos_pinmux_config(int peripheral, int flags)
 {
        if (cpu_is_exynos5()) {
-               if (proid_is_exynos5420() || proid_is_exynos5800())
+               if (proid_is_exynos5420() || proid_is_exynos5422())
                        return exynos5420_pinmux_config(peripheral, flags);
                else if (proid_is_exynos5250())
                        return exynos5_pinmux_config(peripheral, flags);
arch/arm/mach-exynos/power.c +1 -2
index 1b12051..cd2d661 100644
@@ -125,7 +125,7 @@ static void exynos5420_set_usbdev_phy_ctrl(unsigned int enable)
 void set_usbdrd_phy_ctrl(unsigned int enable)
 {
        if (cpu_is_exynos5()) {
-               if (proid_is_exynos5420() || proid_is_exynos5800())
+               if (proid_is_exynos5420() || proid_is_exynos5422())
                        exynos5420_set_usbdev_phy_ctrl(enable);
                else
                        exynos5_set_usbdrd_phy_ctrl(enable);
--
Quoted 2 lines

1.9.1

-Anand Moon

#79 lore raw

PATCH v3 5/14 dm: pmic: add s2mps11 PMIC I/O driver

In reply to Przemyslaw Marczak

This driver allows I/O operations on the Samsung S2MPS11 PMIC, which provides lots of LDO/BUCK outputs.

To enable it, update defconfig with:
- CONFIG_PMIC_S2MPS11
and additional, if were not defined:
- CONFIG_CMD_PMIC
- CONFIG_ERRNO_STR

The binding info: doc/device-tree-bindings/pmic/s2mps11.txt

---
Changes V2:
- remove "DM" prefix from config name
- fix word mistake in binding description Changes V3:
- correct return values for driver's read/write methods

---
 doc/device-tree-bindings/pmic/s2mps11.txt |  17 +++++
 drivers/power/pmic/Kconfig                |  14 ++++
 drivers/power/pmic/Makefile               |   1 +
 drivers/power/pmic/s2mps11.c              |  62 +++++++++++++++++
 include/power/s2mps11.h                   | 109 ++++++++++++++++++++++++++++++
 5 files changed, 203 insertions(+)
 create mode 100644 doc/device-tree-bindings/pmic/s2mps11.txt
 create mode 100644 drivers/power/pmic/s2mps11.c
 create mode 100644 include/power/s2mps11.h
doc/device-tree-bindings/pmic/s2mps11.txt new file +17 -0
new file mode 100644
index 0000000..422f14f
@@ -0,0 +1,17 @@
+SAMSUNG, S2MPS11 PMIC
+
+This file describes the binding info for the PMIC driver:
+- drivers/power/pmic/s2mps11.c
+
+Required properties:
+- compatible: "samsung,s2mps11-pmic"
+- reg = 0x66
+
+With those two properties, the pmic device can be used for read/write only.
+
+Example:
+
+s2mps11 at 66 {
+	compatible = "samsung,s2mps11-pmic";
+	reg = <0x66>;
+};
drivers/power/pmic/Kconfig +14 -0
index 547fd1a..fb29843 100644
@@ -33,6 +33,20 @@ config DM_PMIC_MAX77686
 	This config enables implementation of driver-model pmic uclass features
 	for PMIC MAX77686. The driver implements read/write operations.
 
+config PMIC_S2MPS11
+	bool "Enable Driver Model for PMIC Samsung S2MPS11"
+	depends on DM_PMIC
+	---help---
+	The Samsung S2MPS11 PMIC provides:
+	 - 38 adjustable LDO regulators
+	 - 9 High-Efficiency Buck Converters
+	 - 1 BuckBoost Converter
+	 - RTC with two alarms
+	 - Backup battery charger
+	 - I2C Configuration Interface
+	This driver provides access to I/O interface only.
+	Binding info: doc/device-tree-bindings/pmic/s2mps11.txt
+
 config DM_PMIC_SANDBOX
 	bool "Enable Driver Model for emulated Sandbox PMIC "
 	depends on DM_PMIC
drivers/power/pmic/Makefile +1 -0
index 00fde71..91e78f8 100644
@@ -8,6 +8,7 @@
 obj-$(CONFIG_DM_PMIC) += pmic-uclass.o
 obj-$(CONFIG_DM_PMIC_MAX77686) += max77686.o
 obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze100.o
+obj-$(CONFIG_PMIC_S2MPS11) += s2mps11.o
 obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o
 obj-$(CONFIG_PMIC_ACT8846) += act8846.o
 obj-$(CONFIG_PMIC_TPS65090) += tps65090.o
drivers/power/pmic/s2mps11.c new file +62 -0

62 lines not on this page · raw message

include/power/s2mps11.h new file +109 -0

109 lines not on this page · raw message

Signature · 1 line
1.9.1
#80 lore raw

PATCH v3 5/14 dm: pmic: add s2mps11 PMIC I/O driver

Quoted 18 lines · Przemyslaw Marczak

This driver allows I/O operations on the Samsung S2MPS11 PMIC, which provides lots of LDO/BUCK outputs.

To enable it, update defconfig with:
- CONFIG_PMIC_S2MPS11
and additional, if were not defined:
- CONFIG_CMD_PMIC
- CONFIG_ERRNO_STR

The binding info: doc/device-tree-bindings/pmic/s2mps11.txt

---
Changes V2:
- remove "DM" prefix from config name
- fix word mistake in binding description Changes V3:
- correct return values for driver's read/write methods

Quoted 10 lines
---
 doc/device-tree-bindings/pmic/s2mps11.txt |  17 +++++
 drivers/power/pmic/Kconfig                |  14 ++++
 drivers/power/pmic/Makefile               |   1 +
 drivers/power/pmic/s2mps11.c              |  62 +++++++++++++++++
 include/power/s2mps11.h                   | 109 ++++++++++++++++++++++++++++++
 5 files changed, 203 insertions(+)
 create mode 100644 doc/device-tree-bindings/pmic/s2mps11.txt
 create mode 100644 drivers/power/pmic/s2mps11.c
 create mode 100644 include/power/s2mps11.h
#81 lore raw

PATCH v3 5/14 dm: pmic: add s2mps11 PMIC I/O driver

In reply to Przemyslaw Marczak

hi,

Quoted 273 lines · Przemyslaw Marczak

This driver allows I/O operations on the Samsung S2MPS11 PMIC, which provides lots of LDO/BUCK outputs.

To enable it, update defconfig with:
- CONFIG_PMIC_S2MPS11
and additional, if were not defined:
- CONFIG_CMD_PMIC
- CONFIG_ERRNO_STR

The binding info: doc/device-tree-bindings/pmic/s2mps11.txt

---
Changes V2:
- remove "DM" prefix from config name
- fix word mistake in binding description Changes V3:
- correct return values for driver's read/write methods

---
 doc/device-tree-bindings/pmic/s2mps11.txt |  17 +++++
 drivers/power/pmic/Kconfig                |  14 ++++
 drivers/power/pmic/Makefile               |   1 +
 drivers/power/pmic/s2mps11.c              |  62 +++++++++++++++++
 include/power/s2mps11.h                   | 109 ++++++++++++++++++++++++++++++
 5 files changed, 203 insertions(+)
 create mode 100644 doc/device-tree-bindings/pmic/s2mps11.txt
 create mode 100644 drivers/power/pmic/s2mps11.c
 create mode 100644 include/power/s2mps11.h
doc/device-tree-bindings/pmic/s2mps11.txt new file +17 -0
new file mode 100644
index 0000000..422f14f
@@ -0,0 +1,17 @@
+SAMSUNG, S2MPS11 PMIC
+
+This file describes the binding info for the PMIC driver:
+- drivers/power/pmic/s2mps11.c
+
+Required properties:
+- compatible: "samsung,s2mps11-pmic"
+- reg = 0x66
+
+With those two properties, the pmic device can be used for read/write only.
+
+Example:
+
+s2mps11 at 66 {
+       compatible = "samsung,s2mps11-pmic";
+       reg = <0x66>;
+};
drivers/power/pmic/Kconfig +14 -0
index 547fd1a..fb29843 100644
@@ -33,6 +33,20 @@ config DM_PMIC_MAX77686
        This config enables implementation of driver-model pmic uclass features
        for PMIC MAX77686. The driver implements read/write operations.
 
+config PMIC_S2MPS11
+       bool "Enable Driver Model for PMIC Samsung S2MPS11"
+       depends on DM_PMIC
+       ---help---
+       The Samsung S2MPS11 PMIC provides:
+        - 38 adjustable LDO regulators
+        - 9 High-Efficiency Buck Converters
+        - 1 BuckBoost Converter
+        - RTC with two alarms
+        - Backup battery charger
+        - I2C Configuration Interface
+       This driver provides access to I/O interface only.
+       Binding info: doc/device-tree-bindings/pmic/s2mps11.txt
+
 config DM_PMIC_SANDBOX
        bool "Enable Driver Model for emulated Sandbox PMIC "
        depends on DM_PMIC
drivers/power/pmic/Makefile +1 -0
index 00fde71..91e78f8 100644
@@ -8,6 +8,7 @@
 obj-$(CONFIG_DM_PMIC) += pmic-uclass.o
 obj-$(CONFIG_DM_PMIC_MAX77686) += max77686.o
 obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze100.o
+obj-$(CONFIG_PMIC_S2MPS11) += s2mps11.o
 obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o
 obj-$(CONFIG_PMIC_ACT8846) += act8846.o
 obj-$(CONFIG_PMIC_TPS65090) += tps65090.o
drivers/power/pmic/s2mps11.c new file +62 -0
new file mode 100644
index 0000000..9d83059
@@ -0,0 +1,62 @@
+/*
+ *  Copyright (C) 2015 Samsung Electronics
+ *  Przemyslaw Marczak  <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <errno.h>
+#include <dm.h>
+#include <i2c.h>
+#include <power/pmic.h>
+#include <power/s2mps11.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int s2mps11_reg_count(struct udevice *dev)
+{
+       return S2MPS11_REG_COUNT;
+}
+
+static int s2mps11_write(struct udevice *dev, uint reg, const uint8_t *buff,
+                        int len)
+{
+       int ret;
+
+       ret = dm_i2c_write(dev, reg, buff, len);
+       if (ret)
+               error("write error to device: %p register: %#x!", dev, reg);
+
+       return ret;
+}
+
+static int s2mps11_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
+{
+       int ret;
+
+       ret = dm_i2c_read(dev, reg, buff, len);
+       if (ret)
+               error("read error from device: %p register: %#x!", dev, reg);
+
+       return ret;
+}
+
+static struct dm_pmic_ops s2mps11_ops = {
+       .reg_count = s2mps11_reg_count,
+       .read = s2mps11_read,
+       .write = s2mps11_write,
+};
+
+static const struct udevice_id s2mps11_ids[] = {
+       { .compatible = "samsung,s2mps11-pmic" },
+       { }
+};
+
+U_BOOT_DRIVER(pmic_s2mps11) = {
+       .name = "s2mps11_pmic",
+       .id = UCLASS_PMIC,
+       .of_match = s2mps11_ids,
+       .ops = &s2mps11_ops,
+};
include/power/s2mps11.h new file +109 -1
new file mode 100644
index 0000000..5da4719
@@ -0,0 +1,109 @@
+#ifndef __S2MPS11__H__
+#define __S2MPS11__H__
+
+enum s2mps11_reg {
+       S2MPS11_REG_ID = 0,
+       S2MPS11_REG_INT1,
+       S2MPS11_REG_INT2,
+       S2MPS11_REG_INT3,
+       S2MPS11_REG_INT1M,
+       S2MPS11_REG_INT2M,
+       S2MPS11_REG_INT3M,
+       S2MPS11_REG_STATUS1,
+       S2MPS11_REG_STATUS2,
+       S2MPS11_REG_OFFSRC,
+       S2MPS11_REG_PWRONSRC,
+       S2MPS11_REG_RTC_CTRL,
+       S2MPS11_REG_CTRL1,
+       S2MPS11_REG_ETC_TEST,
+       S2MPS11_REG_RSVD3,
+       S2MPS11_REG_BU_CHG,
+       S2MPS11_REG_RAMP,
+       S2MPS11_REG_RAMP_BUCK,
+       S2MPS11_REG_LDO1_8,
+       S2MPS11_REG_LDO9_16,
+       S2MPS11_REG_LDO17_24,
+       S2MPS11_REG_LDO25_32,
+       S2MPS11_REG_LDO33_38,
+       S2MPS11_REG_LDO1_8_OVC,
+       S2MPS11_REG_LDO9_16_OVC,
+       S2MPS11_REG_LDO17_24_OVC,
+       S2MPS11_REG_LDO25_32_OVC,
+       S2MPS11_REG_LDO33_38_OVC,
+       S2MPS11_REG_RESERVED1,
+       S2MPS11_REG_RESERVED2,
+       S2MPS11_REG_RESERVED3,
+       S2MPS11_REG_RESERVED4,
+       S2MPS11_REG_RESERVED5,
+       S2MPS11_REG_RESERVED6,
+       S2MPS11_REG_RESERVED7,
+       S2MPS11_REG_RESERVED8,
+       S2MPS11_REG_WDRSTEN_CTRL,
+       S2MPS11_REG_B1CTRL1,
+       S2MPS11_REG_B1CTRL2,
+       S2MPS11_REG_B2CTRL1,
+       S2MPS11_REG_B2CTRL2,
+       S2MPS11_REG_B3CTRL1,
+       S2MPS11_REG_B3CTRL2,
+       S2MPS11_REG_B4CTRL1,
+       S2MPS11_REG_B4CTRL2,
+       S2MPS11_REG_B5CTRL1,
+       S2MPS11_REG_BUCK5_SW,
+       S2MPS11_REG_B5CTRL2,
+       S2MPS11_REG_B5CTRL3,
+       S2MPS11_REG_B5CTRL4,
+       S2MPS11_REG_B5CTRL5,
+       S2MPS11_REG_B6CTRL1,
+       S2MPS11_REG_B6CTRL2,
+       S2MPS11_REG_B7CTRL1,
+       S2MPS11_REG_B7CTRL2,
+       S2MPS11_REG_B8CTRL1,
+       S2MPS11_REG_B8CTRL2,
+       S2MPS11_REG_B9CTRL1,
+       S2MPS11_REG_B9CTRL2,
+       S2MPS11_REG_B10CTRL1,
+       S2MPS11_REG_B10CTRL2,
+       S2MPS11_REG_L1CTRL,
+       S2MPS11_REG_L2CTRL,
+       S2MPS11_REG_L3CTRL,
+       S2MPS11_REG_L4CTRL,
+       S2MPS11_REG_L5CTRL,
+       S2MPS11_REG_L6CTRL,
+       S2MPS11_REG_L7CTRL,
+       S2MPS11_REG_L8CTRL,
+       S2MPS11_REG_L9CTRL,
+       S2MPS11_REG_L10CTRL,
+       S2MPS11_REG_L11CTRL,
+       S2MPS11_REG_L12CTRL,
+       S2MPS11_REG_L13CTRL,
+       S2MPS11_REG_L14CTRL,
+       S2MPS11_REG_L15CTRL,
+       S2MPS11_REG_L16CTRL,
+       S2MPS11_REG_L17CTRL,
+       S2MPS11_REG_L18CTRL,
+       S2MPS11_REG_L19CTRL,
+       S2MPS11_REG_L20CTRL,
+       S2MPS11_REG_L21CTRL,
+       S2MPS11_REG_L22CTRL,
+       S2MPS11_REG_L23CTRL,
+       S2MPS11_REG_L24CTRL,
+       S2MPS11_REG_L25CTRL,
+       S2MPS11_REG_L26CTRL,
+       S2MPS11_REG_L27CTRL,
+       S2MPS11_REG_L28CTRL,
+       S2MPS11_REG_L29CTRL,
+       S2MPS11_REG_L30CTRL,
+       S2MPS11_REG_L31CTRL,
+       S2MPS11_REG_L32CTRL,
+       S2MPS11_REG_L33CTRL,
+       S2MPS11_REG_L34CTRL,
+       S2MPS11_REG_L35CTRL,
+       S2MPS11_REG_L36CTRL,
+       S2MPS11_REG_L37CTRL,
+       S2MPS11_REG_L38CTRL,
+       S2MPS11_REG_COUNT,
+};
+
+#define S2MPS11_LDO26_ENABLE   0xec
+
+#endif
--
Quoted 2 lines

1.9.1

-Anand Moon

#82 lore raw

PATCH v3 6/14 dm: regulator: add function device_get_supply_regulator()

In reply to Przemyslaw Marczak

Some devices are supplied by configurable regulator's output. But there was no function for getting it. This commit adds function, that allows for getting the supply device by it's phandle.

The returned regulator device can be used with regulator uclass's API.

---
Changes V3:
- new commit

---
 drivers/power/regulator/regulator-uclass.c |  7 +++++++
 include/power/regulator.h                  | 16 ++++++++++++++++
 2 files changed, 23 insertions(+)
drivers/power/regulator/regulator-uclass.c +7 -0
index a5170df..4241a4c 100644
@@ -138,6 +138,13 @@ int regulator_get_by_devname(const char *devname, struct udevice **devp)
 	return uclass_get_device_by_name(UCLASS_REGULATOR, devname, devp);
 }
 
+int device_get_supply_regulator(struct udevice *dev, const char *supply_name,
+				struct udevice **devp)
+{
+	return uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
+					    supply_name, devp);
+}
+
 int regulator_autoset(struct udevice *dev)
 {
 	struct dm_regulator_uclass_platdata *uc_pdata;
include/power/regulator.h +16 -0
index 1a51c3f..63c0814 100644
@@ -419,4 +419,20 @@ int regulator_get_by_devname(const char *devname, struct udevice **devp);
  */
 int regulator_get_by_platname(const char *platname, struct udevice **devp);
 
+/**
+ * device_get_supply_regulator: returns the pointer to the supply regulator.
+ * Search by phandle, found in device's node.
+ *
+ * Note: Please pay attention to proper order of device bind sequence.
+ * The regulator device searched by the phandle, must be binded before
+ * this function call.
+ *
+ * @dev         - device with supply phandle
+ * @supply_name - phandle name of regulator
+ * @devp        - returned pointer to the supply device
+ * @return 0 on success or negative value of errno.
+ */
+int device_get_supply_regulator(struct udevice *dev, const char *supply_name,
+				struct udevice **devp);
+
 #endif /* _INCLUDE_REGULATOR_H_ */
Signature · 1 line
1.9.1
#83 lore raw

PATCH v3 6/14 dm: regulator: add function device_get_supply_regulator()

Hi Przemyslaw,

Quoted 22 lines · Przemyslaw Marczak

Some devices are supplied by configurable regulator's output. But there was no function for getting it. This commit adds function, that allows for getting the supply device by it's phandle.

The returned regulator device can be used with regulator uclass's API.

---
Changes V3:
- new commit

---
 drivers/power/regulator/regulator-uclass.c |  7 +++++++
 include/power/regulator.h                  | 16 ++++++++++++++++
 2 files changed, 23 insertions(+)
drivers/power/regulator/regulator-uclass.c +0 -0
index a5170df..4241a4c 100644

drivers/power/regulator/regulator-uclass.c int regulator_get_by_devname(const char *devname, struct udevice **devp) · line 142

Quoted 5 lines
drivers/power/regulator/regulator-uclass.c +2 -0
@@ -138,6 +138,13 @@ int regulator_get_by_devname(const char *devname, struct udevice **devp)
        return uclass_get_device_by_name(UCLASS_REGULATOR, devname, devp);
 }
 
+int device_get_supply_regulator(struct udevice *dev, const char *supply_name,
+                               struct udevice **devp)

Can we call this regulator_get_supply()? The 'device_' prefix is used by device.h.

Quoted 34 lines
drivers/power/regulator/regulator-uclass.c +5 -0
+{
+       return uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
+                                           supply_name, devp);
+}
+
 int regulator_autoset(struct udevice *dev)
 {
        struct dm_regulator_uclass_platdata *uc_pdata;
include/power/regulator.h +16 -1
index 1a51c3f..63c0814 100644
@@ -419,4 +419,20 @@ int regulator_get_by_devname(const char *devname, struct udevice **devp);
  */
 int regulator_get_by_platname(const char *platname, struct udevice **devp);
 
+/**
+ * device_get_supply_regulator: returns the pointer to the supply regulator.
+ * Search by phandle, found in device's node.
+ *
+ * Note: Please pay attention to proper order of device bind sequence.
+ * The regulator device searched by the phandle, must be binded before
+ * this function call.
+ *
+ * @dev         - device with supply phandle
+ * @supply_name - phandle name of regulator
+ * @devp        - returned pointer to the supply device
+ * @return 0 on success or negative value of errno.
+ */
+int device_get_supply_regulator(struct udevice *dev, const char *supply_name,
+                               struct udevice **devp);
+
 #endif /* _INCLUDE_REGULATOR_H_ */
--
Quoted 2 lines

1.9.1

Regards,
Simon

#84 lore raw

PATCH v3 7/14 dm: adc: add simple ADC uclass implementation

In reply to Przemyslaw Marczak

This commit adds:
- new uclass id: UCLASS_ADC
- new uclass driver: drivers/adc/adc-uclass.c

The new uclass's API allows for ADC operation on:
* single-channel with channel selection by a number
* multti-channel with channel selection by bit mask

ADC uclass's functions:
* single-channel:

  - adc_start_channel()        - start channel conversion
  - adc_channel_data()         - get conversion data
  - adc_channel_single_shot()  - start/get conversion data

* multi-channel:
- adc_start_channels() - start selected channels conversion
- adc_channels_data() - get conversion data
- adc_channels_single_shot() - start/get conversion data for channels selected by bit mask
* general:
- adc_stop() - stop the conversion
- adc_vdd_value() - positive reference Voltage value with polarity [uV]
- adc_vss_value() - negative reference Voltage value with polarity [uV]
- adc_data_mask() - conversion data bit mask

The device tree can provide below constraints/properties:
- vdd-polarity-negative: if true: Vdd = vdd-microvolts * (-1)
- vss-polarity-negative: if true: Vss = vss-microvolts * (-1)
- vdd-supply: phandle to Vdd regulator's node
- vss-supply: phandle to Vss regulator's node
And optional, checked only if the above corresponding, doesn't exist:
- vdd-microvolts: positive reference Voltage [uV]
- vss-microvolts: negative reference Voltage [uV]

---
Changes V2:
- new commit - introduce ADC uclass driver
Changes V3:
- Add binding info
- ADC uclass's code rework, add single/multi-channel API
- Select single channel by a number and multi, by a bit mask
- Wait for conversion end in uclass's internal function
- Add ADC supply polarity constraint
- Add function for getting supply Voltage with polarity

---
 doc/device-tree-bindings/adc/adc.txt |  62 ++++++
 drivers/Kconfig                      |   2 +
 drivers/Makefile                     |   1 +
 drivers/adc/Kconfig                  |  12 +
 drivers/adc/Makefile                 |   8 +
 drivers/adc/adc-uclass.c             | 409 +++++++++++++++++++++++++++++++++++
 include/adc.h                        | 288 ++++++++++++++++++++++++
 include/dm/uclass-id.h               |   1 +
 8 files changed, 783 insertions(+)
 create mode 100644 doc/device-tree-bindings/adc/adc.txt
 create mode 100644 drivers/adc/Kconfig
 create mode 100644 drivers/adc/Makefile
 create mode 100644 drivers/adc/adc-uclass.c
 create mode 100644 include/adc.h
doc/device-tree-bindings/adc/adc.txt new file +62 -0
new file mode 100644
index 0000000..463de3c
@@ -0,0 +1,62 @@
+ADC device binding
+
+There are no mandatory properties for ADC. However, if Voltage info is required,
+then there are two options:
+- use microvolts constraint or
+- use regulator phandle to enable/read supply's Voltage
+
+Properties and constraints:
+*optional and always checked, Voltage polarity info:
+- vdd-polarity-negative:  positive reference Voltage has a negative polarity
+- vss-polarity-negative:  negative reference Voltage has a negative polarity
+
+Chose one option, for each supply (Vdd/Vss):
+
+*optional and always checked, supply Voltage constants:
+- vdd-supply:            phandle to Vdd regulator's node
+- vss-supply:            phandle to Vss regulator's node
+
+*optional and checked only if the above corresponding, doesn't exist:
+- vdd-microvolts:        positive reference Voltage value [uV]
+- vss-microvolts:        negative reference Voltage value [uV]
+
+Example with constant 'Vdd' value:
+adc at 1000000 {
+	compatible = "some-adc";
+	reg = <0xaabb000 0x100>;
+	status = "enabled";
+	vdd-microvolts = <1800000>;
+};
+
+Example of supply phandle usage, for the ADC's VDD/VSS references as below:
+   _______         _______
+  |Sandbox|       |Sandbox|
+  : PMIC  :       :  ADC  :
+  .       .       .       .
+  |       | (Vdd) |   AIN0|-->
+  |  BUCK2|-------|VDDref |
+  | (3.3V)|      _|VSSref |
+  |_______|     | |_______|
+               _|_
+
+For the above PMIC, the node can be defined as follows:
+sandbox_pmic {
+	compatible = "sandbox,pmic";
+	...
+	buck2: buck2 {
+		regulator-name = "SUPPLY_3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+	...
+};
+
+For the above ADC, the node can be defined as follows:
+adc at 0 {
+	compatible = "sandbox,adc";
+	vdd-supply = <&buck2>;
+	vss-microvolts = <0>;
+};
+
+The ADC uclass code, will enable the supply before start of the conversion,
+but it will not configure the regulator settings.
drivers/Kconfig +2 -0
index ba88b5e..c481e93 100644
@@ -4,6 +4,8 @@ source "drivers/core/Kconfig"
 
 # types of drivers sorted in alphabetical order
 
+source "drivers/adc/Kconfig"
+
 source "drivers/block/Kconfig"
 
 source "drivers/clk/Kconfig"
drivers/Makefile +1 -0
index 4f49bfd..ad29a4f 100644
@@ -35,6 +35,7 @@ obj-$(CONFIG_SPL_SATA_SUPPORT) += block/
 
 else
 
+obj-y += adc/
 obj-$(CONFIG_DM_DEMO) += demo/
 obj-$(CONFIG_BIOSEMU) += bios_emulator/
 obj-y += block/
drivers/adc/Kconfig new file +12 -0
new file mode 100644
index 0000000..b6e226a
@@ -0,0 +1,12 @@
+config ADC
+	bool "Enable ADC drivers using Driver Model"
+	help
+	  This enables ADC API for drivers, which allows driving ADC features
+	  by single and multi-channel methods for:
+	  - start/stop/get data for conversion of a single-channel selected by
+	    a number or multi-channels selected by a bitmask
+	  - get data mask (ADC resolution)
+	  ADC reference Voltage supply options:
+	  - methods for get Vdd/Vss reference Voltage values with polarity
+	  - support supply's phandle with auto-enable
+	  - supply polarity setting in fdt
drivers/adc/Makefile new file +8 -0
new file mode 100644
index 0000000..c4d9618
@@ -0,0 +1,8 @@
+#
+# Copyright (C) 2015 Samsung Electronics
+# Przemyslaw Marczak <[email protected]>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-$(CONFIG_ADC) += adc-uclass.o
drivers/adc/adc-uclass.c new file +409 -0

409 lines not on this page · raw message

include/adc.h new file +288 -0

288 lines not on this page · raw message

include/dm/uclass-id.h +1 -0
index 886a44c..d0cf4ce 100644
@@ -25,6 +25,7 @@ enum uclass_id {
 	UCLASS_SIMPLE_BUS,	/* bus with child devices */
 
 	/* U-Boot uclasses start here - in alphabetical order */
+	UCLASS_ADC,		/* Analog-to-digital converter */
 	UCLASS_CLK,		/* Clock source, e.g. used by peripherals */
 	UCLASS_CPU,		/* CPU, typically part of an SoC */
 	UCLASS_CROS_EC,		/* Chrome OS EC */
Signature · 1 line
1.9.1
#85 lore raw

PATCH v3 7/14 dm: adc: add simple ADC uclass implementation

Hello all,

Quoted 55 lines · Przemyslaw Marczak

This commit adds:
- new uclass id: UCLASS_ADC
- new uclass driver: drivers/adc/adc-uclass.c

The new uclass's API allows for ADC operation on:
* single-channel with channel selection by a number
* multti-channel with channel selection by bit mask

ADC uclass's functions:
* single-channel:

   - adc_start_channel()        - start channel conversion
   - adc_channel_data()         - get conversion data
   - adc_channel_single_shot()  - start/get conversion data

* multi-channel:
- adc_start_channels() - start selected channels conversion
- adc_channels_data() - get conversion data
- adc_channels_single_shot() - start/get conversion data for channels selected by bit mask
* general:
- adc_stop() - stop the conversion
- adc_vdd_value() - positive reference Voltage value with polarity [uV]
- adc_vss_value() - negative reference Voltage value with polarity [uV]
- adc_data_mask() - conversion data bit mask

The device tree can provide below constraints/properties:
- vdd-polarity-negative: if true: Vdd = vdd-microvolts * (-1)
- vss-polarity-negative: if true: Vss = vss-microvolts * (-1)
- vdd-supply: phandle to Vdd regulator's node
- vss-supply: phandle to Vss regulator's node
And optional, checked only if the above corresponding, doesn't exist:
- vdd-microvolts: positive reference Voltage [uV]
- vss-microvolts: negative reference Voltage [uV]

---
Changes V2:
- new commit - introduce ADC uclass driver
Changes V3:
- Add binding info
- ADC uclass's code rework, add single/multi-channel API
- Select single channel by a number and multi, by a bit mask
- Wait for conversion end in uclass's internal function
- Add ADC supply polarity constraint
- Add function for getting supply Voltage with polarity

---
  doc/device-tree-bindings/adc/adc.txt |  62 ++++++
  drivers/Kconfig                      |   2 +
  drivers/Makefile                     |   1 +
  drivers/adc/Kconfig                  |  12 +
  drivers/adc/Makefile                 |   8 +
  drivers/adc/adc-uclass.c             | 409 +++++++++++++++++++++++++++++++++++
  include/adc.h                        | 288 ++++++++++++++++++++++++
  include/dm/uclass-id.h               |   1 +
  8 files changed, 783 insertions(+)
Quoted 6 lines

create mode 100644 doc/device-tree-bindings/adc/adc.txt create mode 100644 drivers/adc/Kconfig
create mode 100644 drivers/adc/Makefile
create mode 100644 drivers/adc/adc-uclass.c create mode 100644 include/adc.h

--- cut ---

Quoted 24 lines
drivers/adc/adc-uclass.c new file +18 -0
new file mode 100644
index 0000000..9233fcd
@@ -0,0 +1,409 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics
+ * Przemyslaw Marczak <[email protected]>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <dm/device-internal.h>
+#include <dm/uclass-internal.h>
+#include <adc.h>
+#include <power/regulator.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+

drivers/adc/adc-uclass.c line 28

Quoted 10 lines
drivers/adc/adc-uclass.c new file +10 -0
+#define ADC_UCLASS_PLATDATA_SIZE	sizeof(struct adc_uclass_platdata)
+#define CHECK_NUMBER			true
+#define CHECK_MASK			(!CHECK_NUMBER)
+
+/* TODO: add support for timer uclass (for early calls) */
+#ifdef CONFIG_SANDBOX_ARCH
+#define sdelay(x)	udelay(x)
+#else
+extern void sdelay(unsigned long loops);
+#endif

--- cut ---

I would like precise the sdelay() calls in this code.

I didn't make the cleanup for the sdelay(), as Simon requested.

For some architectures it's declared in a different headers, but we have timer uclass now, so this sdelay mess can be used temporary.

Now, I don't have time for moving Exynos timer to driver model. And also it should be done as a separated patch set.

Best regards,

Signature · 4 lines
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com
#86 lore raw

PATCH v3 7/14 dm: adc: add simple ADC uclass implementation

In reply to Przemyslaw Marczak

Hi Przemyslaw,

Quoted 33 lines · Przemyslaw Marczak

This commit adds:
- new uclass id: UCLASS_ADC
- new uclass driver: drivers/adc/adc-uclass.c

The new uclass's API allows for ADC operation on:
* single-channel with channel selection by a number
* multti-channel with channel selection by bit mask

ADC uclass's functions:
* single-channel:

  - adc_start_channel()        - start channel conversion
  - adc_channel_data()         - get conversion data
  - adc_channel_single_shot()  - start/get conversion data

* multi-channel:
- adc_start_channels() - start selected channels conversion
- adc_channels_data() - get conversion data
- adc_channels_single_shot() - start/get conversion data for channels selected by bit mask
* general:
- adc_stop() - stop the conversion
- adc_vdd_value() - positive reference Voltage value with polarity [uV]
- adc_vss_value() - negative reference Voltage value with polarity [uV]
- adc_data_mask() - conversion data bit mask

The device tree can provide below constraints/properties:
- vdd-polarity-negative: if true: Vdd = vdd-microvolts * (-1)
- vss-polarity-negative: if true: Vss = vss-microvolts * (-1)
- vdd-supply: phandle to Vdd regulator's node
- vss-supply: phandle to Vss regulator's node
And optional, checked only if the above corresponding, doesn't exist:
- vdd-microvolts: positive reference Voltage [uV]
- vss-microvolts: negative reference Voltage [uV]

Quoted 2 lines

Some comments below.

Quoted 161 lines

---
Changes V2:
- new commit - introduce ADC uclass driver
Changes V3:
- Add binding info
- ADC uclass's code rework, add single/multi-channel API
- Select single channel by a number and multi, by a bit mask
- Wait for conversion end in uclass's internal function
- Add ADC supply polarity constraint
- Add function for getting supply Voltage with polarity

---
 doc/device-tree-bindings/adc/adc.txt |  62 ++++++
 drivers/Kconfig                      |   2 +
 drivers/Makefile                     |   1 +
 drivers/adc/Kconfig                  |  12 +
 drivers/adc/Makefile                 |   8 +
 drivers/adc/adc-uclass.c             | 409 +++++++++++++++++++++++++++++++++++
 include/adc.h                        | 288 ++++++++++++++++++++++++
 include/dm/uclass-id.h               |   1 +
 8 files changed, 783 insertions(+)
 create mode 100644 doc/device-tree-bindings/adc/adc.txt
 create mode 100644 drivers/adc/Kconfig
 create mode 100644 drivers/adc/Makefile
 create mode 100644 drivers/adc/adc-uclass.c
 create mode 100644 include/adc.h
doc/device-tree-bindings/adc/adc.txt new file +62 -0
new file mode 100644
index 0000000..463de3c
@@ -0,0 +1,62 @@
+ADC device binding
+
+There are no mandatory properties for ADC. However, if Voltage info is required,
+then there are two options:
+- use microvolts constraint or
+- use regulator phandle to enable/read supply's Voltage
+
+Properties and constraints:
+*optional and always checked, Voltage polarity info:
+- vdd-polarity-negative:  positive reference Voltage has a negative polarity
+- vss-polarity-negative:  negative reference Voltage has a negative polarity
+
+Chose one option, for each supply (Vdd/Vss):
+
+*optional and always checked, supply Voltage constants:
+- vdd-supply:            phandle to Vdd regulator's node
+- vss-supply:            phandle to Vss regulator's node
+
+*optional and checked only if the above corresponding, doesn't exist:
+- vdd-microvolts:        positive reference Voltage value [uV]
+- vss-microvolts:        negative reference Voltage value [uV]
+
+Example with constant 'Vdd' value:
+adc at 1000000 {
+       compatible = "some-adc";
+       reg = <0xaabb000 0x100>;
+       status = "enabled";
+       vdd-microvolts = <1800000>;
+};
+
+Example of supply phandle usage, for the ADC's VDD/VSS references as below:
+   _______         _______
+  |Sandbox|       |Sandbox|
+  : PMIC  :       :  ADC  :
+  .       .       .       .
+  |       | (Vdd) |   AIN0|-->
+  |  BUCK2|-------|VDDref |
+  | (3.3V)|      _|VSSref |
+  |_______|     | |_______|
+               _|_
+
+For the above PMIC, the node can be defined as follows:
+sandbox_pmic {
+       compatible = "sandbox,pmic";
+       ...
+       buck2: buck2 {
+               regulator-name = "SUPPLY_3.3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+       ...
+};
+
+For the above ADC, the node can be defined as follows:
+adc at 0 {
+       compatible = "sandbox,adc";
+       vdd-supply = <&buck2>;
+       vss-microvolts = <0>;
+};
+
+The ADC uclass code, will enable the supply before start of the conversion,
+but it will not configure the regulator settings.
drivers/Kconfig +2 -0
index ba88b5e..c481e93 100644
@@ -4,6 +4,8 @@ source "drivers/core/Kconfig"
 
 # types of drivers sorted in alphabetical order
 
+source "drivers/adc/Kconfig"
+
 source "drivers/block/Kconfig"
 
 source "drivers/clk/Kconfig"
drivers/Makefile +1 -0
index 4f49bfd..ad29a4f 100644
@@ -35,6 +35,7 @@ obj-$(CONFIG_SPL_SATA_SUPPORT) += block/
 
 else
 
+obj-y += adc/
 obj-$(CONFIG_DM_DEMO) += demo/
 obj-$(CONFIG_BIOSEMU) += bios_emulator/
 obj-y += block/
drivers/adc/Kconfig new file +12 -0
new file mode 100644
index 0000000..b6e226a
@@ -0,0 +1,12 @@
+config ADC
+       bool "Enable ADC drivers using Driver Model"
+       help
+         This enables ADC API for drivers, which allows driving ADC features
+         by single and multi-channel methods for:
+         - start/stop/get data for conversion of a single-channel selected by
+           a number or multi-channels selected by a bitmask
+         - get data mask (ADC resolution)
+         ADC reference Voltage supply options:
+         - methods for get Vdd/Vss reference Voltage values with polarity
+         - support supply's phandle with auto-enable
+         - supply polarity setting in fdt
drivers/adc/Makefile new file +8 -0
new file mode 100644
index 0000000..c4d9618
@@ -0,0 +1,8 @@
+#
+# Copyright (C) 2015 Samsung Electronics
+# Przemyslaw Marczak <[email protected]>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-$(CONFIG_ADC) += adc-uclass.o
drivers/adc/adc-uclass.c new file +4 -0
new file mode 100644
index 0000000..9233fcd
@@ -0,0 +1,409 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics
+ * Przemyslaw Marczak <[email protected]>
+ *

drivers/adc/adc-uclass.c line 14

Quoted 10 lines
drivers/adc/adc-uclass.c new file +10 -0
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <dm/device-internal.h>
+#include <dm/uclass-internal.h>
+#include <adc.h>

That should go below common.h

drivers/adc/adc-uclass.c line 19

Quoted 5 lines
drivers/adc/adc-uclass.c new file +5 -0
+#include <power/regulator.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define ADC_UCLASS_PLATDATA_SIZE       sizeof(struct adc_uclass_platdata)

Please drop this and just use sizeof() where needed.

drivers/adc/adc-uclass.c line 21

Quoted 2 lines
drivers/adc/adc-uclass.c new file +2 -0
+#define CHECK_NUMBER                   true
+#define CHECK_MASK                     (!CHECK_NUMBER)

What are those for? I think you should convert this to an enum:

enum some_name_t {
CHECK_NUMBER,
CHECK_MASK
}

and use an enum parameter instead of bool.

drivers/adc/adc-uclass.c line 23

Quoted 2 lines
drivers/adc/adc-uclass.c new file +2 -0
+
+/* TODO: add support for timer uclass (for early calls) */

TODO(email):

so we know who is going to send the follow-up patch.

drivers/adc/adc-uclass.c line 31

Quoted 8 lines
drivers/adc/adc-uclass.c new file +8 -0
+#ifdef CONFIG_SANDBOX_ARCH
+#define sdelay(x)      udelay(x)
+#else
+extern void sdelay(unsigned long loops);
+#endif
+
+static int check_channel(struct udevice *dev, int value, bool number_or_mask,
+                        const char *caller_function)

What does this function do? I think it needs a function comment.

drivers/adc/adc-uclass.c line 36

Quoted 5 lines
drivers/adc/adc-uclass.c new file +5 -0
+{
+       struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
+       unsigned mask = number_or_mask ? (1 << value) : value;
+
+       /* For the real ADC hardware, some ADC channels can be inactive.

Comment style

/*
* For the....

Quoted 104 lines
drivers/adc/adc-uclass.c new file +104 -0
+        * For example if device has 4 analog channels, and only channels
+        * 1-st and 3-rd are valid, then channel mask is: 0b1010, so request
+        * with mask 0b1110 should return an error.
+       */
+       if ((uc_pdata->channel_mask >= mask) && (uc_pdata->channel_mask & mask))
+               return 0;
+
+       printf("Error in %s/%s().\nWrong channel selection for device: %s\n",
+              __FILE__, caller_function, dev->name);
+
+       return -EINVAL;
+}
+
+static int adc_supply_enable(struct udevice *dev)
+{
+       struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
+       const char *supply_type;
+       int ret = 0;
+
+       if (uc_pdata->vdd_supply) {
+               supply_type = "vdd";
+               ret = regulator_set_enable(uc_pdata->vdd_supply, true);
+       }
+
+       if (!ret && uc_pdata->vss_supply) {
+               supply_type = "vss";
+               ret = regulator_set_enable(uc_pdata->vss_supply, true);
+       }
+
+       if (ret)
+               error("%s: can't enable %s-supply!", dev->name, supply_type);
+
+       return ret;
+}
+
+int adc_data_mask(struct udevice *dev, unsigned int *data_mask)
+{
+       struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
+
+       if (!uc_pdata)
+               return -ENOSYS;
+
+       *data_mask = uc_pdata->data_mask;
+       return 0;
+}
+
+int adc_stop(struct udevice *dev)
+{
+       const struct adc_ops *ops = dev_get_driver_ops(dev);
+
+       if (!ops->stop)
+               return -ENOSYS;
+
+       return ops->stop(dev);
+}
+
+int adc_start_channel(struct udevice *dev, int channel)
+{
+       const struct adc_ops *ops = dev_get_driver_ops(dev);
+       int ret;
+
+       if (!ops->start_channel)
+               return -ENOSYS;
+
+       ret = check_channel(dev, channel, CHECK_NUMBER, __func__);
+       if (ret)
+               return ret;
+
+       ret = adc_supply_enable(dev);
+       if (ret)
+               return ret;
+
+       return ops->start_channel(dev, channel);
+}
+
+int adc_start_channels(struct udevice *dev, unsigned int channel_mask)
+{
+       const struct adc_ops *ops = dev_get_driver_ops(dev);
+       int ret;
+
+       if (!ops->start_channels)
+               return -ENOSYS;
+
+       ret = check_channel(dev, channel_mask, CHECK_MASK, __func__);
+       if (ret)
+               return ret;
+
+       ret = adc_supply_enable(dev);
+       if (ret)
+               return ret;
+
+       return ops->start_channels(dev, channel_mask);
+}
+
+int adc_channel_data(struct udevice *dev, int channel, unsigned int *data)
+{
+       struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
+       const struct adc_ops *ops = dev_get_driver_ops(dev);
+       unsigned int timeout_us = uc_pdata->data_timeout_us;
+       int ret;
+
+       if (!ops->channel_data)
+               return -ENOSYS;
+

drivers/adc/adc-uclass.c line 150

Quoted 10 lines
drivers/adc/adc-uclass.c new file +10 -0
+       ret = check_channel(dev, channel, CHECK_NUMBER, __func__);
+       if (ret)
+               return ret;
+
+       do {
+               ret = ops->channel_data(dev, channel, data);
+               if (!ret || ret != -EBUSY)
+                       break;
+
+               /* TODO: use timer uclass (for early calls). */

Remove '.'

Quoted 109 lines
drivers/adc/adc-uclass.c new file +109 -0
+               sdelay(5);
+       } while (timeout_us--);
+
+       return ret;
+}
+
+int adc_channels_data(struct udevice *dev, unsigned int channel_mask,
+                     struct adc_channel *channels)
+{
+       struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
+       unsigned int timeout_us = uc_pdata->multidata_timeout_us;
+       const struct adc_ops *ops = dev_get_driver_ops(dev);
+       int ret;
+
+       if (!ops->channels_data)
+               return -ENOSYS;
+
+       ret = check_channel(dev, channel_mask, CHECK_MASK, __func__);
+       if (ret)
+               return ret;
+
+       do {
+               ret = ops->channels_data(dev, channel_mask, channels);
+               if (!ret || ret != -EBUSY)
+                       break;
+
+               /* TODO: use timer uclass (for early calls). */
+               sdelay(5);
+       } while (timeout_us--);
+
+       return ret;
+}
+
+int adc_channel_single_shot(const char *name, int channel, unsigned int *data)
+{
+       struct udevice *dev;
+       int ret;
+
+       ret = uclass_get_device_by_name(UCLASS_ADC, name, &dev);
+       if (ret)
+               return ret;
+
+       ret = adc_start_channel(dev, channel);
+       if (ret)
+               return ret;
+
+       ret = adc_channel_data(dev, channel, data);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int _adc_channels_single_shot(struct udevice *dev,
+                                    unsigned int channel_mask,
+                                    struct adc_channel *channels)
+{
+       unsigned int data;
+       int channel, ret;
+
+       for (channel = 0; channel <= ADC_MAX_CHANNEL; channel++) {
+               /* Check channel bit. */
+               if (!((channel_mask >> channel) & 0x1))
+                       continue;
+
+               ret = adc_start_channel(dev, channel);
+               if (ret)
+                       return ret;
+
+               ret = adc_channel_data(dev, channel, &data);
+               if (ret)
+                       return ret;
+
+               channels->id = channel;
+               channels->data = data;
+               channels++;
+       }
+
+       return 0;
+}
+
+int adc_channels_single_shot(const char *name, unsigned int channel_mask,
+                            struct adc_channel *channels)
+{
+       struct udevice *dev;
+       int ret;
+
+       ret = uclass_get_device_by_name(UCLASS_ADC, name, &dev);
+       if (ret)
+               return ret;
+
+       ret = adc_start_channels(dev, channel_mask);
+       if (ret)
+               goto try_manual;
+
+       ret = adc_channels_data(dev, channel_mask, channels);
+       if (ret)
+               return ret;
+
+       return 0;
+
+try_manual:
+       if (ret != -ENOSYS)
+               return ret;
+
+       return _adc_channels_single_shot(dev, channel_mask, channels);
+}
+
+static int adc_vdd_platdata_update(struct udevice *dev)

drivers/adc/adc-uclass.c line 269

Quoted 10 lines
drivers/adc/adc-uclass.c new file +10 -0
+{
+       struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
+       int ret;
+
+       /* Warning!
+        * This function can't return supply device before its bind.
+        * Please pay attention to proper fdt scan sequence. If ADC device
+        * will bind before its supply regulator device, then the below 'get'
+        * will return an error.
+        */

How could this happen? Is this function called before the device is probed?

It seems to be called from adc_pre_probe(), by which time all devices should be bound.

Quoted 73 lines
drivers/adc/adc-uclass.c new file +73 -0
+       ret = device_get_supply_regulator(dev, "vdd-supply",
+                                         &uc_pdata->vdd_supply);
+       if (ret)
+               return ret;
+
+       ret = regulator_get_value(uc_pdata->vdd_supply);
+       if (ret < 0)
+               return ret;
+
+       uc_pdata->vdd_microvolts = ret;
+
+       return 0;
+}
+
+static int adc_vss_platdata_update(struct udevice *dev)
+{
+       struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
+       int ret;
+
+       ret = device_get_supply_regulator(dev, "vss-supply",
+                                         &uc_pdata->vss_supply);
+       if (ret)
+               return ret;
+
+       ret = regulator_get_value(uc_pdata->vss_supply);
+       if (ret < 0)
+               return ret;
+
+       uc_pdata->vss_microvolts = ret;
+
+       return 0;
+}
+
+int adc_vdd_value(struct udevice *dev, int *uV)
+{
+       struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
+       int ret, value_sign = uc_pdata->vdd_polarity_negative ? -1 : 1;
+
+       if (!uc_pdata->vdd_supply)
+               goto nodev;
+
+       /* Update the regulator Value. */
+       ret = adc_vdd_platdata_update(dev);
+       if (ret)
+               return ret;
+nodev:
+       if (uc_pdata->vdd_microvolts == -ENODATA)
+               return -ENODATA;
+
+       *uV = uc_pdata->vdd_microvolts * value_sign;
+
+       return 0;
+}
+
+int adc_vss_value(struct udevice *dev, int *uV)
+{
+       struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
+       int ret, value_sign = uc_pdata->vss_polarity_negative ? -1 : 1;
+
+       if (!uc_pdata->vss_supply)
+               goto nodev;
+
+       /* Update the regulator Value. */
+       ret = adc_vss_platdata_update(dev);
+       if (ret)
+               return ret;
+nodev:
+       if (uc_pdata->vss_microvolts == -ENODATA)
+               return -ENODATA;
+
+       *uV = uc_pdata->vss_microvolts * value_sign;
+
+       return 0;

drivers/adc/adc-uclass.c line 352

Quoted 10 lines
drivers/adc/adc-uclass.c new file +10 -0
+}
+
+static int adc_vdd_platdata_set(struct udevice *dev)
+{
+       struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
+       int ret, offset = dev->of_offset;
+       const void *fdt = gd->fdt_blob;
+       char *prop;
+
+       prop = "vdd-polarity-negative";

Can you just drop this variable and use the string?

Quoted 11 lines
drivers/adc/adc-uclass.c new file +11 -0
+       uc_pdata->vdd_polarity_negative = fdtdec_get_bool(fdt, offset, prop);
+
+       ret = adc_vdd_platdata_update(dev);
+       if (ret != -ENOENT)
+               return ret;
+
+       /* No vdd-supply phandle. */
+       prop  = "vdd-microvolts";
+       uc_pdata->vdd_microvolts = fdtdec_get_int(fdt, offset, prop, -ENODATA);
+
+       return 0;

drivers/adc/adc-uclass.c line 373

Quoted 10 lines
drivers/adc/adc-uclass.c new file +10 -0
+}
+
+static int adc_vss_platdata_set(struct udevice *dev)
+{
+       struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
+       int ret, offset = dev->of_offset;
+       const void *fdt = gd->fdt_blob;
+       char *prop;
+
+       prop = "vss-polarity-negative";

Can you just drop this variable and use the string?

Quoted 11 lines
drivers/adc/adc-uclass.c new file +11 -0
+       uc_pdata->vss_polarity_negative = fdtdec_get_bool(fdt, offset, prop);
+
+       ret = adc_vss_platdata_update(dev);
+       if (ret != -ENOENT)
+               return ret;
+
+       /* No vss-supply phandle. */
+       prop = "vss-microvolts";
+       uc_pdata->vss_microvolts = fdtdec_get_int(fdt, offset, prop, -ENODATA);
+
+       return 0;

drivers/adc/adc-uclass.c line 394

Quoted 10 lines
drivers/adc/adc-uclass.c new file +10 -0
+}
+
+static int adc_pre_probe(struct udevice *dev)
+{
+       int ret;
+
+       /* Set ADC VDD platdata: polarity, uV, regulator (phandle). */
+       ret = adc_vdd_platdata_set(dev);
+       if (ret)
+               error("%s: Can't update Vdd. Error: %d", dev->name, ret);

Shouldn't this return ret?

drivers/adc/adc-uclass.c line 399

Quoted 5 lines
drivers/adc/adc-uclass.c new file +5 -0
+
+       /* Set ADC VSS platdata: polarity, uV, regulator (phandle). */
+       ret = adc_vss_platdata_set(dev);
+       if (ret)
+               error("%s: Can't update Vss. Error: %d", dev->name, ret);

and here?

Quoted 18 lines
drivers/adc/adc-uclass.c new file +10 -0
+
+       return 0;
+}
+
+UCLASS_DRIVER(adc) = {
+       .id     = UCLASS_ADC,
+       .name   = "adc",
+       .pre_probe =  adc_pre_probe,
+       .per_device_platdata_auto_alloc_size = ADC_UCLASS_PLATDATA_SIZE,
+};
include/adc.h new file +2 -0
new file mode 100644
index 0000000..4b14017
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics

include/adc.h line 12

Quoted 10 lines
include/adc.h new file +10 -0
+ * Przemyslaw Marczak <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _ADC_H_
+#define _ADC_H_
+
+/* ADC_CHANNEL() - ADC channel bit mask, to select only required channels */
+#define ADC_CHANNEL(x)         (1 << x)

(1U << (x))

include/adc.h line 15

Quoted 3 lines
include/adc.h new file +3 -0
+
+/* The last possible selected channel with 32-bit mask */
+#define ADC_MAX_CHANNEL                31

Can we use ADC_MAX_CHANNELS = 32 instead? You can adjust to for loop to use < instead of <=.

Quoted 36 lines
include/adc.h new file +36 -0
+
+/**
+ * adc_data_format: define the ADC output data format, can be useful when
+ * the device's input Voltage range is bipolar.
+ * - ADC_DATA_FORMAT_BIN - binary offset
+ * - ADC_DATA_FORMAT_2S  - two's complement
+ *
+ * Note: Device's driver should fill the 'data_format' field of its uclass's
+ * platform data using one of the above data format types.
+ */
+enum adc_data_format {
+       ADC_DATA_FORMAT_BIN,
+       ADC_DATA_FORMAT_2S,
+};
+
+/**
+ * struct adc_channel - structure to hold channel conversion data.
+ * Useful to keep the result of a multi-channel conversion output.
+ *
+ * @id   - channel id
+ * @data - channel conversion data
+ */
+struct adc_channel {
+       int id;
+       unsigned int data;
+};
+
+/**
+ * struct adc_uclass_platdata - basic ADC info
+ *
+ * Note: The positive/negative reference Voltage is only a name and it doesn't
+ * provide an information about the value polarity. It is possible, for both
+ * values to be a negative or positive. For this purpose the uclass's platform
+ * data provides a bool fields: 'vdd/vss_supply_is_negative'. This is useful,
+ * since the regulator API returns only a positive Voltage values.
+ *

include/adc.h line 61

Quoted 10 lines
include/adc.h new file +10 -0
+ * To get the reference Voltage values with polarity, use functions:
+ * - adc_vdd_value()
+ * - adc_vss_value()
+ * Those are useful for some cases of ADC's references, e.g.:
+ * * Vdd: +3.3V; Vss: -3.3V -> 6.6 Vdiff
+ * * Vdd: +3.3V; Vss: +0.3V -> 3.0 Vdiff
+ * * Vdd: +3.3V; Vss:  0.0V -> 3.3 Vdiff
+ * The last one is usually standard and doesn't require the fdt polarity info.
+ *
+ * For more informations read binding info:

information

include/adc.h line 64

Quoted 3 lines
include/adc.h new file +3 -0
+ * - doc/device-tree-bindings/adc/adc.txt
+ *
+ * @data_mask              - conversion output data mask

Use : rather than -

@data_mask: conversion output data mask

Quoted 11 lines
include/adc.h new file +11 -0
+ * @data_timeout_us        - single channel conversion timeout
+ * @multidata_timeout_us   - multi channel conversion timeout
+ * @channel_mask           - bit mask of available channels [0:31]
+ * @vdd_supply             - positive reference Voltage supply (regulator)
+ * @vss_supply             - negative reference Voltage supply (regulator)
+ * @vdd_polarity_negative  - positive reference Voltage has negative polarity
+ * @vss_polarity_negative  - negative reference Voltage has negative polarity
+ * @vdd_microvolts         - positive reference Voltage value
+ * @vss_microvolts         - negative reference Voltage value
+ */
+struct adc_uclass_platdata {

include/adc.h line 85

Quoted 10 lines
include/adc.h new file +10 -0
+       int data_format;
+       unsigned int data_mask;
+       unsigned int data_timeout_us;
+       unsigned int multidata_timeout_us;
+       unsigned int channel_mask;
+       struct udevice *vdd_supply;
+       struct udevice *vss_supply;
+       bool vdd_polarity_negative;
+       bool vss_polarity_negative;
+       int vdd_microvolts;

Would vdd_uv be good enough?

Quoted 65 lines
include/adc.h new file +65 -0
+       int vss_microvolts;
+};
+
+/**
+ * struct adc_ops - ADC device operations for single/multi-channel operation.
+ */
+struct adc_ops {
+       /**
+        * start_channel() - start conversion with its default parameters
+        *                   for the given channel number.
+        *
+        * @dev:          ADC device to init
+        * @channel:      analog channel number
+        * @return:       0 if OK, -ve on error
+        */
+       int (*start_channel)(struct udevice *dev, int channel);
+
+       /**
+        * start_channels() - start conversion with its default parameters
+        *                    for the channel numbers selected by the bit mask.
+        *
+        * This is optional, useful when the hardware supports multichannel
+        * conversion by the single software trigger.
+        *
+        * @dev:          ADC device to init
+        * @channel_mask: bit mask of selected analog channels
+        * @return:       0 if OK, -ve on error
+        */
+       int (*start_channels)(struct udevice *dev, unsigned int channel_mask);
+
+       /**
+        * channel_data() - get conversion output data for the given channel.
+        *
+        * Note: The implementation of this function should only check, that
+        * the conversion data is available at the call time. If the hardware
+        * requires some delay to get the data, then this function should
+        * return with -EBUSY value. The ADC API will call it in a loop,
+        * until the data is available or the timeout expires. The maximum
+        * timeout for this operation is defined by the field 'data_timeout_us'
+        * in ADC uclasses platform data structure.
+        *
+        * @dev:          ADC device to trigger
+        * @channel:      selected analog channel number
+        * @data:         returned pointer to selected channel's output data
+        * @return:       0 if OK, -EBUSY if busy, and other negative on error
+        */
+       int (*channel_data)(struct udevice *dev, int channel,
+                           unsigned int *data);
+
+       /**
+        * channels_data() - get conversion data for the selected channels.
+        *
+        * This is optional, useful when multichannel conversion is supported
+        * by the hardware, by the single software trigger.
+        *
+        * For the proper implementation, please look at the 'Note' for the
+        * above method. The only difference is in used timeout value, which
+        * is defined by field 'multidata_timeout_us'.
+        *
+        * @dev:          ADC device to trigger
+        * @channel_mask: bit mask of selected analog channels
+        * @channels:     returned pointer to array of output data for channels
+        *                selected by the given mask
+        * @return:       0 if OK, -ve on error
+        */

include/adc.h line 160

Quoted 10 lines
include/adc.h new file +10 -0
+       int (*channels_data)(struct udevice *dev, unsigned int channel_mask,
+                            struct adc_channel *channels);
+
+       /**
+        * stop() - stop conversion of the given ADC device
+        *
+        * @dev:          ADC device to stop
+        * @return:       0 if OK, -ve on error
+        */
+       int (*stop)(struct udevice *dev);

Does this stop all channels? Should update the comment to explain the API better here.

Quoted 141 lines
include/adc.h new file +128 -0
+};
+
+/**
+ * adc_start_channel() - start conversion for given device/channel and exit.
+ *
+ * @dev:     ADC device
+ * @channel: analog channel number
+ * @return:  0 if OK, -ve on error
+ */
+int adc_start_channel(struct udevice *dev, int channel);
+
+/**
+ * adc_start_channels() - start conversion for given device/channels and exit.
+ *
+ * Note:
+ * To use this function, device must implement method: start_channels().
+ *
+ * @dev:          ADC device to start
+ * @channel_mask: channel selection - a bit mask
+ * @channel_mask: bit mask of analog channels
+ * @return:       0 if OK, -ve on error
+ */
+int adc_start_channels(struct udevice *dev, unsigned int channel_mask);
+
+/**
+ * adc_channel_data() - get conversion data for the given device channel number.
+ *
+ * @dev:     ADC device to read
+ * @channel: analog channel number
+ * @data:    pointer to returned channel's data
+ * @return:  0 if OK, -ve on error
+ */
+int adc_channel_data(struct udevice *dev, int channel, unsigned int *data);
+
+/**
+ * adc_channels_data() - get conversion data for the channels selected by mask
+ *
+ * Note:
+ * To use this function, device must implement methods:
+ * - start_channels()
+ * - channels_data()
+ *
+ * @dev:          ADC device to read
+ * @channel_mask: channel selection - a bit mask
+ * @channels:     pointer to structure array of returned data for each channel
+ * @return:       0 if OK, -ve on error
+ */
+int adc_channels_data(struct udevice *dev, unsigned int channel_mask,
+                     struct adc_channel *channels);
+
+/**
+ * adc_data_mask() - get data mask (ADC resolution bitmask) for given ADC device
+ *
+ * This can be used if adc uclass platform data is filled.
+ *
+ * @dev:       ADC device to check
+ * @data_mask: pointer to the returned data bitmask
+ * @return: 0 if OK, -ve on error
+ */
+int adc_data_mask(struct udevice *dev, unsigned int *data_mask);
+
+/**
+ * adc_channel_single_shot() - get output data of conversion for the ADC
+ * device's channel. This function searches for the device with the given name,
+ * starts the given channel conversion and returns the output data.
+ *
+ * Note: To use this function, device must implement metods:
+ * - start_channel()
+ * - channel_data()
+ *
+ * @name:    device's name to search
+ * @channel: device's input channel to init
+ * @data:    pointer to conversion output data
+ * @return:  0 if OK, -ve on error
+ */
+int adc_channel_single_shot(const char *name, int channel, unsigned int *data);
+
+/**
+ * adc_channels_single_shot() - get ADC conversion output data for the selected
+ * device's channels. This function searches for the device by the given name,
+ * starts the selected channels conversion and returns the output data as array
+ * of type 'struct adc_channel'.
+ *
+ * Note: This function can be used if device implements one of ADC's single
+ * or multi-channel operation API. If multi-channel operation is not supported,
+ * then each selected channel is triggered by the sequence start/data in a loop.
+ *
+ * @name:         device's name to search
+ * @channel_mask: channel selection - a bit mask
+ * @channels:     pointer to conversion output data for the selected channels
+ * @return:       0 if OK, -ve on error
+ */
+int adc_channels_single_shot(const char *name, unsigned int channel_mask,
+                            struct adc_channel *channels);
+
+/**
+ * adc_vdd_value() - get the ADC device's positive reference Voltage value
+ *
+ * Note: Depending on bool value 'vdd_supply_is_negative' of platform data,
+ * the returned uV value can be negative, and it's not an error.
+ *
+ * @dev:     ADC device to check
+ * @uV:      Voltage value with polarization sign (uV)
+ * @return:  0 on success or -ve on error
+*/
+int adc_vdd_value(struct udevice *dev, int *uV);
+
+/**
+ * adc_vss_value() - get the ADC device's negative reference Voltage value
+ *
+ * Note: Depending on bool value 'vdd_supply_is_negative' of platform data,
+ * the returned uV value can be negative, and it's not an error.
+ *
+ * @dev:     ADC device to check
+ * @uV:      Voltage value with polarization sign (uV)
+ * @return:  0 on success or -ve on error
+*/
+int adc_vss_value(struct udevice *dev, int *uV);
+
+/**
+ * adc_stop() - stop operation for given ADC device.
+ *
+ * @dev:     ADC device to stop
+ * @return:  0 if OK, -ve on error
+ */
+int adc_stop(struct udevice *dev);
+
+#endif
include/dm/uclass-id.h +1 -1
index 886a44c..d0cf4ce 100644
@@ -25,6 +25,7 @@ enum uclass_id {
        UCLASS_SIMPLE_BUS,      /* bus with child devices */
 
        /* U-Boot uclasses start here - in alphabetical order */
+       UCLASS_ADC,             /* Analog-to-digital converter */
        UCLASS_CLK,             /* Clock source, e.g. used by peripherals */
        UCLASS_CPU,             /* CPU, typically part of an SoC */
        UCLASS_CROS_EC,         /* Chrome OS EC */
--
Quoted 2 lines

1.9.1

Regards,
Simon

#87 lore raw

PATCH v3 8/14 dm: adc: add Exynos54xx compatible ADC driver

In reply to Przemyslaw Marczak

This commit adds driver for Exynos54xx ADC subsystem.

The driver is implemented using driver model, amd provides ADC uclass's methods for ADC single channel operations:
- adc_start_channel()
- adc_channel_data()
- adc_stop()

The basic parameters of ADC conversion, are:
- sample rate: 600KSPS
- output the data as average of 8 time conversion

ADC features:
- sample rate: 600KSPS
- resolution: 12-bit
- channels: 10 (analog multiplexer)

---
Changes V2:
- new commit - move previous adc driver from SoC directory to drivers/adc Changes V3:
- rework the driver to fit new API
- remove call to sdelay() from driver's code
- add active_channel to keep consistency between ADC request and result

---
 arch/arm/mach-exynos/include/mach/adc.h |  44 ++++++++++
 drivers/adc/Kconfig                     |   9 ++
 drivers/adc/Makefile                    |   1 +
 drivers/adc/exynos-adc.c                | 145 ++++++++++++++++++++++++++++++++
 4 files changed, 199 insertions(+)
 create mode 100644 drivers/adc/exynos-adc.c
arch/arm/mach-exynos/include/mach/adc.h +44 -0
index a0e26d7..9af51ab 100644
@@ -9,6 +9,39 @@
 #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_MASK	0xf
+#define ADC_V2_CON2_CHAN_SEL(x)		((x) & ADC_V2_CON2_CHAN_SEL_MASK)
+
+#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 +54,17 @@ 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;
+};
 #endif
 
 #endif /* __ASM_ARM_ARCH_ADC_H_ */
drivers/adc/Kconfig +9 -0
index b6e226a..223b65e 100644
@@ -10,3 +10,12 @@ config ADC
 	  - methods for get Vdd/Vss reference Voltage values with polarity
 	  - support supply's phandle with auto-enable
 	  - supply polarity setting in fdt
+
+config ADC_EXYNOS
+	bool "Enable Exynos 54xx ADC driver"
+	help
+	  This enables basic driver for Exynos ADC compatible with Exynos54xx.
+	  It provides:
+	  - 10 analog input channels
+	  - 12-bit resolution
+	  - 600 KSPS of sample rate
drivers/adc/Makefile +1 -0
index c4d9618..eb85b8b 100644
@@ -6,3 +6,4 @@
 #
 
 obj-$(CONFIG_ADC) += adc-uclass.o
+obj-$(CONFIG_ADC_EXYNOS) += exynos-adc.o
drivers/adc/exynos-adc.c new file +145 -0

145 lines not on this page · raw message

Signature · 1 line
1.9.1
#88 lore raw

PATCH v3 8/14 dm: adc: add Exynos54xx compatible ADC driver

Quoted 27 lines · Przemyslaw Marczak

This commit adds driver for Exynos54xx ADC subsystem.

The driver is implemented using driver model, amd provides ADC uclass's methods for ADC single channel operations:
- adc_start_channel()
- adc_channel_data()
- adc_stop()

The basic parameters of ADC conversion, are:
- sample rate: 600KSPS
- output the data as average of 8 time conversion

ADC features:
- sample rate: 600KSPS
- resolution: 12-bit
- channels: 10 (analog multiplexer)

---
Changes V2:
- new commit - move previous adc driver from SoC directory to drivers/adc Changes V3:
- rework the driver to fit new API
- remove call to sdelay() from driver's code
- add active_channel to keep consistency between ADC request and result

Quoted 8 lines
---
 arch/arm/mach-exynos/include/mach/adc.h |  44 ++++++++++
 drivers/adc/Kconfig                     |   9 ++
 drivers/adc/Makefile                    |   1 +
 drivers/adc/exynos-adc.c                | 145 ++++++++++++++++++++++++++++++++
 4 files changed, 199 insertions(+)
 create mode 100644 drivers/adc/exynos-adc.c

Some things below.

Quoted 15 lines
arch/arm/mach-exynos/include/mach/adc.h +7 -0
index a0e26d7..9af51ab 100644
@@ -9,6 +9,39 @@
 #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)

arch/arm/mach-exynos/include/mach/adc.h line 28

Quoted 10 lines
arch/arm/mach-exynos/include/mach/adc.h +10 -0
+#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_MASK      0xf
+#define ADC_V2_CON2_CHAN_SEL(x)                ((x) & ADC_V2_CON2_CHAN_SEL_MASK)
+
+#define ADC_V2_GET_STATUS_FLAG(x)      (((x) >> 2) & 0x1)

Can you please avoid these sorts of macro accessors? Instead define:

#define ADC_V2_STATUS_SHIFT 2
#define ADC_V2_STATUS_MASK (1 << ADC_V2_STATUS_SHIFT)

and then you can put the access directly in the code.

Quoted 69 lines
arch/arm/mach-exynos/include/mach/adc.h +27 -0
+#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 +54,17 @@ 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;
+};
 #endif
 
 #endif /* __ASM_ARM_ARCH_ADC_H_ */
drivers/adc/Kconfig +9 -0
index b6e226a..223b65e 100644
@@ -10,3 +10,12 @@ config ADC
          - methods for get Vdd/Vss reference Voltage values with polarity
          - support supply's phandle with auto-enable
          - supply polarity setting in fdt
+
+config ADC_EXYNOS
+       bool "Enable Exynos 54xx ADC driver"
+       help
+         This enables basic driver for Exynos ADC compatible with Exynos54xx.
+         It provides:
+         - 10 analog input channels
+         - 12-bit resolution
+         - 600 KSPS of sample rate
drivers/adc/Makefile +1 -0
index c4d9618..eb85b8b 100644
@@ -6,3 +6,4 @@
 #
 
 obj-$(CONFIG_ADC) += adc-uclass.o
+obj-$(CONFIG_ADC_EXYNOS) += exynos-adc.o
drivers/adc/exynos-adc.c new file +0 -0
new file mode 100644
index 0000000..534e68d

drivers/adc/exynos-adc.c line 10

Quoted 10 lines
drivers/adc/exynos-adc.c new file +10 -0
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics
+ * Przemyslaw Marczak <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#include <common.h>
+#include <errno.h>
+#include <dm.h>
+#include <adc.h>

That should go below common.h

Quoted 27 lines
drivers/adc/exynos-adc.c new file +27 -0
+#include <asm/arch/adc.h>
+
+struct exynos_adc_priv {
+       int active_channel;
+       struct exynos_adc_v2 *regs;
+};
+
+int exynos_adc_channel_data(struct udevice *dev, int channel,
+                           unsigned int *data)
+{
+       struct exynos_adc_priv *priv = dev_get_priv(dev);
+       struct exynos_adc_v2 *regs = priv->regs;
+
+       if (channel != priv->active_channel) {
+               error("Requested channel is not active!");
+               return -EINVAL;
+       }
+
+       if (ADC_V2_GET_STATUS_FLAG(readl(&regs->status)) != FLAG_CONV_END)
+               return -EBUSY;
+
+       *data = readl(&regs->dat) & ADC_V2_DAT_MASK;
+
+       return 0;
+}
+
+int exynos_adc_start_channel(struct udevice *dev, int channel)

drivers/adc/exynos-adc.c line 47

Quoted 10 lines
drivers/adc/exynos-adc.c new file +10 -0
+{
+       struct exynos_adc_priv *priv = dev_get_priv(dev);
+       struct exynos_adc_v2 *regs = priv->regs;
+       unsigned int cfg;
+
+       /* Choose channel */
+       cfg = readl(&regs->con2);
+       cfg &= ~ADC_V2_CON2_CHAN_SEL_MASK;
+       cfg |= ADC_V2_CON2_CHAN_SEL(channel);
+       writel(cfg, &regs->con2);

Can you use:

clrsetbits_le32(&regs->con2, ADC_V2_CON2_CHAN_SEL_MASK, ADC_V2_CON2_CHAN_SEL(channel))

drivers/adc/exynos-adc.c line 51

Quoted 4 lines
drivers/adc/exynos-adc.c new file +4 -0
+
+       /* Start conversion */
+       cfg = readl(&regs->con1);
+       writel(cfg | ADC_V2_CON1_STC_EN, &regs->con1);

setbits_le32

Quoted 7 lines
drivers/adc/exynos-adc.c new file +7 -0
+
+       priv->active_channel = channel;
+
+       return 0;
+}
+
+int exynos_adc_stop(struct udevice *dev)

drivers/adc/exynos-adc.c line 68

Quoted 10 lines
drivers/adc/exynos-adc.c new file +10 -0
+{
+       struct exynos_adc_priv *priv = dev_get_priv(dev);
+       struct exynos_adc_v2 *regs = priv->regs;
+       unsigned int cfg;
+
+       /* Stop conversion */
+       cfg = readl(&regs->con1);
+       cfg |= ~ADC_V2_CON1_STC_EN;
+
+       writel(cfg, &regs->con1);

clrbits_le32

etc.

Quoted 78 lines
drivers/adc/exynos-adc.c new file +77 -1
+
+       priv->active_channel = -1;
+
+       return 0;
+}
+
+int exynos_adc_probe(struct udevice *dev)
+{
+       struct exynos_adc_priv *priv = dev_get_priv(dev);
+       struct exynos_adc_v2 *regs = priv->regs;
+       unsigned int cfg;
+
+       /* Check HW version */
+       if (readl(&regs->version) != ADC_V2_VERSION) {
+               error("This driver supports only ADC v2!");
+               return -ENXIO;
+       }
+
+       /* ADC Reset */
+       writel(ADC_V2_CON1_SOFT_RESET, &regs->con1);
+
+       /* Disable INT - will read status only */
+       writel(0x0, &regs->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_ESEL(ESEL_ADC_EVAL_TIME_20CLK);
+       cfg |= ADC_V2_CON2_HIGHF(HIGHF_CONV_RATE_600KSPS);
+       writel(cfg, &regs->con2);
+
+       priv->active_channel = -1;
+
+       return 0;
+}
+
+int exynos_adc_ofdata_to_platdata(struct udevice *dev)
+{
+       struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
+       struct exynos_adc_priv *priv = dev_get_priv(dev);
+
+       priv->regs = (struct exynos_adc_v2 *)dev_get_addr(dev);
+       if (priv->regs == (struct exynos_adc_v2 *)FDT_ADDR_T_NONE) {
+               error("Dev: %s - can't get address!", dev->name);
+               return -ENODATA;
+       }
+
+       uc_pdata->data_mask = ADC_V2_DAT_MASK;
+       uc_pdata->data_format = ADC_DATA_FORMAT_BIN;
+       uc_pdata->data_timeout_us = ADC_V2_CONV_TIMEOUT_US;
+
+       /* Mask available channel bits: [0:9] */
+       uc_pdata->channel_mask = (2 << ADC_V2_MAX_CHANNEL) - 1;
+
+       return 0;
+}
+
+static const struct adc_ops exynos_adc_ops = {
+       .start_channel = exynos_adc_start_channel,
+       .channel_data = exynos_adc_channel_data,
+       .stop = exynos_adc_stop,
+};
+
+static const struct udevice_id exynos_adc_ids[] = {
+       { .compatible = "samsung,exynos-adc-v2" },
+       { }
+};
+
+U_BOOT_DRIVER(exynos_adc) = {
+       .name           = "exynos-adc",
+       .id             = UCLASS_ADC,
+       .of_match       = exynos_adc_ids,
+       .ops            = &exynos_adc_ops,
+       .probe          = exynos_adc_probe,
+       .ofdata_to_platdata = exynos_adc_ofdata_to_platdata,
+       .priv_auto_alloc_size = sizeof(struct exynos_adc_priv),
+};
--
Quoted 2 lines

1.9.1

Regards,
Simon

#89 lore raw

PATCH v3 9/14 Odroid-XU3: enable s2mps11 PMIC support

In reply to Przemyslaw Marczak

---
Changes V2:
- none
Chabges V3:
- fix merge conflict in configs/odroid-xu3_defconfig

---
 arch/arm/dts/exynos5422-odroidxu3.dts | 7 +++++++
 configs/odroid-xu3_defconfig          | 3 +++
 2 files changed, 10 insertions(+)
arch/arm/dts/exynos5422-odroidxu3.dts +7 -0
index d0a8621..9dec679 100644
@@ -31,6 +31,13 @@
 			0xb0000000 0xea00000>;
 	};
 
+	i2c at 12CA0000 {
+		s2mps11_pmic at 66 {
+			compatible = "samsung,s2mps11-pmic";
+			reg = <0x66>;
+		};
+	};
+
 	ehci at 12110000 {
 		samsung,vbus-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>;
 	};
configs/odroid-xu3_defconfig +3 -0
index 479af9e..780dcab 100644
@@ -9,7 +9,10 @@ CONFIG_SYS_PROMPT="ODROID-XU3 # "
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_DM_I2C_COMPAT=y
 CONFIG_DM_PMIC=y
+CONFIG_CMD_PMIC=y
+CONFIG_ERRNO_STR=y
 CONFIG_DM_REGULATOR=y
+CONFIG_PMIC_S2MPS11=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_VIDEO_BRIDGE=y
Signature · 1 line
1.9.1
#90 lore raw

PATCH v3 9/14 Odroid-XU3: enable s2mps11 PMIC support

hi,

Quoted 47 lines · Przemyslaw Marczak

---
Changes V2:
- none
Chabges V3:
- fix merge conflict in configs/odroid-xu3_defconfig

---
 arch/arm/dts/exynos5422-odroidxu3.dts | 7 +++++++
 configs/odroid-xu3_defconfig          | 3 +++
 2 files changed, 10 insertions(+)
arch/arm/dts/exynos5422-odroidxu3.dts +7 -0
index d0a8621..9dec679 100644
@@ -31,6 +31,13 @@
                        0xb0000000 0xea00000>;
        };
 
+       i2c at 12CA0000 {
+               s2mps11_pmic at 66 {
+                       compatible = "samsung,s2mps11-pmic";
+                       reg = <0x66>;
+               };
+       };
+
        ehci at 12110000 {
                samsung,vbus-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>;
        };
configs/odroid-xu3_defconfig +3 -1
index 479af9e..780dcab 100644
@@ -9,7 +9,10 @@ CONFIG_SYS_PROMPT="ODROID-XU3 # "
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_DM_I2C_COMPAT=y
 CONFIG_DM_PMIC=y
+CONFIG_CMD_PMIC=y
+CONFIG_ERRNO_STR=y
 CONFIG_DM_REGULATOR=y
+CONFIG_PMIC_S2MPS11=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_VIDEO_BRIDGE=y
--
Quoted 2 lines

1.9.1

-Anand Moon

#91 lore raw

PATCH v3 10/14 Exynos54xx: dts: add ADC node

In reply to Przemyslaw Marczak

This commit adds common ADC node, which is disabled as default.

---
Changes V2:
- new commit

---
 arch/arm/dts/exynos54xx.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)
arch/arm/dts/exynos54xx.dtsi +7 -0
index bd3619d..daa6a33 100644
@@ -42,6 +42,13 @@
 		xhci1 = "/xhci at 12400000";
 	};
 
+	adc at 12D10000 {
+		compatible = "samsung,exynos-adc-v2";
+		reg = <0x12D10000 0x100>;
+		interrupts = <0 106 0>;
+		status = "disabled";
+	};
+
 	i2c at 12CA0000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
Signature · 1 line
1.9.1
#92 lore raw

PATCH v3 10/14 Exynos54xx: dts: add ADC node

Quoted 8 lines · Przemyslaw Marczak

This commit adds common ADC node, which is disabled as default.

---
Changes V2:
- new commit

This does not look like a new commit.

Quoted 25 lines
---
 arch/arm/dts/exynos54xx.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)
arch/arm/dts/exynos54xx.dtsi +7 -1
index bd3619d..daa6a33 100644
@@ -42,6 +42,13 @@
                xhci1 = "/xhci at 12400000";
        };
 
+       adc at 12D10000 {
+               compatible = "samsung,exynos-adc-v2";
+               reg = <0x12D10000 0x100>;
+               interrupts = <0 106 0>;
+               status = "disabled";
+       };
+
        i2c at 12CA0000 {
                #address-cells = <1>;
                #size-cells = <0>;
--

1.9.1

#93 lore raw

PATCH v3 10/14 Exynos54xx: dts: add ADC node

Hi Simon,

Quoted 10 lines · Simon Glass
Quoted 8 lines · Przemyslaw Marczak

This commit adds common ADC node, which is disabled as default.

---
Changes V2:
- new commit

Quoted 4 lines

This does not look like a new commit.

This is V3, and the commit was new in V2.
I didn't edit commit message if no changes made in V3.

Quoted 12 lines
Quoted 12 lines
---
  arch/arm/dts/exynos54xx.dtsi | 7 +++++++
  1 file changed, 7 insertions(+)
arch/arm/dts/exynos54xx.dtsi +0 -0
index bd3619d..daa6a33 100644
@@ -42,6 +42,13 @@
                 xhci1 = "/xhci at 12400000";
         };
 
Quoted 14 lines
Quoted 11 lines
arch/arm/dts/exynos54xx.dtsi +7 -1
+       adc at 12D10000 {
+               compatible = "samsung,exynos-adc-v2";
+               reg = <0x12D10000 0x100>;
+               interrupts = <0 106 0>;
+               status = "disabled";
+       };
+
         i2c at 12CA0000 {
                 #address-cells = <1>;
                 #size-cells = <0>;
--
Quoted 2 lines

1.9.1

Thank you for review.
Are you going to review the rest of patches (11-14)?

Best regards,

Signature · 4 lines
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com
#94 lore raw

PATCH v3 10/14 Exynos54xx: dts: add ADC node

Hi Przemyslaw,

Quoted 52 lines · Przemyslaw Marczak

Hi Simon,

Quoted 14 lines · Simon Glass
Quoted 9 lines · Przemyslaw Marczak

This commit adds common ADC node, which is disabled as default.

---
Changes V2:
- new commit

Quoted 4 lines

This does not look like a new commit.

This is V3, and the commit was new in V2.
I didn't edit commit message if no changes made in V3.

Quoted 12 lines
Quoted 12 lines
---
  arch/arm/dts/exynos54xx.dtsi | 7 +++++++
  1 file changed, 7 insertions(+)
arch/arm/dts/exynos54xx.dtsi +0 -0
index bd3619d..daa6a33 100644
@@ -42,6 +42,13 @@
                 xhci1 = "/xhci at 12400000";
         };
 
Quoted 14 lines
Quoted 11 lines
arch/arm/dts/exynos54xx.dtsi +7 -1
+       adc at 12D10000 {
+               compatible = "samsung,exynos-adc-v2";
+               reg = <0x12D10000 0x100>;
+               interrupts = <0 106 0>;
+               status = "disabled";
+       };
+
         i2c at 12CA0000 {
                 #address-cells = <1>;
                 #size-cells = <0>;
--
Quoted 2 lines

1.9.1

Quoted 2 lines

Thank you for review.
Are you going to review the rest of patches (11-14)?

I just took a look now and made a few comments.

Regards,
Simon

#95 lore raw

PATCH v3 10/14 Exynos54xx: dts: add ADC node

Hello Simon,

Quoted 55 lines · Simon Glass

Hi Przemyslaw,

Quoted 52 lines · Przemyslaw Marczak

Hi Simon,

Quoted 14 lines · Simon Glass
Quoted 9 lines · Przemyslaw Marczak

This commit adds common ADC node, which is disabled as default.

---
Changes V2:
- new commit

Quoted 4 lines

This does not look like a new commit.

This is V3, and the commit was new in V2.
I didn't edit commit message if no changes made in V3.

Quoted 26 lines
Quoted 25 lines
---
   arch/arm/dts/exynos54xx.dtsi | 7 +++++++
   1 file changed, 7 insertions(+)
arch/arm/dts/exynos54xx.dtsi +7 -1
index bd3619d..daa6a33 100644
@@ -42,6 +42,13 @@
                  xhci1 = "/xhci at 12400000";
          };
 
+       adc at 12D10000 {
+               compatible = "samsung,exynos-adc-v2";
+               reg = <0x12D10000 0x100>;
+               interrupts = <0 106 0>;
+               status = "disabled";
+       };
+
          i2c at 12CA0000 {
                  #address-cells = <1>;
                  #size-cells = <0>;
--

1.9.1

Quoted 8 lines
Quoted 2 lines

Thank you for review.
Are you going to review the rest of patches (11-14)?

I just took a look now and made a few comments.

Regards,
Simon

Thank you for the review again, but this patchset was applied to u-boot-samsung four days ago and yesterday the pull request was send. Now I can see that, it's merged to master.

Your comments are cosmetic only, so I can send the cleanup as a separated patch set.

Best regards,

Signature · 4 lines
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com
#96 lore raw

PATCH v3 11/14 Odroid-XU3: dts: enable ADC, with request for pre-reloc bind

In reply to Przemyslaw Marczak

This ADC is required for Odroid's board revision detection. The pre-reloc request is enabled, since board detection will be done in one of early function call.

---
Changes V2:
- new commit

---
 arch/arm/dts/exynos5422-odroidxu3.dts | 5 +++++
 1 file changed, 5 insertions(+)
arch/arm/dts/exynos5422-odroidxu3.dts +5 -0
index 9dec679..690c747 100644
@@ -31,6 +31,11 @@
 			0xb0000000 0xea00000>;
 	};
 
+	adc at 12D10000 {
+		u-boot,dm-pre-reloc;
+		status = "okay";
+	};
+
 	i2c at 12CA0000 {
 		s2mps11_pmic at 66 {
 			compatible = "samsung,s2mps11-pmic";
Signature · 1 line
1.9.1
#97 lore raw

PATCH v3 12/14 exynos5-dt-types: add board detection for Odroid XU3/XU3L/XU4.

In reply to Przemyslaw Marczak

This commit adds additional file with implementation of board detection code for Odroid-XU3/XU4.

The detection depends on compatible found in fdt:
- "samsung,exynos5" - uses Exynos5 generic code
- "samsung,odroidxu3" - try detect XU3 revision

There are few revisions of Odroid XU3/XU4, each can be detected by checking the value of channel 9 of built-in ADC:

 Rev   ADC  Board
 0.1     0  XU3 0.1
 0.2   372  XU3 0.2 | XU3L - no DISPLAYPORT
 0.3  1280  XU4 0.1

The detection code depends on the ADC+10% value.

Implementation of functions:

- set_board_type()     - read ADC and set type
- get_board_rev()      - returns board revision: 1..3
- get_board_type()     - returns board type string

Additional functions with return values of bool:
- board_is_generic() - true if found compatible "samsung,exynos5"
but not "samsung,odroidxu3"
- board_is_odroidxu3() - true if found compatible "samsung,odroidxu3" and one of XU3 revision.
- board_is_odroidxu4() - true if found compatible "samsung,odroidxu3" and XU4 revision.

After I2C controller init, the get_board_type() can check if the XU3 board is a "Lite" variant, by probing chip 0x40 on I2C0 (INA231 - exists only on non-lite). This is useful for setting fdt file name at misc_init_r().

Enabled configs:
- CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
- CONFIG_ODROID_REV_AIN
- CONFIG_REVISION_TAG
- CONFIG_BOARD_TYPES

---
Changes V2:
- move detection code from exynos5-dt.c to exynos5-dt-types.c
- add header with board type function declarations
- check for compatible before do the detection
- update the ADC max values with 20% tolerance
- fix XU4 adc value, related to mistake from table in XU4 schematic
- return "Not supported" for XU4 when calls one of:
--dfu_get_alt_boot()
--dfu_get_alt_system()
- extend ${dfu_alt_system} by strings:
-- 'exynos5422-odroidxu3-lite.dtb'
-- 'exynos5422-odroidxu4.dtb' - allows prepare card on XU3

Changes V3:
- fix merge conflict in: configs/odroid-xu3_defconfig

---
 board/samsung/common/Makefile           |   5 +-
 board/samsung/common/exynos5-dt-types.c | 196 ++++++++++++++++++++++++++++++++
 board/samsung/common/exynos5-dt.c       |  12 ++
 configs/odroid-xu3_defconfig            |   2 +
 include/configs/odroid_xu3.h            |  12 ++
 include/samsung/exynos5-dt-types.h      |  27 +++++
 6 files changed, 253 insertions(+), 1 deletion(-)
 create mode 100644 board/samsung/common/exynos5-dt-types.c
 create mode 100644 include/samsung/exynos5-dt-types.h
board/samsung/common/Makefile +4 -1
index 6cbd906..ef1a8f3 100644
@@ -11,5 +11,8 @@ obj-$(CONFIG_MISC_COMMON) += misc.o
 
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_BOARD_COMMON)	+= board.o
-obj-$(CONFIG_EXYNOS5_DT)	+= exynos5-dt.o
+ifdef CONFIG_EXYNOS5_DT
+obj-y += exynos5-dt.o
+obj-$(CONFIG_BOARD_TYPES) += exynos5-dt-types.o
+endif
 endif
board/samsung/common/exynos5-dt-types.c new file +196 -0

196 lines not on this page · raw message

board/samsung/common/exynos5-dt.c +12 -0
index 4250f72..4d9e151 100644
@@ -27,7 +27,10 @@
 #include <power/pmic.h>
 #include <power/max77686_pmic.h>
 #include <power/regulator.h>
+#include <power/s2mps11.h>
 #include <power/s5m8767.h>
+#include <samsung/exynos5-dt-types.h>
+#include <samsung/misc.h>
 #include <tmu.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -335,15 +338,24 @@ int board_usb_init(int index, enum usb_init_type init)
 #ifdef CONFIG_SET_DFU_ALT_INFO
 char *get_dfu_alt_system(char *interface, char *devstr)
 {
+	char *info = "Not supported!";
+
+	if (board_is_odroidxu4())
+		return info;
+
 	return getenv("dfu_alt_system");
 }
 
 char *get_dfu_alt_boot(char *interface, char *devstr)
 {
+	char *info = "Not supported!";
 	struct mmc *mmc;
 	char *alt_boot;
 	int dev_num;
 
+	if (board_is_odroidxu4())
+		return info;
+
 	dev_num = simple_strtoul(devstr, NULL, 10);
 
 	mmc = find_mmc_device(dev_num);
configs/odroid-xu3_defconfig +2 -0
index 780dcab..4ab91fa 100644
@@ -16,3 +16,5 @@ CONFIG_PMIC_S2MPS11=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_VIDEO_BRIDGE=y
+CONFIG_ADC=y
+CONFIG_ADC_EXYNOS=y
include/configs/odroid_xu3.h +12 -0
index 3c70158..648e48b 100644
@@ -94,6 +94,8 @@
 	"boot.scr fat 0 1;"                 \
 	"boot.cmd fat 0 1;"                 \
 	"exynos5422-odroidxu3.dtb fat 0 1;" \
+	"exynos5422-odroidxu3-lite.dtb fat 0 1;" \
+	"exynos5422-odroidxu4.dtb fat 0 1;" \
 	"boot part 0 1;"                    \
 	"root part 0 2\0"
 
@@ -113,9 +115,19 @@
 
 /* Enable: board/samsung/common/misc.c to use set_dfu_alt_info() */
 #define CONFIG_MISC_COMMON
+#define CONFIG_MISC_INIT_R
 #define CONFIG_SET_DFU_ALT_INFO
 #define CONFIG_SET_DFU_ALT_BUF_LEN	(SZ_1K)
 
+/* Set soc_rev, soc_id, board_rev, boardname, fdtfile */
+#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
+#define CONFIG_ODROID_REV_AIN			9
+#define CONFIG_REVISION_TAG
+#define CONFIG_BOARD_TYPES
+
+#undef CONFIG_SYS_BOARD
+#define CONFIG_SYS_BOARD	"odroid"
+
 /* Define new extra env settings, including DFU settings */
 #undef CONFIG_EXTRA_ENV_SETTINGS
 #define CONFIG_EXTRA_ENV_SETTINGS \
include/samsung/exynos5-dt-types.h new file +27 -0
new file mode 100644
index 0000000..479e2e7
@@ -0,0 +1,27 @@
+#ifndef _EXYNOS5_DT_H_
+#define _EXYNOS5_DT_H_
+
+enum {
+	EXYNOS5_BOARD_GENERIC,
+
+	EXYNOS5_BOARD_ODROID_XU3,
+	EXYNOS5_BOARD_ODROID_XU3_REV01,
+	EXYNOS5_BOARD_ODROID_XU3_REV02,
+	EXYNOS5_BOARD_ODROID_XU4_REV01,
+	EXYNOS5_BOARD_ODROID_UNKNOWN,
+
+	EXYNOS5_BOARD_COUNT,
+};
+
+struct odroid_rev_info {
+	int board_type;
+	int board_rev;
+	int adc_val;
+	const char *name;
+};
+
+bool board_is_generic(void);
+bool board_is_odroidxu3(void);
+bool board_is_odroidxu4(void);
+
+#endif
Signature · 1 line
1.9.1
#98 lore raw

PATCH v3 12/14 exynos5-dt-types: add board detection for Odroid XU3/XU3L/XU4.

hi,

Quoted 403 lines · Przemyslaw Marczak

This commit adds additional file with implementation of board detection code for Odroid-XU3/XU4.

The detection depends on compatible found in fdt:
- "samsung,exynos5" - uses Exynos5 generic code
- "samsung,odroidxu3" - try detect XU3 revision

There are few revisions of Odroid XU3/XU4, each can be detected by checking the value of channel 9 of built-in ADC:

 Rev   ADC  Board
 0.1     0  XU3 0.1
 0.2   372  XU3 0.2 | XU3L - no DISPLAYPORT
 0.3  1280  XU4 0.1

The detection code depends on the ADC+10% value.

Implementation of functions:

- set_board_type()     - read ADC and set type
- get_board_rev()      - returns board revision: 1..3
- get_board_type()     - returns board type string

Additional functions with return values of bool:
- board_is_generic() - true if found compatible "samsung,exynos5"
but not "samsung,odroidxu3"
- board_is_odroidxu3() - true if found compatible "samsung,odroidxu3" and one of XU3 revision.
- board_is_odroidxu4() - true if found compatible "samsung,odroidxu3" and XU4 revision.

After I2C controller init, the get_board_type() can check if the XU3 board is a "Lite" variant, by probing chip 0x40 on I2C0 (INA231 - exists only on non-lite). This is useful for setting fdt file name at misc_init_r().

Enabled configs:
- CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
- CONFIG_ODROID_REV_AIN
- CONFIG_REVISION_TAG
- CONFIG_BOARD_TYPES

---
Changes V2:
- move detection code from exynos5-dt.c to exynos5-dt-types.c
- add header with board type function declarations
- check for compatible before do the detection
- update the ADC max values with 20% tolerance
- fix XU4 adc value, related to mistake from table in XU4 schematic
- return "Not supported" for XU4 when calls one of:
--dfu_get_alt_boot()
--dfu_get_alt_system()
- extend ${dfu_alt_system} by strings:
-- 'exynos5422-odroidxu3-lite.dtb'
-- 'exynos5422-odroidxu4.dtb' - allows prepare card on XU3

Changes V3:
- fix merge conflict in: configs/odroid-xu3_defconfig

---
 board/samsung/common/Makefile           |   5 +-
 board/samsung/common/exynos5-dt-types.c | 196 ++++++++++++++++++++++++++++++++
 board/samsung/common/exynos5-dt.c       |  12 ++
 configs/odroid-xu3_defconfig            |   2 +
 include/configs/odroid_xu3.h            |  12 ++
 include/samsung/exynos5-dt-types.h      |  27 +++++
 6 files changed, 253 insertions(+), 1 deletion(-)
 create mode 100644 board/samsung/common/exynos5-dt-types.c
 create mode 100644 include/samsung/exynos5-dt-types.h
board/samsung/common/Makefile +4 -1
index 6cbd906..ef1a8f3 100644
@@ -11,5 +11,8 @@ obj-$(CONFIG_MISC_COMMON) += misc.o
 
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_BOARD_COMMON)     += board.o
-obj-$(CONFIG_EXYNOS5_DT)       += exynos5-dt.o
+ifdef CONFIG_EXYNOS5_DT
+obj-y += exynos5-dt.o
+obj-$(CONFIG_BOARD_TYPES) += exynos5-dt-types.o
+endif
 endif
board/samsung/common/exynos5-dt-types.c new file +196 -0
new file mode 100644
index 0000000..48fd1f7
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics
+ * Przemyslaw Marczak <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <adc.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <power/pmic.h>
+#include <power/regulator.h>
+#include <power/s2mps11.h>
+#include <samsung/exynos5-dt-types.h>
+#include <samsung/misc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const struct udevice_id board_ids[] = {
+       { .compatible = "samsung,odroidxu3", .data = EXYNOS5_BOARD_ODROID_XU3 },
+       { .compatible = "samsung,exynos5", .data = EXYNOS5_BOARD_GENERIC },
+       { },
+};
+
+/**
+ * Odroix XU3/4 board revisions:
+ * Rev   ADCmax  Board
+ * 0.1     0     XU3 0.1
+ * 0.2   410     XU3 0.2 | XU3L - no DISPLAYPORT (probe I2C0:0x40 / INA231)
+ * 0.3  1408     XU4 0.1
+ * Use +10 % for ADC value tolerance.
+ */
+struct odroid_rev_info odroid_info[] = {
+       { EXYNOS5_BOARD_ODROID_XU3_REV01, 1, 10, "xu3" },
+       { EXYNOS5_BOARD_ODROID_XU3_REV02, 2, 410, "xu3" },
+       { EXYNOS5_BOARD_ODROID_XU4_REV01, 1, 1408, "xu4" },
+       { EXYNOS5_BOARD_ODROID_UNKNOWN, 0, 4095, "unknown" },
+};
+
+static unsigned int odroid_get_rev(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(odroid_info); i++) {
+               if (odroid_info[i].board_type == gd->board_type)
+                       return odroid_info[i].board_rev;
+       }
+
+       return 0;
+}
+
+static int odroid_get_board_type(void)
+{
+       unsigned int adcval;
+       int ret, i;
+
+       ret = adc_channel_single_shot("adc", CONFIG_ODROID_REV_AIN, &adcval);
+       if (ret)
+               goto rev_default;
+
+       for (i = 0; i < ARRAY_SIZE(odroid_info); i++) {
+               /* ADC tolerance: +20 % */
+               if (adcval < odroid_info[i].adc_val)
+                       return odroid_info[i].board_type;
+       }
+
+rev_default:
+       return EXYNOS5_BOARD_ODROID_XU3;
+}
+
+/**
+ * odroid_get_type_str - returns pointer to one of the board type string.
+ * Board types: "xu3", "xu3-lite", "xu4". However the "xu3lite" can be
+ * detected only when the i2c controller is ready to use. Fortunately,
+ * XU3 and XU3L are compatible, and the information about board lite
+ * revision is needed before booting the linux, to set proper environment
+ * variable: $fdtfile.
+ */
+static const char *odroid_get_type_str(void)
+{
+       const char *type_xu3l = "xu3-lite";
+       struct udevice *dev, *chip;
+       int i, ret;
+
+       if (gd->board_type != EXYNOS5_BOARD_ODROID_XU3_REV02)
+               goto exit;
+
+       ret = pmic_get("s2mps11", &dev);
+       if (ret)
+               goto exit;
+
+       /* Enable LDO26: 3.0V */
+       ret = pmic_reg_write(dev, S2MPS11_REG_L26CTRL,
+                            S2MPS11_LDO26_ENABLE);
+       if (ret)
+               goto exit;
+
+       /* Check XU3Lite by probe INA231 I2C0:0x40 */
+       ret = uclass_get_device(UCLASS_I2C, 0, &dev);
+       if (ret)
+               goto exit;
+
+       ret = dm_i2c_probe(dev, 0x40, 0x0, &chip);
+       if (ret)
+               return type_xu3l;
+
+exit:
+       for (i = 0; i < ARRAY_SIZE(odroid_info); i++) {
+               if (odroid_info[i].board_type == gd->board_type)
+                       return odroid_info[i].name;
+       }
+
+       return NULL;
+}
+
+bool board_is_odroidxu3(void)
+{
+       if (gd->board_type >= EXYNOS5_BOARD_ODROID_XU3 &&
+           gd->board_type <= EXYNOS5_BOARD_ODROID_XU3_REV02)
+               return true;
+
+       return false;
+}
+
+bool board_is_odroidxu4(void)
+{
+       if (gd->board_type == EXYNOS5_BOARD_ODROID_XU4_REV01)
+               return true;
+
+       return false;
+}
+
+bool board_is_generic(void)
+{
+       if (gd->board_type == EXYNOS5_BOARD_GENERIC)
+               return true;
+
+       return false;
+}
+
+/**
+ * get_board_rev() - return detected board revision.
+ *
+ * @return:  return board revision number for XU3 or 0 for generic
+ */
+u32 get_board_rev(void)
+{
+       if (board_is_generic())
+               return 0;
+
+       return odroid_get_rev();
+}
+
+/**
+ * get_board_type() - returns board type string.
+ *
+ * @return:  return board type string for XU3 or empty string for generic
+ */
+const char *get_board_type(void)
+{
+       const char *generic = "";
+
+       if (board_is_generic())
+               return generic;
+
+       return odroid_get_type_str();
+}
+
+/**
+ * set_board_type() - set board type in gd->board_type.
+ * As default type set EXYNOS5_BOARD_GENERIC, if detect Odroid,
+ * then set its proper type.
+ */
+void set_board_type(void)
+{
+       const struct udevice_id *of_match = board_ids;
+       int ret;
+
+       gd->board_type = EXYNOS5_BOARD_GENERIC;
+
+       while (of_match->compatible) {
+               ret = fdt_node_check_compatible(gd->fdt_blob, 0,
+                                               of_match->compatible);
+               if (ret)
+                       of_match++;
+
+               gd->board_type = of_match->data;
+               break;
+       }
+
+       /* If Odroid, then check its revision */
+       if (board_is_odroidxu3())
+               gd->board_type = odroid_get_board_type();
+}
board/samsung/common/exynos5-dt.c +12 -0
index 4250f72..4d9e151 100644
@@ -27,7 +27,10 @@
 #include <power/pmic.h>
 #include <power/max77686_pmic.h>
 #include <power/regulator.h>
+#include <power/s2mps11.h>
 #include <power/s5m8767.h>
+#include <samsung/exynos5-dt-types.h>
+#include <samsung/misc.h>
 #include <tmu.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -335,15 +338,24 @@ int board_usb_init(int index, enum usb_init_type init)
 #ifdef CONFIG_SET_DFU_ALT_INFO
 char *get_dfu_alt_system(char *interface, char *devstr)
 {
+       char *info = "Not supported!";
+
+       if (board_is_odroidxu4())
+               return info;
+
        return getenv("dfu_alt_system");
 }
 
 char *get_dfu_alt_boot(char *interface, char *devstr)
 {
+       char *info = "Not supported!";
        struct mmc *mmc;
        char *alt_boot;
        int dev_num;
 
+       if (board_is_odroidxu4())
+               return info;
+
        dev_num = simple_strtoul(devstr, NULL, 10);
 
        mmc = find_mmc_device(dev_num);
configs/odroid-xu3_defconfig +2 -0
index 780dcab..4ab91fa 100644
@@ -16,3 +16,5 @@ CONFIG_PMIC_S2MPS11=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_VIDEO_BRIDGE=y
+CONFIG_ADC=y
+CONFIG_ADC_EXYNOS=y
include/configs/odroid_xu3.h +12 -0
index 3c70158..648e48b 100644
@@ -94,6 +94,8 @@
        "boot.scr fat 0 1;"                 \
        "boot.cmd fat 0 1;"                 \
        "exynos5422-odroidxu3.dtb fat 0 1;" \
+       "exynos5422-odroidxu3-lite.dtb fat 0 1;" \
+       "exynos5422-odroidxu4.dtb fat 0 1;" \
        "boot part 0 1;"                    \
        "root part 0 2\0"
 
@@ -113,9 +115,19 @@
 
 /* Enable: board/samsung/common/misc.c to use set_dfu_alt_info() */
 #define CONFIG_MISC_COMMON
+#define CONFIG_MISC_INIT_R
 #define CONFIG_SET_DFU_ALT_INFO
 #define CONFIG_SET_DFU_ALT_BUF_LEN     (SZ_1K)
 
+/* Set soc_rev, soc_id, board_rev, boardname, fdtfile */
+#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
+#define CONFIG_ODROID_REV_AIN                  9
+#define CONFIG_REVISION_TAG
+#define CONFIG_BOARD_TYPES
+
+#undef CONFIG_SYS_BOARD
+#define CONFIG_SYS_BOARD       "odroid"
+
 /* Define new extra env settings, including DFU settings */
 #undef CONFIG_EXTRA_ENV_SETTINGS
 #define CONFIG_EXTRA_ENV_SETTINGS \
include/samsung/exynos5-dt-types.h new file +27 -1
new file mode 100644
index 0000000..479e2e7
@@ -0,0 +1,27 @@
+#ifndef _EXYNOS5_DT_H_
+#define _EXYNOS5_DT_H_
+
+enum {
+       EXYNOS5_BOARD_GENERIC,
+
+       EXYNOS5_BOARD_ODROID_XU3,
+       EXYNOS5_BOARD_ODROID_XU3_REV01,
+       EXYNOS5_BOARD_ODROID_XU3_REV02,
+       EXYNOS5_BOARD_ODROID_XU4_REV01,
+       EXYNOS5_BOARD_ODROID_UNKNOWN,
+
+       EXYNOS5_BOARD_COUNT,
+};
+
+struct odroid_rev_info {
+       int board_type;
+       int board_rev;
+       int adc_val;
+       const char *name;
+};
+
+bool board_is_generic(void);
+bool board_is_odroidxu3(void);
+bool board_is_odroidxu4(void);
+
+#endif
--
Quoted 2 lines

1.9.1

-Anand Moon

#99 lore raw

PATCH v3 13/14 sandbox: add ADC driver

In reply to Przemyslaw Marczak

This commit adds implementation of Sandbox ADC device emulation. The device provides:
- single and multi-channel conversion
- 4 channels with predefined conversion output data
- 16-bit resolution

---
Changes V3:
- new commit

---
 arch/sandbox/dts/sandbox_pmic.dtsi |   2 +-
 arch/sandbox/dts/test.dts          |   6 ++
 configs/sandbox_defconfig          |   2 +
 drivers/adc/Kconfig                |   9 ++
 drivers/adc/Makefile               |   1 +
 drivers/adc/sandbox.c              | 174 +++++++++++++++++++++++++++++++++++++
 6 files changed, 193 insertions(+), 1 deletion(-)
 create mode 100644 drivers/adc/sandbox.c
arch/sandbox/dts/sandbox_pmic.dtsi +1 -1
index 44a26b1..ce261b9 100644
@@ -55,7 +55,7 @@
 		regulator-always-on;
 	};
 
-	buck2 {
+	buck2: buck2 {
 		regulator-name = "SUPPLY_3.3V";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
arch/sandbox/dts/test.dts +6 -0
index 730de8a..e2c4971 100644
@@ -189,6 +189,12 @@
 		};
 	};
 
+	adc at 0 {
+		compatible = "sandbox,adc";
+		vdd-supply = <&buck2>;
+		vss-microvolts = <0>;
+	};
+
 	leds {
 		compatible = "gpio-leds";
 
configs/sandbox_defconfig +2 -0
index 67ae99b..94c8e68 100644
@@ -65,3 +65,5 @@ CONFIG_UT_DM=y
 CONFIG_UT_ENV=y
 CONFIG_REMOTEPROC_SANDBOX=y
 CONFIG_CMD_REMOTEPROC=y
+CONFIG_ADC=y
+CONFIG_ADC_SANDBOX=y
drivers/adc/Kconfig +9 -0
index 223b65e..e5335f7 100644
@@ -19,3 +19,12 @@ config ADC_EXYNOS
 	  - 10 analog input channels
 	  - 12-bit resolution
 	  - 600 KSPS of sample rate
+
+config ADC_SANDBOX
+	bool "Enable Sandbox ADC test driver"
+	help
+	  This enables driver for Sandbox ADC device emulation.
+	  It provides:
+	  - 4 analog input channels
+	  - 16-bit resolution
+	  - single and multi-channel conversion mode
drivers/adc/Makefile +1 -0
index eb85b8b..cebf26d 100644
@@ -7,3 +7,4 @@
 
 obj-$(CONFIG_ADC) += adc-uclass.o
 obj-$(CONFIG_ADC_EXYNOS) += exynos-adc.o
+obj-$(CONFIG_ADC_SANDBOX) += sandbox.o
drivers/adc/sandbox.c new file +174 -0

174 lines not on this page · raw message

Signature · 1 line
1.9.1
#100 lore raw

PATCH 1/1 Add missing file: include/sandbox-adc.h

This should be squashed to commit:

sandbox: add ADC driver

This commit adds implementation of Sandbox ADC device emulation. The device provides:
- single and multi-channel conversion
- 4 channels with predefined conversion output data
- 16-bit resolution

---
Changes V3:
- new commit

---
 include/sandbox-adc.h | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 include/sandbox-adc.h
include/sandbox-adc.h new file +31 -0
new file mode 100644
index 0000000..79ff01c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 Samsung Electronics
+ * Przemyslaw Marczak <[email protected]>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _SANDBOX_ADC_H_
+#define _SANDBOX_ADC_H_
+
+#define SANDBOX_ADC_DEVNAME		"adc at 0"
+#define SANDBOX_ADC_DATA_MASK		0xffff /* 16-bits resolution */
+#define SANDBOX_ADC_CHANNELS		4
+#define SANDBOX_ADC_CHANNEL0_DATA	0x0
+#define SANDBOX_ADC_CHANNEL1_DATA	0x1000
+#define SANDBOX_ADC_CHANNEL2_DATA	0x2000
+#define SANDBOX_ADC_CHANNEL3_DATA	0x3000
+
+enum sandbox_adc_mode {
+	SANDBOX_ADC_MODE_SINGLE_CHANNEL = 0,
+	SANDBOX_ADC_MODE_MULTI_CHANNEL,
+};
+
+enum sandbox_adc_status {
+	SANDBOX_ADC_INACTIVE = 0,
+	SANDBOX_ADC_ACTIVE,
+};
+
+#define SANDBOX_ADC_VSS_VALUE		0
+
+#endif
Signature · 1 line
1.9.1
#101 lore raw

PATCH 1/1 Add missing file: include/sandbox-adc.h

Quoted 12 lines · Przemyslaw Marczak

This should be squashed to commit:

sandbox: add ADC driver

This commit adds implementation of Sandbox ADC device emulation. The device provides:
- single and multi-channel conversion
- 4 channels with predefined conversion output data
- 16-bit resolution

Quoted 7 lines

---
Changes V3:
- new commit

---
 include/sandbox-adc.h | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 include/sandbox-adc.h

Agreed it should be squashed in:

#102 lore raw

PATCH v3 13/14 sandbox: add ADC driver

In reply to Przemyslaw Marczak

Hi Przemyslaw,

Quoted 11 lines · Przemyslaw Marczak

This commit adds implementation of Sandbox ADC device emulation. The device provides:
- single and multi-channel conversion
- 4 channels with predefined conversion output data
- 16-bit resolution

---
Changes V3:
- new commit

Quoted 10 lines
---
 arch/sandbox/dts/sandbox_pmic.dtsi |   2 +-
 arch/sandbox/dts/test.dts          |   6 ++
 configs/sandbox_defconfig          |   2 +
 drivers/adc/Kconfig                |   9 ++
 drivers/adc/Makefile               |   1 +
 drivers/adc/sandbox.c              | 174 +++++++++++++++++++++++++++++++++++++
 6 files changed, 193 insertions(+), 1 deletion(-)
 create mode 100644 drivers/adc/sandbox.c

(could fix the include order though)

#103 lore raw

PATCH v3 14/14 sandbox: add ADC unit tests

In reply to Przemyslaw Marczak

This commit adds unit tests for ADC uclass's methods using sandbox ADC.

Testing proper ADC binding:
- dm_test_adc_bind() - device binding
- dm_test_adc_wrong_channel_selection() - checking wrong channel selection

Testing ADC supply operations:
- dm_test_adc_supply():
- Vdd/Vss values validating
- Vdd regulator updated value validating
- Vdd regulator's auto enable state validating

Testing ADC operations results:
- dm_test_adc_single_channel_conversion() - single channel start/data

- dm_test_adc_single_channel_shot()       - single channel shot
- dm_test_adc_multi_channel_conversion()  - multi channel start/data
- dm_test_adc_multi_channel_shot()        - multi channel single shot

---
Changes V3:
- new commit

---
 include/power/sandbox_pmic.h |   4 ++
 test/dm/Makefile             |   1 +
 test/dm/adc.c                | 165 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 170 insertions(+)
 create mode 100644 test/dm/adc.c
include/power/sandbox_pmic.h +4 -0
index 8547674..7fdbfb9 100644
@@ -126,6 +126,10 @@ enum {
 #define SANDBOX_BUCK1_AUTOSET_EXPECTED_UA	200000
 #define SANDBOX_BUCK1_AUTOSET_EXPECTED_ENABLE	true
 
+/* BUCK2: for testing sandbox ADC's supply */
+#define SANDBOX_BUCK2_INITIAL_EXPECTED_UV	3000000
+#define SANDBOX_BUCK2_SET_UV			3300000
+
 /* LDO1/2 for testing regulator_list_autoset() */
 #define SANDBOX_LDO1_AUTOSET_EXPECTED_UV	1800000
 #define SANDBOX_LDO1_AUTOSET_EXPECTED_UA	100000
test/dm/Makefile +1 -0
index 7b3626c..39630f6 100644
@@ -33,4 +33,5 @@ obj-y += syscon.o
 obj-$(CONFIG_DM_USB) += usb.o
 obj-$(CONFIG_DM_PMIC) += pmic.o
 obj-$(CONFIG_DM_REGULATOR) += regulator.o
+obj-$(CONFIG_ADC) += adc.o
 endif
test/dm/adc.c new file +165 -0

165 lines not on this page · raw message

Signature · 1 line
1.9.1
#104 lore raw

PATCH v3 14/14 sandbox: add ADC unit tests

Hi Przemyslaw,

Quoted 23 lines · Przemyslaw Marczak

This commit adds unit tests for ADC uclass's methods using sandbox ADC.

Testing proper ADC binding:
- dm_test_adc_bind() - device binding
- dm_test_adc_wrong_channel_selection() - checking wrong channel selection

Testing ADC supply operations:
- dm_test_adc_supply():
- Vdd/Vss values validating
- Vdd regulator updated value validating
- Vdd regulator's auto enable state validating

Testing ADC operations results:
- dm_test_adc_single_channel_conversion() - single channel start/data

- dm_test_adc_single_channel_shot()       - single channel shot
- dm_test_adc_multi_channel_conversion()  - multi channel start/data
- dm_test_adc_multi_channel_shot()        - multi channel single shot

---
Changes V3:
- new commit

Quoted 6 lines
---
 include/power/sandbox_pmic.h |   4 ++
 test/dm/Makefile             |   1 +
 test/dm/adc.c                | 165 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 170 insertions(+)
 create mode 100644 test/dm/adc.c

Great test!

#105 lore raw

v3 cover Add board detection for Odroid XU3 / XU3Lite / XU4

In reply to Przemyslaw Marczak
Quoted 86 lines · Przemyslaw Marczak

This patchset adds:
- 'cpu-model' dts property for Chromebook Peach Pi as Exynos5800
- set the cpu id of Exynos5422 to 0x5422
- S2MPS11 PMIC I/O driver
- ADC uclass implementation
- Exynos5420-compatible (9-channel, 12-bit) ADC driver
- new file for Exynos5: exynos5-dt-types.c
- board detection for Odroid XU3 / XU3lite / XU4
- fixed ADC value for XU4 detection

This was tested on Odroid XU3/XU3 Lite/XU4 and sandbox.

Tested with buildman for samsung.

Available on github:
https://github.com/bobenstein/u-boot/tree/xu3-detect-patchset-v1
https://github.com/bobenstein/u-boot/tree/xu3-detect-patchset-v2
https://github.com/bobenstein/u-boot/tree/xu3-detect-patchset-v3

Przemyslaw Marczak (14):
samsung: board/misc: check returned pointer for get_board_type() calls
s5p: cpu_info: print "cpu-model" if exists in dts
Peach-Pi: dts: add cpu-model string
Exynos5422/5800: set cpu id to 0x5422
dm: pmic: add s2mps11 PMIC I/O driver
dm: regulator: add function device_get_supply_regulator()
dm: adc: add simple ADC uclass implementation
dm: adc: add Exynos54xx compatible ADC driver
Odroid-XU3: enable s2mps11 PMIC support
Exynos54xx: dts: add ADC node
Odroid-XU3: dts: enable ADC, with request for pre-reloc bind
exynos5-dt-types: add board detection for Odroid XU3/XU3L/XU4.
sandbox: add ADC driver
sandbox: add ADC unit tests

 arch/arm/cpu/armv7/s5p-common/cpu_info.c   |  14 +-
 arch/arm/dts/exynos5422-odroidxu3.dts      |  12 +
 arch/arm/dts/exynos54xx.dtsi               |   7 +
 arch/arm/dts/exynos5800-peach-pi.dts       |   1 +
 arch/arm/mach-exynos/clock.c               |  16 +-
 arch/arm/mach-exynos/clock_init_exynos5.c  |   2 +-
 arch/arm/mach-exynos/common_setup.h        |   4 +-
 arch/arm/mach-exynos/include/mach/adc.h    |  44 ++++
 arch/arm/mach-exynos/include/mach/cpu.h    |   6 +-
 arch/arm/mach-exynos/include/mach/gpio.h   |   4 +-
 arch/arm/mach-exynos/pinmux.c              |   2 +-
 arch/arm/mach-exynos/power.c               |   2 +-
 arch/sandbox/dts/sandbox_pmic.dtsi         |   2 +-
 arch/sandbox/dts/test.dts                  |   6 +
 board/samsung/common/Makefile              |   5 +-
 board/samsung/common/board.c               |   4 +-
 board/samsung/common/exynos5-dt-types.c    | 196 ++++++++++++++
 board/samsung/common/exynos5-dt.c          |  12 +
 board/samsung/common/misc.c                |   3 +
 configs/odroid-xu3_defconfig               |   5 +
 configs/sandbox_defconfig                  |   2 +
 doc/device-tree-bindings/adc/adc.txt       |  62 +++++
 doc/device-tree-bindings/exynos/soc.txt    |  21 ++
 doc/device-tree-bindings/pmic/s2mps11.txt  |  17 ++
 drivers/Kconfig                            |   2 +
 drivers/Makefile                           |   1 +
 drivers/adc/Kconfig                        |  30 +++
 drivers/adc/Makefile                       |  10 +
 drivers/adc/adc-uclass.c                   | 409 +++++++++++++++++++++++++++++
 drivers/adc/exynos-adc.c                   | 145 ++++++++++
 drivers/adc/sandbox.c                      | 174 ++++++++++++
 drivers/power/pmic/Kconfig                 |  14 +
 drivers/power/pmic/Makefile                |   1 +
 drivers/power/pmic/s2mps11.c               |  62 +++++
 drivers/power/regulator/regulator-uclass.c |   7 +
 include/adc.h                              | 288 ++++++++++++++++++++
 include/configs/odroid_xu3.h               |  12 +
 include/dm/uclass-id.h                     |   1 +
 include/power/regulator.h                  |  16 ++
 include/power/s2mps11.h                    | 109 ++++++++
 include/power/sandbox_pmic.h               |   4 +
 include/samsung/exynos5-dt-types.h         |  27 ++
 test/dm/Makefile                           |   1 +
 test/dm/adc.c                              | 165 ++++++++++++
 44 files changed, 1904 insertions(+), 23 deletions(-)
 create mode 100644 board/samsung/common/exynos5-dt-types.c
 create mode 100644 doc/device-tree-bindings/adc/adc.txt
 create mode 100644 doc/device-tree-bindings/exynos/soc.txt
 create mode 100644 doc/device-tree-bindings/pmic/s2mps11.txt
 create mode 100644 drivers/adc/Kconfig
 create mode 100644 drivers/adc/Makefile
Quoted 9 lines
 create mode 100644 drivers/adc/adc-uclass.c
 create mode 100644 drivers/adc/exynos-adc.c
 create mode 100644 drivers/adc/sandbox.c
 create mode 100644 drivers/power/pmic/s2mps11.c
 create mode 100644 include/adc.h
 create mode 100644 include/power/s2mps11.h
 create mode 100644 include/samsung/exynos5-dt-types.h
 create mode 100644 test/dm/adc.c

applied to u-boot-samsung.

Thanks,
Minkyu Kang.