Re: [PATCH] rpi: always set fdt_addr to the correct value

2022-02-15 Thread Marek Szyprowski
Hi Matthias,

On 15.02.2022 19:19, Matthias Brugger wrote:
>
> On 15/02/2022 15:55, Matthias Brugger wrote:
>>
>> On 18/02/2022 03:44, Jaehoon Chung wrote:
>>> On 22. 2. 14. 20:25, Marek Szyprowski wrote:
>>>> The fdt_addr env have meaning only for the current runtime and it 
>>>> depends
>>>> on the dtb size or firmware version. If one save the environment to 
>>>> disk
>>>> and the loads it on the latter boot, the fdt_addr might change, what
>>>> result in passing incorrect dtb address to the kernel. Fix this by 
>>>> always
>>>> setting the fdt_addr env. This fixes system operation after saving the
>>>> env to disk and updating i.e. dtb files or firmware.
>>>>
>>>> Signed-off-by: Marek Szyprowski 
>>>
>>> Reviewed-by: Jaehoon Chung 
>>>
>>
>> Could we keep the discussion where we left it the last time you 
>> submitted the patch?
>>
>
> I forgot to add the link to the old discussion:
> https://patchwork.ozlabs.org/project/uboot/patch/20210512123945.25649-1-m.salv...@koansoftware.com/

Well, I'm still not convinced that this is a good idea.

I found this issue while debugging something else and I must admit that 
the current behavior is really counterintuitive. I was surprised that 
after setting some really unrelated things in u-boot's envs (like 
additional kernel arguments to increase debug level) and saving such 
config, I got completely broken system. Right, I've also updated DTB in 
meantime because I was bisecting some kernel related issue, but still 
this is something that a typical user might face during system update.

If we want to keep current behavior, the 'saveenv' command should print 
a large banner that one has to first delete the 'fdt_addr' env if he 
wants to have a working system.

I will check if it would be possible to use some flags for the 
'fdt_addr' env to mark it as 'do-not-save-unless-changed-manually'.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R Institute Poland



[PATCH] rpi: always set fdt_addr to the correct value

2022-02-14 Thread Marek Szyprowski
The fdt_addr env have meaning only for the current runtime and it depends
on the dtb size or firmware version. If one save the environment to disk
and the loads it on the latter boot, the fdt_addr might change, what
result in passing incorrect dtb address to the kernel. Fix this by always
setting the fdt_addr env. This fixes system operation after saving the
env to disk and updating i.e. dtb files or firmware.

Signed-off-by: Marek Szyprowski 
---
 board/raspberrypi/rpi/rpi.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
index bc3cc597adb..6d6d2e69234 100644
--- a/board/raspberrypi/rpi/rpi.c
+++ b/board/raspberrypi/rpi/rpi.c
@@ -347,9 +347,6 @@ static void set_fdtfile(void)
  */
 static void set_fdt_addr(void)
 {
-   if (env_get("fdt_addr"))
-   return;
-
if (fdt_magic(fw_dtb_pointer) != FDT_MAGIC)
return;
 
-- 
2.17.1



[PATCH] arm: rpi: perform XHCI firmware upload only once

2021-09-17 Thread Marek Szyprowski
XHCI firmware upload must be performed only once after initializing the
PCI bridge. This fixes USB stack initialization after calling "usb stop;
usb start" on Raspberry Pi 4B.

Signed-off-by: Marek Szyprowski 
---
 arch/arm/mach-bcm283x/msg.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/mach-bcm283x/msg.c b/arch/arm/mach-bcm283x/msg.c
index 347aece3cd..345f7fe2b7 100644
--- a/arch/arm/mach-bcm283x/msg.c
+++ b/arch/arm/mach-bcm283x/msg.c
@@ -170,6 +170,12 @@ int bcm2711_notify_vl805_reset(void)
ALLOC_CACHE_ALIGN_BUFFER(struct msg_notify_vl805_reset,
 msg_notify_vl805_reset, 1);
int ret;
+   static int done = false;
+
+   if (done)
+   return 0;
+
+   done = true;
 
BCM2835_MBOX_INIT_HDR(msg_notify_vl805_reset);
BCM2835_MBOX_INIT_TAG(_notify_vl805_reset->dev_addr,
-- 
2.17.1



Re: u-boot on RPi4 32bit - issue after upgrading the firmware

2021-06-17 Thread Marek Szyprowski
Hi

On 04.03.2021 02:33, Jaehoon Chung wrote:
> On 2/25/21 8:11 PM, Marek Szyprowski wrote:
>> On 25.02.2021 11:55, Nicolas Saenz Julienne wrote:
>>> On Thu, 2021-02-25 at 11:43 +0100, Marek Szyprowski wrote:
>>>> Recently I've upgraded a video core firmware on my RPi4 and I've noticed
>>>> that u-boot in ARM 32bit mode stopped working properly or even randomly
>>>> crashes. I've bisected the firmware releases and the issue appears for
>>>> the first time in the commit 63b1922311 ("firmware: arm_loader: Update
>>>> armstubs with those from PR 117 See:
>>>> https://protect2.fireeye.com/v1/url?k=a201e8b0-fd9ad069-a20063ff-0cc47a3356b2-1ab72bd783ec5635=1=5f377675-c909-4cc4-a1d5-b740cbf6255e=https%3A%2F%2Fgithub.com%2Fraspberrypi%2Ftools%2Fpull%2F117;).
>>> Just for confirmation,
>>>> This issue can be easily observed as a failure of the xhci. See the
>>>> attached log:
>>>>
>>>> Read start4x.elf bytes  2984808 hnd 0x06e2 sha256 d21bf9d3954fea04
>>>> Read fixup4x.dat bytes 8432 hnd 0x06dd sha256 10d3b073ab232613
>>>> 0x00a03111 0x 0x001f
>>>> MEM GPU: 76 ARM: 948 TOTAL: 1024
>>>> Starting start4x.elf @ 0xfec00200 partition 0
>>>> PCI reset
>>>> +
>>>>
>>>> MESS:00:00:04.800023:0: arasan: arasan_emmc_open
>>>> MESS:00:00:04.975752:0: brfs: File read: /mfs/sd/config.txt
>>>> MESS:00:00:04.979162:0: brfs: File read: 2153 bytes
>>>> MESS:00:00:05.046081:0: brfs: File read: /mfs/sd/config.txt
>>>> MESS:00:00:06.121174:0: gpioman: gpioman_get_pin_num: pin
>>>> DISPLAY_DSI_PORT not defined
>>>> MESS:00:00:06.128433:0: *** Restart logging
>>>> MESS:00:00:06.129897:0: brfs: File read: 2153 bytes
>>>> MESS:00:00:06.148533:0: hdmi: HDMI:hdmi_get_state is deprecated, use
>>>> hdmi_get_display_state instead
>>>> MESS:00:00:06.154474:0: HDMI0: hdmi_pixel_encoding: 3
>>>> MESS:00:00:06.159948:0: HDMI1: hdmi_pixel_encoding: 3
>>>> MESS:00:00:06.166901:0: dtb_file 'bcm2711-rpi-4-b.dtb'
>>>> MESS:00:00:06.178359:0: brfs: File read: /mfs/sd/bcm2711-rpi-4-b.dtb
>>>> MESS:00:00:06.181601:0: Loading 'bcm2711-rpi-4-b.dtb' to 0x100 size 0xc901
>>>> MESS:00:00:06.201386:0: brfs: File read: 51457 bytes
>>>> MESS:00:00:06.267975:0: brfs: File read: /mfs/sd/config.txt
>>>> MESS:00:00:06.270915:0: dtparam: audio=on
>>>> MESS:00:00:06.283974:0: brfs: File read: 2153 bytes
>>>> MESS:00:00:06.286148:0: Failed to load overlay 'vc4-fkms-v3d'
>>>> MESS:00:00:06.291378:0: brfs: File read: /mfs/sd/overlays/vc4-fkms-v3d.dtbo
>>>> MESS:00:00:06.304096:0: Failed to open command line file 'cmdline.txt'
>>>> MESS:00:00:07.484256:0: brfs: File read: /mfs/sd/u-boot.bin
>>>> MESS:00:00:07.486726:0: Loading 'u-boot.bin' to 0x8000 size 0x84cf4
>>>> MESS:00:00:07.492726:0: Device tree loaded to 0x2eff3100 (size 0xce24)
>>>> MESS:00:00:07.500863:0: uart: Set PL011 baud rate to 103448.30 Hz
>>>> MESS:00:00:07.508031:0: uart: Baud rate change done...
>>>> MESS:00:00:07.510053:0:
>>>>
>>>> U-Boot 2021.04-rc2 (Feb 25 2021 - 11:21:44 +0100)
>>> Can you try with today's master branch, I'm specially interested in seeing 
>>> if
>>> 56f1bcc4b7fb helps.
>> I've checked the mentioned commit, sadly nothing changes:
>>
>> U-Boot 2021.04-rc2-00041-g56f1bcc4b7 (Feb 25 2021 - 12:05:07 +0100)
>>
>> DRAM:  948 MiB
>> RPI 4 Model B (0xa03111)
>> MMC:   mmcnr@7e30: 1, emmc2@7e34: 0
>> Loading Environment from FAT... OK
>> In:    serial
>> Out:   serial
>> Err:   serial
>> Net:   eth0: ethernet@7d58
>> Hit any key to stop autoboot:  0
>> U-Boot> pci enum
>> PCIe BRCM: link up, 5.0 Gbps x1 (SSC)
>> U-Boot> usb start
>> starting USB...
>> Bus xhci_pci: Host not halted after 16000 microseconds.
>> probe failed, error -16
>> No working controllers found
>> U-Boot>
>>
>> I've checked that on two RPi4 boards (one with 1GB RAM and one with 8GB).
> It seems that couldn't get hc_length from capbase.
>
> us xhci_pci: XHCI-PCI init hccr ff80 and hcor ff80 hc_length 0
> xhci_register: dev='xhci_pci', ctrl=3a3679c0, hccr=ff80, hcor=ff80
>
> When i have compared with working and not, hc_length is different.
> hc_length should be to set 0x20 when it's working fine.
>
> I don't have the knowledge of USB..So it's taking too more time for debugging.
>
> Could you share what i do to check more?

I've finally had some time to analyze it more. It looks that 0xff80 
base address in ARM 32bit virtual address space chosen for XHCI PCI 
device conflicts with the updated ARM/VideoCore firmware. I have no idea 
why, but switching to 0xffc0 fixed the issue.

Best regards

-- 
Marek Szyprowski, PhD
Samsung R Institute Poland



[PATCH] ARM: bcm283x: change the virtual address of the XHCI PCI device base

2021-06-17 Thread Marek Szyprowski
Move the XHCI PCI device base up in the virtual address space. This fixes
initialization failure observed with newer Raspberry Pi firmware, later
than 63b1922311 ("firmware: arm_loader: Update armstubs with those from
PR 117). It looks that chosing 0xff80 as the XHCI PCI device base
conflicts with the updated ARM/VideoCore firmware.

This also requires to reduce the size of the mapped PCI device region
from 8MiB to 4MiB to fit into 32bit address space. This is still enough
for the XHCI PCI device.

Signed-off-by: Marek Szyprowski 
---
This fixes the issue observed on ARM 32bit after upgrading the RPi4
firmware files, described some time ago here:
https://lists.denx.de/pipermail/u-boot/2021-February/442317.html
---
 arch/arm/mach-bcm283x/init.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-bcm283x/init.c b/arch/arm/mach-bcm283x/init.c
index 49027ce0a2..9803499985 100644
--- a/arch/arm/mach-bcm283x/init.c
+++ b/arch/arm/mach-bcm283x/init.c
@@ -14,7 +14,7 @@
 #include 
 
 #define BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS   0x6UL
-#define BCM2711_RPI4_PCIE_XHCI_MMIO_SIZE   0x80UL
+#define BCM2711_RPI4_PCIE_XHCI_MMIO_SIZE   0x40UL
 
 #ifdef CONFIG_ARM64
 #include 
@@ -148,7 +148,7 @@ int mach_cpu_init(void)
 
 #ifdef CONFIG_ARMV7_LPAE
 #ifdef CONFIG_TARGET_RPI_4_32B
-#define BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT   0xff80UL
+#define BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT   0xffc0UL
 #include 
 #include 
 
-- 
2.17.1



Re: u-boot on RPi4 32bit - issue after upgrading the firmware

2021-02-25 Thread Marek Szyprowski
Hi Nicolas,

On 25.02.2021 11:55, Nicolas Saenz Julienne wrote:
> On Thu, 2021-02-25 at 11:43 +0100, Marek Szyprowski wrote:
>> Recently I've upgraded a video core firmware on my RPi4 and I've noticed
>> that u-boot in ARM 32bit mode stopped working properly or even randomly
>> crashes. I've bisected the firmware releases and the issue appears for
>> the first time in the commit 63b1922311 ("firmware: arm_loader: Update
>> armstubs with those from PR 117 See:
>> https://protect2.fireeye.com/v1/url?k=a201e8b0-fd9ad069-a20063ff-0cc47a3356b2-1ab72bd783ec5635=1=5f377675-c909-4cc4-a1d5-b740cbf6255e=https%3A%2F%2Fgithub.com%2Fraspberrypi%2Ftools%2Fpull%2F117;).
> Just for confirmation,
>> This issue can be easily observed as a failure of the xhci. See the
>> attached log:
>>
>> Read start4x.elf bytes  2984808 hnd 0x06e2 sha256 d21bf9d3954fea04
>> Read fixup4x.dat bytes 8432 hnd 0x06dd sha256 10d3b073ab232613
>> 0x00a03111 0x 0x001f
>> MEM GPU: 76 ARM: 948 TOTAL: 1024
>> Starting start4x.elf @ 0xfec00200 partition 0
>> PCI reset
>> +
>>
>> MESS:00:00:04.800023:0: arasan: arasan_emmc_open
>> MESS:00:00:04.975752:0: brfs: File read: /mfs/sd/config.txt
>> MESS:00:00:04.979162:0: brfs: File read: 2153 bytes
>> MESS:00:00:05.046081:0: brfs: File read: /mfs/sd/config.txt
>> MESS:00:00:06.121174:0: gpioman: gpioman_get_pin_num: pin
>> DISPLAY_DSI_PORT not defined
>> MESS:00:00:06.128433:0: *** Restart logging
>> MESS:00:00:06.129897:0: brfs: File read: 2153 bytes
>> MESS:00:00:06.148533:0: hdmi: HDMI:hdmi_get_state is deprecated, use
>> hdmi_get_display_state instead
>> MESS:00:00:06.154474:0: HDMI0: hdmi_pixel_encoding: 3
>> MESS:00:00:06.159948:0: HDMI1: hdmi_pixel_encoding: 3
>> MESS:00:00:06.166901:0: dtb_file 'bcm2711-rpi-4-b.dtb'
>> MESS:00:00:06.178359:0: brfs: File read: /mfs/sd/bcm2711-rpi-4-b.dtb
>> MESS:00:00:06.181601:0: Loading 'bcm2711-rpi-4-b.dtb' to 0x100 size 0xc901
>> MESS:00:00:06.201386:0: brfs: File read: 51457 bytes
>> MESS:00:00:06.267975:0: brfs: File read: /mfs/sd/config.txt
>> MESS:00:00:06.270915:0: dtparam: audio=on
>> MESS:00:00:06.283974:0: brfs: File read: 2153 bytes
>> MESS:00:00:06.286148:0: Failed to load overlay 'vc4-fkms-v3d'
>> MESS:00:00:06.291378:0: brfs: File read: /mfs/sd/overlays/vc4-fkms-v3d.dtbo
>> MESS:00:00:06.304096:0: Failed to open command line file 'cmdline.txt'
>> MESS:00:00:07.484256:0: brfs: File read: /mfs/sd/u-boot.bin
>> MESS:00:00:07.486726:0: Loading 'u-boot.bin' to 0x8000 size 0x84cf4
>> MESS:00:00:07.492726:0: Device tree loaded to 0x2eff3100 (size 0xce24)
>> MESS:00:00:07.500863:0: uart: Set PL011 baud rate to 103448.30 Hz
>> MESS:00:00:07.508031:0: uart: Baud rate change done...
>> MESS:00:00:07.510053:0:
>>
>> U-Boot 2021.04-rc2 (Feb 25 2021 - 11:21:44 +0100)
> Can you try with today's master branch, I'm specially interested in seeing if
> 56f1bcc4b7fb helps.

I've checked the mentioned commit, sadly nothing changes:

U-Boot 2021.04-rc2-00041-g56f1bcc4b7 (Feb 25 2021 - 12:05:07 +0100)

DRAM:  948 MiB
RPI 4 Model B (0xa03111)
MMC:   mmcnr@7e30: 1, emmc2@7e34: 0
Loading Environment from FAT... OK
In:    serial
Out:   serial
Err:   serial
Net:   eth0: ethernet@7d58
Hit any key to stop autoboot:  0
U-Boot> pci enum
PCIe BRCM: link up, 5.0 Gbps x1 (SSC)
U-Boot> usb start
starting USB...
Bus xhci_pci: Host not halted after 16000 microseconds.
probe failed, error -16
No working controllers found
U-Boot>

I've checked that on two RPi4 boards (one with 1GB RAM and one with 8GB).

Best regards

-- 
Marek Szyprowski, PhD
Samsung R Institute Poland



u-boot on RPi4 32bit - issue after upgrading the firmware

2021-02-25 Thread Marek Szyprowski
Hi!

Recently I've upgraded a video core firmware on my RPi4 and I've noticed 
that u-boot in ARM 32bit mode stopped working properly or even randomly 
crashes. I've bisected the firmware releases and the issue appears for 
the first time in the commit 63b1922311 ("firmware: arm_loader: Update 
armstubs with those from PR 117 See: 
https://github.com/raspberrypi/tools/pull/117;).

This issue can be easily observed as a failure of the xhci. See the 
attached log:

Read start4x.elf bytes  2984808 hnd 0x06e2 sha256 d21bf9d3954fea04
Read fixup4x.dat bytes 8432 hnd 0x06dd sha256 10d3b073ab232613
0x00a03111 0x 0x001f
MEM GPU: 76 ARM: 948 TOTAL: 1024
Starting start4x.elf @ 0xfec00200 partition 0
PCI reset
+

MESS:00:00:04.800023:0: arasan: arasan_emmc_open
MESS:00:00:04.975752:0: brfs: File read: /mfs/sd/config.txt
MESS:00:00:04.979162:0: brfs: File read: 2153 bytes
MESS:00:00:05.046081:0: brfs: File read: /mfs/sd/config.txt
MESS:00:00:06.121174:0: gpioman: gpioman_get_pin_num: pin 
DISPLAY_DSI_PORT not defined
MESS:00:00:06.128433:0: *** Restart logging
MESS:00:00:06.129897:0: brfs: File read: 2153 bytes
MESS:00:00:06.148533:0: hdmi: HDMI:hdmi_get_state is deprecated, use 
hdmi_get_display_state instead
MESS:00:00:06.154474:0: HDMI0: hdmi_pixel_encoding: 3
MESS:00:00:06.159948:0: HDMI1: hdmi_pixel_encoding: 3
MESS:00:00:06.166901:0: dtb_file 'bcm2711-rpi-4-b.dtb'
MESS:00:00:06.178359:0: brfs: File read: /mfs/sd/bcm2711-rpi-4-b.dtb
MESS:00:00:06.181601:0: Loading 'bcm2711-rpi-4-b.dtb' to 0x100 size 0xc901
MESS:00:00:06.201386:0: brfs: File read: 51457 bytes
MESS:00:00:06.267975:0: brfs: File read: /mfs/sd/config.txt
MESS:00:00:06.270915:0: dtparam: audio=on
MESS:00:00:06.283974:0: brfs: File read: 2153 bytes
MESS:00:00:06.286148:0: Failed to load overlay 'vc4-fkms-v3d'
MESS:00:00:06.291378:0: brfs: File read: /mfs/sd/overlays/vc4-fkms-v3d.dtbo
MESS:00:00:06.304096:0: Failed to open command line file 'cmdline.txt'
MESS:00:00:07.484256:0: brfs: File read: /mfs/sd/u-boot.bin
MESS:00:00:07.486726:0: Loading 'u-boot.bin' to 0x8000 size 0x84cf4
MESS:00:00:07.492726:0: Device tree loaded to 0x2eff3100 (size 0xce24)
MESS:00:00:07.500863:0: uart: Set PL011 baud rate to 103448.30 Hz
MESS:00:00:07.508031:0: uart: Baud rate change done...
MESS:00:00:07.510053:0:

U-Boot 2021.04-rc2 (Feb 25 2021 - 11:21:44 +0100)

DRAM:  948 MiB
RPI 4 Model B (0xa03111)
MMC:   mmcnr@7e30: 1, emmc2@7e34: 0
Loading Environment from FAT... OK
In:    serial
Out:   serial
Err:   serial
Net:   eth0: ethernet@7d58
Hit any key to stop autoboot:  0
U-Boot> pci enum
PCIe BRCM: link up, 5.0 Gbps x1 (SSC)
U-Boot> usb start
starting USB...
Bus xhci_pci: Host not halted after 16000 microseconds.
probe failed, error -16
No working controllers found
U-Boot>

Is it a known issue? In ARM64 mode everything works fine, but this not 
very surprising, because the firmware change in the mentioned commit is 
related to the ARM 32bit mode. Does anyone have an idea how to fix this 
issue? I've checked also the latest version of the RPi firmware, but the 
issue is still there.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R Institute Poland



Re: [PATCH] button: adc: fix treshold typo

2021-02-23 Thread Marek Szyprowski
On 23.02.2021 16:10, Neil Armstrong wrote:
> Fix the treshold typo in code by threshold.
>
> Fixes: c0165c85c3 ("button: add a simple Analog to Digital Converter device 
> based button driver")
> Suggested-by: Tom Rini 
> Signed-off-by: Neil Armstrong 
Acked-by: Marek Szyprowski 
> ---
>   drivers/button/button-adc.c | 14 +++---
>   1 file changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/button/button-adc.c b/drivers/button/button-adc.c
> index eed86564fb..fd896c76f9 100644
> --- a/drivers/button/button-adc.c
> +++ b/drivers/button/button-adc.c
> @@ -55,7 +55,7 @@ static int button_adc_of_to_plat(struct udevice *dev)
>   struct button_uc_plat *uc_plat = dev_get_uclass_plat(dev);
>   struct button_adc_priv *priv = dev_get_priv(dev);
>   struct ofnode_phandle_args args;
> - u32 treshold, up_treshold, t;
> + u32 threshold, up_threshold, t;
>   ofnode node;
>   int ret;
>   
> @@ -73,12 +73,12 @@ static int button_adc_of_to_plat(struct udevice *dev)
>   return ret;
>   
>   ret = ofnode_read_u32(dev_ofnode(dev->parent),
> -   "keyup-threshold-microvolt", _treshold);
> +   "keyup-threshold-microvolt", _threshold);
>   if (ret)
>   return ret;
>   
>   ret = ofnode_read_u32(dev_ofnode(dev), "press-threshold-microvolt",
> -   );
> +   );
>   if (ret)
>   return ret;
>   
> @@ -87,13 +87,13 @@ static int button_adc_of_to_plat(struct udevice *dev)
>   if (ret)
>   return ret;
>   
> - if (t > treshold)
> - up_treshold = t;
> + if (t > threshold)
> + up_threshold = t;
>   }
>   
>   priv->channel = args.args[0];
> - priv->min = treshold;
> - priv->max = up_treshold;
> + priv->min = threshold;
> + priv->max = up_threshold;
>   
>   return ret;
>   }

Best regards
-- 
Marek Szyprowski, PhD
Samsung R Institute Poland



[PATCH v7 1/5] dt-bindings: input: adc-keys bindings documentation

2021-02-18 Thread Marek Szyprowski
Dump adc-keys bindings documentation from Linux kernel source tree from
commit 698dc0cf9447 ("dt-bindings: input: adc-keys: clarify
description").

Signed-off-by: Marek Szyprowski 
Reviewed-by: Simon Glass 
---
 doc/device-tree-bindings/input/adc-keys.txt | 67 +
 1 file changed, 67 insertions(+)
 create mode 100644 doc/device-tree-bindings/input/adc-keys.txt

diff --git a/doc/device-tree-bindings/input/adc-keys.txt 
b/doc/device-tree-bindings/input/adc-keys.txt
new file mode 100644
index 00..6c8be6a9ac
--- /dev/null
+++ b/doc/device-tree-bindings/input/adc-keys.txt
@@ -0,0 +1,67 @@
+ADC attached resistor ladder buttons
+
+
+Required properties:
+ - compatible: "adc-keys"
+ - io-channels: Phandle to an ADC channel
+ - io-channel-names = "buttons";
+ - keyup-threshold-microvolt: Voltage above or equal to which all the keys are
+ considered up.
+
+Optional properties:
+   - poll-interval: Poll interval time in milliseconds
+   - autorepeat: Boolean, Enable auto repeat feature of Linux input
+ subsystem.
+
+Each button (key) is represented as a sub-node of "adc-keys":
+
+Required subnode-properties:
+   - label: Descriptive name of the key.
+   - linux,code: Keycode to emit.
+   - press-threshold-microvolt: voltage above or equal to which this key is
+considered pressed.
+
+No two values of press-threshold-microvolt may be the same.
+All values of press-threshold-microvolt must be less than
+keyup-threshold-microvolt.
+
+Example:
+
+#include 
+
+   adc-keys {
+   compatible = "adc-keys";
+   io-channels = < 0>;
+   io-channel-names = "buttons";
+   keyup-threshold-microvolt = <200>;
+
+   button-up {
+   label = "Volume Up";
+   linux,code = ;
+   press-threshold-microvolt = <150>;
+   };
+
+   button-down {
+   label = "Volume Down";
+   linux,code = ;
+   press-threshold-microvolt = <100>;
+   };
+
+   button-enter {
+   label = "Enter";
+   linux,code = ;
+   press-threshold-microvolt = <50>;
+   };
+   };
+
++++
+| 2.000.000 <= value | no key pressed |
++++
+| 1.500.000 <= value < 2.000.000 | KEY_VOLUMEUP pressed   |
++++
+| 1.000.000 <= value < 1.500.000 | KEY_VOLUMEDOWN pressed |
++++
+|   500.000 <= value < 1.000.000 | KEY_ENTER pressed  |
++++
+|  value <   500.000 | no key pressed |
++++
-- 
2.17.1



[PATCH v7 0/5] VIM3: add support for checking 'Function' button state

2021-02-18 Thread Marek Szyprowski
Hi All,

This patchset adds all building blocks needed for checking the 'Function'
button state in the boot script on Amlogic A311D based VIM3 board. This
button is connected to the ADC line of the SoC, so it required to enable
meson SARADC, the clocks needed for it and a simple button-adc drivers.

Once applied, one can use following commands in the boot scripts:
-->8---
echo Checking Func button state: \\c
if button Function
then
echo Selected alternative boot
...
fi
--->8---

Best regards
Marek Szyprowski
Samsung R Institute Poland


Changelog:
v7:
- added linux,code properties to the test.dts

v6: https://lists.denx.de/pipermail/u-boot/2021-February/441039.html
- added a simple sandbox test for adc-keys
- use of_to_plat and adc_raw_to_uV to simplify code in the adc button driver

v5: https://lists.denx.de/pipermail/u-boot/2021-January/438751.html
- rebased onto latest uboot-amlogic/u-boot-amlogic-next branch
- synchronized adc-keys binding with the recent version from the Linux
  kernel
- updated adc-keys driver to match behavior from dt-bindings
- added a patch for meson-saradc driver to register vdd reference supply
  to the ADC framework

v4: https://lists.denx.de/pipermail/u-boot/2020-December/435641.html
- rebased onto uboot-amlogic/u-boot-amlogic-next and dropped merged patches
- added adc-keys bindings docs (copied from Linux kernel)
- minor code adjustments pointed by Simon
- enabled driver also in khadas-vim3l_defconfig

v3: https://lists.denx.de/pipermail/u-boot/2020-December/435072.html
- removed 'button' env variable
- extended kconfig and patch descriptions

v2: https://lists.denx.de/pipermail/u-boot/2020-December/434991.html
- removed Change-Id tags
- split defconfig changes into ADC and button related

v1: https://lists.denx.de/pipermail/u-boot/2020-December/434875.html
- initial submission


Patch summary:

Marek Szyprowski (5):
  dt-bindings: input: adc-keys bindings documentation
  button: add a simple Analog to Digital Converter device based button
driver
  adc: meson-saradc: add support for getting reference voltage value
  configs: khadas-vim3(l): enable Function button support
  test: add a simple test for the adc-keys button driver

 arch/sandbox/dts/test.dts   |  27 +++-
 configs/khadas-vim3_defconfig   |   2 +
 configs/khadas-vim3l_defconfig  |   2 +
 configs/sandbox_defconfig   |   1 +
 doc/device-tree-bindings/input/adc-keys.txt |  67 +
 drivers/adc/meson-saradc.c  |  21 +++
 drivers/button/Kconfig  |   8 ++
 drivers/button/Makefile |   1 +
 drivers/button/button-adc.c | 146 
 test/dm/button.c|  50 ++-
 10 files changed, 322 insertions(+), 3 deletions(-)
 create mode 100644 doc/device-tree-bindings/input/adc-keys.txt
 create mode 100644 drivers/button/button-adc.c

-- 
2.17.1



[PATCH v7 3/5] adc: meson-saradc: add support for getting reference voltage value

2021-02-18 Thread Marek Szyprowski
Add support for getting the 'vref-supply' regulator and register it as
ADC's reference voltage regulator, so clients can translate sampled ADC
values to the voltage.

Signed-off-by: Marek Szyprowski 
Reviewed-by: Simon Glass 
---
 drivers/adc/meson-saradc.c | 21 +
 1 file changed, 21 insertions(+)

diff --git a/drivers/adc/meson-saradc.c b/drivers/adc/meson-saradc.c
index 21db55831d..1a45a3a265 100644
--- a/drivers/adc/meson-saradc.c
+++ b/drivers/adc/meson-saradc.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define MESON_SAR_ADC_REG0 0x00
#define MESON_SAR_ADC_REG0_PANEL_DETECT BIT(31)
@@ -656,7 +657,10 @@ static int meson_saradc_stop(struct udevice *dev)
 
 static int meson_saradc_probe(struct udevice *dev)
 {
+   struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
struct meson_saradc_priv *priv = dev_get_priv(dev);
+   struct udevice *vref;
+   int vref_uv;
int ret;
 
ret = regmap_init_mem(dev_ofnode(dev), >regmap);
@@ -675,6 +679,23 @@ static int meson_saradc_probe(struct udevice *dev)
 
priv->active_channel = -1;
 
+   ret = device_get_supply_regulator(dev, "vref-supply", );
+   if (ret) {
+   printf("can't get vref-supply: %d\n", ret);
+   return ret;
+   }
+
+   vref_uv = regulator_get_value(vref);
+   if (vref_uv < 0) {
+   printf("can't get vref-supply value: %d\n", vref_uv);
+   return vref_uv;
+   }
+
+   /* VDD supplied by common vref pin */
+   uc_pdata->vdd_supply = vref;
+   uc_pdata->vdd_microvolts = vref_uv;
+   uc_pdata->vss_microvolts = 0;
+
return 0;
 }
 
-- 
2.17.1



[PATCH v7 2/5] button: add a simple Analog to Digital Converter device based button driver

2021-02-18 Thread Marek Szyprowski
Add a simple Analog to Digital Converter device based button driver. This
driver binds to the 'adc-keys' device tree node.

Signed-off-by: Marek Szyprowski 
Reviewed-by: Simon Glass 
---
 drivers/button/Kconfig  |   8 ++
 drivers/button/Makefile |   1 +
 drivers/button/button-adc.c | 146 
 3 files changed, 155 insertions(+)
 create mode 100644 drivers/button/button-adc.c

diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig
index 6b3ec7e55d..6db3c5e93a 100644
--- a/drivers/button/Kconfig
+++ b/drivers/button/Kconfig
@@ -9,6 +9,14 @@ config BUTTON
  can provide access to board-specific buttons. Use of the device tree
  for configuration is encouraged.
 
+config BUTTON_ADC
+   bool "Button adc"
+   depends on BUTTON
+   help
+ Enable support for buttons which are connected to Analog to Digital
+ Converter device. The ADC driver must use driver model. Buttons are
+ configured using the device tree.
+
 config BUTTON_GPIO
bool "Button gpio"
depends on BUTTON
diff --git a/drivers/button/Makefile b/drivers/button/Makefile
index fcc10ebe8d..bbd18af149 100644
--- a/drivers/button/Makefile
+++ b/drivers/button/Makefile
@@ -3,4 +3,5 @@
 # Copyright (C) 2020 Philippe Reynes 
 
 obj-$(CONFIG_BUTTON) += button-uclass.o
+obj-$(CONFIG_BUTTON_ADC) += button-adc.o
 obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o
diff --git a/drivers/button/button-adc.c b/drivers/button/button-adc.c
new file mode 100644
index 00..eed86564fb
--- /dev/null
+++ b/drivers/button/button-adc.c
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Author: Marek Szyprowski 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * struct button_adc_priv - private data for button-adc driver.
+ *
+ * @adc: Analog to Digital Converter device to which button is connected.
+ * @channel: channel of the ADC device to probe the button state.
+ * @min: minimal uV value to consider button as pressed.
+ * @max: maximal uV value to consider button as pressed.
+ */
+struct button_adc_priv {
+   struct udevice *adc;
+   int channel;
+   int min;
+   int max;
+};
+
+static enum button_state_t button_adc_get_state(struct udevice *dev)
+{
+   struct button_adc_priv *priv = dev_get_priv(dev);
+   unsigned int val;
+   int ret, uV;
+
+   ret = adc_start_channel(priv->adc, priv->channel);
+   if (ret)
+   return ret;
+
+   ret = adc_channel_data(priv->adc, priv->channel, );
+   if (ret)
+   return ret;
+
+   ret = adc_raw_to_uV(priv->adc, val, );
+   if (ret)
+   return ret;
+
+   return (uV >= priv->min && uV < priv->max) ? BUTTON_ON : BUTTON_OFF;
+}
+
+static int button_adc_of_to_plat(struct udevice *dev)
+{
+   struct button_uc_plat *uc_plat = dev_get_uclass_plat(dev);
+   struct button_adc_priv *priv = dev_get_priv(dev);
+   struct ofnode_phandle_args args;
+   u32 treshold, up_treshold, t;
+   ofnode node;
+   int ret;
+
+   /* Ignore the top-level button node */
+   if (!uc_plat->label)
+   return 0;
+
+   ret = dev_read_phandle_with_args(dev->parent, "io-channels",
+"#io-channel-cells", 0, 0, );
+   if (ret)
+   return ret;
+
+   ret = uclass_get_device_by_ofnode(UCLASS_ADC, args.node, >adc);
+   if (ret)
+   return ret;
+
+   ret = ofnode_read_u32(dev_ofnode(dev->parent),
+ "keyup-threshold-microvolt", _treshold);
+   if (ret)
+   return ret;
+
+   ret = ofnode_read_u32(dev_ofnode(dev), "press-threshold-microvolt",
+ );
+   if (ret)
+   return ret;
+
+   dev_for_each_subnode(node, dev->parent) {
+   ret = ofnode_read_u32(node, "press-threshold-microvolt", );
+   if (ret)
+   return ret;
+
+   if (t > treshold)
+   up_treshold = t;
+   }
+
+   priv->channel = args.args[0];
+   priv->min = treshold;
+   priv->max = up_treshold;
+
+   return ret;
+}
+
+static int button_adc_bind(struct udevice *parent)
+{
+   struct udevice *dev;
+   ofnode node;
+   int ret;
+
+   dev_for_each_subnode(node, parent) {
+   struct button_uc_plat *uc_plat;
+   const char *label;
+
+   label = ofnode_read_string(node, "label");
+   if (!label) {
+   debug("%s: node %s has no label\n", __func__,
+   

[PATCH v7 4/5] configs: khadas-vim3(l): enable Function button support

2021-02-18 Thread Marek Szyprowski
Add options required to check the 'Function' button state.

Signed-off-by: Marek Szyprowski 
Reviewed-by: Simon Glass 
---
 configs/khadas-vim3_defconfig  | 2 ++
 configs/khadas-vim3l_defconfig | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/configs/khadas-vim3_defconfig b/configs/khadas-vim3_defconfig
index 5d16652fd6..bc17430569 100644
--- a/configs/khadas-vim3_defconfig
+++ b/configs/khadas-vim3_defconfig
@@ -31,6 +31,8 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_ADC=y
 CONFIG_SARADC_MESON=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_ADC=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MESON=y
 CONFIG_DM_MMC=y
diff --git a/configs/khadas-vim3l_defconfig b/configs/khadas-vim3l_defconfig
index 6b13ce045c..c1877922c7 100644
--- a/configs/khadas-vim3l_defconfig
+++ b/configs/khadas-vim3l_defconfig
@@ -31,6 +31,8 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_ADC=y
 CONFIG_SARADC_MESON=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_ADC=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MESON=y
 CONFIG_DM_MMC=y
-- 
2.17.1



[PATCH v7 5/5] test: add a simple test for the adc-keys button driver

2021-02-18 Thread Marek Szyprowski
Add adc-keys device to the sandbox/test.dts and connect it to the channel
#3 of the sandbox_adc driver. The default values sampled by sandbox_adc
driver determines that button3 and button4 are released and button5 is
pressed.

Signed-off-by: Marek Szyprowski 
Reviewed-by: Simon Glass 
---
 arch/sandbox/dts/test.dts | 28 +-
 configs/sandbox_defconfig |  1 +
 test/dm/button.c  | 50 +--
 3 files changed, 76 insertions(+), 3 deletions(-)

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index e95f4631bf..202e091841 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -2,6 +2,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -69,6 +70,30 @@
};
};
 
+   buttons2 {
+   compatible = "adc-keys";
+   io-channels = < 3>;
+   keyup-threshold-microvolt = <300>;
+
+   button-up {
+   label = "button3";
+   linux,code = ;
+   press-threshold-microvolt = <150>;
+   };
+
+   button-down {
+   label = "button4";
+   linux,code = ;
+   press-threshold-microvolt = <100>;
+   };
+
+   button-enter {
+   label = "button5";
+   linux,code = ;
+   press-threshold-microvolt = <50>;
+   };
+   };
+
cros_ec: cros-ec {
reg = <0 0>;
compatible = "google,cros-ec-sandbox";
@@ -587,8 +612,9 @@
i2c-eeprom = <_i2c>;
};
 
-   adc@0 {
+   adc: adc@0 {
compatible = "sandbox,adc";
+   #io-channel-cells = <1>;
vdd-supply = <>;
vss-microvolts = <0>;
};
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 0c7674efc9..3731bf05ff 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -122,6 +122,7 @@ CONFIG_DM_BOOTCOUNT=y
 CONFIG_DM_BOOTCOUNT_RTC=y
 CONFIG_DM_BOOTCOUNT_I2C_EEPROM=y
 CONFIG_BUTTON=y
+CONFIG_BUTTON_ADC=y
 CONFIG_BUTTON_GPIO=y
 CONFIG_CLK=y
 CONFIG_CLK_COMPOSITE_CCF=y
diff --git a/test/dm/button.c b/test/dm/button.c
index ecaa47cf5f..f8a7fab61d 100644
--- a/test/dm/button.c
+++ b/test/dm/button.c
@@ -7,7 +7,10 @@
 
 #include 
 #include 
+#include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -17,11 +20,20 @@ static int dm_test_button_base(struct unit_test_state *uts)
 {
struct udevice *dev;
 
-   /* Get the top-level device */
+   /* Get the top-level gpio buttons device */
ut_assertok(uclass_get_device(UCLASS_BUTTON, 0, ));
+   /* Get the 2 gpio buttons */
ut_assertok(uclass_get_device(UCLASS_BUTTON, 1, ));
ut_assertok(uclass_get_device(UCLASS_BUTTON, 2, ));
-   ut_asserteq(-ENODEV, uclass_get_device(UCLASS_BUTTON, 3, ));
+
+   /* Get the top-level adc buttons device */
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 3, ));
+   /* Get the 3 adc buttons */
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 4, ));
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 5, ));
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 6, ));
+
+   ut_asserteq(-ENODEV, uclass_get_device(UCLASS_BUTTON, 7, ));
 
return 0;
 }
@@ -72,3 +84,37 @@ static int dm_test_button_label(struct unit_test_state *uts)
return 0;
 }
 DM_TEST(dm_test_button_label, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
+/* Test adc-keys driver */
+static int dm_test_button_keys_adc(struct unit_test_state *uts)
+{
+   struct udevice *supply;
+   struct udevice *dev;
+   int uV;
+
+   ut_assertok(uclass_get_device_by_name(UCLASS_ADC, "adc@0", ));
+
+   ut_assertok(regulator_get_by_devname(SANDBOX_BUCK2_DEVNAME, ));
+   ut_assertok(regulator_set_value(supply, SANDBOX_BUCK2_SET_UV));
+   ut_asserteq(SANDBOX_BUCK2_SET_UV, regulator_get_value(supply));
+   /* Update ADC plat and get new Vdd value */
+   ut_assertok(adc_vdd_value(dev, ));
+   ut_asserteq(SANDBOX_BUCK2_SET_UV, uV);
+
+   /*
+* sandbox-adc returns constant value on channel 3, is used by adc-keys:
+* SANDBOX_ADC_CHANNEL3_DATA * SANDBOX_BUCK2_SET_UV / 
SANDBOX_ADC_DATA_MASK =
+* 0x3000 * 330 / 0x = 618759uV
+* This means that button3 and button4 are released and button5
+* is pressed.
+*/
+   ut_assertok(button_get_by_label("button3", ));
+   ut_asserteq(BUTTON_OFF, button_get_state(dev));
+   ut_assertok(button_get_by_label("button4", ));
+   ut_asserteq(BUTTON_OFF, button_get_state(dev));
+   ut_assertok(button_get_by_la

[PATCH v6 5/5] test: add a simple test for the adc-keys button driver

2021-02-11 Thread Marek Szyprowski
Add adc-keys device to the sandbox/test.dts and connect it to the channel
#3 of the sandbox_adc driver. The default values sampled by sandbox_adc
driver determines that button3 and button4 are released and button5 is
pressed.

Signed-off-by: Marek Szyprowski 
---
 arch/sandbox/dts/test.dts | 24 ++-
 configs/sandbox_defconfig |  1 +
 test/dm/button.c  | 50 +--
 3 files changed, 72 insertions(+), 3 deletions(-)

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index e95f4631bf..a32b019ae7 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -69,6 +69,27 @@
};
};
 
+   buttons2 {
+   compatible = "adc-keys";
+   io-channels = < 3>;
+   keyup-threshold-microvolt = <300>;
+
+   button-up {
+   label = "button3";
+   press-threshold-microvolt = <150>;
+   };
+
+   button-down {
+   label = "button4";
+   press-threshold-microvolt = <100>;
+   };
+
+   button-enter {
+   label = "button5";
+   press-threshold-microvolt = <50>;
+   };
+   };
+
cros_ec: cros-ec {
reg = <0 0>;
compatible = "google,cros-ec-sandbox";
@@ -587,8 +608,9 @@
i2c-eeprom = <_i2c>;
};
 
-   adc@0 {
+   adc: adc@0 {
compatible = "sandbox,adc";
+   #io-channel-cells = <1>;
vdd-supply = <>;
vss-microvolts = <0>;
};
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 0c7674efc9..3731bf05ff 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -122,6 +122,7 @@ CONFIG_DM_BOOTCOUNT=y
 CONFIG_DM_BOOTCOUNT_RTC=y
 CONFIG_DM_BOOTCOUNT_I2C_EEPROM=y
 CONFIG_BUTTON=y
+CONFIG_BUTTON_ADC=y
 CONFIG_BUTTON_GPIO=y
 CONFIG_CLK=y
 CONFIG_CLK_COMPOSITE_CCF=y
diff --git a/test/dm/button.c b/test/dm/button.c
index ecaa47cf5f..f8a7fab61d 100644
--- a/test/dm/button.c
+++ b/test/dm/button.c
@@ -7,7 +7,10 @@
 
 #include 
 #include 
+#include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -17,11 +20,20 @@ static int dm_test_button_base(struct unit_test_state *uts)
 {
struct udevice *dev;
 
-   /* Get the top-level device */
+   /* Get the top-level gpio buttons device */
ut_assertok(uclass_get_device(UCLASS_BUTTON, 0, ));
+   /* Get the 2 gpio buttons */
ut_assertok(uclass_get_device(UCLASS_BUTTON, 1, ));
ut_assertok(uclass_get_device(UCLASS_BUTTON, 2, ));
-   ut_asserteq(-ENODEV, uclass_get_device(UCLASS_BUTTON, 3, ));
+
+   /* Get the top-level adc buttons device */
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 3, ));
+   /* Get the 3 adc buttons */
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 4, ));
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 5, ));
+   ut_assertok(uclass_get_device(UCLASS_BUTTON, 6, ));
+
+   ut_asserteq(-ENODEV, uclass_get_device(UCLASS_BUTTON, 7, ));
 
return 0;
 }
@@ -72,3 +84,37 @@ static int dm_test_button_label(struct unit_test_state *uts)
return 0;
 }
 DM_TEST(dm_test_button_label, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
+/* Test adc-keys driver */
+static int dm_test_button_keys_adc(struct unit_test_state *uts)
+{
+   struct udevice *supply;
+   struct udevice *dev;
+   int uV;
+
+   ut_assertok(uclass_get_device_by_name(UCLASS_ADC, "adc@0", ));
+
+   ut_assertok(regulator_get_by_devname(SANDBOX_BUCK2_DEVNAME, ));
+   ut_assertok(regulator_set_value(supply, SANDBOX_BUCK2_SET_UV));
+   ut_asserteq(SANDBOX_BUCK2_SET_UV, regulator_get_value(supply));
+   /* Update ADC plat and get new Vdd value */
+   ut_assertok(adc_vdd_value(dev, ));
+   ut_asserteq(SANDBOX_BUCK2_SET_UV, uV);
+
+   /*
+* sandbox-adc returns constant value on channel 3, is used by adc-keys:
+* SANDBOX_ADC_CHANNEL3_DATA * SANDBOX_BUCK2_SET_UV / 
SANDBOX_ADC_DATA_MASK =
+* 0x3000 * 330 / 0x = 618759uV
+* This means that button3 and button4 are released and button5
+* is pressed.
+*/
+   ut_assertok(button_get_by_label("button3", ));
+   ut_asserteq(BUTTON_OFF, button_get_state(dev));
+   ut_assertok(button_get_by_label("button4", ));
+   ut_asserteq(BUTTON_OFF, button_get_state(dev));
+   ut_assertok(button_get_by_label("button5", ));
+   ut_asserteq(BUTTON_ON, button_get_state(dev));
+
+   return 0;
+}
+DM_TEST(dm_test_button_keys_adc, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
-- 
2.17.1



[PATCH v6 2/5] button: add a simple Analog to Digital Converter device based button driver

2021-02-11 Thread Marek Szyprowski
Add a simple Analog to Digital Converter device based button driver. This
driver binds to the 'adc-keys' device tree node.

Signed-off-by: Marek Szyprowski 
---
 drivers/button/Kconfig  |   8 ++
 drivers/button/Makefile |   1 +
 drivers/button/button-adc.c | 146 
 3 files changed, 155 insertions(+)
 create mode 100644 drivers/button/button-adc.c

diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig
index 6b3ec7e55d..6db3c5e93a 100644
--- a/drivers/button/Kconfig
+++ b/drivers/button/Kconfig
@@ -9,6 +9,14 @@ config BUTTON
  can provide access to board-specific buttons. Use of the device tree
  for configuration is encouraged.
 
+config BUTTON_ADC
+   bool "Button adc"
+   depends on BUTTON
+   help
+ Enable support for buttons which are connected to Analog to Digital
+ Converter device. The ADC driver must use driver model. Buttons are
+ configured using the device tree.
+
 config BUTTON_GPIO
bool "Button gpio"
depends on BUTTON
diff --git a/drivers/button/Makefile b/drivers/button/Makefile
index fcc10ebe8d..bbd18af149 100644
--- a/drivers/button/Makefile
+++ b/drivers/button/Makefile
@@ -3,4 +3,5 @@
 # Copyright (C) 2020 Philippe Reynes 
 
 obj-$(CONFIG_BUTTON) += button-uclass.o
+obj-$(CONFIG_BUTTON_ADC) += button-adc.o
 obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o
diff --git a/drivers/button/button-adc.c b/drivers/button/button-adc.c
new file mode 100644
index 00..eed86564fb
--- /dev/null
+++ b/drivers/button/button-adc.c
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Author: Marek Szyprowski 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * struct button_adc_priv - private data for button-adc driver.
+ *
+ * @adc: Analog to Digital Converter device to which button is connected.
+ * @channel: channel of the ADC device to probe the button state.
+ * @min: minimal uV value to consider button as pressed.
+ * @max: maximal uV value to consider button as pressed.
+ */
+struct button_adc_priv {
+   struct udevice *adc;
+   int channel;
+   int min;
+   int max;
+};
+
+static enum button_state_t button_adc_get_state(struct udevice *dev)
+{
+   struct button_adc_priv *priv = dev_get_priv(dev);
+   unsigned int val;
+   int ret, uV;
+
+   ret = adc_start_channel(priv->adc, priv->channel);
+   if (ret)
+   return ret;
+
+   ret = adc_channel_data(priv->adc, priv->channel, );
+   if (ret)
+   return ret;
+
+   ret = adc_raw_to_uV(priv->adc, val, );
+   if (ret)
+   return ret;
+
+   return (uV >= priv->min && uV < priv->max) ? BUTTON_ON : BUTTON_OFF;
+}
+
+static int button_adc_of_to_plat(struct udevice *dev)
+{
+   struct button_uc_plat *uc_plat = dev_get_uclass_plat(dev);
+   struct button_adc_priv *priv = dev_get_priv(dev);
+   struct ofnode_phandle_args args;
+   u32 treshold, up_treshold, t;
+   ofnode node;
+   int ret;
+
+   /* Ignore the top-level button node */
+   if (!uc_plat->label)
+   return 0;
+
+   ret = dev_read_phandle_with_args(dev->parent, "io-channels",
+"#io-channel-cells", 0, 0, );
+   if (ret)
+   return ret;
+
+   ret = uclass_get_device_by_ofnode(UCLASS_ADC, args.node, >adc);
+   if (ret)
+   return ret;
+
+   ret = ofnode_read_u32(dev_ofnode(dev->parent),
+ "keyup-threshold-microvolt", _treshold);
+   if (ret)
+   return ret;
+
+   ret = ofnode_read_u32(dev_ofnode(dev), "press-threshold-microvolt",
+ );
+   if (ret)
+   return ret;
+
+   dev_for_each_subnode(node, dev->parent) {
+   ret = ofnode_read_u32(node, "press-threshold-microvolt", );
+   if (ret)
+   return ret;
+
+   if (t > treshold)
+   up_treshold = t;
+   }
+
+   priv->channel = args.args[0];
+   priv->min = treshold;
+   priv->max = up_treshold;
+
+   return ret;
+}
+
+static int button_adc_bind(struct udevice *parent)
+{
+   struct udevice *dev;
+   ofnode node;
+   int ret;
+
+   dev_for_each_subnode(node, parent) {
+   struct button_uc_plat *uc_plat;
+   const char *label;
+
+   label = ofnode_read_string(node, "label");
+   if (!label) {
+   debug("%s: node %s has no label\n", __func__,
+ ofnode_get_name(node));
+   return -EINVAL;
+ 

[PATCH v6 4/5] configs: khadas-vim3(l): enable Function button support

2021-02-11 Thread Marek Szyprowski
Add options required to check the 'Function' button state.

Signed-off-by: Marek Szyprowski 
Reviewed-by: Simon Glass 
---
 configs/khadas-vim3_defconfig  | 2 ++
 configs/khadas-vim3l_defconfig | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/configs/khadas-vim3_defconfig b/configs/khadas-vim3_defconfig
index 5d16652fd6..bc17430569 100644
--- a/configs/khadas-vim3_defconfig
+++ b/configs/khadas-vim3_defconfig
@@ -31,6 +31,8 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_ADC=y
 CONFIG_SARADC_MESON=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_ADC=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MESON=y
 CONFIG_DM_MMC=y
diff --git a/configs/khadas-vim3l_defconfig b/configs/khadas-vim3l_defconfig
index 6b13ce045c..c1877922c7 100644
--- a/configs/khadas-vim3l_defconfig
+++ b/configs/khadas-vim3l_defconfig
@@ -31,6 +31,8 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_ADC=y
 CONFIG_SARADC_MESON=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_ADC=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MESON=y
 CONFIG_DM_MMC=y
-- 
2.17.1



[PATCH v6 0/5] VIM3: add support for checking 'Function' button state

2021-02-11 Thread Marek Szyprowski
Hi All,

This patchset adds all building blocks needed for checking the 'Function'
button state in the boot script on Amlogic A311D based VIM3 board. This
button is connected to the ADC line of the SoC, so it required to enable
meson SARADC, the clocks needed for it and a simple button-adc drivers.

Once applied, one can use following commands in the boot scripts:
-->8---
echo Checking Func button state: \\c
if button Function
then
echo Selected alternative boot
...
fi
--->8---

Best regards
Marek Szyprowski
Samsung R Institute Poland


Changelog:
v6:
- added a simple sandbox test for adc-keys
- use of_to_plat and adc_raw_to_uV to simplify code in the adc button driver

v5: https://lists.denx.de/pipermail/u-boot/2021-January/438751.html
- rebased onto latest uboot-amlogic/u-boot-amlogic-next branch
- synchronized adc-keys binding with the recent version from the Linux
  kernel
- updated adc-keys driver to match behavior from dt-bindings
- added a patch for meson-saradc driver to register vdd reference supply
  to the ADC framework

v4: https://lists.denx.de/pipermail/u-boot/2020-December/435641.html
- rebased onto uboot-amlogic/u-boot-amlogic-next and dropped merged patches
- added adc-keys bindings docs (copied from Linux kernel)
- minor code adjustments pointed by Simon
- enabled driver also in khadas-vim3l_defconfig

v3: https://lists.denx.de/pipermail/u-boot/2020-December/435072.html
- removed 'button' env variable
- extended kconfig and patch descriptions

v2: https://lists.denx.de/pipermail/u-boot/2020-December/434991.html
- removed Change-Id tags
- split defconfig changes into ADC and button related

v1: https://lists.denx.de/pipermail/u-boot/2020-December/434875.html
- initial submission


Patch summary:

Marek Szyprowski (5):
  dt-bindings: input: adc-keys bindings documentation
  button: add a simple Analog to Digital Converter device based button
driver
  adc: meson-saradc: add support for getting reference voltage value
  configs: khadas-vim3(l): enable Function button support
  test: add a simple test for the adc-keys button driver

 arch/sandbox/dts/test.dts   |  24 +++-
 configs/khadas-vim3_defconfig   |   2 +
 configs/khadas-vim3l_defconfig  |   2 +
 configs/sandbox_defconfig   |   1 +
 doc/device-tree-bindings/input/adc-keys.txt |  67 +
 drivers/adc/meson-saradc.c  |  21 +++
 drivers/button/Kconfig  |   8 ++
 drivers/button/Makefile |   1 +
 drivers/button/button-adc.c | 146 
 test/dm/button.c|  50 ++-
 10 files changed, 319 insertions(+), 3 deletions(-)
 create mode 100644 doc/device-tree-bindings/input/adc-keys.txt
 create mode 100644 drivers/button/button-adc.c

-- 
2.17.1



[PATCH v6 1/5] dt-bindings: input: adc-keys bindings documentation

2021-02-11 Thread Marek Szyprowski
Dump adc-keys bindings documentation from Linux kernel source tree from
commit 698dc0cf9447 ("dt-bindings: input: adc-keys: clarify
description").

Signed-off-by: Marek Szyprowski 
Reviewed-by: Simon Glass 
---
 doc/device-tree-bindings/input/adc-keys.txt | 67 +
 1 file changed, 67 insertions(+)
 create mode 100644 doc/device-tree-bindings/input/adc-keys.txt

diff --git a/doc/device-tree-bindings/input/adc-keys.txt 
b/doc/device-tree-bindings/input/adc-keys.txt
new file mode 100644
index 00..6c8be6a9ac
--- /dev/null
+++ b/doc/device-tree-bindings/input/adc-keys.txt
@@ -0,0 +1,67 @@
+ADC attached resistor ladder buttons
+
+
+Required properties:
+ - compatible: "adc-keys"
+ - io-channels: Phandle to an ADC channel
+ - io-channel-names = "buttons";
+ - keyup-threshold-microvolt: Voltage above or equal to which all the keys are
+ considered up.
+
+Optional properties:
+   - poll-interval: Poll interval time in milliseconds
+   - autorepeat: Boolean, Enable auto repeat feature of Linux input
+ subsystem.
+
+Each button (key) is represented as a sub-node of "adc-keys":
+
+Required subnode-properties:
+   - label: Descriptive name of the key.
+   - linux,code: Keycode to emit.
+   - press-threshold-microvolt: voltage above or equal to which this key is
+considered pressed.
+
+No two values of press-threshold-microvolt may be the same.
+All values of press-threshold-microvolt must be less than
+keyup-threshold-microvolt.
+
+Example:
+
+#include 
+
+   adc-keys {
+   compatible = "adc-keys";
+   io-channels = < 0>;
+   io-channel-names = "buttons";
+   keyup-threshold-microvolt = <200>;
+
+   button-up {
+   label = "Volume Up";
+   linux,code = ;
+   press-threshold-microvolt = <150>;
+   };
+
+   button-down {
+   label = "Volume Down";
+   linux,code = ;
+   press-threshold-microvolt = <100>;
+   };
+
+   button-enter {
+   label = "Enter";
+   linux,code = ;
+   press-threshold-microvolt = <50>;
+   };
+   };
+
++++
+| 2.000.000 <= value | no key pressed |
++++
+| 1.500.000 <= value < 2.000.000 | KEY_VOLUMEUP pressed   |
++++
+| 1.000.000 <= value < 1.500.000 | KEY_VOLUMEDOWN pressed |
++++
+|   500.000 <= value < 1.000.000 | KEY_ENTER pressed  |
++++
+|  value <   500.000 | no key pressed |
++++
-- 
2.17.1



[PATCH v6 3/5] adc: meson-saradc: add support for getting reference voltage value

2021-02-11 Thread Marek Szyprowski
Add support for getting the 'vref-supply' regulator and register it as
ADC's reference voltage regulator, so clients can translate sampled ADC
values to the voltage.

Signed-off-by: Marek Szyprowski 
Reviewed-by: Simon Glass 
---
 drivers/adc/meson-saradc.c | 21 +
 1 file changed, 21 insertions(+)

diff --git a/drivers/adc/meson-saradc.c b/drivers/adc/meson-saradc.c
index 21db55831d..1a45a3a265 100644
--- a/drivers/adc/meson-saradc.c
+++ b/drivers/adc/meson-saradc.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define MESON_SAR_ADC_REG0 0x00
#define MESON_SAR_ADC_REG0_PANEL_DETECT BIT(31)
@@ -656,7 +657,10 @@ static int meson_saradc_stop(struct udevice *dev)
 
 static int meson_saradc_probe(struct udevice *dev)
 {
+   struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
struct meson_saradc_priv *priv = dev_get_priv(dev);
+   struct udevice *vref;
+   int vref_uv;
int ret;
 
ret = regmap_init_mem(dev_ofnode(dev), >regmap);
@@ -675,6 +679,23 @@ static int meson_saradc_probe(struct udevice *dev)
 
priv->active_channel = -1;
 
+   ret = device_get_supply_regulator(dev, "vref-supply", );
+   if (ret) {
+   printf("can't get vref-supply: %d\n", ret);
+   return ret;
+   }
+
+   vref_uv = regulator_get_value(vref);
+   if (vref_uv < 0) {
+   printf("can't get vref-supply value: %d\n", vref_uv);
+   return vref_uv;
+   }
+
+   /* VDD supplied by common vref pin */
+   uc_pdata->vdd_supply = vref;
+   uc_pdata->vdd_microvolts = vref_uv;
+   uc_pdata->vss_microvolts = 0;
+
return 0;
 }
 
-- 
2.17.1



Re: [PATCH v5 2/4] button: add a simple Analog to Digital Converter device based button driver

2021-02-09 Thread Marek Szyprowski
Hi Simon,

On 08.02.2021 18:08, Simon Glass wrote:
> On Mon, 8 Feb 2021 at 09:10, Marek Szyprowski  
> wrote:
>> On 06.02.2021 17:21, Simon Glass wrote:
>>> On Thu, 4 Feb 2021 at 03:36, Marek Szyprowski  
>>> wrote:
>>>> ...
>>>> Could you give me a bit more hints or point where to start? I've tried
>>>> to build sandbox, but it fails for v2021.01 release (I've did make
>>>> sandbox_defconfig && make all). I assume I would need to add adc and
>>>> adc-keys devices to some sandbox dts and some code triggering and
>>>> checking the key values, but that's all I know now.
>>> Well you do need to be able to build sandbox or you will get
>>> nowhere...what error did you get? Once we understand what went wrong
>>> we can update the docs. Maybe it is missing a dependency.
>> $ gcc --version
>> gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
>> Copyright (C) 2017 Free Software Foundation, Inc.
>> This is free software; see the source for copying conditions. There is NO
>> warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
>>
>> $ git checkout v2021.01
>>
>> $ make sandbox_defconfig
>> #
>> # configuration written to .config
>> #
>>
>> $ make
>> scripts/kconfig/conf  --syncconfig Kconfig
>> CFG u-boot.cfg
>> GEN include/autoconf.mk
>> GEN include/autoconf.mk.dep
>> CFGCHK  u-boot.cfg
>> UPD include/generated/timestamp_autogenerated.h
>> HOSTCC  tools/mkenvimage.o
>> HOSTLD  tools/mkenvimage
>> HOSTCC  tools/fit_image.o
>> HOSTCC  tools/image-host.o
>> HOSTCC  tools/dumpimage.o
>> HOSTLD  tools/dumpimage
>> HOSTCC  tools/mkimage.o
>> HOSTLD  tools/mkimage
>> HOSTLD  tools/fit_info
>> HOSTLD  tools/fit_check_sign
>>
>> ...
>>
>> CC  arch/sandbox/cpu/cpu.o
>> In file included from include/common.h:26:0,
>>from arch/sandbox/cpu/cpu.c:6:
>> include/asm/global_data.h:112:58: warning: call-clobbered register used
>> for global register variable
>>#define DECLARE_GLOBAL_DATA_PTR  register volatile gd_t *gd asm ("r9")
>> ^
>> include/dm/of.h:86:1: note: in expansion of macro ‘DECLARE_GLOBAL_DATA_PTR’
>>DECLARE_GLOBAL_DATA_PTR;
> This is pretty mysterious. Are you sure you are using an x86_64 machine?

I've finally found what caused the issue on my build system. It is 
x86_64 machine, but after some old cross-builds I had an 'asm' symlink 
in u-boot/include directory pointing to arch/arm directory. I'm quite 
surprised that it has not been removed by make clean/distclean/mrproper 
combo.

Best regards

-- 
Marek Szyprowski, PhD
Samsung R Institute Poland



Re: [PATCH v5 2/4] button: add a simple Analog to Digital Converter device based button driver

2021-02-08 Thread Marek Szyprowski
Hi Simon,

On 06.02.2021 17:21, Simon Glass wrote:
> On Thu, 4 Feb 2021 at 03:36, Marek Szyprowski  
> wrote:
>> ...
>> Could you give me a bit more hints or point where to start? I've tried
>> to build sandbox, but it fails for v2021.01 release (I've did make
>> sandbox_defconfig && make all). I assume I would need to add adc and
>> adc-keys devices to some sandbox dts and some code triggering and
>> checking the key values, but that's all I know now.
> Well you do need to be able to build sandbox or you will get
> nowhere...what error did you get? Once we understand what went wrong
> we can update the docs. Maybe it is missing a dependency.

$ gcc --version
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ git checkout v2021.01

$ make sandbox_defconfig
#
# configuration written to .config
#

$ make
scripts/kconfig/conf  --syncconfig Kconfig
   CFG u-boot.cfg
   GEN include/autoconf.mk
   GEN include/autoconf.mk.dep
   CFGCHK  u-boot.cfg
   UPD include/generated/timestamp_autogenerated.h
   HOSTCC  tools/mkenvimage.o
   HOSTLD  tools/mkenvimage
   HOSTCC  tools/fit_image.o
   HOSTCC  tools/image-host.o
   HOSTCC  tools/dumpimage.o
   HOSTLD  tools/dumpimage
   HOSTCC  tools/mkimage.o
   HOSTLD  tools/mkimage
   HOSTLD  tools/fit_info
   HOSTLD  tools/fit_check_sign

...

   CC  arch/sandbox/cpu/cpu.o
In file included from include/common.h:26:0,
  from arch/sandbox/cpu/cpu.c:6:
include/asm/global_data.h:112:58: warning: call-clobbered register used 
for global register variable
  #define DECLARE_GLOBAL_DATA_PTR  register volatile gd_t *gd asm ("r9")
   ^
include/dm/of.h:86:1: note: in expansion of macro ‘DECLARE_GLOBAL_DATA_PTR’
  DECLARE_GLOBAL_DATA_PTR;
  ^~~
In file included from arch/sandbox/cpu/cpu.c:18:0:
./arch/sandbox/include/asm/state.h:98:30: error: 
‘CONFIG_SANDBOX_SPI_MAX_BUS’ undeclared here (not in a function); did 
you mean ‘CONFIG_SANDBOX_SPI’?
   struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS]
   ^~
   CONFIG_SANDBOX_SPI
./arch/sandbox/include/asm/state.h:99:7: error: 
‘CONFIG_SANDBOX_SPI_MAX_CS’ undeclared here (not in a function); did you 
mean ‘CONFIG_SANDBOX_SPI_MAX_BUS’?
   [CONFIG_SANDBOX_SPI_MAX_CS];
    ^
    CONFIG_SANDBOX_SPI_MAX_BUS
arch/sandbox/cpu/cpu.c: In function ‘is_in_sandbox_mem’:
arch/sandbox/cpu/cpu.c:83:41: error: ‘volatile struct arch_global_data’ 
has no member named ‘ram_buf’
   return (const uint8_t *)ptr >= gd->arch.ram_buf &&
  ^
arch/sandbox/cpu/cpu.c:84:34: error: ‘volatile struct arch_global_data’ 
has no member named ‘ram_buf’
    (const uint8_t *)ptr < gd->arch.ram_buf + gd->ram_size;
   ^
arch/sandbox/cpu/cpu.c: At top level:
arch/sandbox/cpu/cpu.c:97:7: error: redefinition of ‘phys_to_virt’
  void *phys_to_virt(phys_addr_t paddr)
    ^~~~
In file included from include/asm/io.h:495:0,
  from arch/sandbox/cpu/cpu.c:15:
include/asm-generic/io.h:30:21: note: previous definition of 
‘phys_to_virt’ was here
  static inline void *phys_to_virt(phys_addr_t paddr)
  ^~~~
arch/sandbox/cpu/cpu.c: In function ‘phys_to_virt’:
arch/sandbox/cpu/cpu.c:104:27: error: ‘volatile struct arch_global_data’ 
has no member named ‘ram_buf’
    return (void *)(gd->arch.ram_buf + paddr);
    ^
In file included from include/linux/posix_types.h:4:0,
  from include/linux/types.h:4,
  from include/time.h:7,
  from include/common.h:18,
  from arch/sandbox/cpu/cpu.c:6:
include/linux/stddef.h:17:33: warning: cast from pointer to integer of 
different size [-Wpointer-to-int-cast]
  #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
  ^
include/linux/kernel.h:274:29: note: in expansion of macro ‘offsetof’
   (type *)( (char *)__mptr - offsetof(type,member) );})
  ^~~~
include/linux/list.h:327:2: note: in expansion of macro ‘container_of’
   container_of(ptr, type, member)
   ^~~~
include/linux/list.h:424:13: note: in expansion of macro ‘list_entry’
   for (pos = list_entry((head)->next, typeof(*pos), member); \
  ^~
arch/sandbox/cpu/cpu.c:111:2: note: in expansion of macro 
‘list_for_each_entry’
   list_for_each_entry(mentry, >mapmem_head, sibling_node) {
   ^~~
include/linux/stddef.h:17:33: warning: cast from pointer to intege

Re: [PATCH v5 2/4] button: add a simple Analog to Digital Converter device based button driver

2021-02-04 Thread Marek Szyprowski
Hi Simon,

On 01.02.2021 21:38, Simon Glass wrote:
> On Tue, 26 Jan 2021 at 06:03, Heinrich Schuchardt  wrote:
>> On 26.01.21 12:25, Marek Szyprowski wrote:
>>> On 26.01.2021 12:10, Heinrich Schuchardt wrote:
>>>> On 1/26/21 10:50 AM, Marek Szyprowski wrote:
>>>>> Add a simple Analog to Digital Converter device based button driver.
>>>>> This
>>>>> driver binds to the 'adc-keys' device tree node.
>>>>>
>>>>> Signed-off-by: Marek Szyprowski 
>>>>> ---
>>>>>drivers/button/Kconfig  |   8 ++
>>>>>drivers/button/Makefile |   1 +
>>>>>drivers/button/button-adc.c | 156 
>>>>>3 files changed, 165 insertions(+)
>>>>>create mode 100644 drivers/button/button-adc.c
>>>>>
>>>>> diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig
>>>>> index 6b3ec7e55d..6db3c5e93a 100644
>>>>> --- a/drivers/button/Kconfig
>>>>> +++ b/drivers/button/Kconfig
>>>>> @@ -9,6 +9,14 @@ config BUTTON
>>>>>  can provide access to board-specific buttons. Use of the
>>>>> device tree
>>>>>  for configuration is encouraged.
>>>>>
>>>>> +config BUTTON_ADC
>>>>> +bool "Button adc"
>>>>> +depends on BUTTON
>>>>> +help
>>>>> +  Enable support for buttons which are connected to Analog to
>>>>> Digital
>>>>> +  Converter device. The ADC driver must use driver model.
>>>>> Buttons are
>>>>> +  configured using the device tree.
>>>>> +
>>>>>config BUTTON_GPIO
>>>>>bool "Button gpio"
>>>>>depends on BUTTON
>>>>> diff --git a/drivers/button/Makefile b/drivers/button/Makefile
>>>>> index fcc10ebe8d..bbd18af149 100644
>>>>> --- a/drivers/button/Makefile
>>>>> +++ b/drivers/button/Makefile
>>>>> @@ -3,4 +3,5 @@
>>>>># Copyright (C) 2020 Philippe Reynes 
>>>>>
>>>>>obj-$(CONFIG_BUTTON) += button-uclass.o
>>>>> +obj-$(CONFIG_BUTTON_ADC) += button-adc.o
>>>>>obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o
>>>>> diff --git a/drivers/button/button-adc.c b/drivers/button/button-adc.c
>>>>> new file mode 100644
>>>>> index 00..1901d59a0e
>>>>> --- /dev/null
>>>>> +++ b/drivers/button/button-adc.c
>>>>> @@ -0,0 +1,156 @@
>>>>> +// SPDX-License-Identifier: GPL-2.0
>>>>> +/*
>>>>> + * Copyright (C) 2021 Samsung Electronics Co., Ltd.
>>>>> + *http://www.samsung.com
>>>>> + * Author: Marek Szyprowski 
>>>>> + */
>>>>> +
>>>>> +#include 
>>>>> +#include 
>>>>> +#include 
>>>>> +#include 
>>>>> +#include 
>>>>> +#include 
>>>>> +#include 
>>>>> +#include 
>>>>> +
>>>>> +/**
>>>>> + * struct button_adc_priv - private data for button-adc driver.
>>>>> + *
>>>>> + * @adc: Analog to Digital Converter device to which button is
>>>>> connected.
>>>>> + * @channel: channel of the ADC device to probe the button state.
>>>>> + * @min: minimal raw ADC sample value to consider button as pressed.
>>>>> + * @max: maximal raw ADC sample value to consider button as pressed.
>>>>> + */
>>>>> +struct button_adc_priv {
>>>>> +struct udevice *adc;
>>>>> +int channel;
>>>>> +int min;
>>>>> +int max;
>>>>> +};
>>>>> +
>>>>> +static enum button_state_t button_adc_get_state(struct udevice *dev)
>>>>> +{
>>>>> +struct button_adc_priv *priv = dev_get_priv(dev);
>>>>> +unsigned int val;
>>>>> +int ret;
>>>>> +
>>>>> +ret = adc_start_channel(priv->adc, priv->channel);
>>>>> +if (ret)
>>>>> +return ret;
>>>>> +
>>>>> +ret = adc_channel_data(priv->adc, priv->channel, );
>>>>> +if (ret)
>>>>> +return ret;
>&g

[PATCH] board: amlogic: odroid: add runtime detection of the N2/N2+/C4/HC4 variants

2021-02-04 Thread Marek Szyprowski
Use the ADC channel 1 to check the hardware revision of the board and
detect the N2 vs. N2+ and the C4 vs. HC4 variants. Each of them use
different dtb file, so adjust fdtfile environment variable to the
detected variant.

The ADC min/max values for each variant are taken from the vendor code,
adjusted to the 12-bit ADC driver operation mode (vendor code use 10-bit
mode).

Signed-off-by: Marek Szyprowski 
---
The relevant vendor's code is here:
https://github.com/hardkernel/u-boot/blob/odroidg12-v2015.01/board/hardkernel/odroid-common/board.c#L55
---
 arch/arm/dts/meson-g12b-odroid-n2-u-boot.dtsi |  6 ++
 arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi  |  6 ++
 board/amlogic/odroid-n2/odroid-n2.c   | 80 +++
 configs/odroid-c4_defconfig   |  4 +-
 configs/odroid-n2_defconfig   |  4 +-
 5 files changed, 98 insertions(+), 2 deletions(-)

diff --git a/arch/arm/dts/meson-g12b-odroid-n2-u-boot.dtsi 
b/arch/arm/dts/meson-g12b-odroid-n2-u-boot.dtsi
index 236f2468dc..a92f9e9ff1 100644
--- a/arch/arm/dts/meson-g12b-odroid-n2-u-boot.dtsi
+++ b/arch/arm/dts/meson-g12b-odroid-n2-u-boot.dtsi
@@ -5,3 +5,9 @@
  */
 
 #include "meson-g12-common-u-boot.dtsi"
+
+/* SARADC is needed for proper board variant detection */
+ {
+   status = "okay";
+   vref-supply = <_1v8>;
+};
diff --git a/arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi 
b/arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi
index fbcc8287c5..963bf96b25 100644
--- a/arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi
+++ b/arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi
@@ -12,6 +12,12 @@
snps,reset-active-low;
 };
 
+/* SARADC is needed for proper board variant detection */
+ {
+   status = "okay";
+   vref-supply = <_1v8>;
+};
+
 _vdd {
gpio = <_ao GPIOAO_3 GPIO_OPEN_DRAIN>;
 };
diff --git a/board/amlogic/odroid-n2/odroid-n2.c 
b/board/amlogic/odroid-n2/odroid-n2.c
index d9955433bf..2eb7fa93be 100644
--- a/board/amlogic/odroid-n2/odroid-n2.c
+++ b/board/amlogic/odroid-n2/odroid-n2.c
@@ -6,6 +6,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -19,6 +20,11 @@
 #define EFUSE_MAC_SIZE 12
 #define MAC_ADDR_LEN   6
 
+#define ODROID_HW_VS_ADC_CHANNEL   1
+
+#define MESON_SOC_ID_G12B  0x29
+#define MESON_SOC_ID_SM1   0x2b
+
 int mmc_get_env_dev(void)
 {
if (meson_get_boot_device() == BOOT_DEVICE_EMMC)
@@ -26,6 +32,79 @@ int mmc_get_env_dev(void)
return 0;
 }
 
+/* Variant detection is based on the ADC RAW values for the channel #1 */
+static struct meson_odroid_boards {
+   unsigned int soc_id;
+   unsigned int adc_min;
+   unsigned int adc_max;
+   char *variant;
+} boards[] = {
+   /* OdroidN2 rev 2018,7,23 */
+   { MESON_SOC_ID_G12B, 80 * 4,  90 * 4, "n2" },
+   /* OdroidN2 rev 2018,12,6 */
+   { MESON_SOC_ID_G12B, 160 * 4, 170 * 4, "n2" },
+   /* OdroidN2 rev 2019,1,17 */
+   { MESON_SOC_ID_G12B, 245 * 4, 255 * 4, "n2" },
+   /* OdroidN2 rev 2019,2,7 */
+   { MESON_SOC_ID_G12B, 330 * 4, 350 * 4, "n2" },
+   /* OdroidN2plus rev 2019,11,20 */
+   { MESON_SOC_ID_G12B, 410 * 4, 430 * 4, "n2_plus" },
+   /* OdroidC4 rev 2020,01,29 */
+   { MESON_SOC_ID_SM1,   80 * 4, 100 * 4, "c4" },
+   /* OdroidHC4 rev 2019,12,10 */
+   { MESON_SOC_ID_SM1,  300 * 4, 320 * 4, "hc4" },
+   /* OdroidC4 rev 2019,11,29 */
+   { MESON_SOC_ID_SM1,  335 * 4, 345 * 4, "c4" },
+   /* OdroidHC4 rev 2020,8,7 */
+   { MESON_SOC_ID_SM1,  590 * 4, 610 * 4, "hc4" },
+};
+
+static void odroid_set_fdtfile(char *soc, char *variant)
+{
+   char s[128];
+
+   snprintf(s, sizeof(s), "amlogic/meson-%s-odroid-%s.dtb", soc, variant);
+   env_set("fdtfile", s);
+}
+
+static int odroid_detect_variant(void)
+{
+   char *variant = "", *soc = "";
+   unsigned int adcval = 0;
+   int ret, i, soc_id = 0;
+
+   if (of_machine_is_compatible("amlogic,sm1")) {
+   soc_id = MESON_SOC_ID_SM1;
+   soc = "sm1";
+   } else if (of_machine_is_compatible("amlogic,g12b")) {
+   soc_id = MESON_SOC_ID_G12B;
+   soc = "g12b";
+   } else {
+   return -1;
+   }
+
+   ret = adc_channel_single_shot("adc@9000", ODROID_HW_VS_ADC_CHANNEL,
+ );
+   if (ret)
+   return ret;
+
+   for (i = 0 ; i < ARRAY_SIZE(boards) ; ++i) {
+   if (soc_id == boards[i].soc_id &&
+   adcval >= boards[i].adc_min &&
+   adcval < boards[i].adc_max) {
+   variant = boards[i].variant;
+   break;
+   }
+   }
+
+

[PATCH] rpi: limit size of the RAM to the multiple of the MMU_SECTION_SIZE

2021-02-01 Thread Marek Szyprowski
When RPi4 is booted from USB Mass Storage, the firmware reports 947MiB of
the ARM memory (948 in case of the standard SD-card boot). This value is
not MMU_SECTION_SIZE aligned, so the dram_bank_mmu_setup() skips mapping
of the last 1MiB. This later causes u-boot in ARM 32bit mode to freeze,
because it relocated itself into that unmapped memory and fails to
execute.

Fix this by limiting the size of the first bank to the multiple of
MMU_SECTION_SIZE.

Signed-off-by: Marek Szyprowski 
---
 board/raspberrypi/rpi/rpi.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
index 6b1fa5fc14..83ccd3e3fc 100644
--- a/board/raspberrypi/rpi/rpi.c
+++ b/board/raspberrypi/rpi/rpi.c
@@ -268,6 +268,13 @@ int dram_init(void)
 
gd->ram_size = msg->get_arm_mem.body.resp.mem_size;
 
+   /*
+* In some configurations the memory size returned by VideoCore
+* is not aligned to the section size, what is mandatory for
+* the u-boot's memory setup.
+*/
+   gd->ram_size &= ~MMU_SECTION_SIZE;
+
return 0;
 }
 
-- 
2.17.1



Re: [PATCH v2] disk: part_dos: update partition table entries after write

2021-01-28 Thread Marek Szyprowski
Hi,

On 28.01.2021 09:10, Gary Bisson wrote:
> Fixes issues when switching from GPT to MBR partition tables.
>
> Signed-off-by: Gary Bisson 
Acked-by: Marek Szyprowski 
> ---
> Changes for v2:
> - added part_init() inside write_mbr_partitions(), as suggested by
>Heinrich
> ---
>   disk/part_dos.c | 6 ++
>   1 file changed, 6 insertions(+)
>
> diff --git a/disk/part_dos.c b/disk/part_dos.c
> index f431925745c..60addc6e00d 100644
> --- a/disk/part_dos.c
> +++ b/disk/part_dos.c
> @@ -423,6 +423,9 @@ int write_mbr_partitions(struct blk_desc *dev,
>   ext_part_sect = next_ebr;
>   }
>   
> + /* Update the partition table entries*/
> + part_init(dev_desc);
> +
>   return 0;
>   }
>   
> @@ -499,6 +502,9 @@ int write_mbr_sector(struct blk_desc *dev_desc, void *buf)
>   return 1;
>   }
>   
> + /* Update the partition table entries*/
> + part_init(dev_desc);
> +
>   return 0;
>   }
>   

Best regards
-- 
Marek Szyprowski, PhD
Samsung R Institute Poland



Re: [PATCH v5 2/4] button: add a simple Analog to Digital Converter device based button driver

2021-01-26 Thread Marek Szyprowski
Hi Heinrich,

On 26.01.2021 12:10, Heinrich Schuchardt wrote:
> On 1/26/21 10:50 AM, Marek Szyprowski wrote:
>> Add a simple Analog to Digital Converter device based button driver. 
>> This
>> driver binds to the 'adc-keys' device tree node.
>>
>> Signed-off-by: Marek Szyprowski 
>> ---
>>   drivers/button/Kconfig  |   8 ++
>>   drivers/button/Makefile |   1 +
>>   drivers/button/button-adc.c | 156 
>>   3 files changed, 165 insertions(+)
>>   create mode 100644 drivers/button/button-adc.c
>>
>> diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig
>> index 6b3ec7e55d..6db3c5e93a 100644
>> --- a/drivers/button/Kconfig
>> +++ b/drivers/button/Kconfig
>> @@ -9,6 +9,14 @@ config BUTTON
>>     can provide access to board-specific buttons. Use of the 
>> device tree
>>     for configuration is encouraged.
>>
>> +config BUTTON_ADC
>> +    bool "Button adc"
>> +    depends on BUTTON
>> +    help
>> +  Enable support for buttons which are connected to Analog to 
>> Digital
>> +  Converter device. The ADC driver must use driver model. 
>> Buttons are
>> +  configured using the device tree.
>> +
>>   config BUTTON_GPIO
>>   bool "Button gpio"
>>   depends on BUTTON
>> diff --git a/drivers/button/Makefile b/drivers/button/Makefile
>> index fcc10ebe8d..bbd18af149 100644
>> --- a/drivers/button/Makefile
>> +++ b/drivers/button/Makefile
>> @@ -3,4 +3,5 @@
>>   # Copyright (C) 2020 Philippe Reynes 
>>
>>   obj-$(CONFIG_BUTTON) += button-uclass.o
>> +obj-$(CONFIG_BUTTON_ADC) += button-adc.o
>>   obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o
>> diff --git a/drivers/button/button-adc.c b/drivers/button/button-adc.c
>> new file mode 100644
>> index 00..1901d59a0e
>> --- /dev/null
>> +++ b/drivers/button/button-adc.c
>> @@ -0,0 +1,156 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (C) 2021 Samsung Electronics Co., Ltd.
>> + *    http://www.samsung.com
>> + * Author: Marek Szyprowski 
>> + */
>> +
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +/**
>> + * struct button_adc_priv - private data for button-adc driver.
>> + *
>> + * @adc: Analog to Digital Converter device to which button is 
>> connected.
>> + * @channel: channel of the ADC device to probe the button state.
>> + * @min: minimal raw ADC sample value to consider button as pressed.
>> + * @max: maximal raw ADC sample value to consider button as pressed.
>> + */
>> +struct button_adc_priv {
>> +    struct udevice *adc;
>> +    int channel;
>> +    int min;
>> +    int max;
>> +};
>> +
>> +static enum button_state_t button_adc_get_state(struct udevice *dev)
>> +{
>> +    struct button_adc_priv *priv = dev_get_priv(dev);
>> +    unsigned int val;
>> +    int ret;
>> +
>> +    ret = adc_start_channel(priv->adc, priv->channel);
>> +    if (ret)
>> +    return ret;
>> +
>> +    ret = adc_channel_data(priv->adc, priv->channel, );
>> +    if (ret)
>> +    return ret;
>> +
>> +    if (ret == 0)
>> +    return (val >= priv->min && val < priv->max) ?
>> +    BUTTON_ON : BUTTON_OFF;
>> +
>> +    return ret;
>> +}
>> +
>> +static int button_adc_probe(struct udevice *dev)
>> +{
>> +    struct button_uc_plat *uc_plat = dev_get_uclass_plat(dev);
>> +    struct button_adc_priv *priv = dev_get_priv(dev);
>> +    struct ofnode_phandle_args args;
>> +    u32 treshold, up_treshold, t;
>> +    unsigned int mask;
>> +    ofnode node;
>> +    int ret, vdd;
>> +
>> +    /* Ignore the top-level button node */
>> +    if (!uc_plat->label)
>> +    return 0;
>> +
>> +    ret = dev_read_phandle_with_args(dev->parent, "io-channels",
>> + "#io-channel-cells", 0, 0, );
>> +    if (ret)
>> +    return ret;
>> +
>> +    ret = uclass_get_device_by_ofnode(UCLASS_ADC, args.node, 
>> >adc);
>> +    if (ret)
>> +    return ret;
>> +
>> +    ret = ofnode_read_u32(dev_ofnode(dev->parent),
>> +  "keyup-threshold-microvolt", _treshold);
>> +    if (ret)
>> +    return ret;
>> +
>&

[PATCH v5 2/4] button: add a simple Analog to Digital Converter device based button driver

2021-01-26 Thread Marek Szyprowski
Add a simple Analog to Digital Converter device based button driver. This
driver binds to the 'adc-keys' device tree node.

Signed-off-by: Marek Szyprowski 
---
 drivers/button/Kconfig  |   8 ++
 drivers/button/Makefile |   1 +
 drivers/button/button-adc.c | 156 
 3 files changed, 165 insertions(+)
 create mode 100644 drivers/button/button-adc.c

diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig
index 6b3ec7e55d..6db3c5e93a 100644
--- a/drivers/button/Kconfig
+++ b/drivers/button/Kconfig
@@ -9,6 +9,14 @@ config BUTTON
  can provide access to board-specific buttons. Use of the device tree
  for configuration is encouraged.
 
+config BUTTON_ADC
+   bool "Button adc"
+   depends on BUTTON
+   help
+ Enable support for buttons which are connected to Analog to Digital
+ Converter device. The ADC driver must use driver model. Buttons are
+ configured using the device tree.
+
 config BUTTON_GPIO
bool "Button gpio"
depends on BUTTON
diff --git a/drivers/button/Makefile b/drivers/button/Makefile
index fcc10ebe8d..bbd18af149 100644
--- a/drivers/button/Makefile
+++ b/drivers/button/Makefile
@@ -3,4 +3,5 @@
 # Copyright (C) 2020 Philippe Reynes 
 
 obj-$(CONFIG_BUTTON) += button-uclass.o
+obj-$(CONFIG_BUTTON_ADC) += button-adc.o
 obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o
diff --git a/drivers/button/button-adc.c b/drivers/button/button-adc.c
new file mode 100644
index 00..1901d59a0e
--- /dev/null
+++ b/drivers/button/button-adc.c
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Author: Marek Szyprowski 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * struct button_adc_priv - private data for button-adc driver.
+ *
+ * @adc: Analog to Digital Converter device to which button is connected.
+ * @channel: channel of the ADC device to probe the button state.
+ * @min: minimal raw ADC sample value to consider button as pressed.
+ * @max: maximal raw ADC sample value to consider button as pressed.
+ */
+struct button_adc_priv {
+   struct udevice *adc;
+   int channel;
+   int min;
+   int max;
+};
+
+static enum button_state_t button_adc_get_state(struct udevice *dev)
+{
+   struct button_adc_priv *priv = dev_get_priv(dev);
+   unsigned int val;
+   int ret;
+
+   ret = adc_start_channel(priv->adc, priv->channel);
+   if (ret)
+   return ret;
+
+   ret = adc_channel_data(priv->adc, priv->channel, );
+   if (ret)
+   return ret;
+
+   if (ret == 0)
+   return (val >= priv->min && val < priv->max) ?
+   BUTTON_ON : BUTTON_OFF;
+
+   return ret;
+}
+
+static int button_adc_probe(struct udevice *dev)
+{
+   struct button_uc_plat *uc_plat = dev_get_uclass_plat(dev);
+   struct button_adc_priv *priv = dev_get_priv(dev);
+   struct ofnode_phandle_args args;
+   u32 treshold, up_treshold, t;
+   unsigned int mask;
+   ofnode node;
+   int ret, vdd;
+
+   /* Ignore the top-level button node */
+   if (!uc_plat->label)
+   return 0;
+
+   ret = dev_read_phandle_with_args(dev->parent, "io-channels",
+"#io-channel-cells", 0, 0, );
+   if (ret)
+   return ret;
+
+   ret = uclass_get_device_by_ofnode(UCLASS_ADC, args.node, >adc);
+   if (ret)
+   return ret;
+
+   ret = ofnode_read_u32(dev_ofnode(dev->parent),
+ "keyup-threshold-microvolt", _treshold);
+   if (ret)
+   return ret;
+
+   ret = ofnode_read_u32(dev_ofnode(dev), "press-threshold-microvolt",
+ );
+   if (ret)
+   return ret;
+
+   dev_for_each_subnode(node, dev->parent) {
+   ret = ofnode_read_u32(dev_ofnode(dev),
+ "press-threshold-microvolt", );
+   if (ret)
+   return ret;
+
+   if (t > treshold)
+   up_treshold = t;
+   }
+
+   ret = adc_vdd_value(priv->adc, );
+   if (ret)
+   return ret;
+
+   ret = adc_data_mask(priv->adc, );
+   if (ret)
+   return ret;
+
+   priv->channel = args.args[0];
+   priv->min = mask * (treshold / 1000) / (vdd / 1000);
+   priv->max = mask * (up_treshold / 1000) / (vdd / 1000);
+
+   return ret;
+}
+
+static int button_adc_bind(struct udevice *parent)
+{
+   struct udevice *dev;
+   ofnode node;
+   int ret;
+
+   dev_for_each_subnode(node, parent) {
+   struct button_uc_pl

[PATCH v5 3/4] adc: meson-saradc: add support for getting reference voltage value

2021-01-26 Thread Marek Szyprowski
Add support for getting the 'vref-supply' regulator and register it as
ADC's reference voltage regulator, so clients can translate sampled ADC
values to the voltage.

Signed-off-by: Marek Szyprowski 
---
 drivers/adc/meson-saradc.c | 21 +
 1 file changed, 21 insertions(+)

diff --git a/drivers/adc/meson-saradc.c b/drivers/adc/meson-saradc.c
index 21db55831d..1a45a3a265 100644
--- a/drivers/adc/meson-saradc.c
+++ b/drivers/adc/meson-saradc.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define MESON_SAR_ADC_REG0 0x00
#define MESON_SAR_ADC_REG0_PANEL_DETECT BIT(31)
@@ -656,7 +657,10 @@ static int meson_saradc_stop(struct udevice *dev)
 
 static int meson_saradc_probe(struct udevice *dev)
 {
+   struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
struct meson_saradc_priv *priv = dev_get_priv(dev);
+   struct udevice *vref;
+   int vref_uv;
int ret;
 
ret = regmap_init_mem(dev_ofnode(dev), >regmap);
@@ -675,6 +679,23 @@ static int meson_saradc_probe(struct udevice *dev)
 
priv->active_channel = -1;
 
+   ret = device_get_supply_regulator(dev, "vref-supply", );
+   if (ret) {
+   printf("can't get vref-supply: %d\n", ret);
+   return ret;
+   }
+
+   vref_uv = regulator_get_value(vref);
+   if (vref_uv < 0) {
+   printf("can't get vref-supply value: %d\n", vref_uv);
+   return vref_uv;
+   }
+
+   /* VDD supplied by common vref pin */
+   uc_pdata->vdd_supply = vref;
+   uc_pdata->vdd_microvolts = vref_uv;
+   uc_pdata->vss_microvolts = 0;
+
return 0;
 }
 
-- 
2.17.1



[PATCH v5 4/4] configs: khadas-vim3(l): enable Function button support

2021-01-26 Thread Marek Szyprowski
Add options required to check the 'Function' button state.

Signed-off-by: Marek Szyprowski 
---
 configs/khadas-vim3_defconfig  | 2 ++
 configs/khadas-vim3l_defconfig | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/configs/khadas-vim3_defconfig b/configs/khadas-vim3_defconfig
index 5d16652fd6..bc17430569 100644
--- a/configs/khadas-vim3_defconfig
+++ b/configs/khadas-vim3_defconfig
@@ -31,6 +31,8 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_ADC=y
 CONFIG_SARADC_MESON=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_ADC=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MESON=y
 CONFIG_DM_MMC=y
diff --git a/configs/khadas-vim3l_defconfig b/configs/khadas-vim3l_defconfig
index 6b13ce045c..c1877922c7 100644
--- a/configs/khadas-vim3l_defconfig
+++ b/configs/khadas-vim3l_defconfig
@@ -31,6 +31,8 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_ADC=y
 CONFIG_SARADC_MESON=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_ADC=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MESON=y
 CONFIG_DM_MMC=y
-- 
2.17.1



[PATCH v5 1/4] dt-bindings: input: adc-keys bindings documentation

2021-01-26 Thread Marek Szyprowski
Dump adc-keys bindings documentation from Linux kernel source tree from
commit 698dc0cf9447 ("dt-bindings: input: adc-keys: clarify
description").

Signed-off-by: Marek Szyprowski 
---
 doc/device-tree-bindings/input/adc-keys.txt | 67 +
 1 file changed, 67 insertions(+)
 create mode 100644 doc/device-tree-bindings/input/adc-keys.txt

diff --git a/doc/device-tree-bindings/input/adc-keys.txt 
b/doc/device-tree-bindings/input/adc-keys.txt
new file mode 100644
index 00..6c8be6a9ac
--- /dev/null
+++ b/doc/device-tree-bindings/input/adc-keys.txt
@@ -0,0 +1,67 @@
+ADC attached resistor ladder buttons
+
+
+Required properties:
+ - compatible: "adc-keys"
+ - io-channels: Phandle to an ADC channel
+ - io-channel-names = "buttons";
+ - keyup-threshold-microvolt: Voltage above or equal to which all the keys are
+ considered up.
+
+Optional properties:
+   - poll-interval: Poll interval time in milliseconds
+   - autorepeat: Boolean, Enable auto repeat feature of Linux input
+ subsystem.
+
+Each button (key) is represented as a sub-node of "adc-keys":
+
+Required subnode-properties:
+   - label: Descriptive name of the key.
+   - linux,code: Keycode to emit.
+   - press-threshold-microvolt: voltage above or equal to which this key is
+considered pressed.
+
+No two values of press-threshold-microvolt may be the same.
+All values of press-threshold-microvolt must be less than
+keyup-threshold-microvolt.
+
+Example:
+
+#include 
+
+   adc-keys {
+   compatible = "adc-keys";
+   io-channels = < 0>;
+   io-channel-names = "buttons";
+   keyup-threshold-microvolt = <200>;
+
+   button-up {
+   label = "Volume Up";
+   linux,code = ;
+   press-threshold-microvolt = <150>;
+   };
+
+   button-down {
+   label = "Volume Down";
+   linux,code = ;
+   press-threshold-microvolt = <100>;
+   };
+
+   button-enter {
+   label = "Enter";
+   linux,code = ;
+   press-threshold-microvolt = <50>;
+   };
+   };
+
++++
+| 2.000.000 <= value | no key pressed |
++++
+| 1.500.000 <= value < 2.000.000 | KEY_VOLUMEUP pressed   |
++++
+| 1.000.000 <= value < 1.500.000 | KEY_VOLUMEDOWN pressed |
++++
+|   500.000 <= value < 1.000.000 | KEY_ENTER pressed  |
++++
+|  value <   500.000 | no key pressed |
++++
-- 
2.17.1



[PATCH v5 0/4] VIM3: add support for checking 'Function' button state

2021-01-26 Thread Marek Szyprowski
Hi All,

This patchset adds all building blocks needed for checking the 'Function'
button state in the boot script on Amlogic A311D based VIM3 board. This
button is connected to the ADC lines of the SoC, so it required to enable
meson SARADC, the clocks needed for it and a simple button-adc drivers.

Once applied, one can use following commands in the boot scripts:
-->8---
echo Checking Func button state: \\c
if button Function
then
echo Selected alternative boot
...
fi
--->8---

Best regards
Marek Szyprowski
Samsung R Institute Poland


Changelog:
v5:
- rebased onto latest uboot-amlogic/u-boot-amlogic-next branch
- synchronized adc-keys binding with the recent version from the Linux
  kernel
- updated adc-keys driver to match behavior from dt-bindings
- added a patch for meson-saradc driver to register vdd reference supply
  to the ADC framework

v4: https://lists.denx.de/pipermail/u-boot/2020-December/435641.html
- rebased onto uboot-amlogic/u-boot-amlogic-next and dropped merged patches
- added adc-keys bindings docs (copied from Linux kernel)
- minor code adjustments pointed by Simon
- enabled driver also in khadas-vim3l_defconfig

v3: https://lists.denx.de/pipermail/u-boot/2020-December/435072.html
- removed 'button' env variable
- extended kconfig and patch descriptions

v2: https://lists.denx.de/pipermail/u-boot/2020-December/434991.html
- removed Change-Id tags
- split defconfig changes into ADC and button related

v1: https://lists.denx.de/pipermail/u-boot/2020-December/434875.html
- initial submission


Patch summary:

Marek Szyprowski (4):
  dt-bindings: input: adc-keys bindings documentation
  button: add a simple Analog to Digital Converter device based button
driver
  adc: meson-saradc: add support for getting reference voltage value
  configs: khadas-vim3(l): enable Function button support

 configs/khadas-vim3_defconfig   |   2 +
 configs/khadas-vim3l_defconfig  |   2 +
 doc/device-tree-bindings/input/adc-keys.txt |  67 +
 drivers/adc/meson-saradc.c  |  21 +++
 drivers/button/Kconfig  |   8 +
 drivers/button/Makefile |   1 +
 drivers/button/button-adc.c | 156 
 7 files changed, 257 insertions(+)
 create mode 100644 doc/device-tree-bindings/input/adc-keys.txt
 create mode 100644 drivers/button/button-adc.c

-- 
2.17.1



Re: [PATCH v4 0/3] VIM3: add support for checking 'Function' button state

2021-01-22 Thread Marek Szyprowski
Hi Neil,

On 18.01.2021 13:55, Neil Armstrong wrote:
> On 18/01/2021 13:48, Heinrich Schuchardt wrote:
>> On 18.01.21 11:24, Neil Armstrong wrote:
>>> On 22/12/2020 09:56, Marek Szyprowski wrote:
>>>> Hi All,
>>>>
>>>> This patchset adds all building blocks needed for checking the 'Function'
>>>> button state in the boot script on Amlogic A311D based VIM3 board. This
>>>> button is connected to the ADC lines of the SoC, so it required to enable
>>>> meson SARADC, the clocks needed for it and a simple button-adc drivers.
>>>>
>>>> Once applied, one can use following commands in the boot scripts:
>>>> -->8---
>>>> echo Checking Func button state: \\c
>>>> if button Function
>>>> then
>>>>echo Selected alternative boot
>>>>...
>>>> fi
>>>> --->8---
>>>>
>>>> Best regards
>>>> Marek Szyprowski
>>>> Samsung R Institute Poland
>>>>
>>>>
>>>> Changelog:
>>>> v4:
>>>> - rebased onto uboot-amlogic/u-boot-amlogic-next and dropped merged patches
>>>> - added adc-keys bindings docs (copied from Linux kernel)
>>>> - minor code adjustments pointed by Simon
>>>> - enabled driver also in khadas-vim3l_defconfig
>>>>
>>>> v3: 
>>>> https://protect2.fireeye.com/v1/url?k=fc4a4b97-a3d1734e-fc4bc0d8-0cc47a3356b2-eb4ba315795a3f17=1=b660ed0e-7d37-47e8-877d-c8391317e3e0=https%3A%2F%2Flists.denx.de%2Fpipermail%2Fu-boot%2F2020-December%2F435072.html
>>>> - removed 'button' env variable
>>>> - extended kconfig and patch descriptions
>>>>
>>>> v2: 
>>>> https://protect2.fireeye.com/v1/url?k=11f0ed69-4e6bd5b0-11f16626-0cc47a3356b2-f341d16b01448534=1=b660ed0e-7d37-47e8-877d-c8391317e3e0=https%3A%2F%2Flists.denx.de%2Fpipermail%2Fu-boot%2F2020-December%2F434991.html
>>>> - removed Change-Id tags
>>>> - split defconfig changes into ADC and button related
>>>>
>>>> v1: 
>>>> https://protect2.fireeye.com/v1/url?k=7c601119-23fb29c0-7c619a56-0cc47a3356b2-55caa8afe3085a65=1=b660ed0e-7d37-47e8-877d-c8391317e3e0=https%3A%2F%2Flists.denx.de%2Fpipermail%2Fu-boot%2F2020-December%2F434875.html
>>>> - initial submission
>>> What's the state of the patchset ?
>> Hello Neil,
>>
>> the series is assigned to you. Patch 2 is incorrect. Patch 1 can be
>> updated to match Linux. So I suggest to set the status for the series to
>> "changes requested".
> Sure, it was more a question to Marek, but yeah I'll tag them "changes 
> requested"

I'm sorry for the late reply, I've been busy with other stuff. I will 
try to update the adc-keys driver to use the threshold values and add 
the updated device tree bindings soon.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R Institute Poland



[PATCH] cmd: misc: Fix return value for the sleep command

2021-01-22 Thread Marek Szyprowski
If sleeping has been interrupted, return CMD_RET_FAILURE instead of -1
(CMD_RET_USAGE).

Signed-off-by: Marek Szyprowski 
---
 cmd/sleep.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/cmd/sleep.c b/cmd/sleep.c
index f0c78a8efb..1fff400c79 100644
--- a/cmd/sleep.c
+++ b/cmd/sleep.c
@@ -40,7 +40,7 @@ static int do_sleep(struct cmd_tbl *cmdtp, int flag, int argc,
 
while (get_timer(start) < delay) {
if (ctrlc())
-   return (-1);
+   return CMD_RET_FAILURE;
 
udelay(100);
}
-- 
2.17.1



Re: [PATCH] board: amlogic: vim3: fix setup ethernet mac from efuse

2021-01-12 Thread Marek Szyprowski
Hi Artem,

On 12.01.2021 06:03, Artem Lapkin wrote:
> Fix reading built-in ethernet MAC address from efuse
>
> NOTE: MAC is stored in ASCII format, 1bytes = 2characters by 0 offset
>
> if mac from efuse not valid we use meson_generate_serial_ethaddr
>
> NOTE: remake odroid-n2.c variant from Neil Armstrong 
>
> Signed-off-by: Artem Lapkin 

First of all, thanks pointing again at this issue.

I've implemented reading of MAC address from EFUSE for VIM boards and I 
was convinced that it is stored in binary format. I've based my 
assumptions on the vendor code, especially the message from the vendor 
kernel:

[    4.028236] efusekeynum: 1
[    4.031072] efusekeyname: mac    offset: 0 size: 6
[    4.037542] efuse efuse: probe OK!

and the vendors dts:

https://github.com/khadas/linux/blob/khadas-vims-4.9.y/arch/arm64/boot/dts/amlogic/kvim3_linux.dts#L506

which both points that the EFUSE key has only 6 bytes, what means binary 
format. I didn't check it further what is really stored there.

Now I checked again and it looks that the DTS (and thus vendor's kernel 
message) is incorrect, as the MAC is stored in ASCII and occupies 12 
bytes in efuse. One can check that with vendor's kernel:

# cat /sys/class/efuse/userdata
0x00: 43 38 36 33 31 34 37 30 41 38 44 37 00 00 00 00
0x10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
...

This means that your patch is correct, although I would change it a bit.

BTW, the Odroid N2/C4 boards don't have MAC stored explicitly in the 
EFUSE, but the boards UUID. The original code use the last bytes of the 
UUID as the MAC address.

> ---
>   board/amlogic/vim3/vim3.c | 22 +++---
>   1 file changed, 19 insertions(+), 3 deletions(-)
>
> diff --git a/board/amlogic/vim3/vim3.c b/board/amlogic/vim3/vim3.c
> index 824fff8262..87d9fe1f02 100644
> --- a/board/amlogic/vim3/vim3.c
> +++ b/board/amlogic/vim3/vim3.c
> @@ -139,26 +139,42 @@ int meson_ft_board_setup(void *blob, struct bd_info *bd)
>   }
>   
>   #define EFUSE_MAC_OFFSET0
> -#define EFUSE_MAC_SIZE   6
> +#define EFUSE_MAC_SIZE   12
> +#define MAC_ADDR_LEN 6
>   
>   int misc_init_r(void)
>   {
> - uint8_t mac_addr[EFUSE_MAC_SIZE];
> + uint8_t mac_addr[MAC_ADDR_LEN];
> + char efuse_mac_addr[EFUSE_MAC_SIZE], tmp[3];
>   ssize_t len;
>   
>   meson_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
>   
>   if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
>   len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
> -   mac_addr, EFUSE_MAC_SIZE);
> +   efuse_mac_addr, EFUSE_MAC_SIZE);
>   if (len != EFUSE_MAC_SIZE)
>   return 0;
>   
> + /* MAC is stored in ASCII format, 1bytes = 2characters */
> + for (int i = 0; i < 6; i++) {
> + tmp[0] = efuse_mac_addr[i * 2];
> + tmp[1] = efuse_mac_addr[i * 2 + 1];
> + tmp[2] = '\0';
> + mac_addr[i] = simple_strtoul(tmp, NULL, 16);
> + }
> +
>   if (is_valid_ethaddr(mac_addr))
>   eth_env_set_enetaddr("ethaddr", mac_addr);
>   else
>   meson_generate_serial_ethaddr();

Now the above code is the same as for Odroid N2/C4, so it can be moved 
to arch/arm/mach-meson/board-common.c, maybe as 
meson_read_efuse_mac_addr() with the offset as parameter, so it can be 
directly used by Odroids and VIMs.

> +
> + eth_env_get_enetaddr("ethaddr", mac_addr);
> + printf("[i] setup onboard mac %02X:%02X:%02X:%02X:%02X:%02X\n",
> + mac_addr[0],mac_addr[1],mac_addr[2],
> +     mac_addr[3],mac_addr[4],mac_addr[5]);

I'm not really convinced that this message has to be displayed. If so, 
then use "%pM" for printing MAC address.

>   }
>   
>   return 0;
>   }
> +

Best regards
-- 
Marek Szyprowski, PhD
Samsung R Institute Poland



[PATCH v3 0/6] Add MBR partition table creation and verify command

2020-12-23 Thread Marek Szyprowski
Hi All,

This patchset adds 'mbr' command to let one to create or verify MBR
(Master Boot Record) partition layout based on the provided text
description. This can be used in scripts to help system flashing
tools/scripts to ensure proper partition layout. It has been inspired by
the 'gpt' command already present in u-boot.

Best regards
Marek Szyprowski
Samsung R Institute Poland


Changelog:

v3:
- fixed minor issues in the docs

v2: https://lists.denx.de/pipermail/u-boot/2020-December/435689.html
- added docs and minor fixes in the code style

v1: https://lists.denx.de/pipermail/u-boot/2020-December/435208.html
- initial version


Patch summary:

Marek Szyprowski (6):
  disk: dos: rename write_mbr_partition to write_mbr_sector
  disk: dos: add some defines for the hardcoded numbers
  disk: dos: use generic macro for unaligned le32 access
  disk: dos: make some functions static
  disk: dos: add code for creating MBR partition layout
  cmd: Add MBR partition layout control utility

 cmd/Kconfig   |   8 +
 cmd/Makefile  |   1 +
 cmd/mbr.c | 314 ++
 disk/part_dos.c   | 207 ++---
 disk/part_dos.h   |   5 +
 doc/usage/index.rst   |   1 +
 doc/usage/mbr.rst |  93 +++
 drivers/fastboot/fb_mmc.c |   2 +-
 include/part.h|   9 +-
 9 files changed, 612 insertions(+), 28 deletions(-)
 create mode 100644 cmd/mbr.c
 create mode 100644 doc/usage/mbr.rst

-- 
2.17.1



[PATCH v3 4/6] disk: dos: make some functions static

2020-12-23 Thread Marek Szyprowski
Make functions not used outside this file static.

Signed-off-by: Marek Szyprowski 
---
 disk/part_dos.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/disk/part_dos.c b/disk/part_dos.c
index 3b79b9b1b8..2c4ad0b6ba 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -302,13 +302,13 @@ static int part_get_info_extended(struct blk_desc 
*dev_desc,
return -1;
 }
 
-void part_print_dos(struct blk_desc *dev_desc)
+static void part_print_dos(struct blk_desc *dev_desc)
 {
printf("Part\tStart Sector\tNum Sectors\tUUID\t\tType\n");
print_partition_extended(dev_desc, 0, 0, 1, 0);
 }
 
-int part_get_info_dos(struct blk_desc *dev_desc, int part,
+static int part_get_info_dos(struct blk_desc *dev_desc, int part,
  struct disk_partition *info)
 {
return part_get_info_extended(dev_desc, 0, 0, 1, part, info, 0);
-- 
2.17.1



[PATCH v3 6/6] cmd: Add MBR partition layout control utility

2020-12-23 Thread Marek Szyprowski
Add a 'mbr' command to let users create or verify MBR partition layout
based on the provided text description. The partition layout is
alternatively read from the 'mbr_parts' environment variable. This can be
used in scripts to help system image flashing tools to ensure proper
partition layout.

The syntax of the text description of the partition list is similar to
the one used by the 'gpt' command. Supported parameters are: name
(currently ignored), start (partition start offset in bytes), size (in
bytes or '-' to expand it to the whole free area), bootable (boolean
flag) and id (MBR partition type). If one wants to create more than 4
partitions, an 'Extended' primary partition (with 0x05 ID) has to be
explicitely provided as a one of the first 4 entries.

Here is an example how to create a 6 partitions (3 on the 'extended
volume'), some of the predefined sizes:

> setenv mbr_parts 'name=boot,start=4M,size=128M,bootable,id=0x0e;
  name=rootfs,size=3072M,id=0x83;
  name=system-data,size=512M,id=0x83;
  name=[ext],size=-,id=0x05;
  name=user,size=-,id=0x83;
  name=modules,size=100M,id=0x83;
  name=ramdisk,size=8M,id=0x83'
> mbr write mmc 0

Signed-off-by: Marek Szyprowski 
---
 cmd/Kconfig |   8 ++
 cmd/Makefile|   1 +
 cmd/mbr.c   | 314 
 doc/usage/index.rst |   1 +
 doc/usage/mbr.rst   |  93 +
 5 files changed, 417 insertions(+)
 create mode 100644 cmd/mbr.c
 create mode 100644 doc/usage/mbr.rst

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 1595de999b..2c3358e359 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1025,6 +1025,14 @@ config CMD_LSBLK
  Print list of available block device drivers, and for each, the list
  of known block devices.
 
+config CMD_MBR
+   bool "MBR (Master Boot Record) command"
+   select DOS_PARTITION
+   select HAVE_BLOCK_DEVICE
+   help
+ Enable the 'mbr' command to ready and write MBR (Master Boot Record)
+ style partition tables.
+
 config CMD_MISC
bool "misc"
depends on MISC
diff --git a/cmd/Makefile b/cmd/Makefile
index dd86675bf2..41379d9a0e 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -178,6 +178,7 @@ obj-$(CONFIG_CMD_ZFS) += zfs.o
 
 obj-$(CONFIG_CMD_DFU) += dfu.o
 obj-$(CONFIG_CMD_GPT) += gpt.o
+obj-$(CONFIG_CMD_MBR) += mbr.o
 obj-$(CONFIG_CMD_ETHSW) += ethsw.o
 obj-$(CONFIG_CMD_AXI) += axi.o
 obj-$(CONFIG_CMD_PVBLOCK) += pvblock.o
diff --git a/cmd/mbr.c b/cmd/mbr.c
new file mode 100644
index 00..da2e3a4722
--- /dev/null
+++ b/cmd/mbr.c
@@ -0,0 +1,314 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * cmd_mbr.c -- MBR (Master Boot Record) handling command
+ *
+ * Copyright (C) 2020 Samsung Electronics
+ * author: Marek Szyprowski 
+ *
+ * based on the gpt command.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * extract_val() - Extract a value from the key=value pair list
+ * @str: pointer to string with key=values pairs
+ * @key: pointer to the key to search for
+ *
+ * The list of parameters is come separated, only a value for
+ * the given key is returend.
+ *
+ * Function allocates memory for the value, remember to free!
+ *
+ * Return: Pointer to allocated string with the value.
+ */
+static char *extract_val(const char *str, const char *key)
+{
+   char *v, *k;
+   char *s, *strcopy;
+   char *new = NULL;
+
+   strcopy = strdup(str);
+   if (strcopy == NULL)
+   return NULL;
+
+   s = strcopy;
+   while (s) {
+   v = strsep(, ",");
+   if (!v)
+   break;
+   k = strsep(, "=");
+   if (!k)
+   break;
+   if  (strcmp(k, key) == 0) {
+   new = strdup(v);
+   break;
+   }
+   }
+
+   free(strcopy);
+
+   return new;
+}
+
+/**
+ * found_key() - Search for a key without a value in the parameter list
+ * @str: pointer to string with key
+ * @key: pointer to the key to search for
+ *
+ * The list of parameters is come separated.
+ *
+ * Return: True if key has been found.
+ */
+static bool found_key(const char *str, const char *key)
+{
+   char *k;
+   char *s, *strcopy;
+   bool result = false;
+
+   strcopy = strdup(str);
+   if (!strcopy)
+   return NULL;
+
+   s = strcopy;
+   while (s) {
+   k = strsep(, ",");
+   if (!k)
+   break;
+   if  (strcmp(k, key) == 0) {
+   result = true;
+   break;
+   }
+   }
+
+   free(strcopy);
+
+   return result;
+}
+
+static int str_to_partitions(const char *str_part, int blksz,
+   unsigned long *disk_uuid, struct disk_partition **partitions,
+   int *parts_count)
+{
+   char *tok, *str, *s;
+   int i;
+   char *val, *p;
+

[PATCH v3 5/6] disk: dos: add code for creating MBR partition layout

2020-12-23 Thread Marek Szyprowski
Add a code for creating and writing MBR partition layout. The code generates
similar layout of EBRs (Exteneded Block Records) and logical volumes as
Linux's fdisk utility.

Signed-off-by: Marek Szyprowski 
---
 disk/part_dos.c | 167 
 disk/part_dos.h |   2 +
 include/part.h  |   5 ++
 3 files changed, 174 insertions(+)

diff --git a/disk/part_dos.c b/disk/part_dos.c
index 2c4ad0b6ba..f77f927995 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -319,6 +319,173 @@ int is_valid_dos_buf(void *buf)
return test_block_type(buf) == DOS_MBR ? 0 : -1;
 }
 
+#if CONFIG_IS_ENABLED(CMD_MBR)
+static void lba_to_chs(lbaint_t lba, unsigned char *rc, unsigned char *rh,
+  unsigned char *rs)
+{
+   unsigned int c, h, s;
+   /* use fixed CHS geometry */
+   unsigned int sectpertrack = 63;
+   unsigned int heads = 255;
+
+   c = (lba + 1) / sectpertrack / heads;
+   h = (lba + 1) / sectpertrack - c * heads;
+   s = (lba + 1) - (c * heads + h) * sectpertrack;
+
+   if (c > 1023) {
+   c = 1023;
+   h = 254;
+   s = 63;
+   }
+
+   *rc = c & 0xff;
+   *rh = h;
+   *rs = s + ((c & 0x300) >> 2);
+}
+
+static void mbr_fill_pt_entry(dos_partition_t *pt, lbaint_t start,
+   lbaint_t relative, lbaint_t size, uchar sys_ind, bool bootable)
+{
+   pt->boot_ind = bootable ? 0x80 : 0x00;
+   pt->sys_ind = sys_ind;
+   lba_to_chs(start, >cyl, >head, >sector);
+   lba_to_chs(start + size - 1, >end_cyl, >end_head, 
>end_sector);
+   put_unaligned_le32(relative, >start4);
+   put_unaligned_le32(size, >size4);
+}
+
+int write_mbr_partitions(struct blk_desc *dev,
+   struct disk_partition *p, int count, unsigned int disksig)
+{
+   ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev->blksz);
+   lbaint_t ext_part_start = 0, ext_part_size = 0, ext_part_sect = 0;
+   dos_partition_t *pt;
+   int i;
+
+   memset(buffer, 0, dev->blksz);
+   buffer[DOS_PART_MAGIC_OFFSET] = 0x55;
+   buffer[DOS_PART_MAGIC_OFFSET + 1] = 0xaa;
+   put_unaligned_le32(disksig, [DOS_PART_DISKSIG_OFFSET]);
+   pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
+
+   /* create all primary partitions */
+   for (i = 0; i < 4 && i < count; i++, pt++) {
+   mbr_fill_pt_entry(pt, p[i].start, p[i].start, p[i].size,
+ p[i].sys_ind, p[i].bootable);
+   if (is_extended(p[i].sys_ind)) {
+   ext_part_start = p[i].start;
+   ext_part_size = p[i].size;
+   ext_part_sect = p[i].start;
+   }
+   }
+
+   if (i < count && !ext_part_start) {
+   printf("%s: extended partition is needed for more than 4 
partitions\n",
+   __func__);
+   return -1;
+   }
+
+   /* write MBR */
+   if (blk_dwrite(dev, 0, 1, buffer) != 1) {
+   printf("%s: failed writing 'MBR' (1 blks at 0x0)\n",
+  __func__);
+   return -1;
+   }
+
+   /* create extended volumes */
+   for (; i < count; i++) {
+   lbaint_t next_ebr = 0;
+
+   memset(buffer, 0, dev->blksz);
+   buffer[DOS_PART_MAGIC_OFFSET] = 0x55;
+   buffer[DOS_PART_MAGIC_OFFSET + 1] = 0xaa;
+   pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
+
+   mbr_fill_pt_entry(pt, p[i].start, p[i].start - ext_part_sect,
+ p[i].size, p[i].sys_ind, p[i].bootable);
+
+   if (i + 1 < count) {
+   pt++;
+   next_ebr = p[i].start + p[i].size;
+   mbr_fill_pt_entry(pt, next_ebr,
+ next_ebr - ext_part_start,
+ p[i+1].start + p[i+1].size - next_ebr,
+ DOS_PART_TYPE_EXTENDED, 0);
+   }
+
+   /* write EBR */
+   if (blk_dwrite(dev, ext_part_sect, 1, buffer) != 1) {
+   printf("%s: failed writing 'EBR' (1 blks at 0x%lx)\n",
+  __func__, ext_part_sect);
+   return -1;
+   }
+   ext_part_sect = next_ebr;
+   }
+
+   return 0;
+}
+
+int layout_mbr_partitions(struct disk_partition *p, int count,
+ lbaint_t total_sectors)
+{
+   struct disk_partition *ext = NULL;
+   int i, j;
+   lbaint_t ext_vol_start;
+
+   /* calculate primary partitions start and size if needed */
+   if (!p[0].start)
+   p[0].start = DOS_PART_DEFAULT_GAP;
+   for (i = 0; i < 4 && i < count; i+

[PATCH v3 2/6] disk: dos: add some defines for the hardcoded numbers

2020-12-23 Thread Marek Szyprowski
Add some handy defines for some hardcoded magic numbers related to
extended partition handling.

Signed-off-by: Marek Szyprowski 
---
 disk/part_dos.c | 6 +++---
 disk/part_dos.h | 3 +++
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/disk/part_dos.c b/disk/part_dos.c
index ef706fb59c..20d35dc9cd 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -42,9 +42,9 @@ static inline unsigned int le32_to_int(unsigned char *le32)
 
 static inline int is_extended(int part_type)
 {
-return (part_type == 0x5 ||
-   part_type == 0xf ||
-   part_type == 0x85);
+return (part_type == DOS_PART_TYPE_EXTENDED ||
+   part_type == DOS_PART_TYPE_EXTENDED_LBA ||
+   part_type == DOS_PART_TYPE_EXTENDED_LINUX);
 }
 
 static int get_bootable(dos_partition_t *p)
diff --git a/disk/part_dos.h b/disk/part_dos.h
index 434b021ae8..dd909a9317 100644
--- a/disk/part_dos.h
+++ b/disk/part_dos.h
@@ -15,6 +15,9 @@
 #define DOS_PBR_MEDIA_TYPE_OFFSET  0x15
 #define DOS_MBR0
 #define DOS_PBR1
+#define DOS_PART_TYPE_EXTENDED 0x05
+#define DOS_PART_TYPE_EXTENDED_LBA 0x0F
+#define DOS_PART_TYPE_EXTENDED_LINUX   0x85
 
 typedef struct dos_partition {
unsigned char boot_ind; /* 0x80 - active
*/
-- 
2.17.1



[PATCH v3 1/6] disk: dos: rename write_mbr_partition to write_mbr_sector

2020-12-23 Thread Marek Szyprowski
write_mbr_partition() function name is a bit misleading, so rename it to
write_mbr_sector(). This is a preparation for adding code for writing a
complete MBR partition layout.

Signed-off-by: Marek Szyprowski 
---
 disk/part_dos.c   | 2 +-
 drivers/fastboot/fb_mmc.c | 2 +-
 include/part.h| 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/disk/part_dos.c b/disk/part_dos.c
index 04f53106f7..ef706fb59c 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -329,7 +329,7 @@ int is_valid_dos_buf(void *buf)
return test_block_type(buf) == DOS_MBR ? 0 : -1;
 }
 
-int write_mbr_partition(struct blk_desc *dev_desc, void *buf)
+int write_mbr_sector(struct blk_desc *dev_desc, void *buf)
 {
if (is_valid_dos_buf(buf))
return -1;
diff --git a/drivers/fastboot/fb_mmc.c b/drivers/fastboot/fb_mmc.c
index ae8e8e512f..4e26cef941 100644
--- a/drivers/fastboot/fb_mmc.c
+++ b/drivers/fastboot/fb_mmc.c
@@ -508,7 +508,7 @@ void fastboot_mmc_flash_write(const char *cmd, void 
*download_buffer,
fastboot_fail("invalid MBR partition", response);
return;
}
-   if (write_mbr_partition(dev_desc, download_buffer)) {
+   if (write_mbr_sector(dev_desc, download_buffer)) {
printf("%s: writing MBR partition failed\n", __func__);
fastboot_fail("writing MBR partition failed",
  response);
diff --git a/include/part.h b/include/part.h
index 55be724d20..67b8b2a5cc 100644
--- a/include/part.h
+++ b/include/part.h
@@ -465,14 +465,14 @@ int get_disk_guid(struct blk_desc *dev_desc, char *guid);
 int is_valid_dos_buf(void *buf);
 
 /**
- * write_mbr_partition() - write DOS MBR
+ * write_mbr_sector() - write DOS MBR
  *
  * @param dev_desc - block device descriptor
  * @param buf - buffer which contains the MBR
  *
  * @return - '0' on success, otherwise error
  */
-int write_mbr_partition(struct blk_desc *dev_desc, void *buf);
+int write_mbr_sector(struct blk_desc *dev_desc, void *buf);
 
 #endif
 
-- 
2.17.1



[PATCH v3 3/6] disk: dos: use generic macro for unaligned le32 access

2020-12-23 Thread Marek Szyprowski
Use a generic helper for reading LE32 integers.

Signed-off-by: Marek Szyprowski 
---
 disk/part_dos.c | 28 +---
 1 file changed, 9 insertions(+), 19 deletions(-)

diff --git a/disk/part_dos.c b/disk/part_dos.c
index 20d35dc9cd..3b79b9b1b8 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "part_dos.h"
 #include 
 
@@ -29,17 +30,6 @@
  * to use large numbers of partitions */
 #define MAX_EXT_PARTS 256
 
-/* Convert char[4] in little endian format to the host format integer
- */
-static inline unsigned int le32_to_int(unsigned char *le32)
-{
-return ((le32[3] << 24) +
-   (le32[2] << 16) +
-   (le32[1] << 8) +
-le32[0]
-  );
-}
-
 static inline int is_extended(int part_type)
 {
 return (part_type == DOS_PART_TYPE_EXTENDED ||
@@ -61,8 +51,8 @@ static int get_bootable(dos_partition_t *p)
 static void print_one_part(dos_partition_t *p, lbaint_t ext_part_sector,
   int part_num, unsigned int disksig)
 {
-   lbaint_t lba_start = ext_part_sector + le32_to_int (p->start4);
-   lbaint_t lba_size  = le32_to_int (p->size4);
+   lbaint_t lba_start = ext_part_sector + get_unaligned_le32(p->start4);
+   lbaint_t lba_size  = get_unaligned_le32(p->size4);
 
printf("%3d\t%-10" LBAFlength "u\t%-10" LBAFlength
"u\t%08x-%02x\t%02x%s%s\n",
@@ -171,7 +161,7 @@ static void print_partition_extended(struct blk_desc 
*dev_desc,
}
 
if (!ext_part_sector)
-   disksig = le32_to_int([DOS_PART_DISKSIG_OFFSET]);
+   disksig = get_unaligned_le32([DOS_PART_DISKSIG_OFFSET]);
 
/* Print all primary/logical partitions */
pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
@@ -198,7 +188,7 @@ static void print_partition_extended(struct blk_desc 
*dev_desc,
for (i = 0; i < 4; i++, pt++) {
if (is_extended (pt->sys_ind)) {
lbaint_t lba_start
-   = le32_to_int (pt->start4) + relative;
+   = get_unaligned_le32 (pt->start4) + relative;
 
print_partition_extended(dev_desc, lba_start,
ext_part_sector == 0  ? lba_start : relative,
@@ -244,7 +234,7 @@ static int part_get_info_extended(struct blk_desc *dev_desc,
 
 #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
if (!ext_part_sector)
-   disksig = le32_to_int([DOS_PART_DISKSIG_OFFSET]);
+   disksig = get_unaligned_le32([DOS_PART_DISKSIG_OFFSET]);
 #endif
 
/* Print all primary/logical partitions */
@@ -260,8 +250,8 @@ static int part_get_info_extended(struct blk_desc *dev_desc,
(ext_part_sector == 0 || is_extended(pt->sys_ind) == 0)) {
info->blksz = DOS_PART_DEFAULT_SECTOR;
info->start = (lbaint_t)(ext_part_sector +
-   le32_to_int(pt->start4));
-   info->size  = (lbaint_t)le32_to_int(pt->size4);
+   get_unaligned_le32(pt->start4));
+   info->size  = (lbaint_t)get_unaligned_le32(pt->size4);
part_set_generic_name(dev_desc, part_num,
  (char *)info->name);
/* sprintf(info->type, "%d, pt->sys_ind); */
@@ -286,7 +276,7 @@ static int part_get_info_extended(struct blk_desc *dev_desc,
for (i = 0; i < 4; i++, pt++) {
if (is_extended (pt->sys_ind)) {
lbaint_t lba_start
-   = le32_to_int (pt->start4) + relative;
+   = get_unaligned_le32 (pt->start4) + relative;
 
return part_get_info_extended(dev_desc, lba_start,
 ext_part_sector == 0 ? lba_start : relative,
-- 
2.17.1



[PATCH v2 0/6] Add MBR partition table creation and verify command

2020-12-22 Thread Marek Szyprowski
Hi All,

This patchset adds 'mbr' command to let one create or verify MBR (Master
Boot Record) partition layout based on the provided text description.
This can be used in scripts to help system flashing tools/scripts to
ensure proper partition layout. It has been inspired by the 'gpt' command
already present in u-boot.

Best regards
Marek Szyprowski
Samsung R Institute Poland


Changelog:

v2:
- added docs and minor fixes in the code style

v1: https://lists.denx.de/pipermail/u-boot/2020-December/435208.html
- initial version


Patch summary:

Marek Szyprowski (6):
  disk: dos: rename write_mbr_partition to write_mbr_sector
  disk: dos: add some defines for the hardcoded numbers
  disk: dos: use generic macro for unaligned le32 access
  disk: dos: make some functions static
  disk: dos: add code for creating MBR partition layout
  cmd: Add MBR partition layout control utility

 cmd/Kconfig   |   8 +
 cmd/Makefile  |   1 +
 cmd/mbr.c | 314 ++
 disk/part_dos.c   | 207 ++---
 disk/part_dos.h   |   5 +
 doc/usage/index.rst   |   1 +
 doc/usage/mbr.rst |  93 +++
 drivers/fastboot/fb_mmc.c |   2 +-
 include/part.h|   9 +-
 9 files changed, 612 insertions(+), 28 deletions(-)
 create mode 100644 cmd/mbr.c
 create mode 100644 doc/usage/mbr.rst

-- 
2.17.1



[PATCH v2 6/6] cmd: Add MBR partition layout control utility

2020-12-22 Thread Marek Szyprowski
Add a 'mbr' command to let user create or verify MBR partition layout
based on the provided text description. The partition layout is
altearnatively read from 'mbr_parts' environment variable. This can be
used in scripts to help system image flashing tools to ensure proper
partition layout.

The syntax of the text description of the partition list is similar to
the one used by the 'gpt' command. Supported parameters are: name
(currently ignored), start (partition start offset in bytes), size (in
bytes or '-' to expand it to the whole free area), bootable (boolean
flag) and id (MBR partition system ID). If one wants to create more than
4 partitions, an 'Extended' primary partition (with 0x05 ID) has to be
explicitely provided as a one of the first 4 entries.

Here is the example how to create a 6 partitions (3 on the 'extended
volume'), some of the predefined sizes:

> setenv mbr_parts 'name=boot,start=4M,size=128M,bootable,id=0x0e;
  name=rootfs,size=3072M,id=0x83;
  name=system-data,size=512M,id=0x83;
  name=[ext],size=-,id=0x05;
  name=user,size=-,id=0x83;
  name=modules,size=100M,id=0x83;
  name=ramdisk,size=8M,id=0x83'
> mbr write mmc 0

Signed-off-by: Marek Szyprowski 
---
 cmd/Kconfig |   8 ++
 cmd/Makefile|   1 +
 cmd/mbr.c   | 314 
 doc/usage/index.rst |   1 +
 doc/usage/mbr.rst   |  93 +
 5 files changed, 417 insertions(+)
 create mode 100644 cmd/mbr.c
 create mode 100644 doc/usage/mbr.rst

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 1595de999b..2c3358e359 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1025,6 +1025,14 @@ config CMD_LSBLK
  Print list of available block device drivers, and for each, the list
  of known block devices.
 
+config CMD_MBR
+   bool "MBR (Master Boot Record) command"
+   select DOS_PARTITION
+   select HAVE_BLOCK_DEVICE
+   help
+ Enable the 'mbr' command to ready and write MBR (Master Boot Record)
+ style partition tables.
+
 config CMD_MISC
bool "misc"
depends on MISC
diff --git a/cmd/Makefile b/cmd/Makefile
index dd86675bf2..41379d9a0e 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -178,6 +178,7 @@ obj-$(CONFIG_CMD_ZFS) += zfs.o
 
 obj-$(CONFIG_CMD_DFU) += dfu.o
 obj-$(CONFIG_CMD_GPT) += gpt.o
+obj-$(CONFIG_CMD_MBR) += mbr.o
 obj-$(CONFIG_CMD_ETHSW) += ethsw.o
 obj-$(CONFIG_CMD_AXI) += axi.o
 obj-$(CONFIG_CMD_PVBLOCK) += pvblock.o
diff --git a/cmd/mbr.c b/cmd/mbr.c
new file mode 100644
index 00..da2e3a4722
--- /dev/null
+++ b/cmd/mbr.c
@@ -0,0 +1,314 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * cmd_mbr.c -- MBR (Master Boot Record) handling command
+ *
+ * Copyright (C) 2020 Samsung Electronics
+ * author: Marek Szyprowski 
+ *
+ * based on the gpt command.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * extract_val() - Extract a value from the key=value pair list
+ * @str: pointer to string with key=values pairs
+ * @key: pointer to the key to search for
+ *
+ * The list of parameters is come separated, only a value for
+ * the given key is returend.
+ *
+ * Function allocates memory for the value, remember to free!
+ *
+ * Return: Pointer to allocated string with the value.
+ */
+static char *extract_val(const char *str, const char *key)
+{
+   char *v, *k;
+   char *s, *strcopy;
+   char *new = NULL;
+
+   strcopy = strdup(str);
+   if (strcopy == NULL)
+   return NULL;
+
+   s = strcopy;
+   while (s) {
+   v = strsep(, ",");
+   if (!v)
+   break;
+   k = strsep(, "=");
+   if (!k)
+   break;
+   if  (strcmp(k, key) == 0) {
+   new = strdup(v);
+   break;
+   }
+   }
+
+   free(strcopy);
+
+   return new;
+}
+
+/**
+ * found_key() - Search for a key without a value in the parameter list
+ * @str: pointer to string with key
+ * @key: pointer to the key to search for
+ *
+ * The list of parameters is come separated.
+ *
+ * Return: True if key has been found.
+ */
+static bool found_key(const char *str, const char *key)
+{
+   char *k;
+   char *s, *strcopy;
+   bool result = false;
+
+   strcopy = strdup(str);
+   if (!strcopy)
+   return NULL;
+
+   s = strcopy;
+   while (s) {
+   k = strsep(, ",");
+   if (!k)
+   break;
+   if  (strcmp(k, key) == 0) {
+   result = true;
+   break;
+   }
+   }
+
+   free(strcopy);
+
+   return result;
+}
+
+static int str_to_partitions(const char *str_part, int blksz,
+   unsigned long *disk_uuid, struct disk_partition **partitions,
+   int *parts_count)
+{
+   char *tok, *str, *s;
+   int i;
+   char *val, *p;
+

[PATCH v2 3/6] disk: dos: use generic macro for unaligned le32 access

2020-12-22 Thread Marek Szyprowski
Use a generic helper for reading LE32 integers.

Signed-off-by: Marek Szyprowski 
---
 disk/part_dos.c | 28 +---
 1 file changed, 9 insertions(+), 19 deletions(-)

diff --git a/disk/part_dos.c b/disk/part_dos.c
index 20d35dc9cd..3b79b9b1b8 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "part_dos.h"
 #include 
 
@@ -29,17 +30,6 @@
  * to use large numbers of partitions */
 #define MAX_EXT_PARTS 256
 
-/* Convert char[4] in little endian format to the host format integer
- */
-static inline unsigned int le32_to_int(unsigned char *le32)
-{
-return ((le32[3] << 24) +
-   (le32[2] << 16) +
-   (le32[1] << 8) +
-le32[0]
-  );
-}
-
 static inline int is_extended(int part_type)
 {
 return (part_type == DOS_PART_TYPE_EXTENDED ||
@@ -61,8 +51,8 @@ static int get_bootable(dos_partition_t *p)
 static void print_one_part(dos_partition_t *p, lbaint_t ext_part_sector,
   int part_num, unsigned int disksig)
 {
-   lbaint_t lba_start = ext_part_sector + le32_to_int (p->start4);
-   lbaint_t lba_size  = le32_to_int (p->size4);
+   lbaint_t lba_start = ext_part_sector + get_unaligned_le32(p->start4);
+   lbaint_t lba_size  = get_unaligned_le32(p->size4);
 
printf("%3d\t%-10" LBAFlength "u\t%-10" LBAFlength
"u\t%08x-%02x\t%02x%s%s\n",
@@ -171,7 +161,7 @@ static void print_partition_extended(struct blk_desc 
*dev_desc,
}
 
if (!ext_part_sector)
-   disksig = le32_to_int([DOS_PART_DISKSIG_OFFSET]);
+   disksig = get_unaligned_le32([DOS_PART_DISKSIG_OFFSET]);
 
/* Print all primary/logical partitions */
pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
@@ -198,7 +188,7 @@ static void print_partition_extended(struct blk_desc 
*dev_desc,
for (i = 0; i < 4; i++, pt++) {
if (is_extended (pt->sys_ind)) {
lbaint_t lba_start
-   = le32_to_int (pt->start4) + relative;
+   = get_unaligned_le32 (pt->start4) + relative;
 
print_partition_extended(dev_desc, lba_start,
ext_part_sector == 0  ? lba_start : relative,
@@ -244,7 +234,7 @@ static int part_get_info_extended(struct blk_desc *dev_desc,
 
 #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
if (!ext_part_sector)
-   disksig = le32_to_int([DOS_PART_DISKSIG_OFFSET]);
+   disksig = get_unaligned_le32([DOS_PART_DISKSIG_OFFSET]);
 #endif
 
/* Print all primary/logical partitions */
@@ -260,8 +250,8 @@ static int part_get_info_extended(struct blk_desc *dev_desc,
(ext_part_sector == 0 || is_extended(pt->sys_ind) == 0)) {
info->blksz = DOS_PART_DEFAULT_SECTOR;
info->start = (lbaint_t)(ext_part_sector +
-   le32_to_int(pt->start4));
-   info->size  = (lbaint_t)le32_to_int(pt->size4);
+   get_unaligned_le32(pt->start4));
+   info->size  = (lbaint_t)get_unaligned_le32(pt->size4);
part_set_generic_name(dev_desc, part_num,
  (char *)info->name);
/* sprintf(info->type, "%d, pt->sys_ind); */
@@ -286,7 +276,7 @@ static int part_get_info_extended(struct blk_desc *dev_desc,
for (i = 0; i < 4; i++, pt++) {
if (is_extended (pt->sys_ind)) {
lbaint_t lba_start
-   = le32_to_int (pt->start4) + relative;
+   = get_unaligned_le32 (pt->start4) + relative;
 
return part_get_info_extended(dev_desc, lba_start,
 ext_part_sector == 0 ? lba_start : relative,
-- 
2.17.1



[PATCH v2 5/6] disk: dos: add code for creating MBR partition layout

2020-12-22 Thread Marek Szyprowski
Add a code for creating and writing MBR partition layout. The code
generates similar layout of EBRs (Exteneded Block Records) and logical
volumes as Linux's fdisk utility.

Signed-off-by: Marek Szyprowski 
---
 disk/part_dos.c | 167 
 disk/part_dos.h |   2 +
 include/part.h  |   5 ++
 3 files changed, 174 insertions(+)

diff --git a/disk/part_dos.c b/disk/part_dos.c
index 2c4ad0b6ba..f77f927995 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -319,6 +319,173 @@ int is_valid_dos_buf(void *buf)
return test_block_type(buf) == DOS_MBR ? 0 : -1;
 }
 
+#if CONFIG_IS_ENABLED(CMD_MBR)
+static void lba_to_chs(lbaint_t lba, unsigned char *rc, unsigned char *rh,
+  unsigned char *rs)
+{
+   unsigned int c, h, s;
+   /* use fixed CHS geometry */
+   unsigned int sectpertrack = 63;
+   unsigned int heads = 255;
+
+   c = (lba + 1) / sectpertrack / heads;
+   h = (lba + 1) / sectpertrack - c * heads;
+   s = (lba + 1) - (c * heads + h) * sectpertrack;
+
+   if (c > 1023) {
+   c = 1023;
+   h = 254;
+   s = 63;
+   }
+
+   *rc = c & 0xff;
+   *rh = h;
+   *rs = s + ((c & 0x300) >> 2);
+}
+
+static void mbr_fill_pt_entry(dos_partition_t *pt, lbaint_t start,
+   lbaint_t relative, lbaint_t size, uchar sys_ind, bool bootable)
+{
+   pt->boot_ind = bootable ? 0x80 : 0x00;
+   pt->sys_ind = sys_ind;
+   lba_to_chs(start, >cyl, >head, >sector);
+   lba_to_chs(start + size - 1, >end_cyl, >end_head, 
>end_sector);
+   put_unaligned_le32(relative, >start4);
+   put_unaligned_le32(size, >size4);
+}
+
+int write_mbr_partitions(struct blk_desc *dev,
+   struct disk_partition *p, int count, unsigned int disksig)
+{
+   ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev->blksz);
+   lbaint_t ext_part_start = 0, ext_part_size = 0, ext_part_sect = 0;
+   dos_partition_t *pt;
+   int i;
+
+   memset(buffer, 0, dev->blksz);
+   buffer[DOS_PART_MAGIC_OFFSET] = 0x55;
+   buffer[DOS_PART_MAGIC_OFFSET + 1] = 0xaa;
+   put_unaligned_le32(disksig, [DOS_PART_DISKSIG_OFFSET]);
+   pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
+
+   /* create all primary partitions */
+   for (i = 0; i < 4 && i < count; i++, pt++) {
+   mbr_fill_pt_entry(pt, p[i].start, p[i].start, p[i].size,
+ p[i].sys_ind, p[i].bootable);
+   if (is_extended(p[i].sys_ind)) {
+   ext_part_start = p[i].start;
+   ext_part_size = p[i].size;
+   ext_part_sect = p[i].start;
+   }
+   }
+
+   if (i < count && !ext_part_start) {
+   printf("%s: extended partition is needed for more than 4 
partitions\n",
+   __func__);
+   return -1;
+   }
+
+   /* write MBR */
+   if (blk_dwrite(dev, 0, 1, buffer) != 1) {
+   printf("%s: failed writing 'MBR' (1 blks at 0x0)\n",
+  __func__);
+   return -1;
+   }
+
+   /* create extended volumes */
+   for (; i < count; i++) {
+   lbaint_t next_ebr = 0;
+
+   memset(buffer, 0, dev->blksz);
+   buffer[DOS_PART_MAGIC_OFFSET] = 0x55;
+   buffer[DOS_PART_MAGIC_OFFSET + 1] = 0xaa;
+   pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
+
+   mbr_fill_pt_entry(pt, p[i].start, p[i].start - ext_part_sect,
+ p[i].size, p[i].sys_ind, p[i].bootable);
+
+   if (i + 1 < count) {
+   pt++;
+   next_ebr = p[i].start + p[i].size;
+   mbr_fill_pt_entry(pt, next_ebr,
+ next_ebr - ext_part_start,
+ p[i+1].start + p[i+1].size - next_ebr,
+ DOS_PART_TYPE_EXTENDED, 0);
+   }
+
+   /* write EBR */
+   if (blk_dwrite(dev, ext_part_sect, 1, buffer) != 1) {
+   printf("%s: failed writing 'EBR' (1 blks at 0x%lx)\n",
+  __func__, ext_part_sect);
+   return -1;
+   }
+   ext_part_sect = next_ebr;
+   }
+
+   return 0;
+}
+
+int layout_mbr_partitions(struct disk_partition *p, int count,
+ lbaint_t total_sectors)
+{
+   struct disk_partition *ext = NULL;
+   int i, j;
+   lbaint_t ext_vol_start;
+
+   /* calculate primary partitions start and size if needed */
+   if (!p[0].start)
+   p[0].start = DOS_PART_DEFAULT_GAP;
+   for (i = 0; i < 4 && i < count; i+

[PATCH v2 4/6] disk: dos: make some functions static

2020-12-22 Thread Marek Szyprowski
Make functions not used outside this file static.

Signed-off-by: Marek Szyprowski 
---
 disk/part_dos.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/disk/part_dos.c b/disk/part_dos.c
index 3b79b9b1b8..2c4ad0b6ba 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -302,13 +302,13 @@ static int part_get_info_extended(struct blk_desc 
*dev_desc,
return -1;
 }
 
-void part_print_dos(struct blk_desc *dev_desc)
+static void part_print_dos(struct blk_desc *dev_desc)
 {
printf("Part\tStart Sector\tNum Sectors\tUUID\t\tType\n");
print_partition_extended(dev_desc, 0, 0, 1, 0);
 }
 
-int part_get_info_dos(struct blk_desc *dev_desc, int part,
+static int part_get_info_dos(struct blk_desc *dev_desc, int part,
  struct disk_partition *info)
 {
return part_get_info_extended(dev_desc, 0, 0, 1, part, info, 0);
-- 
2.17.1



[PATCH v2 1/6] disk: dos: rename write_mbr_partition to write_mbr_sector

2020-12-22 Thread Marek Szyprowski
write_mbr_partition() function name is a bit misleading, so rename it to
write_mbr_sector(). This is a preparation for adding code for writing a
complete MBR partition layout.

Signed-off-by: Marek Szyprowski 
---
 disk/part_dos.c   | 2 +-
 drivers/fastboot/fb_mmc.c | 2 +-
 include/part.h| 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/disk/part_dos.c b/disk/part_dos.c
index 04f53106f7..ef706fb59c 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -329,7 +329,7 @@ int is_valid_dos_buf(void *buf)
return test_block_type(buf) == DOS_MBR ? 0 : -1;
 }
 
-int write_mbr_partition(struct blk_desc *dev_desc, void *buf)
+int write_mbr_sector(struct blk_desc *dev_desc, void *buf)
 {
if (is_valid_dos_buf(buf))
return -1;
diff --git a/drivers/fastboot/fb_mmc.c b/drivers/fastboot/fb_mmc.c
index ae8e8e512f..4e26cef941 100644
--- a/drivers/fastboot/fb_mmc.c
+++ b/drivers/fastboot/fb_mmc.c
@@ -508,7 +508,7 @@ void fastboot_mmc_flash_write(const char *cmd, void 
*download_buffer,
fastboot_fail("invalid MBR partition", response);
return;
}
-   if (write_mbr_partition(dev_desc, download_buffer)) {
+   if (write_mbr_sector(dev_desc, download_buffer)) {
printf("%s: writing MBR partition failed\n", __func__);
fastboot_fail("writing MBR partition failed",
  response);
diff --git a/include/part.h b/include/part.h
index 55be724d20..67b8b2a5cc 100644
--- a/include/part.h
+++ b/include/part.h
@@ -465,14 +465,14 @@ int get_disk_guid(struct blk_desc *dev_desc, char *guid);
 int is_valid_dos_buf(void *buf);
 
 /**
- * write_mbr_partition() - write DOS MBR
+ * write_mbr_sector() - write DOS MBR
  *
  * @param dev_desc - block device descriptor
  * @param buf - buffer which contains the MBR
  *
  * @return - '0' on success, otherwise error
  */
-int write_mbr_partition(struct blk_desc *dev_desc, void *buf);
+int write_mbr_sector(struct blk_desc *dev_desc, void *buf);
 
 #endif
 
-- 
2.17.1



[PATCH v2 2/6] disk: dos: add some defines for the hardcoded numbers

2020-12-22 Thread Marek Szyprowski
Add some handy defines for some hardcoded magic numbers related to
extended partition handling.

Signed-off-by: Marek Szyprowski 
---
 disk/part_dos.c | 6 +++---
 disk/part_dos.h | 3 +++
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/disk/part_dos.c b/disk/part_dos.c
index ef706fb59c..20d35dc9cd 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -42,9 +42,9 @@ static inline unsigned int le32_to_int(unsigned char *le32)
 
 static inline int is_extended(int part_type)
 {
-return (part_type == 0x5 ||
-   part_type == 0xf ||
-   part_type == 0x85);
+return (part_type == DOS_PART_TYPE_EXTENDED ||
+   part_type == DOS_PART_TYPE_EXTENDED_LBA ||
+   part_type == DOS_PART_TYPE_EXTENDED_LINUX);
 }
 
 static int get_bootable(dos_partition_t *p)
diff --git a/disk/part_dos.h b/disk/part_dos.h
index 434b021ae8..dd909a9317 100644
--- a/disk/part_dos.h
+++ b/disk/part_dos.h
@@ -15,6 +15,9 @@
 #define DOS_PBR_MEDIA_TYPE_OFFSET  0x15
 #define DOS_MBR0
 #define DOS_PBR1
+#define DOS_PART_TYPE_EXTENDED 0x05
+#define DOS_PART_TYPE_EXTENDED_LBA 0x0F
+#define DOS_PART_TYPE_EXTENDED_LINUX   0x85
 
 typedef struct dos_partition {
unsigned char boot_ind; /* 0x80 - active
*/
-- 
2.17.1



[PATCH v2 1/5] dfu: mmc: use the default MMC device if entity specifies it as -1

2020-12-22 Thread Marek Szyprowski
Use the default MMC device set in the command line if entity specifies it
as -1. This allows to use the same dfu_alt_info string for different MMC
devices (like embedded eMMC and external SD card if data layout is the
same on both devices).

Signed-off-by: Marek Szyprowski 
---
 drivers/dfu/dfu_mmc.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c
index 691d01c7eb..784d0ec76b 100644
--- a/drivers/dfu/dfu_mmc.c
+++ b/drivers/dfu/dfu_mmc.c
@@ -316,7 +316,7 @@ void dfu_free_entity_mmc(struct dfu_entity *dfu)
 int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr, char *s)
 {
const char *entity_type;
-   size_t second_arg;
+   ssize_t second_arg;
size_t third_arg;
 
struct mmc *mmc;
@@ -339,7 +339,7 @@ int dfu_fill_entity_mmc(struct dfu_entity *dfu, char 
*devstr, char *s)
 * Base 0 means we'll accept (prefixed with 0x or 0) base 16, 8,
 * with default 10.
 */
-   second_arg = simple_strtoul(argv[1], NULL, 0);
+   second_arg = simple_strtol(argv[1], NULL, 0);
third_arg = simple_strtoul(argv[2], NULL, 0);
 
mmc = find_mmc_device(dfu->data.mmc.dev_num);
@@ -406,7 +406,8 @@ int dfu_fill_entity_mmc(struct dfu_entity *dfu, char 
*devstr, char *s)
 
/* if it's NOT a raw write */
if (strcmp(entity_type, "raw")) {
-   dfu->data.mmc.dev = second_arg;
+   dfu->data.mmc.dev = (second_arg != -1) ? second_arg :
+dfu->data.mmc.dev_num;
dfu->data.mmc.part = third_arg;
}
 
-- 
2.17.1



[PATCH v2 3/5] dfu: add 'SCRIPT' entity

2020-12-22 Thread Marek Szyprowski
Define a new 'SCRIPT' type for DFU entities. The downloaded data are
treated as simple u-boot's scripts and executed with run_command_list()
function.

Flashing the 'SCRIPT' entity might result in changing the 'dfu_alt_info'
environment variable from the flashed script, so add a global variable
for tracking the potential need to reinitialize the dfu_alt_info related
structures.

Signed-off-by: Marek Szyprowski 
---
 doc/README.dfu| 17 -
 drivers/dfu/dfu.c |  7 ++-
 drivers/dfu/dfu_mmc.c | 23 +--
 include/dfu.h |  3 +++
 4 files changed, 46 insertions(+), 4 deletions(-)

diff --git a/doc/README.dfu b/doc/README.dfu
index 6cb1cba9d7..eacd5bbfb4 100644
--- a/doc/README.dfu
+++ b/doc/README.dfu
@@ -17,7 +17,7 @@ Overview:
   - The access to mediums is done in DFU backends (driver/dfu)
 
   Today the supported DFU backends are:
-  - MMC (RAW or FAT / EXT2 / EXT3 / EXT4 file system / SKIP)
+  - MMC (RAW or FAT / EXT2 / EXT3 / EXT4 file system / SKIP / SCRIPT)
   - NAND
   - RAM
   - SF (serial flash)
@@ -92,6 +92,7 @@ Commands:
fat   [mmcpart ]   file in FAT partition
ext4   [mmcpart ]  file in EXT4 partition
skip 0 0  ignore flashed data
+   script 0 0execute commands in shell
 
   with  being the GPT or DOS partition index,
   with  being the eMMC hardware partition number.
@@ -116,6 +117,20 @@ Commands:
 
   "u-boot-.bin raw 0x80 0x800; u-boot-.bin skip 0 0"
 
+When flashing new system image requires do some more complex things
+than just writing data to the storage medium, one can use 'script'
+type. Data written to such entity will be executed as a command list
+in the u-boot's shell. This for example allows to re-create partition
+layout and even set new dfu_alt_info for the newly created paritions.
+Such script would look like:
+   --->8---
+   setenv dfu_alt_info ...
+   setenv mbr_parts ...
+   mbr write ...
+   --->8---
+Please note that this means that user will be able to execute any
+arbitrary commands just like in the u-boot's shell.
+
   "nand" (raw slc nand device)
 cmd: dfu 0 nand 
 each element in "dfu_alt_info" =
diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
index fc32a53323..213a20e7bc 100644
--- a/drivers/dfu/dfu.c
+++ b/drivers/dfu/dfu.c
@@ -26,6 +26,8 @@ static struct hash_algo *dfu_hash_algo;
 static unsigned long dfu_timeout = 0;
 #endif
 
+bool dfu_reinit_needed = false;
+
 /*
  * The purpose of the dfu_flush_callback() function is to
  * provide callback for dfu user
@@ -139,6 +141,8 @@ int dfu_init_env_entities(char *interface, char *devstr)
char *env_bkp;
int ret = 0;
 
+   dfu_reinit_needed = false;
+
 #ifdef CONFIG_SET_DFU_ALT_INFO
set_dfu_alt_info(interface, devstr);
 #endif
@@ -614,7 +618,8 @@ const char *dfu_get_dev_type(enum dfu_device_type t)
 const char *dfu_get_layout(enum dfu_layout l)
 {
const char *const dfu_layout[] = {NULL, "RAW_ADDR", "FAT", "EXT2",
- "EXT3", "EXT4", "RAM_ADDR", "SKIP" };
+ "EXT3", "EXT4", "RAM_ADDR", "SKIP",
+ "SCRIPT" };
return dfu_layout[l];
 }
 
diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c
index d1af11d94c..e63fa84ce4 100644
--- a/drivers/dfu/dfu_mmc.c
+++ b/drivers/dfu/dfu_mmc.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static unsigned char *dfu_file_buf;
 static u64 dfu_file_buf_len;
@@ -206,6 +207,9 @@ int dfu_write_medium_mmc(struct dfu_entity *dfu,
case DFU_FS_EXT4:
ret = mmc_file_buf_write(dfu, offset, buf, len);
break;
+   case DFU_SCRIPT:
+   ret = run_command_list(buf, *len, 0);
+   break;
case DFU_SKIP:
ret = 0;
break;
@@ -221,9 +225,21 @@ int dfu_flush_medium_mmc(struct dfu_entity *dfu)
 {
int ret = 0;
 
-   if (dfu->layout != DFU_RAW_ADDR) {
-   /* Do stuff here. */
+   switch (dfu->layout) {
+   case DFU_FS_FAT:
+   case DFU_FS_EXT4:
ret = mmc_file_buf_write_finish(dfu);
+   break;
+   case DFU_SCRIPT:
+   /* script may have changed the dfu_alt_info */
+   dfu_reinit_needed = true;
+   break;
+   case DFU_RAW_ADDR:
+   case DFU_SKIP:
+   break;
+   default:
+   printf("%s: Layout (%s) not (yet) supported!\n", __func__,
+  dfu_get_layout(dfu->layout));
}
 
return ret;
@@ -243,6 +259,7 @@ int dfu_get_medium_size_mmc(struct dfu_entity *dfu, u64 
*size)

[PATCH v2 4/5] dfu: add support for the dfu_alt_info reintialization from the flashed script

2020-12-22 Thread Marek Szyprowski
Reinitialize DFU USB gadget after flashing the 'SCRIPT' entity to ensure
that the potential changes to the 'dfu_alt_info' environment variable are
applied.

Signed-off-by: Marek Szyprowski 
---
 cmd/dfu.c| 14 +-
 common/dfu.c |  3 +++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/cmd/dfu.c b/cmd/dfu.c
index 7310595a02..89b1b2268e 100644
--- a/cmd/dfu.c
+++ b/cmd/dfu.c
@@ -34,6 +34,7 @@ static int do_dfu(struct cmd_tbl *cmdtp, int flag, int argc, 
char *const argv[])
 #if defined(CONFIG_DFU_TIMEOUT) || defined(CONFIG_DFU_OVER_TFTP)
unsigned long value = 0;
 #endif
+   bool retry = false;
 
if (argc >= 4) {
interface = argv[2];
@@ -68,7 +69,18 @@ static int do_dfu(struct cmd_tbl *cmdtp, int flag, int argc, 
char *const argv[])
 
int controller_index = simple_strtoul(usb_controller, NULL, 0);
 
-   run_usb_dnl_gadget(controller_index, "usb_dnl_dfu");
+   do {
+   retry = false;
+   run_usb_dnl_gadget(controller_index, "usb_dnl_dfu");
+
+   if (dfu_reinit_needed) {
+   dfu_free_entities();
+   ret = dfu_init_env_entities(interface, devstring);
+   if (ret)
+   goto done;
+   retry = true;
+   }
+   } while (retry);
 
 done:
dfu_free_entities();
diff --git a/common/dfu.c b/common/dfu.c
index d23cf67f19..16bd1ba588 100644
--- a/common/dfu.c
+++ b/common/dfu.c
@@ -98,6 +98,9 @@ int run_usb_dnl_gadget(int usbctrl_index, char 
*usb_dnl_gadget)
}
 #endif
 
+   if (dfu_reinit_needed)
+   goto exit;
+
WATCHDOG_RESET();
usb_gadget_handle_interrupts(usbctrl_index);
}
-- 
2.17.1



[PATCH v2 5/5] thor: add support for the dfu_alt_info reintialization from the flashed script

2020-12-22 Thread Marek Szyprowski
Reinitialize dfu_env_entities after flashing the 'SCRIPT' entity to
ensure that the potential changes to the 'dfu_alt_info' environment
variable are applied.

Signed-off-by: Marek Szyprowski 
---
 cmd/thordown.c  | 19 ---
 drivers/usb/gadget/f_thor.c |  3 +++
 include/thor.h  |  2 ++
 3 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/cmd/thordown.c b/cmd/thordown.c
index ae20dddfdd..838764ccef 100644
--- a/cmd/thordown.c
+++ b/cmd/thordown.c
@@ -52,13 +52,18 @@ int do_thor_down(struct cmd_tbl *cmdtp, int flag, int argc, 
char *const argv[])
goto exit;
}
 
-   ret = thor_handle();
-   if (ret) {
-   pr_err("THOR failed: %d\n", ret);
-   ret = CMD_RET_FAILURE;
-   goto exit;
-   }
-
+   do {
+   ret = thor_handle();
+   if (ret == THOR_DFU_REINIT_NEEDED) {
+   dfu_free_entities();
+   ret = dfu_init_env_entities(interface, devstring);
+   }
+   if (ret) {
+   pr_err("THOR failed: %d\n", ret);
+   ret = CMD_RET_FAILURE;
+   goto exit;
+   }
+   } while (ret == 0);
 exit:
g_dnl_unregister();
usb_gadget_release(controller_index);
diff --git a/drivers/usb/gadget/f_thor.c b/drivers/usb/gadget/f_thor.c
index 88fc87f2e9..3e69746ee6 100644
--- a/drivers/usb/gadget/f_thor.c
+++ b/drivers/usb/gadget/f_thor.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "f_thor.h"
 
@@ -735,6 +736,8 @@ int thor_handle(void)
printf("%s: No data received!\n", __func__);
break;
}
+   if (dfu_reinit_needed)
+   return THOR_DFU_REINIT_NEEDED;
}
 
return 0;
diff --git a/include/thor.h b/include/thor.h
index 62501bda17..ee67ab0a27 100644
--- a/include/thor.h
+++ b/include/thor.h
@@ -12,6 +12,8 @@
 
 #include 
 
+#define THOR_DFU_REINIT_NEEDED 0xFFFE
+
 int thor_handle(void);
 int thor_init(void);
 int thor_add(struct usb_configuration *c);
-- 
2.17.1



[PATCH v2 2/5] dfu: add 'SKIP' entity

2020-12-22 Thread Marek Szyprowski
From: Jaehoon Chung 

Define a new 'SKIP' type for the DFU entities. The flashed data for that
entity is simply ignored without returning any error values.

This allows to have one flashing procedure and images for the different
board types or variants, where each board uses only the images relevant
to it and skips the rest. This is especially usefull for the THOR
protocol, which usually transfers more than one file in a single session.

Signed-off-by: Jaehoon Chung 
Reviewed-by: Minkyu Kang 
[mszyprow: rephrased commit message and docs for easier reading, changed
   subject to "dfu: add 'SKIP' entity"]
Signed-off-by: Marek Szyprowski 
---
Original version of this patch is available here:
https://patchwork.ozlabs.org/project/uboot/patch/20201109115757.24601-1-jh80.ch...@samsung.com/
---
 doc/README.dfu| 15 ++-
 drivers/dfu/dfu.c |  2 +-
 drivers/dfu/dfu_mmc.c |  9 +
 include/dfu.h |  1 +
 4 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/doc/README.dfu b/doc/README.dfu
index be53b5b393..6cb1cba9d7 100644
--- a/doc/README.dfu
+++ b/doc/README.dfu
@@ -17,7 +17,7 @@ Overview:
   - The access to mediums is done in DFU backends (driver/dfu)
 
   Today the supported DFU backends are:
-  - MMC (RAW or FAT / EXT2 / EXT3 / EXT4 file system)
+  - MMC (RAW or FAT / EXT2 / EXT3 / EXT4 file system / SKIP)
   - NAND
   - RAM
   - SF (serial flash)
@@ -91,6 +91,7 @@ Commands:
part   [mmcpart ]  raw access to partition
fat   [mmcpart ]   file in FAT partition
ext4   [mmcpart ]  file in EXT4 partition
+   skip 0 0  ignore flashed data
 
   with  being the GPT or DOS partition index,
   with  being the eMMC hardware partition number.
@@ -103,6 +104,18 @@ Commands:
 
   "u-boot raw 0x80 0x800;uImage ext4 0 2"
 
+If don't want to flash given image file to storage, use "skip" type
+entity.
+- It can be used to protect flashing wrong image for the specific board.
+- Especailly, this layout will be useful when thor protocol is used,
+  which performs flashing in batch mode, where more than one file is
+  processed.
+For example, if one makes a single tar file with support for the two
+boards with u-boot-.bin and u-boot-.bin files, one
+can use it to flash a proper u-boot image on both without a failure:
+
+  "u-boot-.bin raw 0x80 0x800; u-boot-.bin skip 0 0"
+
   "nand" (raw slc nand device)
 cmd: dfu 0 nand 
 each element in "dfu_alt_info" =
diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
index 501a60b344..fc32a53323 100644
--- a/drivers/dfu/dfu.c
+++ b/drivers/dfu/dfu.c
@@ -614,7 +614,7 @@ const char *dfu_get_dev_type(enum dfu_device_type t)
 const char *dfu_get_layout(enum dfu_layout l)
 {
const char *const dfu_layout[] = {NULL, "RAW_ADDR", "FAT", "EXT2",
- "EXT3", "EXT4", "RAM_ADDR" };
+ "EXT3", "EXT4", "RAM_ADDR", "SKIP" };
return dfu_layout[l];
 }
 
diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c
index 784d0ec76b..d1af11d94c 100644
--- a/drivers/dfu/dfu_mmc.c
+++ b/drivers/dfu/dfu_mmc.c
@@ -108,6 +108,8 @@ static int mmc_file_op(enum dfu_op op, struct dfu_entity 
*dfu,
case DFU_FS_EXT4:
fstype = FS_TYPE_EXT;
break;
+   case DFU_SKIP:
+   return 0;
default:
printf("%s: Layout (%s) not (yet) supported!\n", __func__,
   dfu_get_layout(dfu->layout));
@@ -204,6 +206,9 @@ int dfu_write_medium_mmc(struct dfu_entity *dfu,
case DFU_FS_EXT4:
ret = mmc_file_buf_write(dfu, offset, buf, len);
break;
+   case DFU_SKIP:
+   ret = 0;
+   break;
default:
printf("%s: Layout (%s) not (yet) supported!\n", __func__,
   dfu_get_layout(dfu->layout));
@@ -238,6 +243,8 @@ int dfu_get_medium_size_mmc(struct dfu_entity *dfu, u64 
*size)
if (ret < 0)
return ret;
return 0;
+   case DFU_SKIP:
+   return 0;
default:
printf("%s: Layout (%s) not (yet) supported!\n", __func__,
   dfu_get_layout(dfu->layout));
@@ -399,6 +406,8 @@ int dfu_fill_entity_mmc(struct dfu_entity *dfu, char 
*devstr, char *s)
dfu->layout = DFU_FS_FAT;
} else if (!strcmp(entity_type, "ext4")) {
dfu->layout = DFU_FS_EXT4;
+   } else if (!strcmp(entity_type, "skip")) {
+   dfu->layout = DFU_SKIP;
} else {
pr_err("Memory layout (%s) not supported!\n", 

[PATCH v2 0/5] DFU: new entity types and minor improvements

2020-12-22 Thread Marek Szyprowski
Hi All,

This patchset adds support for SKIP and SCRIPT entity types to the DFU
subsystem. They significantly extends the flexibility of the storage
flashing commands. Together with the recently posted 'Add MBR partition
table creation and verify command' patchset and proper script it allows
to create the whole partition table during the board flashing. It also
easies the flashing by allowing to use the same images for different
board variants/types, as each board can now use only the relevant images
and skip the other ones without returning a failure.

Best regards
Marek Szyprowski
Samsung R Institute Poland


Changelog:
v2:
- updated the "dfu: add 'SKIP' entity" patch to the latest version
- added 'SCRIPT' DFU entity docs

v1: https://lists.denx.de/pipermail/u-boot/2020-December/435214.html
- initial version


Patch summary:

Jaehoon Chung (1):
  dfu: add 'SKIP' entity

Marek Szyprowski (4):
  dfu: mmc: use the default MMC device if entity specifies it as -1
  dfu: add 'SCRIPT' entity
  dfu: add support for the dfu_alt_info reintialization from the flashed
script
  thor: add support for the dfu_alt_info reintialization from the
flashed script

 cmd/dfu.c   | 14 -
 cmd/thordown.c  | 19 +++---
 common/dfu.c|  3 +++
 doc/README.dfu  | 30 +++-
 drivers/dfu/dfu.c   |  7 ++-
 drivers/dfu/dfu_mmc.c   | 39 -
 drivers/usb/gadget/f_thor.c |  3 +++
 include/dfu.h   |  4 
 include/thor.h  |  2 ++
 9 files changed, 106 insertions(+), 15 deletions(-)

-- 
2.17.1



[PATCH v4 3/3] configs: khadas-vim3(l): enable Function button support

2020-12-22 Thread Marek Szyprowski
Add options required to check the 'Function' button state.

Signed-off-by: Marek Szyprowski 
---
 configs/khadas-vim3_defconfig  | 2 ++
 configs/khadas-vim3l_defconfig | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/configs/khadas-vim3_defconfig b/configs/khadas-vim3_defconfig
index 5d16652fd6..bc17430569 100644
--- a/configs/khadas-vim3_defconfig
+++ b/configs/khadas-vim3_defconfig
@@ -31,6 +31,8 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_ADC=y
 CONFIG_SARADC_MESON=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_ADC=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MESON=y
 CONFIG_DM_MMC=y
diff --git a/configs/khadas-vim3l_defconfig b/configs/khadas-vim3l_defconfig
index 6b13ce045c..c1877922c7 100644
--- a/configs/khadas-vim3l_defconfig
+++ b/configs/khadas-vim3l_defconfig
@@ -31,6 +31,8 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_ADC=y
 CONFIG_SARADC_MESON=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_ADC=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MESON=y
 CONFIG_DM_MMC=y
-- 
2.17.1



[PATCH v4 2/3] button: add a simple Analog to Digital Converter device based button driver

2020-12-22 Thread Marek Szyprowski
Add a simple Analog to Digital Converter device based button driver. This
driver binds to the 'adc-keys' device tree node.

Signed-off-by: Marek Szyprowski 
---
 drivers/button/Kconfig  |   8 +++
 drivers/button/Makefile |   1 +
 drivers/button/button-adc.c | 121 
 3 files changed, 130 insertions(+)
 create mode 100644 drivers/button/button-adc.c

diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig
index 6b3ec7e55d..6db3c5e93a 100644
--- a/drivers/button/Kconfig
+++ b/drivers/button/Kconfig
@@ -9,6 +9,14 @@ config BUTTON
  can provide access to board-specific buttons. Use of the device tree
  for configuration is encouraged.
 
+config BUTTON_ADC
+   bool "Button adc"
+   depends on BUTTON
+   help
+ Enable support for buttons which are connected to Analog to Digital
+ Converter device. The ADC driver must use driver model. Buttons are
+ configured using the device tree.
+
 config BUTTON_GPIO
bool "Button gpio"
depends on BUTTON
diff --git a/drivers/button/Makefile b/drivers/button/Makefile
index fcc10ebe8d..bbd18af149 100644
--- a/drivers/button/Makefile
+++ b/drivers/button/Makefile
@@ -3,4 +3,5 @@
 # Copyright (C) 2020 Philippe Reynes 
 
 obj-$(CONFIG_BUTTON) += button-uclass.o
+obj-$(CONFIG_BUTTON_ADC) += button-adc.o
 obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o
diff --git a/drivers/button/button-adc.c b/drivers/button/button-adc.c
new file mode 100644
index 00..bf99dd8b43
--- /dev/null
+++ b/drivers/button/button-adc.c
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Author: Marek Szyprowski 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * struct button_adc_priv - private data for button-adc driver.
+ *
+ * @adc: Analog to Digital Converter device to which button is connected.
+ * @channel: channel of the ADC device to probe the button state.
+ */
+struct button_adc_priv {
+   struct udevice *adc;
+   int channel;
+};
+
+static enum button_state_t button_adc_get_state(struct udevice *dev)
+{
+   struct button_adc_priv *priv = dev_get_priv(dev);
+   unsigned int val, mask;
+   int ret;
+
+   ret = adc_start_channel(priv->adc, priv->channel);
+   if (ret)
+   return ret;
+
+   ret = adc_channel_data(priv->adc, priv->channel, );
+   if (ret)
+   return ret;
+
+   ret = adc_data_mask(priv->adc, );
+   if (ret)
+   return ret;
+
+   /* getting state is simplified a bit */
+   if (ret == 0)
+   return (val < mask / 2) ? BUTTON_ON : BUTTON_OFF;
+
+   return ret;
+}
+
+static int button_adc_probe(struct udevice *dev)
+{
+   struct button_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
+   struct button_adc_priv *priv = dev_get_priv(dev);
+   struct ofnode_phandle_args args;
+   int ret;
+
+   /* Ignore the top-level button node */
+   if (!uc_plat->label)
+   return 0;
+
+   ret = dev_read_phandle_with_args(dev->parent, "io-channels",
+"#io-channel-cells", 0, 0, );
+   if (ret)
+   return ret;
+
+   ret = uclass_get_device_by_ofnode(UCLASS_ADC, args.node, >adc);
+   if (ret)
+   return ret;
+
+   priv->channel = args.args[0];
+
+   return ret;
+}
+
+static int button_adc_bind(struct udevice *parent)
+{
+   struct udevice *dev;
+   ofnode node;
+   int ret;
+
+   dev_for_each_subnode(node, parent) {
+   struct button_uc_plat *uc_plat;
+   const char *label;
+
+   label = ofnode_read_string(node, "label");
+   if (!label) {
+   debug("%s: node %s has no label\n", __func__,
+ ofnode_get_name(node));
+   return -EINVAL;
+   }
+   ret = device_bind_driver_to_node(parent, "button_adc",
+ofnode_get_name(node),
+node, );
+   if (ret)
+   return ret;
+   uc_plat = dev_get_uclass_platdata(dev);
+   uc_plat->label = label;
+   }
+
+   return 0;
+}
+
+static const struct button_ops button_adc_ops = {
+   .get_state  = button_adc_get_state,
+};
+
+static const struct udevice_id button_adc_ids[] = {
+   { .compatible = "adc-keys" },
+   { }
+};
+
+U_BOOT_DRIVER(button_adc) = {
+   .name   = "button_adc",
+   .id = UCLASS_BUTTON,
+   .of_match   = button_adc_ids,
+   .ops= _adc_ops,
+   .priv_auto_alloc_size = sizeof(struct button_adc_priv),
+   .bind   = button_adc_bind,
+   .probe  = button_adc_probe,
+};
-- 
2.17.1



[PATCH v4 0/3] VIM3: add support for checking 'Function' button state

2020-12-22 Thread Marek Szyprowski
Hi All,

This patchset adds all building blocks needed for checking the 'Function'
button state in the boot script on Amlogic A311D based VIM3 board. This
button is connected to the ADC lines of the SoC, so it required to enable
meson SARADC, the clocks needed for it and a simple button-adc drivers.

Once applied, one can use following commands in the boot scripts:
-->8---
echo Checking Func button state: \\c
if button Function
then
echo Selected alternative boot
...
fi
--->8---

Best regards
Marek Szyprowski
Samsung R Institute Poland


Changelog:
v4:
- rebased onto uboot-amlogic/u-boot-amlogic-next and dropped merged patches
- added adc-keys bindings docs (copied from Linux kernel)
- minor code adjustments pointed by Simon
- enabled driver also in khadas-vim3l_defconfig

v3: https://lists.denx.de/pipermail/u-boot/2020-December/435072.html
- removed 'button' env variable
- extended kconfig and patch descriptions

v2: https://lists.denx.de/pipermail/u-boot/2020-December/434991.html
- removed Change-Id tags
- split defconfig changes into ADC and button related

v1: https://lists.denx.de/pipermail/u-boot/2020-December/434875.html
- initial submission


Patch summary:

Marek Szyprowski (3):
  dt-bindings: input: adc-keys bindings documentation
  button: add a simple Analog to Digital Converter device based button
driver
  configs: khadas-vim3(l): enable Function button support

 configs/khadas-vim3_defconfig   |   2 +
 configs/khadas-vim3l_defconfig  |   2 +
 doc/device-tree-bindings/input/adc-keys.txt |  49 
 drivers/button/Kconfig  |   8 ++
 drivers/button/Makefile |   1 +
 drivers/button/button-adc.c | 121 
 6 files changed, 183 insertions(+)
 create mode 100644 doc/device-tree-bindings/input/adc-keys.txt
 create mode 100644 drivers/button/button-adc.c

-- 
2.17.1



[PATCH v4 1/3] dt-bindings: input: adc-keys bindings documentation

2020-12-22 Thread Marek Szyprowski
Dump adc-keys bindings documentation from Linux kernel source tree v5.10.

Signed-off-by: Marek Szyprowski 
---
 doc/device-tree-bindings/input/adc-keys.txt | 49 +
 1 file changed, 49 insertions(+)
 create mode 100644 doc/device-tree-bindings/input/adc-keys.txt

diff --git a/doc/device-tree-bindings/input/adc-keys.txt 
b/doc/device-tree-bindings/input/adc-keys.txt
new file mode 100644
index 00..e551814629
--- /dev/null
+++ b/doc/device-tree-bindings/input/adc-keys.txt
@@ -0,0 +1,49 @@
+ADC attached resistor ladder buttons
+
+
+Required properties:
+ - compatible: "adc-keys"
+ - io-channels: Phandle to an ADC channel
+ - io-channel-names = "buttons";
+ - keyup-threshold-microvolt: Voltage at which all the keys are considered up.
+
+Optional properties:
+   - poll-interval: Poll interval time in milliseconds
+   - autorepeat: Boolean, Enable auto repeat feature of Linux input
+ subsystem.
+
+Each button (key) is represented as a sub-node of "adc-keys":
+
+Required subnode-properties:
+   - label: Descriptive name of the key.
+   - linux,code: Keycode to emit.
+   - press-threshold-microvolt: Voltage ADC input when this key is pressed.
+
+Example:
+
+#include 
+
+   adc-keys {
+   compatible = "adc-keys";
+   io-channels = < 0>;
+   io-channel-names = "buttons";
+   keyup-threshold-microvolt = <200>;
+
+   button-up {
+   label = "Volume Up";
+   linux,code = ;
+   press-threshold-microvolt = <150>;
+   };
+
+   button-down {
+   label = "Volume Down";
+   linux,code = ;
+   press-threshold-microvolt = <100>;
+   };
+
+   button-enter {
+   label = "Enter";
+   linux,code = ;
+   press-threshold-microvolt = <50>;
+   };
+   };
-- 
2.17.1



Re: [PATCH 4/6] button: add a simple ADC-based button driver

2020-12-21 Thread Marek Szyprowski
Hi Simon,

On 19.12.2020 03:28, Simon Glass wrote:
> On Mon, 14 Dec 2020 at 04:25, Marek Szyprowski  
> wrote:
>> Add a simple ADC-based button driver. This driver binds to the 'adc-keys'
>> device tree node.
>>
>> Signed-off-by: Marek Szyprowski 
>> Change-Id: I6da7101eff3ce53766d899f49f5839d728d52fb3
>> ---
>>   drivers/button/Kconfig  |   8 +++
>>   drivers/button/Makefile |   1 +
>>   drivers/button/button-adc.c | 117 
>>   3 files changed, 126 insertions(+)
>>   create mode 100644 drivers/button/button-adc.c
>>
>> diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig
>> index 6b3ec7e55de..283367f2bd3 100644
>> --- a/drivers/button/Kconfig
>> +++ b/drivers/button/Kconfig
>> @@ -9,6 +9,14 @@ config BUTTON
>>can provide access to board-specific buttons. Use of the device 
>> tree
>>for configuration is encouraged.
>>
>> +config BUTTON_ADC
>> +   bool "Button adc"
>> +   depends on BUTTON
>> +   help
>> + Enable support for buttons which are connected to ADC lines. The 
>> ADC
>> + driver must use driver model. Buttons are configured using the 
>> device
>> + tree.
>> +
>>   config BUTTON_GPIO
>>  bool "Button gpio"
>>  depends on BUTTON
>> diff --git a/drivers/button/Makefile b/drivers/button/Makefile
>> index fcc10ebe8db..bbd18af1494 100644
>> --- a/drivers/button/Makefile
>> +++ b/drivers/button/Makefile
>> @@ -3,4 +3,5 @@
>>   # Copyright (C) 2020 Philippe Reynes 
>>
>>   obj-$(CONFIG_BUTTON) += button-uclass.o
>> +obj-$(CONFIG_BUTTON_ADC) += button-adc.o
>>   obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o
>> diff --git a/drivers/button/button-adc.c b/drivers/button/button-adc.c
>> new file mode 100644
>> index 000..086c676c02a
>> --- /dev/null
>> +++ b/drivers/button/button-adc.c
>> @@ -0,0 +1,117 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (C) 2020 Samsung Electronics Co., Ltd.
>> + * http://www.samsung.com
>> + * Author: Marek Szyprowski 
>> + */
>> +
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
> Please check header order
>
> https://protect2.fireeye.com/v1/url?k=0827922c-57bcaba3-08261963-0cc47a31307c-c2add94742a708a4=1=e6ddd072-23a6-4591-9ca7-8d41aa498536=https%3A%2F%2Fwww.denx.de%2Fwiki%2FU-Boot%2FCodingStyle
>
>> +
>> +struct button_adc_priv {
>> +   struct udevice *adc;
>> +   int channel;
> comments
>
>> +};
>> +
>> +static enum button_state_t button_adc_get_state(struct udevice *dev)
>> +{
>> +   struct button_adc_priv *priv = dev_get_priv(dev);
>> +   unsigned int val, mask;
>> +   int ret;
>> +
>> +   ret = adc_start_channel(priv->adc, priv->channel);
>> +   if (ret)
>> +   return ret;
>> +
>> +   ret = adc_channel_data(priv->adc, priv->channel, );
>> +   if (ret)
>> +   return ret;
>> +
>> +   ret = adc_data_mask(priv->adc, );
>> +   if (ret)
>> +   return ret;
>> +
>> +   /* getting state is simplified a bit */
>> +   if (ret == 0)
>> +   return (val < mask / 2) ? BUTTON_ON : BUTTON_OFF;
>> +
>> +   return ret;
>> +}
>> +
>> +static int button_adc_probe(struct udevice *dev)
>> +{
>> +   struct button_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
>> +   struct button_adc_priv *priv = dev_get_priv(dev);
>> +   struct ofnode_phandle_args args;
>> +   int ret;
>> +
>> +   /* Ignore the top-level button node */
>> +   if (!uc_plat->label)
>> +   return 0;
>> +
>> +   ret = dev_read_phandle_with_args(dev->parent, "io-channels",
>> +"#io-channel-cells", 0, 0, );
>> +   if (ret)
>> +   return ret;
>> +
>> +   ret = uclass_get_device_by_name(UCLASS_ADC, 
>> ofnode_get_name(args.node),
>> +   >adc);
> How about uclass_get_device_by_ofnode() ?
>
>> +   if (ret)
>> +   return ret;
>> +
>> +   priv->channel = args.args[0];
>> +
>> +   return ret;
>> +}
>> +
>> +static int button_adc_bind(struct 

Re: [PATCH 0/5] DFU: new entity types and minor improvements

2020-12-20 Thread Marek Szyprowski
Hi Jaehoon,

On 20.12.2020 23:17, Jaehoon Chung wrote:
> On 12/17/20 9:10 PM, Marek Szyprowski wrote:
>> This patchset adds support for SKIP and SCRIPT entity types to the DFU
>> subsystem. They significantly extends the flexibility of the DFU
>> subsystem. Together with the recently posted 'Add MBR partition table
>> creation and verify command' patchset it allows to create the whole
>> partition table during the board flashing when one prepares a proper
>> script. It also easies the flashing by allowing to use the same images
>> for different board variants/types, as each board can now use only the
>> relevant images and skip the other ones without returning a failure.
> I sent the patch about skip entity. At that time, Lukasz mentioned to update 
> dfu documentation.
>
> https://patchwork.ozlabs.org/project/uboot/patch/20201109115757.24601-1-jh80.ch...@samsung.com/
>
> Could you update also README.dfu and Minkyu's reviewed-tag about my patch?

Thanks for pointing this. I missed that. I will include your v2 patch 
and also update the readme about the SCRIPT type.

Best regards

-- 
Marek Szyprowski, PhD
Samsung R Institute Poland



[PATCH] board: amlogic: add MMC boot device detection for environment load

2020-12-18 Thread Marek Szyprowski
Detect eMMC or SD card boot on Odroid-C4/N2 and Khadas VIM3(l) boards and
report proper MMC device for the environment loading code. This allows to
automatically load and store environment variables on the FAT partition
or RAW offset of the MMC device without the need to use different
configurations on eMMC and SD card.

To use this feature with environment stored on FAT partition, one has to
specify an empty device part (i.e. ":1" for the first partition) in
CONFIG_ENV_FAT_DEVICE_AND_PART to let the code to set the device to the
value returned by mmc_get_env_dev() function.

Signed-off-by: Marek Szyprowski 
---
 board/amlogic/odroid-n2/odroid-n2.c | 8 
 board/amlogic/vim3/vim3.c   | 8 
 2 files changed, 16 insertions(+)

diff --git a/board/amlogic/odroid-n2/odroid-n2.c 
b/board/amlogic/odroid-n2/odroid-n2.c
index caf7fd6810..12ee5d3abc 100644
--- a/board/amlogic/odroid-n2/odroid-n2.c
+++ b/board/amlogic/odroid-n2/odroid-n2.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -17,6 +18,13 @@
 #define EFUSE_MAC_SIZE 12
 #define MAC_ADDR_LEN   6
 
+int mmc_get_env_dev(void)
+{
+   if (meson_get_boot_device() == BOOT_DEVICE_EMMC)
+   return 1;
+   return 0;
+}
+
 int misc_init_r(void)
 {
u8 mac_addr[MAC_ADDR_LEN];
diff --git a/board/amlogic/vim3/vim3.c b/board/amlogic/vim3/vim3.c
index 09ef39ff30..f9049e0172 100644
--- a/board/amlogic/vim3/vim3.c
+++ b/board/amlogic/vim3/vim3.c
@@ -10,10 +10,18 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include "khadas-mcu.h"
 
+int mmc_get_env_dev(void)
+{
+   if (meson_get_boot_device() == BOOT_DEVICE_EMMC)
+   return 2;
+   return 1;
+}
+
 /*
  * The VIM3 on-board  MCU can mux the PCIe/USB3.0 shared differential
  * lines using a FUSB340TMX USB 3.1 SuperSpeed Data Switch between
-- 
2.17.1



[PATCH] ARM: dts: meson: switch TFLASH_VDD_EN pin to open drain on Odroid-C4

2020-12-18 Thread Marek Szyprowski
For the proper reboot Odroid-C4 board requires to switch TFLASH_VDD_EN
pin to the high impedance mode, otherwise the board is stuck in the
middle of loading early stages of the bootloader from SD card.

This can be achieved by using the OPEN_DRAIN flag instead if the
ACTIVE_HIGH, what will leave the pin in input to achieve high state (pin
has the pull-up) and solve the issue.

Suggested-by: Neil Armstrong 
Signed-off-by: Marek Szyprowski 
---
This is a result of the discussion in the "[PATCH/RFC] board: amlogic:
Fix Odroid-C4 SD card reboot issue" thread:
https://lists.denx.de/pipermail/u-boot/2020-December/435295.html

Patch for the upstream Linux DTS has been already submitted:
https://lore.kernel.org/linux-amlogic/20201218102228.16211-1-m.szyprow...@samsung.com/
---
 arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi 
b/arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi
index c431988075..fbcc8287c5 100644
--- a/arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi
+++ b/arch/arm/dts/meson-sm1-odroid-c4-u-boot.dtsi
@@ -11,3 +11,7 @@
snps,reset-delays-us = <0 1 100>;
snps,reset-active-low;
 };
+
+_vdd {
+   gpio = <_ao GPIOAO_3 GPIO_OPEN_DRAIN>;
+};
-- 
2.17.1



Re: [PATCH/RFC] board: amlogic: Fix Odroid-C4 SD card reboot issue

2020-12-18 Thread Marek Szyprowski
Hi Neil,

On 18.12.2020 10:24, Neil Armstrong wrote:
> On 18/12/2020 10:11, Marek Szyprowski wrote:
>> On 18.12.2020 09:36, Neil Armstrong wrote:
>>> On 17/12/2020 10:06, Marek Szyprowski wrote:
>>>> For the proper reboot Odroid C4 board requires to switch TFLASH_VDD_EN
>>>> pin to the input (high impedance?) mode, otherwise the board is stuck
>>>> in the middle of loading early stages of the bootloader from SD card.
>>> Did you try taking the regulator-tflash_vdd and doing a disable/enable 
>>> sequence
>>> to reset the card ?
>>>
>>> The GPIOAO_3 has a default pull-up, so I don't see why moving it to input 
>>> could change
>>> anything.
>>>
>>> So maybe simply doing a 0->1 transition could do the same, using the 
>>> regulator
>>> would be much better.
>>>
>>> Can't we add "shutdown" or equivalent method to  the mmc driver that could 
>>> do this
>>> directly with the vdd regulator ?
>> Yes, I've tried all combinations of playing this that GPIO and regulator
>> that came to my mind. Switching pin to the input is the only one I've
>> found working.
> Thanks for the dumps !
>
> Could you try switching the tflash_vdd to opendrain like :
>
> --->8---
>
> --- a/arch/arm/dts/meson-sm1-odroid-c4.dts
> +++ b/arch/arm/dts/meson-sm1-odroid-c4.dts
> @@ -52,7 +52,7 @@
>  regulator-min-microvolt = <330>;
>  regulator-max-microvolt = <330>;
>
> -   gpio = <_ao GPIOAO_3 GPIO_ACTIVE_HIGH>;
> +   gpio = <_ao GPIOAO_3 GPIO_OPEN_DRAIN>;
>  enable-active-high;
>  regulator-always-on;
>  };
>
> --->8---
>
> This should leave the pin in input to achieve high state, and solve the issue.
>
Right, this fixed the issue! Thanks!

Do you want me to submit it as a patch to uboot and mainline Linux 
kernel or do you want to handle it by yourself?

Best regards

-- 
Marek Szyprowski, PhD
Samsung R Institute Poland



Re: [PATCH/RFC] board: amlogic: Fix Odroid-C4 SD card reboot issue

2020-12-18 Thread Marek Szyprowski
Hi Neil,

On 18.12.2020 09:36, Neil Armstrong wrote:
> On 17/12/2020 10:06, Marek Szyprowski wrote:
>> For the proper reboot Odroid C4 board requires to switch TFLASH_VDD_EN
>> pin to the input (high impedance?) mode, otherwise the board is stuck
>> in the middle of loading early stages of the bootloader from SD card.
> Did you try taking the regulator-tflash_vdd and doing a disable/enable 
> sequence
> to reset the card ?
>
> The GPIOAO_3 has a default pull-up, so I don't see why moving it to input 
> could change
> anything.
>
> So maybe simply doing a 0->1 transition could do the same, using the regulator
> would be much better.
>
> Can't we add "shutdown" or equivalent method to  the mmc driver that could do 
> this
> directly with the vdd regulator ?

Yes, I've tried all combinations of playing this that GPIO and regulator 
that came to my mind. Switching pin to the input is the only one I've 
found working.

It looks that there must be some additional (hw?) logic there, which 
does the SD card reset during the BL, which in turn conflicts with the 
constant 0 or constant 1 driven from TFLASH_VDD_EN gpio. This is also 
what the vendor's kernel does: 
https://github.com/hardkernel/linux/commit/84628497332a5cd2154c92436ec86fad900fe0af
 
That commit states that it is according to the odroid schematic, but on 
the public schematics of C4 I cannot find anything what might need such 
workaround/fix.

Here is how it behaves without the fix:

1. if SD card is not used (TFLASH regulator is not even instantiated, so 
GPIO pin is in input state as its initial value left by earlier BL 
stages), the reboot works fine:

--->8---

U-Boot 2021.01-rc3 (Dec 18 2020 - 10:00:48 +0100) odroid-c4

Model: Hardkernel ODROID-C4
SoC:   Amlogic Meson SM1 (S905X3) Revision 2b:c (10:2)
DRAM:  3.8 GiB
MMC:   sd@ffe05000: 0, mmc@ffe07000: 1
In:    serial
Out:   serial
Err:   serial
Net:   eth0: ethernet@ff3f
Hit any key to stop autoboot:  0
=>
=> reset
resetting ...
bl31 reboot reason: 0xd
bl31 reboot reason: 0x0
system cmd  1.
SM1:BL:511f6b:81ca2f;FEAT:A0F83180:20282000;POC:F;RCY:0;EMMC:800;NAND:81;SD?:0;SD:0;READ:0;0.0;CHK:0;
bl2_stage_init 0x01
bl2_stage_init 0x81
hw id: 0x - pwm id 0x01
bl2_stage_init 0xc1
bl2_stage_init 0x02

no sdio debug board detected
L0:
L1:0703
L2:8067
L3:1520
S1:
B2:20282000
B1:a0f83180

TE: 143230

BL2 Built : 22:54:32, Apr 28 2020. g12a ga659aac-dirty - 
changqing.gao@droid11

Board ID = 1
Set cpu clk to 24M
Set clk81 to 24M
Use GP1_pll as DSU clk.
DSU clk: 1200 Mhz
CPU clk: 1200 MHz
Set clk81 to 166.6M
DDR driver_vesion: LPDDR4_PHY_V_0_1_15 build time: Apr 28 2020 22:54:28
board id: 1
Load FIP HDR from SD, src: 0x00010200, des: 0xfffd, size: 
0x4000, part: 0
fw parse done
Load ddrfw from SD, src: 0x00060200, des: 0xfffd, size: 0xc000, 
part: 0
Load ddrfw from SD, src: 0x00038200, des: 0xfffd, size: 0x4000, 
part: 0
PIEI prepare done
fastboot data load
fastboot data verify
verify result: 255
Cfg max: 2, cur: 1. Board id: 255. Force loop cfg
DDR4 probe
ddr clk to 1320MHz
Load ddrfw from SD, src: 0x00014200, des: 0xfffd, size: 0xc000, 
part: 0

dmc_version 0001
Check phy result
INFO : End of initialization
INFO : End of read enable training
INFO : End of fine write leveling
INFO : End of read dq deskew training
INFO : End of MPR read delay center optimization
INFO : End of Write leveling coarse delay
INFO : End of write delay center optimization
INFO : End of read delay center optimization
INFO : End of max read latency training
INFO : Training has run successfully!
1D training succeed
Load ddrfw from SD, src: 0x00020200, des: 0xfffd, size: 0xc000, 
part: 0
Check phy result
INFO : End of initialization
INFO : End of 2D read delay Voltage center optimization
INFO : End of 2D write delay Voltage center optimization
INFO : Training has run successfully!

R0_RxClkDly_Margin==94 ps 8
R0_TxDqDly_Margi==106 ps 9


R1_RxClkDly_Margin==0 ps 0
R1_TxDqDly_Margi==0 ps 0

  dwc_ddrphy_apb_wr((0<<20)|(2<<16)|(0<<12)|(0xb0):0001

soc_vref_reg_value 0x 004e 004f 004e 004f 0050 
004f 004f 004e 004d 004c 004f 004d 0050 
0050 004f 004f 004e 004f 004e 004e 004e 
004d 004e 004e 0050 004e 004f 004d 004d 
004e 004e 004d dram_vref_reg_value 0x 0022
2D training succeed
aml_ddr_fw_vesion: LPDDR4_PHY_V_0_1_15 build time: Jun 18 2019 20:29:43
auto size-- 65535DDR cs0 size: 2048MB
DDR cs1 size: 2048MB
DMC_DDR_CTRL: 00700024DDR size: 3928MB
cs0 DataBus test pass
cs1 DataBus test pass
cs0 AddrBus test pass
cs1 AddrBus test pass

non-sec scramble use zero key
ddr scramble enabled

100bdlr_step_size ps== 425
result report
boot times 1Enable ddr reg access
Load FIP HDR from SD, src: 0x00010200, des: 0x0170, size: 
0x400

[PATCH 4/5] dfu: add support for the dfu_alt_info reintialization from the flashed script

2020-12-17 Thread Marek Szyprowski
Reinitialize DFU USB gadget after flashing the 'SCRIPT' entity to ensure
that the potential changes to the 'dfu_alt_info' environment variable are
applied.

Signed-off-by: Marek Szyprowski 
---
 cmd/dfu.c| 14 +-
 common/dfu.c |  3 +++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/cmd/dfu.c b/cmd/dfu.c
index 7310595a02..89b1b2268e 100644
--- a/cmd/dfu.c
+++ b/cmd/dfu.c
@@ -34,6 +34,7 @@ static int do_dfu(struct cmd_tbl *cmdtp, int flag, int argc, 
char *const argv[])
 #if defined(CONFIG_DFU_TIMEOUT) || defined(CONFIG_DFU_OVER_TFTP)
unsigned long value = 0;
 #endif
+   bool retry = false;
 
if (argc >= 4) {
interface = argv[2];
@@ -68,7 +69,18 @@ static int do_dfu(struct cmd_tbl *cmdtp, int flag, int argc, 
char *const argv[])
 
int controller_index = simple_strtoul(usb_controller, NULL, 0);
 
-   run_usb_dnl_gadget(controller_index, "usb_dnl_dfu");
+   do {
+   retry = false;
+   run_usb_dnl_gadget(controller_index, "usb_dnl_dfu");
+
+   if (dfu_reinit_needed) {
+   dfu_free_entities();
+   ret = dfu_init_env_entities(interface, devstring);
+   if (ret)
+   goto done;
+   retry = true;
+   }
+   } while (retry);
 
 done:
dfu_free_entities();
diff --git a/common/dfu.c b/common/dfu.c
index d23cf67f19..16bd1ba588 100644
--- a/common/dfu.c
+++ b/common/dfu.c
@@ -98,6 +98,9 @@ int run_usb_dnl_gadget(int usbctrl_index, char 
*usb_dnl_gadget)
}
 #endif
 
+   if (dfu_reinit_needed)
+   goto exit;
+
WATCHDOG_RESET();
usb_gadget_handle_interrupts(usbctrl_index);
}
-- 
2.17.1



[PATCH 0/5] DFU: new entity types and minor improvements

2020-12-17 Thread Marek Szyprowski
Hi All,

This patchset adds support for SKIP and SCRIPT entity types to the DFU
subsystem. They significantly extends the flexibility of the DFU
subsystem. Together with the recently posted 'Add MBR partition table
creation and verify command' patchset it allows to create the whole
partition table during the board flashing when one prepares a proper
script. It also easies the flashing by allowing to use the same images
for different board variants/types, as each board can now use only the
relevant images and skip the other ones without returning a failure.

Best regards
Marek Szyprowski
Samsung R Institute Poland


Jaehoon Chung (1):
  dfu: add 'SKIP' entity

Marek Szyprowski (4):
  dfu: mmc: use the default MMC device if entity specifies it as -1
  dfu: add 'SCRIPT' entity
  dfu: add support for the dfu_alt_info reintialization from the flashed
script
  thor: add support for the dfu_alt_info reintialization from the
flashed script

 cmd/dfu.c   | 14 -
 cmd/thordown.c  | 19 +++---
 common/dfu.c|  3 +++
 drivers/dfu/dfu.c   |  6 +-
 drivers/dfu/dfu_mmc.c   | 39 -
 drivers/usb/gadget/f_thor.c |  3 +++
 include/dfu.h   |  4 
 include/thor.h  |  2 ++
 8 files changed, 76 insertions(+), 14 deletions(-)

-- 
2.17.1



[PATCH 1/5] dfu: mmc: use the default MMC device if entity specifies it as -1

2020-12-17 Thread Marek Szyprowski
Use the default MMC device set in the command line if entity specifies it
as -1. This allows to use the same dfu_alt_info string for different MMC
devices (like embedded eMMC and external SD card if data layout is the
same on both devices).

Signed-off-by: Marek Szyprowski 
---
 drivers/dfu/dfu_mmc.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c
index 691d01c7eb..784d0ec76b 100644
--- a/drivers/dfu/dfu_mmc.c
+++ b/drivers/dfu/dfu_mmc.c
@@ -316,7 +316,7 @@ void dfu_free_entity_mmc(struct dfu_entity *dfu)
 int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr, char *s)
 {
const char *entity_type;
-   size_t second_arg;
+   ssize_t second_arg;
size_t third_arg;
 
struct mmc *mmc;
@@ -339,7 +339,7 @@ int dfu_fill_entity_mmc(struct dfu_entity *dfu, char 
*devstr, char *s)
 * Base 0 means we'll accept (prefixed with 0x or 0) base 16, 8,
 * with default 10.
 */
-   second_arg = simple_strtoul(argv[1], NULL, 0);
+   second_arg = simple_strtol(argv[1], NULL, 0);
third_arg = simple_strtoul(argv[2], NULL, 0);
 
mmc = find_mmc_device(dfu->data.mmc.dev_num);
@@ -406,7 +406,8 @@ int dfu_fill_entity_mmc(struct dfu_entity *dfu, char 
*devstr, char *s)
 
/* if it's NOT a raw write */
if (strcmp(entity_type, "raw")) {
-   dfu->data.mmc.dev = second_arg;
+   dfu->data.mmc.dev = (second_arg != -1) ? second_arg :
+dfu->data.mmc.dev_num;
dfu->data.mmc.part = third_arg;
}
 
-- 
2.17.1



[PATCH 5/5] thor: add support for the dfu_alt_info reintialization from the flashed script

2020-12-17 Thread Marek Szyprowski
Reinitialize dfu_env_entities after flashing the 'SCRIPT' entity to
ensure that the potential changes to the 'dfu_alt_info' environment
variable are applied.

Signed-off-by: Marek Szyprowski 
---
 cmd/thordown.c  | 19 ---
 drivers/usb/gadget/f_thor.c |  3 +++
 include/thor.h  |  2 ++
 3 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/cmd/thordown.c b/cmd/thordown.c
index ae20dddfdd..838764ccef 100644
--- a/cmd/thordown.c
+++ b/cmd/thordown.c
@@ -52,13 +52,18 @@ int do_thor_down(struct cmd_tbl *cmdtp, int flag, int argc, 
char *const argv[])
goto exit;
}
 
-   ret = thor_handle();
-   if (ret) {
-   pr_err("THOR failed: %d\n", ret);
-   ret = CMD_RET_FAILURE;
-   goto exit;
-   }
-
+   do {
+   ret = thor_handle();
+   if (ret == THOR_DFU_REINIT_NEEDED) {
+   dfu_free_entities();
+   ret = dfu_init_env_entities(interface, devstring);
+   }
+   if (ret) {
+   pr_err("THOR failed: %d\n", ret);
+   ret = CMD_RET_FAILURE;
+   goto exit;
+   }
+   } while (ret == 0);
 exit:
g_dnl_unregister();
usb_gadget_release(controller_index);
diff --git a/drivers/usb/gadget/f_thor.c b/drivers/usb/gadget/f_thor.c
index 88fc87f2e9..3e69746ee6 100644
--- a/drivers/usb/gadget/f_thor.c
+++ b/drivers/usb/gadget/f_thor.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "f_thor.h"
 
@@ -735,6 +736,8 @@ int thor_handle(void)
printf("%s: No data received!\n", __func__);
break;
}
+   if (dfu_reinit_needed)
+   return THOR_DFU_REINIT_NEEDED;
}
 
return 0;
diff --git a/include/thor.h b/include/thor.h
index 62501bda17..ee67ab0a27 100644
--- a/include/thor.h
+++ b/include/thor.h
@@ -12,6 +12,8 @@
 
 #include 
 
+#define THOR_DFU_REINIT_NEEDED 0xFFFE
+
 int thor_handle(void);
 int thor_init(void);
 int thor_add(struct usb_configuration *c);
-- 
2.17.1



[PATCH 2/5] dfu: add 'SKIP' entity

2020-12-17 Thread Marek Szyprowski
From: Jaehoon Chung 

Define a new 'SKIP' type for DFU entities. The flashed data are simply
ignored without returning any error values.

This allows to have the same board flashing procedure and images for the
different board types or variants, where each board uses only the images
relevant to it and skips the rest.

Signed-off-by: Jaehoon Chung 
[mszyprow: rephrased commit message and subject]
Signed-off-by: Marek Szyprowski 
---
 drivers/dfu/dfu.c | 2 +-
 drivers/dfu/dfu_mmc.c | 9 +
 include/dfu.h | 1 +
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
index 501a60b344..fc32a53323 100644
--- a/drivers/dfu/dfu.c
+++ b/drivers/dfu/dfu.c
@@ -614,7 +614,7 @@ const char *dfu_get_dev_type(enum dfu_device_type t)
 const char *dfu_get_layout(enum dfu_layout l)
 {
const char *const dfu_layout[] = {NULL, "RAW_ADDR", "FAT", "EXT2",
- "EXT3", "EXT4", "RAM_ADDR" };
+ "EXT3", "EXT4", "RAM_ADDR", "SKIP" };
return dfu_layout[l];
 }
 
diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c
index 784d0ec76b..d1af11d94c 100644
--- a/drivers/dfu/dfu_mmc.c
+++ b/drivers/dfu/dfu_mmc.c
@@ -108,6 +108,8 @@ static int mmc_file_op(enum dfu_op op, struct dfu_entity 
*dfu,
case DFU_FS_EXT4:
fstype = FS_TYPE_EXT;
break;
+   case DFU_SKIP:
+   return 0;
default:
printf("%s: Layout (%s) not (yet) supported!\n", __func__,
   dfu_get_layout(dfu->layout));
@@ -204,6 +206,9 @@ int dfu_write_medium_mmc(struct dfu_entity *dfu,
case DFU_FS_EXT4:
ret = mmc_file_buf_write(dfu, offset, buf, len);
break;
+   case DFU_SKIP:
+   ret = 0;
+   break;
default:
printf("%s: Layout (%s) not (yet) supported!\n", __func__,
   dfu_get_layout(dfu->layout));
@@ -238,6 +243,8 @@ int dfu_get_medium_size_mmc(struct dfu_entity *dfu, u64 
*size)
if (ret < 0)
return ret;
return 0;
+   case DFU_SKIP:
+   return 0;
default:
printf("%s: Layout (%s) not (yet) supported!\n", __func__,
   dfu_get_layout(dfu->layout));
@@ -399,6 +406,8 @@ int dfu_fill_entity_mmc(struct dfu_entity *dfu, char 
*devstr, char *s)
dfu->layout = DFU_FS_FAT;
} else if (!strcmp(entity_type, "ext4")) {
dfu->layout = DFU_FS_EXT4;
+   } else if (!strcmp(entity_type, "skip")) {
+   dfu->layout = DFU_SKIP;
} else {
pr_err("Memory layout (%s) not supported!\n", entity_type);
return -ENODEV;
diff --git a/include/dfu.h b/include/dfu.h
index a767adee41..0b1dae0b3b 100644
--- a/include/dfu.h
+++ b/include/dfu.h
@@ -33,6 +33,7 @@ enum dfu_layout {
DFU_FS_EXT3,
DFU_FS_EXT4,
DFU_RAM_ADDR,
+   DFU_SKIP,
 };
 
 enum dfu_op {
-- 
2.17.1



[PATCH 3/5] dfu: add 'SCRIPT' entity

2020-12-17 Thread Marek Szyprowski
Define a new 'SCRIPT' type for DFU entities. The downloaded data are
treated as simple u-boot's scripts and executed with run_command_list()
function.

Flashing the 'SCRIPT' entity might result in changing the 'dfu_alt_info'
environment variable from the flashed script, so add a global variable
for tracking the potential need to reinitialize the dfu_alt_info related
structures.

Signed-off-by: Marek Szyprowski 
---
 drivers/dfu/dfu.c |  6 +-
 drivers/dfu/dfu_mmc.c | 23 +--
 include/dfu.h |  3 +++
 3 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
index fc32a53323..eccfb4c745 100644
--- a/drivers/dfu/dfu.c
+++ b/drivers/dfu/dfu.c
@@ -26,6 +26,8 @@ static struct hash_algo *dfu_hash_algo;
 static unsigned long dfu_timeout = 0;
 #endif
 
+bool dfu_reinit_needed = false;
+
 /*
  * The purpose of the dfu_flush_callback() function is to
  * provide callback for dfu user
@@ -139,6 +141,8 @@ int dfu_init_env_entities(char *interface, char *devstr)
char *env_bkp;
int ret = 0;
 
+   dfu_reinit_needed = false;
+
 #ifdef CONFIG_SET_DFU_ALT_INFO
set_dfu_alt_info(interface, devstr);
 #endif
@@ -614,7 +618,7 @@ const char *dfu_get_dev_type(enum dfu_device_type t)
 const char *dfu_get_layout(enum dfu_layout l)
 {
const char *const dfu_layout[] = {NULL, "RAW_ADDR", "FAT", "EXT2",
- "EXT3", "EXT4", "RAM_ADDR", "SKIP" };
+ "EXT3", "EXT4", "RAM_ADDR", "SKIP", 
"SCRIPT" };
return dfu_layout[l];
 }
 
diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c
index d1af11d94c..e63fa84ce4 100644
--- a/drivers/dfu/dfu_mmc.c
+++ b/drivers/dfu/dfu_mmc.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static unsigned char *dfu_file_buf;
 static u64 dfu_file_buf_len;
@@ -206,6 +207,9 @@ int dfu_write_medium_mmc(struct dfu_entity *dfu,
case DFU_FS_EXT4:
ret = mmc_file_buf_write(dfu, offset, buf, len);
break;
+   case DFU_SCRIPT:
+   ret = run_command_list(buf, *len, 0);
+   break;
case DFU_SKIP:
ret = 0;
break;
@@ -221,9 +225,21 @@ int dfu_flush_medium_mmc(struct dfu_entity *dfu)
 {
int ret = 0;
 
-   if (dfu->layout != DFU_RAW_ADDR) {
-   /* Do stuff here. */
+   switch (dfu->layout) {
+   case DFU_FS_FAT:
+   case DFU_FS_EXT4:
ret = mmc_file_buf_write_finish(dfu);
+   break;
+   case DFU_SCRIPT:
+   /* script may have changed the dfu_alt_info */
+   dfu_reinit_needed = true;
+   break;
+   case DFU_RAW_ADDR:
+   case DFU_SKIP:
+   break;
+   default:
+   printf("%s: Layout (%s) not (yet) supported!\n", __func__,
+  dfu_get_layout(dfu->layout));
}
 
return ret;
@@ -243,6 +259,7 @@ int dfu_get_medium_size_mmc(struct dfu_entity *dfu, u64 
*size)
if (ret < 0)
return ret;
return 0;
+   case DFU_SCRIPT:
case DFU_SKIP:
return 0;
default:
@@ -408,6 +425,8 @@ int dfu_fill_entity_mmc(struct dfu_entity *dfu, char 
*devstr, char *s)
dfu->layout = DFU_FS_EXT4;
} else if (!strcmp(entity_type, "skip")) {
dfu->layout = DFU_SKIP;
+   } else if (!strcmp(entity_type, "script")) {
+   dfu->layout = DFU_SCRIPT;
} else {
pr_err("Memory layout (%s) not supported!\n", entity_type);
return -ENODEV;
diff --git a/include/dfu.h b/include/dfu.h
index 0b1dae0b3b..d18b701728 100644
--- a/include/dfu.h
+++ b/include/dfu.h
@@ -34,6 +34,7 @@ enum dfu_layout {
DFU_FS_EXT4,
DFU_RAM_ADDR,
DFU_SKIP,
+   DFU_SCRIPT,
 };
 
 enum dfu_op {
@@ -497,6 +498,8 @@ static inline int dfu_fill_entity_virt(struct dfu_entity 
*dfu, char *devstr,
 }
 #endif
 
+extern bool dfu_reinit_needed;
+
 #if CONFIG_IS_ENABLED(DFU_WRITE_ALT)
 /**
  * dfu_write_by_name() - write data to DFU medium
-- 
2.17.1



[PATCH 2/6] disk: dos: add some defines for the hardcoded numbers

2020-12-17 Thread Marek Szyprowski
Add some handy defines for some hardcoded magic numbers related to
extended partition handling.

Signed-off-by: Marek Szyprowski 
---
 disk/part_dos.c | 6 +++---
 disk/part_dos.h | 3 +++
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/disk/part_dos.c b/disk/part_dos.c
index ef706fb59c..20d35dc9cd 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -42,9 +42,9 @@ static inline unsigned int le32_to_int(unsigned char *le32)
 
 static inline int is_extended(int part_type)
 {
-return (part_type == 0x5 ||
-   part_type == 0xf ||
-   part_type == 0x85);
+return (part_type == DOS_PART_TYPE_EXTENDED ||
+   part_type == DOS_PART_TYPE_EXTENDED_LBA ||
+   part_type == DOS_PART_TYPE_EXTENDED_LINUX);
 }
 
 static int get_bootable(dos_partition_t *p)
diff --git a/disk/part_dos.h b/disk/part_dos.h
index 434b021ae8..dd909a9317 100644
--- a/disk/part_dos.h
+++ b/disk/part_dos.h
@@ -15,6 +15,9 @@
 #define DOS_PBR_MEDIA_TYPE_OFFSET  0x15
 #define DOS_MBR0
 #define DOS_PBR1
+#define DOS_PART_TYPE_EXTENDED 0x05
+#define DOS_PART_TYPE_EXTENDED_LBA 0x0F
+#define DOS_PART_TYPE_EXTENDED_LINUX   0x85
 
 typedef struct dos_partition {
unsigned char boot_ind; /* 0x80 - active
*/
-- 
2.17.1



[PATCH 0/6] Add MBR partition table creation and verify command

2020-12-17 Thread Marek Szyprowski
Hi All,

This patchset adds 'mbr' command to let one create or verify MBR (Master
Boot Record) partition layout based on the provided text description.
This can be used in scripts to help system flashing tools/scripts to
ensure proper partition layout. It has been inspired by the 'gpt' command
already present in u-boot.

Best regards
Marek Szyprowski
Samsung R Institute Poland


Marek Szyprowski (6):
  disk: dos: rename write_mbr_partition to write_mbr_sector
  disk: dos: add some defines for the hardcoded numbers
  disk: dos: use generic macro for unaligned le32 access
  disk: dos: make some functions static
  disk: dos: add code for creating MBR partition layout
  cmd: Add MBR partition layout control utility

 cmd/Kconfig   |   8 +
 cmd/Makefile  |   1 +
 cmd/mbr.c | 308 ++
 disk/part_dos.c   | 207 +
 disk/part_dos.h   |   5 +
 drivers/fastboot/fb_mmc.c |   2 +-
 include/part.h|   9 +-
 7 files changed, 512 insertions(+), 28 deletions(-)
 create mode 100644 cmd/mbr.c

-- 
2.17.1



[PATCH 1/6] disk: dos: rename write_mbr_partition to write_mbr_sector

2020-12-17 Thread Marek Szyprowski
write_mbr_partition() function name is a bit misleading, so rename it to
write_mbr_sector(). This is a preparation for adding code for writing a
complete MBR partition layout.

Signed-off-by: Marek Szyprowski 
---
 disk/part_dos.c   | 2 +-
 drivers/fastboot/fb_mmc.c | 2 +-
 include/part.h| 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/disk/part_dos.c b/disk/part_dos.c
index 04f53106f7..ef706fb59c 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -329,7 +329,7 @@ int is_valid_dos_buf(void *buf)
return test_block_type(buf) == DOS_MBR ? 0 : -1;
 }
 
-int write_mbr_partition(struct blk_desc *dev_desc, void *buf)
+int write_mbr_sector(struct blk_desc *dev_desc, void *buf)
 {
if (is_valid_dos_buf(buf))
return -1;
diff --git a/drivers/fastboot/fb_mmc.c b/drivers/fastboot/fb_mmc.c
index ae8e8e512f..4e26cef941 100644
--- a/drivers/fastboot/fb_mmc.c
+++ b/drivers/fastboot/fb_mmc.c
@@ -508,7 +508,7 @@ void fastboot_mmc_flash_write(const char *cmd, void 
*download_buffer,
fastboot_fail("invalid MBR partition", response);
return;
}
-   if (write_mbr_partition(dev_desc, download_buffer)) {
+   if (write_mbr_sector(dev_desc, download_buffer)) {
printf("%s: writing MBR partition failed\n", __func__);
fastboot_fail("writing MBR partition failed",
  response);
diff --git a/include/part.h b/include/part.h
index 55be724d20..67b8b2a5cc 100644
--- a/include/part.h
+++ b/include/part.h
@@ -465,14 +465,14 @@ int get_disk_guid(struct blk_desc *dev_desc, char *guid);
 int is_valid_dos_buf(void *buf);
 
 /**
- * write_mbr_partition() - write DOS MBR
+ * write_mbr_sector() - write DOS MBR
  *
  * @param dev_desc - block device descriptor
  * @param buf - buffer which contains the MBR
  *
  * @return - '0' on success, otherwise error
  */
-int write_mbr_partition(struct blk_desc *dev_desc, void *buf);
+int write_mbr_sector(struct blk_desc *dev_desc, void *buf);
 
 #endif
 
-- 
2.17.1



[PATCH 3/6] disk: dos: use generic macro for unaligned le32 access

2020-12-17 Thread Marek Szyprowski
Use a generic helper for reading LE32 integers.

Signed-off-by: Marek Szyprowski 
---
 disk/part_dos.c | 28 +---
 1 file changed, 9 insertions(+), 19 deletions(-)

diff --git a/disk/part_dos.c b/disk/part_dos.c
index 20d35dc9cd..3b79b9b1b8 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "part_dos.h"
 #include 
 
@@ -29,17 +30,6 @@
  * to use large numbers of partitions */
 #define MAX_EXT_PARTS 256
 
-/* Convert char[4] in little endian format to the host format integer
- */
-static inline unsigned int le32_to_int(unsigned char *le32)
-{
-return ((le32[3] << 24) +
-   (le32[2] << 16) +
-   (le32[1] << 8) +
-le32[0]
-  );
-}
-
 static inline int is_extended(int part_type)
 {
 return (part_type == DOS_PART_TYPE_EXTENDED ||
@@ -61,8 +51,8 @@ static int get_bootable(dos_partition_t *p)
 static void print_one_part(dos_partition_t *p, lbaint_t ext_part_sector,
   int part_num, unsigned int disksig)
 {
-   lbaint_t lba_start = ext_part_sector + le32_to_int (p->start4);
-   lbaint_t lba_size  = le32_to_int (p->size4);
+   lbaint_t lba_start = ext_part_sector + get_unaligned_le32(p->start4);
+   lbaint_t lba_size  = get_unaligned_le32(p->size4);
 
printf("%3d\t%-10" LBAFlength "u\t%-10" LBAFlength
"u\t%08x-%02x\t%02x%s%s\n",
@@ -171,7 +161,7 @@ static void print_partition_extended(struct blk_desc 
*dev_desc,
}
 
if (!ext_part_sector)
-   disksig = le32_to_int([DOS_PART_DISKSIG_OFFSET]);
+   disksig = get_unaligned_le32([DOS_PART_DISKSIG_OFFSET]);
 
/* Print all primary/logical partitions */
pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
@@ -198,7 +188,7 @@ static void print_partition_extended(struct blk_desc 
*dev_desc,
for (i = 0; i < 4; i++, pt++) {
if (is_extended (pt->sys_ind)) {
lbaint_t lba_start
-   = le32_to_int (pt->start4) + relative;
+   = get_unaligned_le32 (pt->start4) + relative;
 
print_partition_extended(dev_desc, lba_start,
ext_part_sector == 0  ? lba_start : relative,
@@ -244,7 +234,7 @@ static int part_get_info_extended(struct blk_desc *dev_desc,
 
 #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
if (!ext_part_sector)
-   disksig = le32_to_int([DOS_PART_DISKSIG_OFFSET]);
+   disksig = get_unaligned_le32([DOS_PART_DISKSIG_OFFSET]);
 #endif
 
/* Print all primary/logical partitions */
@@ -260,8 +250,8 @@ static int part_get_info_extended(struct blk_desc *dev_desc,
(ext_part_sector == 0 || is_extended(pt->sys_ind) == 0)) {
info->blksz = DOS_PART_DEFAULT_SECTOR;
info->start = (lbaint_t)(ext_part_sector +
-   le32_to_int(pt->start4));
-   info->size  = (lbaint_t)le32_to_int(pt->size4);
+   get_unaligned_le32(pt->start4));
+   info->size  = (lbaint_t)get_unaligned_le32(pt->size4);
part_set_generic_name(dev_desc, part_num,
  (char *)info->name);
/* sprintf(info->type, "%d, pt->sys_ind); */
@@ -286,7 +276,7 @@ static int part_get_info_extended(struct blk_desc *dev_desc,
for (i = 0; i < 4; i++, pt++) {
if (is_extended (pt->sys_ind)) {
lbaint_t lba_start
-   = le32_to_int (pt->start4) + relative;
+   = get_unaligned_le32 (pt->start4) + relative;
 
return part_get_info_extended(dev_desc, lba_start,
 ext_part_sector == 0 ? lba_start : relative,
-- 
2.17.1



[PATCH 6/6] cmd: Add MBR partition layout control utility

2020-12-17 Thread Marek Szyprowski
Add a 'mbr' command to let user create or verify MBR partition layout
based on the provided text description. The partition layout is
altearnatively read from 'mbr_parts' environment variable. This can be
used in scripts to help system image flashing tools to ensure proper
partition layout.

The syntax of the text description of the partition list is similar to
the one used by the 'gpt' command. Supported parameters are: name
(currently ignored), start (partition start offset in bytes), size (in
bytes or '-' to expand it to the whole free area), bootable (boolean flag)
and id (MBR partition system ID). If one wants to create more than 4
partitions, an 'Extended' primary partition (with 0x05 ID) has to be
explicitely provided as a one of the first 4 entries.

Here is the example how to create a 6 partitions (3 on the 'extended
volume'), some of the predefined sizes:

> setenv mbr_parts 'name=boot,start=4M,size=128M,bootable,id=0x0e;
  name=rootfs,size=3072M,id=0x83;
  name=system-data,size=512M,id=0x83;
  name=[ext],size=-,id=0x05;
  name=user,size=-,id=0x83;
  name=modules,size=100M,id=0x83;
  name=ramdisk,size=8M,id=0x83'
> mbr write mmc 0

Signed-off-by: Marek Szyprowski 
---
 cmd/Kconfig  |   8 ++
 cmd/Makefile |   1 +
 cmd/mbr.c| 308 +++
 3 files changed, 317 insertions(+)
 create mode 100644 cmd/mbr.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 1595de999b..2c3358e359 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1025,6 +1025,14 @@ config CMD_LSBLK
  Print list of available block device drivers, and for each, the list
  of known block devices.
 
+config CMD_MBR
+   bool "MBR (Master Boot Record) command"
+   select DOS_PARTITION
+   select HAVE_BLOCK_DEVICE
+   help
+ Enable the 'mbr' command to ready and write MBR (Master Boot Record)
+ style partition tables.
+
 config CMD_MISC
bool "misc"
depends on MISC
diff --git a/cmd/Makefile b/cmd/Makefile
index dd86675bf2..41379d9a0e 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -178,6 +178,7 @@ obj-$(CONFIG_CMD_ZFS) += zfs.o
 
 obj-$(CONFIG_CMD_DFU) += dfu.o
 obj-$(CONFIG_CMD_GPT) += gpt.o
+obj-$(CONFIG_CMD_MBR) += mbr.o
 obj-$(CONFIG_CMD_ETHSW) += ethsw.o
 obj-$(CONFIG_CMD_AXI) += axi.o
 obj-$(CONFIG_CMD_PVBLOCK) += pvblock.o
diff --git a/cmd/mbr.c b/cmd/mbr.c
new file mode 100644
index 00..25a3f694d3
--- /dev/null
+++ b/cmd/mbr.c
@@ -0,0 +1,308 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * cmd_mbr.c -- MBR (Master Boot Record) handling command
+ *
+ * Copyright (C) 2020 Samsung Electronics
+ * author: Marek Szyprowski 
+ *
+ * based on the gpt command.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * extract_val(): Extract value from a key=value pair list (comma separated).
+ *Only value for the given key is returend.
+ *Function allocates memory for the value, remember to free!
+ *
+ * @param str - pointer to string with key=values pairs
+ * @param key - pointer to the key to search for
+ *
+ * @return - pointer to allocated string with the value
+ */
+static char *extract_val(const char *str, const char *key)
+{
+   char *v, *k;
+   char *s, *strcopy;
+   char *new = NULL;
+
+   strcopy = strdup(str);
+   if (strcopy == NULL)
+   return NULL;
+
+   s = strcopy;
+   while (s) {
+   v = strsep(, ",");
+   if (!v)
+   break;
+   k = strsep(, "=");
+   if (!k)
+   break;
+   if  (strcmp(k, key) == 0) {
+   new = strdup(v);
+   break;
+   }
+   }
+
+   free(strcopy);
+
+   return new;
+}
+
+/**
+ * found_key(): Found key without value in parameter list (comma separated).
+ *
+ * @param str - pointer to string with key
+ * @param key - pointer to the key to search for
+ *
+ * @return - true on found key
+ */
+static bool found_key(const char *str, const char *key)
+{
+   char *k;
+   char *s, *strcopy;
+   bool result = false;
+
+   strcopy = strdup(str);
+   if (!strcopy)
+   return NULL;
+
+   s = strcopy;
+   while (s) {
+   k = strsep(, ",");
+   if (!k)
+   break;
+   if  (strcmp(k, key) == 0) {
+   result = true;
+   break;
+   }
+   }
+
+   free(strcopy);
+
+   return result;
+}
+
+static int str_to_partition_info(const char *str_part, unsigned long 
*disk_uuid,
+   struct disk_partition **partitions, int *parts_count)
+{
+   char *tok, *str, *s;
+   int i;
+   char *val, *p;
+   int p_count;
+   struct disk_partition *parts;
+   int errno = 0;
+   uint64_t size_ll, start_ll;
+
+   if (str_part == NULL)
+ 

[PATCH 5/6] disk: dos: add code for creating MBR partition layout

2020-12-17 Thread Marek Szyprowski
Add a code for creating and writing MBR partition layout. The code generates
similar layout of EBRs (Exteneded Block Records) and logical volumes as
Linux's fdisk utility.

Signed-off-by: Marek Szyprowski 
---
 disk/part_dos.c | 167 
 disk/part_dos.h |   2 +
 include/part.h  |   5 ++
 3 files changed, 174 insertions(+)

diff --git a/disk/part_dos.c b/disk/part_dos.c
index 2c4ad0b6ba..f77f927995 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -319,6 +319,173 @@ int is_valid_dos_buf(void *buf)
return test_block_type(buf) == DOS_MBR ? 0 : -1;
 }
 
+#if CONFIG_IS_ENABLED(CMD_MBR)
+static void lba_to_chs(lbaint_t lba, unsigned char *rc, unsigned char *rh,
+  unsigned char *rs)
+{
+   unsigned int c, h, s;
+   /* use fixed CHS geometry */
+   unsigned int sectpertrack = 63;
+   unsigned int heads = 255;
+
+   c = (lba + 1) / sectpertrack / heads;
+   h = (lba + 1) / sectpertrack - c * heads;
+   s = (lba + 1) - (c * heads + h) * sectpertrack;
+
+   if (c > 1023) {
+   c = 1023;
+   h = 254;
+   s = 63;
+   }
+
+   *rc = c & 0xff;
+   *rh = h;
+   *rs = s + ((c & 0x300) >> 2);
+}
+
+static void mbr_fill_pt_entry(dos_partition_t *pt, lbaint_t start,
+   lbaint_t relative, lbaint_t size, uchar sys_ind, bool bootable)
+{
+   pt->boot_ind = bootable ? 0x80 : 0x00;
+   pt->sys_ind = sys_ind;
+   lba_to_chs(start, >cyl, >head, >sector);
+   lba_to_chs(start + size - 1, >end_cyl, >end_head, 
>end_sector);
+   put_unaligned_le32(relative, >start4);
+   put_unaligned_le32(size, >size4);
+}
+
+int write_mbr_partitions(struct blk_desc *dev,
+   struct disk_partition *p, int count, unsigned int disksig)
+{
+   ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev->blksz);
+   lbaint_t ext_part_start = 0, ext_part_size = 0, ext_part_sect = 0;
+   dos_partition_t *pt;
+   int i;
+
+   memset(buffer, 0, dev->blksz);
+   buffer[DOS_PART_MAGIC_OFFSET] = 0x55;
+   buffer[DOS_PART_MAGIC_OFFSET + 1] = 0xaa;
+   put_unaligned_le32(disksig, [DOS_PART_DISKSIG_OFFSET]);
+   pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
+
+   /* create all primary partitions */
+   for (i = 0; i < 4 && i < count; i++, pt++) {
+   mbr_fill_pt_entry(pt, p[i].start, p[i].start, p[i].size,
+ p[i].sys_ind, p[i].bootable);
+   if (is_extended(p[i].sys_ind)) {
+   ext_part_start = p[i].start;
+   ext_part_size = p[i].size;
+   ext_part_sect = p[i].start;
+   }
+   }
+
+   if (i < count && !ext_part_start) {
+   printf("%s: extended partition is needed for more than 4 
partitions\n",
+   __func__);
+   return -1;
+   }
+
+   /* write MBR */
+   if (blk_dwrite(dev, 0, 1, buffer) != 1) {
+   printf("%s: failed writing 'MBR' (1 blks at 0x0)\n",
+  __func__);
+   return -1;
+   }
+
+   /* create extended volumes */
+   for (; i < count; i++) {
+   lbaint_t next_ebr = 0;
+
+   memset(buffer, 0, dev->blksz);
+   buffer[DOS_PART_MAGIC_OFFSET] = 0x55;
+   buffer[DOS_PART_MAGIC_OFFSET + 1] = 0xaa;
+   pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
+
+   mbr_fill_pt_entry(pt, p[i].start, p[i].start - ext_part_sect,
+ p[i].size, p[i].sys_ind, p[i].bootable);
+
+   if (i + 1 < count) {
+   pt++;
+   next_ebr = p[i].start + p[i].size;
+   mbr_fill_pt_entry(pt, next_ebr,
+ next_ebr - ext_part_start,
+ p[i+1].start + p[i+1].size - next_ebr,
+ DOS_PART_TYPE_EXTENDED, 0);
+   }
+
+   /* write EBR */
+   if (blk_dwrite(dev, ext_part_sect, 1, buffer) != 1) {
+   printf("%s: failed writing 'EBR' (1 blks at 0x%lx)\n",
+  __func__, ext_part_sect);
+   return -1;
+   }
+   ext_part_sect = next_ebr;
+   }
+
+   return 0;
+}
+
+int layout_mbr_partitions(struct disk_partition *p, int count,
+ lbaint_t total_sectors)
+{
+   struct disk_partition *ext = NULL;
+   int i, j;
+   lbaint_t ext_vol_start;
+
+   /* calculate primary partitions start and size if needed */
+   if (!p[0].start)
+   p[0].start = DOS_PART_DEFAULT_GAP;
+   for (i = 0; i < 4 && i < count; i+

[PATCH 4/6] disk: dos: make some functions static

2020-12-17 Thread Marek Szyprowski
Make functions not used outside this file static.

Signed-off-by: Marek Szyprowski 
---
 disk/part_dos.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/disk/part_dos.c b/disk/part_dos.c
index 3b79b9b1b8..2c4ad0b6ba 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -302,13 +302,13 @@ static int part_get_info_extended(struct blk_desc 
*dev_desc,
return -1;
 }
 
-void part_print_dos(struct blk_desc *dev_desc)
+static void part_print_dos(struct blk_desc *dev_desc)
 {
printf("Part\tStart Sector\tNum Sectors\tUUID\t\tType\n");
print_partition_extended(dev_desc, 0, 0, 1, 0);
 }
 
-int part_get_info_dos(struct blk_desc *dev_desc, int part,
+static int part_get_info_dos(struct blk_desc *dev_desc, int part,
  struct disk_partition *info)
 {
return part_get_info_extended(dev_desc, 0, 0, 1, part, info, 0);
-- 
2.17.1



[PATCH] cmd: usb_mass_storage: show device interface name

2020-12-17 Thread Marek Szyprowski
Show the interface name (i.e. 'mmc') in the information string to ease
user checking which device is exported via USB Mass Storage protocol.

Signed-off-by: Marek Szyprowski 
---
 cmd/usb_mass_storage.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/cmd/usb_mass_storage.c b/cmd/usb_mass_storage.c
index cf2f55994e..14fa7233c7 100644
--- a/cmd/usb_mass_storage.c
+++ b/cmd/usb_mass_storage.c
@@ -115,8 +115,8 @@ static int ums_init(const char *devtype, const char 
*devnums_part_str)
ums[ums_count].name = name;
ums[ums_count].block_dev = *block_dev;
 
-   printf("UMS: LUN %d, dev %d, hwpart %d, sector %#x, count 
%#x\n",
-  ums_count, ums[ums_count].block_dev.devnum,
+   printf("UMS: LUN %d, dev %s %d, hwpart %d, sector %#x, count 
%#x\n",
+  ums_count, devtype, ums[ums_count].block_dev.devnum,
   ums[ums_count].block_dev.hwpart,
   ums[ums_count].start_sector,
   ums[ums_count].num_sectors);
-- 
2.17.1



[PATCH/RFC] board: amlogic: Fix Odroid-C4 SD card reboot issue

2020-12-17 Thread Marek Szyprowski
For the proper reboot Odroid C4 board requires to switch TFLASH_VDD_EN
pin to the input (high impedance?) mode, otherwise the board is stuck
in the middle of loading early stages of the bootloader from SD card.

This has been achieved by hijacking reset_misc() callback from the PSCI
firmware in the Odroid board code. The common meson cpu_reset() function,
which is called later during the reboot procedure, will call PSCI reboot
anyway.

This issue doesn't happen if board is booted from eMMC.

Signed-off-by: Marek Szyprowski 
---
 board/amlogic/odroid-n2/odroid-n2.c | 15 +++
 configs/odroid-c4_defconfig |  1 +
 2 files changed, 16 insertions(+)

diff --git a/board/amlogic/odroid-n2/odroid-n2.c 
b/board/amlogic/odroid-n2/odroid-n2.c
index caf7fd6810..ad91de7ac5 100644
--- a/board/amlogic/odroid-n2/odroid-n2.c
+++ b/board/amlogic/odroid-n2/odroid-n2.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -47,3 +48,17 @@ int misc_init_r(void)
 
return 0;
 }
+
+#ifndef CONFIG_PSCI_RESET
+void reset_misc(void)
+{
+   if (of_machine_is_compatible("hardkernel,odroid-c4")) {
+   unsigned int gpio;
+   const char *str_gpio = "aobus-banks3";
+
+   gpio_lookup_name(str_gpio, NULL, NULL, );
+   gpio_request(gpio, "reboot");
+   gpio_direction_input(gpio);
+   }
+}
+#endif
diff --git a/configs/odroid-c4_defconfig b/configs/odroid-c4_defconfig
index 367d22db0b..ca0ab71a7a 100644
--- a/configs/odroid-c4_defconfig
+++ b/configs/odroid-c4_defconfig
@@ -14,6 +14,7 @@ CONFIG_DEBUG_UART=y
 CONFIG_OF_BOARD_SETUP=y
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_MISC_INIT_R=y
+# CONFIG_PSCI_RESET is not set
 # CONFIG_CMD_BDI is not set
 # CONFIG_CMD_IMI is not set
 CONFIG_CMD_GPIO=y
-- 
2.17.1



[PATCH] board: amlogic: vim3: read ethernet MAC address from efuse

2020-12-16 Thread Marek Szyprowski
Add the board specific code for reading built-in ethernet MAC address
from efuse.

Signed-off-by: Marek Szyprowski 
---
 board/amlogic/vim3/vim3.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/board/amlogic/vim3/vim3.c b/board/amlogic/vim3/vim3.c
index 09ef39ff30..a36df61583 100644
--- a/board/amlogic/vim3/vim3.c
+++ b/board/amlogic/vim3/vim3.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include "khadas-mcu.h"
 
@@ -129,9 +130,27 @@ int meson_ft_board_setup(void *blob, struct bd_info *bd)
return 0;
 }
 
+#define EFUSE_MAC_OFFSET   0
+#define EFUSE_MAC_SIZE 6
+
 int misc_init_r(void)
 {
+   uint8_t mac_addr[EFUSE_MAC_SIZE];
+   ssize_t len;
+
meson_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
 
+   if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
+   len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
+ mac_addr, EFUSE_MAC_SIZE);
+   if (len != EFUSE_MAC_SIZE)
+   return 0;
+
+   if (is_valid_ethaddr(mac_addr))
+   eth_env_set_enetaddr("ethaddr", mac_addr);
+   else
+   meson_generate_serial_ethaddr();
+   }
+
return 0;
 }
-- 
2.17.1



[PATCH v3 5/6] button: add a simple ADC-based button driver

2020-12-15 Thread Marek Szyprowski
Add a simple Analog to Digital Converter device based button driver. This
driver binds to the 'adc-keys' device tree node.

Signed-off-by: Marek Szyprowski 
---
 drivers/button/Kconfig  |   8 +++
 drivers/button/Makefile |   1 +
 drivers/button/button-adc.c | 117 
 3 files changed, 126 insertions(+)
 create mode 100644 drivers/button/button-adc.c

diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig
index 6b3ec7e55d..6db3c5e93a 100644
--- a/drivers/button/Kconfig
+++ b/drivers/button/Kconfig
@@ -9,6 +9,14 @@ config BUTTON
  can provide access to board-specific buttons. Use of the device tree
  for configuration is encouraged.
 
+config BUTTON_ADC
+   bool "Button adc"
+   depends on BUTTON
+   help
+ Enable support for buttons which are connected to Analog to Digital
+ Converter device. The ADC driver must use driver model. Buttons are
+ configured using the device tree.
+
 config BUTTON_GPIO
bool "Button gpio"
depends on BUTTON
diff --git a/drivers/button/Makefile b/drivers/button/Makefile
index fcc10ebe8d..bbd18af149 100644
--- a/drivers/button/Makefile
+++ b/drivers/button/Makefile
@@ -3,4 +3,5 @@
 # Copyright (C) 2020 Philippe Reynes 
 
 obj-$(CONFIG_BUTTON) += button-uclass.o
+obj-$(CONFIG_BUTTON_ADC) += button-adc.o
 obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o
diff --git a/drivers/button/button-adc.c b/drivers/button/button-adc.c
new file mode 100644
index 00..086c676c02
--- /dev/null
+++ b/drivers/button/button-adc.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Author: Marek Szyprowski 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct button_adc_priv {
+   struct udevice *adc;
+   int channel;
+};
+
+static enum button_state_t button_adc_get_state(struct udevice *dev)
+{
+   struct button_adc_priv *priv = dev_get_priv(dev);
+   unsigned int val, mask;
+   int ret;
+
+   ret = adc_start_channel(priv->adc, priv->channel);
+   if (ret)
+   return ret;
+
+   ret = adc_channel_data(priv->adc, priv->channel, );
+   if (ret)
+   return ret;
+
+   ret = adc_data_mask(priv->adc, );
+   if (ret)
+   return ret;
+
+   /* getting state is simplified a bit */
+   if (ret == 0)
+   return (val < mask / 2) ? BUTTON_ON : BUTTON_OFF;
+
+   return ret;
+}
+
+static int button_adc_probe(struct udevice *dev)
+{
+   struct button_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
+   struct button_adc_priv *priv = dev_get_priv(dev);
+   struct ofnode_phandle_args args;
+   int ret;
+
+   /* Ignore the top-level button node */
+   if (!uc_plat->label)
+   return 0;
+
+   ret = dev_read_phandle_with_args(dev->parent, "io-channels",
+"#io-channel-cells", 0, 0, );
+   if (ret)
+   return ret;
+
+   ret = uclass_get_device_by_name(UCLASS_ADC, ofnode_get_name(args.node),
+   >adc);
+   if (ret)
+   return ret;
+
+   priv->channel = args.args[0];
+
+   return ret;
+}
+
+static int button_adc_bind(struct udevice *parent)
+{
+   struct udevice *dev;
+   ofnode node;
+   int ret;
+
+   dev_for_each_subnode(node, parent) {
+   struct button_uc_plat *uc_plat;
+   const char *label;
+
+   label = ofnode_read_string(node, "label");
+   if (!label) {
+   debug("%s: node %s has no label\n", __func__,
+ ofnode_get_name(node));
+   return -EINVAL;
+   }
+   ret = device_bind_driver_to_node(parent, "button_adc",
+ofnode_get_name(node),
+node, );
+   if (ret)
+   return ret;
+   uc_plat = dev_get_uclass_platdata(dev);
+   uc_plat->label = label;
+   }
+
+   return 0;
+}
+
+static const struct button_ops button_adc_ops = {
+   .get_state  = button_adc_get_state,
+};
+
+static const struct udevice_id button_adc_ids[] = {
+   { .compatible = "adc-keys" },
+   { }
+};
+
+U_BOOT_DRIVER(button_adc) = {
+   .name   = "button_adc",
+   .id = UCLASS_BUTTON,
+   .of_match   = button_adc_ids,
+   .ops= _adc_ops,
+   .priv_auto_alloc_size = sizeof(struct button_adc_priv),
+   .bind   = button_adc_bind,
+   .probe  = button_adc_probe,
+};
-- 
2.17.1



[PATCH v3 6/6] configs: khadas-vim3: enable Function button support

2020-12-15 Thread Marek Szyprowski
Add options required to check the 'Function' button state.

Signed-off-by: Marek Szyprowski 
---
 configs/khadas-vim3_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/configs/khadas-vim3_defconfig b/configs/khadas-vim3_defconfig
index 5d16652fd6..bc17430569 100644
--- a/configs/khadas-vim3_defconfig
+++ b/configs/khadas-vim3_defconfig
@@ -31,6 +31,8 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_ADC=y
 CONFIG_SARADC_MESON=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_ADC=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MESON=y
 CONFIG_DM_MMC=y
-- 
2.17.1



[PATCH v3 0/6] VIM3: add support for checking 'Function' button state

2020-12-15 Thread Marek Szyprowski
Hi All,

This patchset adds all building blocks needed for checking the 'Function'
button state in the boot script on Amlogic A311D based VIM3 board. This
button is connected to the ADC lines of the SoC, so it required to enable
meson SARADC, the clocks needed for it and a simple button-adc drivers.

Once applied, one can use following commands in the boot scripts:
-->8---
echo Checking Func button state: \\c
if button Function
then
echo Selected alternative boot
...
fi
--->8---
The above script requires commit a6bfd71a96 ("cmd/button: return button
status") already present in mainline tree.

Best regards
Marek Szyprowski
Samsung R Institute Poland


Changelog:
v3:
- removed 'button' env variable
- extended kconfig and patch descriptions

v2: https://lists.denx.de/pipermail/u-boot/2020-December/434991.html
- removed Change-Id tags
- split defconfig changes into ADC and button related

v1: https://lists.denx.de/pipermail/u-boot/2020-December/434875.html
- initial submission


Patch summary:

Marek Szyprowski (6):
  clk: meson: add minimal driver for g12a-ao clocks
  adc: meson-saradc: add G12A variant
  adc: meson-saradc: skip hardware init only if ADC is enabled
  configs: khadas-vim3: enable ADC device support
  button: add a simple ADC-based button driver
  configs: khadas-vim3: enable Function button support

 configs/khadas-vim3_defconfig |   4 ++
 drivers/adc/meson-saradc.c|   9 ++-
 drivers/button/Kconfig|   8 +++
 drivers/button/Makefile   |   1 +
 drivers/button/button-adc.c   | 117 ++
 drivers/clk/meson/Makefile|   1 +
 drivers/clk/meson/g12a-ao.c   |  83 
 7 files changed, 221 insertions(+), 2 deletions(-)
 create mode 100644 drivers/button/button-adc.c
 create mode 100644 drivers/clk/meson/g12a-ao.c

-- 
2.17.1



[PATCH v3 4/6] configs: khadas-vim3: enable ADC device support

2020-12-15 Thread Marek Szyprowski
Analog to Digital Converter device (Meson SARADC) will be used for
probing 'Function' button state.

Signed-off-by: Marek Szyprowski 
---
 configs/khadas-vim3_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/configs/khadas-vim3_defconfig b/configs/khadas-vim3_defconfig
index 9d7ba72d44..5d16652fd6 100644
--- a/configs/khadas-vim3_defconfig
+++ b/configs/khadas-vim3_defconfig
@@ -29,6 +29,8 @@ CONFIG_CMD_REGULATOR=y
 CONFIG_OF_CONTROL=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_ADC=y
+CONFIG_SARADC_MESON=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MESON=y
 CONFIG_DM_MMC=y
-- 
2.17.1



[PATCH v3 3/6] adc: meson-saradc: skip hardware init only if ADC is enabled

2020-12-15 Thread Marek Szyprowski
The driver skips hardware initialization if it is already configured by
the earlier bootloader stage (BL30). Skip the initialization only if the
hardware is really initialized and enabled.

Signed-off-by: Marek Szyprowski 
Reviewed-by: Neil Armstrong 
Tested-by: Jaehoon Chung 
Reviewed-by: Jaehoon Chung 
---
 drivers/adc/meson-saradc.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/adc/meson-saradc.c b/drivers/adc/meson-saradc.c
index 998cef24d8..ce7ae990ad 100644
--- a/drivers/adc/meson-saradc.c
+++ b/drivers/adc/meson-saradc.c
@@ -512,8 +512,11 @@ static int meson_saradc_init(struct meson_saradc_priv 
*priv)
 * reading the temperature sensor.
 */
regmap_read(priv->regmap, MESON_SAR_ADC_REG3, );
-   if (regval & MESON_SAR_ADC_REG3_BL30_INITIALIZED)
-   return 0;
+   if (regval & MESON_SAR_ADC_REG3_BL30_INITIALIZED) {
+   regmap_read(priv->regmap, MESON_SAR_ADC_REG3, );
+   if (regval & MESON_SAR_ADC_REG3_ADC_EN)
+   return 0;
+   }
 
meson_saradc_stop_sample_engine(priv);
 
-- 
2.17.1



[PATCH v3 2/6] adc: meson-saradc: add G12A variant

2020-12-15 Thread Marek Szyprowski
Add support for the SARADC variant found on the G12A SoCs family.

Signed-off-by: Marek Szyprowski 
Reviewed-by: Neil Armstrong 
Tested-by: Jaehoon Chung 
Reviewed-by: Jaehoon Chung 
---
 drivers/adc/meson-saradc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/adc/meson-saradc.c b/drivers/adc/meson-saradc.c
index 72b0cc4e5b..998cef24d8 100644
--- a/drivers/adc/meson-saradc.c
+++ b/drivers/adc/meson-saradc.c
@@ -711,6 +711,8 @@ static const struct udevice_id meson_saradc_ids[] = {
  .data = (ulong)_saradc_data },
{ .compatible = "amlogic,meson-gxm-saradc",
  .data = (ulong)_saradc_data },
+   { .compatible = "amlogic,meson-g12a-saradc",
+ .data = (ulong)_saradc_data },
{ }
 };
 
-- 
2.17.1



[PATCH v3 1/6] clk: meson: add minimal driver for g12a-ao clocks

2020-12-15 Thread Marek Szyprowski
Add minimal driver AO clocks on meson G12A family. Only ADC related clocks
are supported.

Signed-off-by: Marek Szyprowski 
Reviewed-by: Neil Armstrong 
Tested-by: Jaehoon Chung 
Reviewed-by: Jaehoon Chung 
---
 drivers/clk/meson/Makefile  |  1 +
 drivers/clk/meson/g12a-ao.c | 83 +
 2 files changed, 84 insertions(+)
 create mode 100644 drivers/clk/meson/g12a-ao.c

diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index c873d6976f..7204383e17 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -6,4 +6,5 @@
 obj-$(CONFIG_CLK_MESON_GX) += gxbb.o
 obj-$(CONFIG_CLK_MESON_AXG) += axg.o
 obj-$(CONFIG_CLK_MESON_G12A) += g12a.o
+obj-$(CONFIG_CLK_MESON_G12A) += g12a-ao.o
 
diff --git a/drivers/clk/meson/g12a-ao.c b/drivers/clk/meson/g12a-ao.c
new file mode 100644
index 00..7a0abea77c
--- /dev/null
+++ b/drivers/clk/meson/g12a-ao.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "clk_meson.h"
+
+struct meson_clk {
+   struct regmap *map;
+};
+
+#define AO_CLK_GATE0   0x4c
+#define AO_SAR_CLK 0x90
+
+static struct meson_gate gates[] = {
+   MESON_GATE(CLKID_AO_SAR_ADC, AO_CLK_GATE0, 8),
+   MESON_GATE(CLKID_AO_SAR_ADC_CLK, AO_SAR_CLK, 8),
+};
+
+static int meson_set_gate(struct clk *clk, bool on)
+{
+   struct meson_clk *priv = dev_get_priv(clk->dev);
+   struct meson_gate *gate;
+
+   if (clk->id >= ARRAY_SIZE(gates))
+   return -ENOENT;
+
+   gate = [clk->id];
+
+   if (gate->reg == 0)
+   return 0;
+
+   regmap_update_bits(priv->map, gate->reg,
+  BIT(gate->bit), on ? BIT(gate->bit) : 0);
+
+   return 0;
+}
+
+static int meson_clk_enable(struct clk *clk)
+{
+   return meson_set_gate(clk, true);
+}
+
+static int meson_clk_disable(struct clk *clk)
+{
+   return meson_set_gate(clk, false);
+}
+
+static int meson_clk_probe(struct udevice *dev)
+{
+   struct meson_clk *priv = dev_get_priv(dev);
+
+   priv->map = syscon_node_to_regmap(dev_get_parent(dev)->node);
+   if (IS_ERR(priv->map))
+   return PTR_ERR(priv->map);
+
+   return 0;
+}
+
+static struct clk_ops meson_clk_ops = {
+   .disable= meson_clk_disable,
+   .enable = meson_clk_enable,
+};
+
+static const struct udevice_id meson_clk_ids[] = {
+   { .compatible = "amlogic,meson-g12a-aoclkc" },
+   { }
+};
+
+U_BOOT_DRIVER(meson_clk_axg) = {
+   .name   = "meson_clk_g12a_ao",
+   .id = UCLASS_CLK,
+   .of_match   = meson_clk_ids,
+   .priv_auto_alloc_size = sizeof(struct meson_clk),
+   .ops= _clk_ops,
+   .probe  = meson_clk_probe,
+};
-- 
2.17.1



Re: [PATCH v2 6/7 RESEND] cmd: button: store button state in the 'button' env

2020-12-15 Thread Marek Szyprowski
On 16.12.2020 08:29, Heinrich Schuchardt wrote:
> On 12/16/20 8:08 AM, Marek Szyprowski wrote:
>> On 15.12.2020 20:07, Heinrich Schuchardt wrote:
>>> On 12/15/20 5:54 PM, Marek Szyprowski wrote:
>>>> Save examined button state in 'button' environment variable to enable
>>>> checking button state in the scripts.
>>>>
>>>> Signed-off-by: Marek Szyprowski 
>>>> ---
>>>> Resend reason: get rid of the Change-Id tag, that was still in v2.
>>>> ---
>>>>    cmd/button.c | 4 +++-
>>>>    1 file changed, 3 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/cmd/button.c b/cmd/button.c
>>>> index 64c5a8fa04..8da911068a 100644
>>>> --- a/cmd/button.c
>>>> +++ b/cmd/button.c
>>>> @@ -23,8 +23,10 @@ static int show_button_state(struct udevice *dev)
>>>>    ret = button_get_state(dev);
>>>>    if (ret >= BUTTON_COUNT)
>>>>    ret = -EINVAL;
>>>> -    if (ret >= 0)
>>>> +    if (ret >= 0) {
>>>>    printf("%s\n", state_label[ret]);
>>>> +    env_set("button", state_label[ret]);
>>>
>>> Using a hard coded environment variable does not make much sense to me.
>>> The button command has a return value. So just use
>>>
>>> button mybutton; setenv myvar $?
>>>
>> Thanks for the hint, I wasn't aware that uboot supports '$?'. By setting
>> the 'button' env variable I've tried to mimic the behavior of the
>> various network and file related commands, which sets 'filesize' env
>> variable.
>>
>> I will need to add the return value propagation to the button command
>> anyway to make it usable from the scripts.
>
> Nothing to be done for the button command. Since
>
>     a6bfd71a96201127836d59736abcb54dc2d5e1a5
>     cmd/button: return button status
>
> the button command returns
>
>     0 (true) - pressed, on
>     1 (false) - not pressed, off
>
Right, I've missed that commit. I've developed my code on top of 
v2020.10 release.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R Institute Poland



Re: [PATCH v2 6/7 RESEND] cmd: button: store button state in the 'button' env

2020-12-15 Thread Marek Szyprowski
On 15.12.2020 20:07, Heinrich Schuchardt wrote:
> On 12/15/20 5:54 PM, Marek Szyprowski wrote:
>> Save examined button state in 'button' environment variable to enable
>> checking button state in the scripts.
>>
>> Signed-off-by: Marek Szyprowski 
>> ---
>> Resend reason: get rid of the Change-Id tag, that was still in v2.
>> ---
>>   cmd/button.c | 4 +++-
>>   1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/cmd/button.c b/cmd/button.c
>> index 64c5a8fa04..8da911068a 100644
>> --- a/cmd/button.c
>> +++ b/cmd/button.c
>> @@ -23,8 +23,10 @@ static int show_button_state(struct udevice *dev)
>>   ret = button_get_state(dev);
>>   if (ret >= BUTTON_COUNT)
>>   ret = -EINVAL;
>> -    if (ret >= 0)
>> +    if (ret >= 0) {
>>   printf("%s\n", state_label[ret]);
>> +    env_set("button", state_label[ret]);
>
> Using a hard coded environment variable does not make much sense to me.
> The button command has a return value. So just use
>
> button mybutton; setenv myvar $?
>
Thanks for the hint, I wasn't aware that uboot supports '$?'. By setting 
the 'button' env variable I've tried to mimic the behavior of the 
various network and file related commands, which sets 'filesize' env 
variable.

I will need to add the return value propagation to the button command 
anyway to make it usable from the scripts.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R Institute Poland



[PATCH v2 6/7 RESEND] cmd: button: store button state in the 'button' env

2020-12-15 Thread Marek Szyprowski
Save examined button state in 'button' environment variable to enable
checking button state in the scripts.

Signed-off-by: Marek Szyprowski 
---
Resend reason: get rid of the Change-Id tag, that was still in v2.
---
 cmd/button.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/cmd/button.c b/cmd/button.c
index 64c5a8fa04..8da911068a 100644
--- a/cmd/button.c
+++ b/cmd/button.c
@@ -23,8 +23,10 @@ static int show_button_state(struct udevice *dev)
ret = button_get_state(dev);
if (ret >= BUTTON_COUNT)
ret = -EINVAL;
-   if (ret >= 0)
+   if (ret >= 0) {
printf("%s\n", state_label[ret]);
+   env_set("button", state_label[ret]);
+   }
 
return ret;
 }
-- 
2.17.1



[PATCH v2 5/7] button: add a simple ADC-based button driver

2020-12-15 Thread Marek Szyprowski
Add a simple ADC-based button driver. This driver binds to the 'adc-keys'
device tree node.

Signed-off-by: Marek Szyprowski 
---
 drivers/button/Kconfig  |   8 +++
 drivers/button/Makefile |   1 +
 drivers/button/button-adc.c | 117 
 3 files changed, 126 insertions(+)
 create mode 100644 drivers/button/button-adc.c

diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig
index 6b3ec7e55d..283367f2bd 100644
--- a/drivers/button/Kconfig
+++ b/drivers/button/Kconfig
@@ -9,6 +9,14 @@ config BUTTON
  can provide access to board-specific buttons. Use of the device tree
  for configuration is encouraged.
 
+config BUTTON_ADC
+   bool "Button adc"
+   depends on BUTTON
+   help
+ Enable support for buttons which are connected to ADC lines. The ADC
+ driver must use driver model. Buttons are configured using the device
+ tree.
+
 config BUTTON_GPIO
bool "Button gpio"
depends on BUTTON
diff --git a/drivers/button/Makefile b/drivers/button/Makefile
index fcc10ebe8d..bbd18af149 100644
--- a/drivers/button/Makefile
+++ b/drivers/button/Makefile
@@ -3,4 +3,5 @@
 # Copyright (C) 2020 Philippe Reynes 
 
 obj-$(CONFIG_BUTTON) += button-uclass.o
+obj-$(CONFIG_BUTTON_ADC) += button-adc.o
 obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o
diff --git a/drivers/button/button-adc.c b/drivers/button/button-adc.c
new file mode 100644
index 00..086c676c02
--- /dev/null
+++ b/drivers/button/button-adc.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Author: Marek Szyprowski 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct button_adc_priv {
+   struct udevice *adc;
+   int channel;
+};
+
+static enum button_state_t button_adc_get_state(struct udevice *dev)
+{
+   struct button_adc_priv *priv = dev_get_priv(dev);
+   unsigned int val, mask;
+   int ret;
+
+   ret = adc_start_channel(priv->adc, priv->channel);
+   if (ret)
+   return ret;
+
+   ret = adc_channel_data(priv->adc, priv->channel, );
+   if (ret)
+   return ret;
+
+   ret = adc_data_mask(priv->adc, );
+   if (ret)
+   return ret;
+
+   /* getting state is simplified a bit */
+   if (ret == 0)
+   return (val < mask / 2) ? BUTTON_ON : BUTTON_OFF;
+
+   return ret;
+}
+
+static int button_adc_probe(struct udevice *dev)
+{
+   struct button_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
+   struct button_adc_priv *priv = dev_get_priv(dev);
+   struct ofnode_phandle_args args;
+   int ret;
+
+   /* Ignore the top-level button node */
+   if (!uc_plat->label)
+   return 0;
+
+   ret = dev_read_phandle_with_args(dev->parent, "io-channels",
+"#io-channel-cells", 0, 0, );
+   if (ret)
+   return ret;
+
+   ret = uclass_get_device_by_name(UCLASS_ADC, ofnode_get_name(args.node),
+   >adc);
+   if (ret)
+   return ret;
+
+   priv->channel = args.args[0];
+
+   return ret;
+}
+
+static int button_adc_bind(struct udevice *parent)
+{
+   struct udevice *dev;
+   ofnode node;
+   int ret;
+
+   dev_for_each_subnode(node, parent) {
+   struct button_uc_plat *uc_plat;
+   const char *label;
+
+   label = ofnode_read_string(node, "label");
+   if (!label) {
+   debug("%s: node %s has no label\n", __func__,
+ ofnode_get_name(node));
+   return -EINVAL;
+   }
+   ret = device_bind_driver_to_node(parent, "button_adc",
+ofnode_get_name(node),
+node, );
+   if (ret)
+   return ret;
+   uc_plat = dev_get_uclass_platdata(dev);
+   uc_plat->label = label;
+   }
+
+   return 0;
+}
+
+static const struct button_ops button_adc_ops = {
+   .get_state  = button_adc_get_state,
+};
+
+static const struct udevice_id button_adc_ids[] = {
+   { .compatible = "adc-keys" },
+   { }
+};
+
+U_BOOT_DRIVER(button_adc) = {
+   .name   = "button_adc",
+   .id = UCLASS_BUTTON,
+   .of_match   = button_adc_ids,
+   .ops= _adc_ops,
+   .priv_auto_alloc_size = sizeof(struct button_adc_priv),
+   .bind   = button_adc_bind,
+   .probe  = button_adc_probe,
+};
-- 
2.17.1



[PATCH v2 1/7] clk: meson: add minimal driver for g12a-ao clocks

2020-12-15 Thread Marek Szyprowski
Add minimal driver AO clocks on meson G12A family. Only ADC related clocks
are supported.

Signed-off-by: Marek Szyprowski 
Reviewed-by: Neil Armstrong 
Tested-by: Jaehoon Chung 
Reviewed-by: Jaehoon Chung 
---
 drivers/clk/meson/Makefile  |  1 +
 drivers/clk/meson/g12a-ao.c | 83 +
 2 files changed, 84 insertions(+)
 create mode 100644 drivers/clk/meson/g12a-ao.c

diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index c873d6976f..7204383e17 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -6,4 +6,5 @@
 obj-$(CONFIG_CLK_MESON_GX) += gxbb.o
 obj-$(CONFIG_CLK_MESON_AXG) += axg.o
 obj-$(CONFIG_CLK_MESON_G12A) += g12a.o
+obj-$(CONFIG_CLK_MESON_G12A) += g12a-ao.o
 
diff --git a/drivers/clk/meson/g12a-ao.c b/drivers/clk/meson/g12a-ao.c
new file mode 100644
index 00..7a0abea77c
--- /dev/null
+++ b/drivers/clk/meson/g12a-ao.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "clk_meson.h"
+
+struct meson_clk {
+   struct regmap *map;
+};
+
+#define AO_CLK_GATE0   0x4c
+#define AO_SAR_CLK 0x90
+
+static struct meson_gate gates[] = {
+   MESON_GATE(CLKID_AO_SAR_ADC, AO_CLK_GATE0, 8),
+   MESON_GATE(CLKID_AO_SAR_ADC_CLK, AO_SAR_CLK, 8),
+};
+
+static int meson_set_gate(struct clk *clk, bool on)
+{
+   struct meson_clk *priv = dev_get_priv(clk->dev);
+   struct meson_gate *gate;
+
+   if (clk->id >= ARRAY_SIZE(gates))
+   return -ENOENT;
+
+   gate = [clk->id];
+
+   if (gate->reg == 0)
+   return 0;
+
+   regmap_update_bits(priv->map, gate->reg,
+  BIT(gate->bit), on ? BIT(gate->bit) : 0);
+
+   return 0;
+}
+
+static int meson_clk_enable(struct clk *clk)
+{
+   return meson_set_gate(clk, true);
+}
+
+static int meson_clk_disable(struct clk *clk)
+{
+   return meson_set_gate(clk, false);
+}
+
+static int meson_clk_probe(struct udevice *dev)
+{
+   struct meson_clk *priv = dev_get_priv(dev);
+
+   priv->map = syscon_node_to_regmap(dev_get_parent(dev)->node);
+   if (IS_ERR(priv->map))
+   return PTR_ERR(priv->map);
+
+   return 0;
+}
+
+static struct clk_ops meson_clk_ops = {
+   .disable= meson_clk_disable,
+   .enable = meson_clk_enable,
+};
+
+static const struct udevice_id meson_clk_ids[] = {
+   { .compatible = "amlogic,meson-g12a-aoclkc" },
+   { }
+};
+
+U_BOOT_DRIVER(meson_clk_axg) = {
+   .name   = "meson_clk_g12a_ao",
+   .id = UCLASS_CLK,
+   .of_match   = meson_clk_ids,
+   .priv_auto_alloc_size = sizeof(struct meson_clk),
+   .ops= _clk_ops,
+   .probe  = meson_clk_probe,
+};
-- 
2.17.1



[PATCH v2 4/7] configs: khadas-vim3: enable ADC device support

2020-12-15 Thread Marek Szyprowski
ADC device (Meson SARADC) will be used for probing 'Function' button state.

Signed-off-by: Marek Szyprowski 
---
 configs/khadas-vim3_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/configs/khadas-vim3_defconfig b/configs/khadas-vim3_defconfig
index 9d7ba72d44..5d16652fd6 100644
--- a/configs/khadas-vim3_defconfig
+++ b/configs/khadas-vim3_defconfig
@@ -29,6 +29,8 @@ CONFIG_CMD_REGULATOR=y
 CONFIG_OF_CONTROL=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_ADC=y
+CONFIG_SARADC_MESON=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MESON=y
 CONFIG_DM_MMC=y
-- 
2.17.1



[PATCH v2 0/7] VIM3: add support for checking 'Function' button state

2020-12-15 Thread Marek Szyprowski
Hi All,

This patchset adds all building blocks needed for checking the 'Function'
button state in the boot script on Amlogic A311D based VIM3 board. This
button is connected to the ADC lines of the SoC, so it required to enable
meson SARADC, the clocks needed for it and a simple button-adc drivers.

Once applied, one can use following commands in the boot scripts:
-->8---
echo Checking Func button state: \\c
button Function
if test ${button} = on
then
echo Selected alternative boot
...
fi
--->8---

Best regards
Marek Szyprowski
Samsung R Institute Poland


Changelog:
v2:
- removed Change-Id tags
- split defconfig changes into ADC and button related

v1: https://lists.denx.de/pipermail/u-boot/2020-December/434875.html
- initial submission


Patch summary:

Marek Szyprowski (7):
  clk: meson: add minimal driver for g12a-ao clocks
  adc: meson-saradc: add G12A variant
  adc: meson-saradc: skip hardware init only if ADC is enabled
  configs: khadas-vim3: enable ADC device support
  button: add a simple ADC-based button driver
  cmd: button: store button state in the 'button' env
  configs: khadas-vim3: enable Function button support

 cmd/button.c  |   4 +-
 configs/khadas-vim3_defconfig |   4 ++
 drivers/adc/meson-saradc.c|   9 ++-
 drivers/button/Kconfig|   8 +++
 drivers/button/Makefile   |   1 +
 drivers/button/button-adc.c   | 117 ++
 drivers/clk/meson/Makefile|   1 +
 drivers/clk/meson/g12a-ao.c   |  83 
 8 files changed, 224 insertions(+), 3 deletions(-)
 create mode 100644 drivers/button/button-adc.c
 create mode 100644 drivers/clk/meson/g12a-ao.c

-- 
2.17.1



[PATCH v2 2/7] adc: meson-saradc: add G12A variant

2020-12-15 Thread Marek Szyprowski
Add support for the SARADC variant found on the G12A SoCs family.

Signed-off-by: Marek Szyprowski 
Reviewed-by: Neil Armstrong 
Tested-by: Jaehoon Chung 
Reviewed-by: Jaehoon Chung 
---
 drivers/adc/meson-saradc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/adc/meson-saradc.c b/drivers/adc/meson-saradc.c
index 72b0cc4e5b..998cef24d8 100644
--- a/drivers/adc/meson-saradc.c
+++ b/drivers/adc/meson-saradc.c
@@ -711,6 +711,8 @@ static const struct udevice_id meson_saradc_ids[] = {
  .data = (ulong)_saradc_data },
{ .compatible = "amlogic,meson-gxm-saradc",
  .data = (ulong)_saradc_data },
+   { .compatible = "amlogic,meson-g12a-saradc",
+ .data = (ulong)_saradc_data },
{ }
 };
 
-- 
2.17.1



[PATCH v2 7/7] configs: khadas-vim3: enable Function button support

2020-12-15 Thread Marek Szyprowski
Add options needed to check the 'Function' button state.

Signed-off-by: Marek Szyprowski 
---
 configs/khadas-vim3_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/configs/khadas-vim3_defconfig b/configs/khadas-vim3_defconfig
index 5d16652fd6..bc17430569 100644
--- a/configs/khadas-vim3_defconfig
+++ b/configs/khadas-vim3_defconfig
@@ -31,6 +31,8 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_ADC=y
 CONFIG_SARADC_MESON=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_ADC=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MESON=y
 CONFIG_DM_MMC=y
-- 
2.17.1



[PATCH v2 6/7] cmd: button: store button state in the 'button' env

2020-12-15 Thread Marek Szyprowski
Save examined button state in 'button' environment variable to enable
checking button state in the scripts.

Signed-off-by: Marek Szyprowski 
Change-Id: I78b539e1516573fcfea4401f75469291844daae4
---
 cmd/button.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/cmd/button.c b/cmd/button.c
index 64c5a8fa04..8da911068a 100644
--- a/cmd/button.c
+++ b/cmd/button.c
@@ -23,8 +23,10 @@ static int show_button_state(struct udevice *dev)
ret = button_get_state(dev);
if (ret >= BUTTON_COUNT)
ret = -EINVAL;
-   if (ret >= 0)
+   if (ret >= 0) {
printf("%s\n", state_label[ret]);
+   env_set("button", state_label[ret]);
+   }
 
return ret;
 }
-- 
2.17.1



[PATCH v2 3/7] adc: meson-saradc: skip hardware init only if ADC is enabled

2020-12-15 Thread Marek Szyprowski
The driver skips hardware initialization if it is already configured by
the earlier bootloader stage (BL30). Skip the initialization only if the
hardware is really initialized and enabled.

Signed-off-by: Marek Szyprowski 
Reviewed-by: Neil Armstrong 
Tested-by: Jaehoon Chung 
Reviewed-by: Jaehoon Chung 
---
 drivers/adc/meson-saradc.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/adc/meson-saradc.c b/drivers/adc/meson-saradc.c
index 998cef24d8..ce7ae990ad 100644
--- a/drivers/adc/meson-saradc.c
+++ b/drivers/adc/meson-saradc.c
@@ -512,8 +512,11 @@ static int meson_saradc_init(struct meson_saradc_priv 
*priv)
 * reading the temperature sensor.
 */
regmap_read(priv->regmap, MESON_SAR_ADC_REG3, );
-   if (regval & MESON_SAR_ADC_REG3_BL30_INITIALIZED)
-   return 0;
+   if (regval & MESON_SAR_ADC_REG3_BL30_INITIALIZED) {
+   regmap_read(priv->regmap, MESON_SAR_ADC_REG3, );
+   if (regval & MESON_SAR_ADC_REG3_ADC_EN)
+   return 0;
+   }
 
meson_saradc_stop_sample_engine(priv);
 
-- 
2.17.1



Re: [PATCH 6/6] configs: khadas-vim3: enable Function button support

2020-12-14 Thread Marek Szyprowski
Hi Neil,

On 14.12.2020 19:55, Neil Armstrong wrote:
> On 14/12/2020 12:24, Marek Szyprowski wrote:
>> Add options required to check the 'Function' button state.
>>
>> Signed-off-by: Marek Szyprowski 
>> ---
>>   configs/khadas-vim3_defconfig | 4 
>>   1 file changed, 4 insertions(+)
>>
>> diff --git a/configs/khadas-vim3_defconfig b/configs/khadas-vim3_defconfig
>> index 9d7ba72d440..bc174305692 100644
>> --- a/configs/khadas-vim3_defconfig
>> +++ b/configs/khadas-vim3_defconfig
>> @@ -29,6 +29,10 @@ CONFIG_CMD_REGULATOR=y
>>   CONFIG_OF_CONTROL=y
>>   CONFIG_SYS_RELOC_GD_ENV_ADDR=y
>>   CONFIG_NET_RANDOM_ETHADDR=y
>> +CONFIG_ADC=y
>> +CONFIG_SARADC_MESON=y
>> +CONFIG_BUTTON=y
>> +CONFIG_BUTTON_ADC=y
>>   CONFIG_DM_I2C=y
>>   CONFIG_SYS_I2C_MESON=y
>>   CONFIG_DM_MMC=y
>>
> If you separate the ADC configs and Button configs, I can directly apply the 
> clk-ao & adc patches
> for next release.

Sure, no problem. I'm sorry for the change-id mess, I forgot to clean it 
before submission. I will send v2 soon.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R Institute Poland



  1   2   3   >