mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-06-22 14:41:42 +00:00
Merge branch '2020-04-16-master-imports'
- DM GPIO improvements - BTRFS fixes - Corrections around gd->new_bootstage alignment - Start documentation improvements to support 'make refcheckdocs'
This commit is contained in:
commit
8d5d3bcf3c
85 changed files with 1403 additions and 489 deletions
2
Kconfig
2
Kconfig
|
@ -233,7 +233,7 @@ config BUILD_ROM
|
|||
This option allows to build a ROM version of U-Boot.
|
||||
The build process generally requires several binary blobs
|
||||
which are not shipped in the U-Boot source tree.
|
||||
Please, see doc/README.x86 for details.
|
||||
Please, see doc/arch/x86.rst for details.
|
||||
|
||||
config SPL_IMAGE
|
||||
string "SPL image used in the combined SPL+U-Boot image"
|
||||
|
|
4
README
4
README
|
@ -4639,7 +4639,7 @@ int main(int argc, char *argv[])
|
|||
while (learning) {
|
||||
Read the README file in the top level directory;
|
||||
Read http://www.denx.de/twiki/bin/view/DULG/Manual;
|
||||
Read applicable doc/*.README;
|
||||
Read applicable doc/README.*;
|
||||
Read the source, Luke;
|
||||
/* find . -name "*.[chS]" | xargs grep -i <keyword> */
|
||||
}
|
||||
|
@ -4734,8 +4734,6 @@ it:
|
|||
* For new features: a description of the feature and your
|
||||
implementation.
|
||||
|
||||
* A CHANGELOG entry as plaintext (separate from the patch)
|
||||
|
||||
* For major contributions, add a MAINTAINERS file with your
|
||||
information and associated file and directory references.
|
||||
|
||||
|
|
|
@ -127,8 +127,7 @@ ENTRY(_main)
|
|||
ldr r0, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp */
|
||||
bic r0, r0, #7 /* 8-byte alignment for ABI compliance */
|
||||
mov sp, r0
|
||||
ldr r9, [r9, #GD_BD] /* r9 = gd->bd */
|
||||
sub r9, r9, #GD_SIZE /* new GD is below bd */
|
||||
ldr r9, [r9, #GD_NEW_GD] /* r9 <- gd->new_gd */
|
||||
|
||||
adr lr, here
|
||||
ldr r0, [r9, #GD_RELOC_OFF] /* r0 = gd->reloc_off */
|
||||
|
|
|
@ -41,7 +41,7 @@ config IMX_HAB
|
|||
imply CMD_DEKBLOB
|
||||
help
|
||||
This option enables the support for secure boot (HAB).
|
||||
See doc/README.mxc_hab for more details.
|
||||
See doc/imx/habv4/* for more details.
|
||||
|
||||
config CSF_SIZE
|
||||
hex "Maximum size for Command Sequence File (CSF) binary"
|
||||
|
@ -69,7 +69,7 @@ config CMD_DEKBLOB
|
|||
help
|
||||
This enables the 'dek_blob' command which is used with the
|
||||
Freescale secure boot mechanism. This command encapsulates and
|
||||
creates a blob of data. See also CMD_BLOB and doc/README.mxc_hab for
|
||||
creates a blob of data. See also CMD_BLOB and doc/imx/habv4/* for
|
||||
more information.
|
||||
|
||||
config CMD_HDMIDETECT
|
||||
|
|
|
@ -63,7 +63,9 @@ config TARGET_ST_STM32MP15x
|
|||
bool "STMicroelectronics STM32MP15x boards"
|
||||
select STM32MP15x
|
||||
imply BOOTCOUNT_LIMIT
|
||||
imply BOOTSTAGE
|
||||
imply CMD_BOOTCOUNT
|
||||
imply CMD_BOOTSTAGE
|
||||
imply CMD_CLS if CMD_BMP
|
||||
imply DISABLE_CONSOLE
|
||||
imply PRE_CONSOLE_BUFFER
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
/dts-v1/;
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/gpio/sandbox-gpio.h>
|
||||
|
||||
/ {
|
||||
model = "sandbox";
|
||||
compatible = "sandbox";
|
||||
|
@ -13,6 +16,7 @@
|
|||
eth5 = ð_5;
|
||||
gpio1 = &gpio_a;
|
||||
gpio2 = &gpio_b;
|
||||
gpio3 = &gpio_c;
|
||||
i2c0 = "/i2c@0";
|
||||
mmc0 = "/mmc0";
|
||||
mmc1 = "/mmc1";
|
||||
|
@ -86,11 +90,21 @@
|
|||
ping-expect = <0>;
|
||||
ping-add = <0>;
|
||||
u-boot,dm-pre-reloc;
|
||||
test-gpios = <&gpio_a 1>, <&gpio_a 4>, <&gpio_b 5 0 3 2 1>,
|
||||
test-gpios = <&gpio_a 1>, <&gpio_a 4>,
|
||||
<&gpio_b 5 GPIO_ACTIVE_HIGH 3 2 1>,
|
||||
<0>, <&gpio_a 12>;
|
||||
test2-gpios = <&gpio_a 1>, <&gpio_a 4>, <&gpio_b 6 1 3 2 1>,
|
||||
<&gpio_b 7 2 3 2 1>, <&gpio_b 8 4 3 2 1>,
|
||||
<&gpio_b 9 0xc 3 2 1>;
|
||||
test2-gpios = <&gpio_a 1>, <&gpio_a 4>,
|
||||
<&gpio_b 6 GPIO_ACTIVE_LOW 3 2 1>,
|
||||
<&gpio_b 7 GPIO_IN 3 2 1>,
|
||||
<&gpio_b 8 GPIO_OUT 3 2 1>,
|
||||
<&gpio_b 9 (GPIO_OUT|GPIO_OUT_ACTIVE) 3 2 1>;
|
||||
test3-gpios =
|
||||
<&gpio_c 0 (GPIO_OUT|GPIO_OPEN_DRAIN)>,
|
||||
<&gpio_c 1 (GPIO_OUT|GPIO_OPEN_SOURCE)>,
|
||||
<&gpio_c 2 GPIO_OUT>,
|
||||
<&gpio_c 3 (GPIO_IN|GPIO_PULL_UP)>,
|
||||
<&gpio_c 4 (GPIO_IN|GPIO_PULL_DOWN)>,
|
||||
<&gpio_c 5 GPIO_IN>;
|
||||
int-value = <1234>;
|
||||
uint-value = <(-1234)>;
|
||||
int64-value = /bits/ 64 <0x1111222233334444>;
|
||||
|
@ -285,20 +299,32 @@
|
|||
};
|
||||
};
|
||||
|
||||
gpio_a: base-gpios {
|
||||
compatible = "sandbox,gpio";
|
||||
gpio-controller;
|
||||
#gpio-cells = <1>;
|
||||
gpio-bank-name = "a";
|
||||
sandbox,gpio-count = <20>;
|
||||
};
|
||||
pinctrl-gpio {
|
||||
compatible = "sandbox,pinctrl-gpio";
|
||||
|
||||
gpio_b: extra-gpios {
|
||||
compatible = "sandbox,gpio";
|
||||
gpio-controller;
|
||||
#gpio-cells = <5>;
|
||||
gpio-bank-name = "b";
|
||||
sandbox,gpio-count = <10>;
|
||||
gpio_a: base-gpios {
|
||||
compatible = "sandbox,gpio";
|
||||
gpio-controller;
|
||||
#gpio-cells = <1>;
|
||||
gpio-bank-name = "a";
|
||||
sandbox,gpio-count = <20>;
|
||||
};
|
||||
|
||||
gpio_b: extra-gpios {
|
||||
compatible = "sandbox,gpio";
|
||||
gpio-controller;
|
||||
#gpio-cells = <5>;
|
||||
gpio-bank-name = "b";
|
||||
sandbox,gpio-count = <10>;
|
||||
};
|
||||
|
||||
gpio_c: pinmux-gpios {
|
||||
compatible = "sandbox,gpio";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
gpio-bank-name = "c";
|
||||
sandbox,gpio-count = <10>;
|
||||
};
|
||||
};
|
||||
|
||||
i2c@0 {
|
||||
|
@ -905,6 +931,31 @@
|
|||
|
||||
pinctrl {
|
||||
compatible = "sandbox,pinctrl";
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&gpios>;
|
||||
|
||||
gpios: gpios {
|
||||
gpio0 {
|
||||
pins = "GPIO0";
|
||||
bias-pull-up;
|
||||
input-disable;
|
||||
};
|
||||
gpio1 {
|
||||
pins = "GPIO1";
|
||||
output-high;
|
||||
drive-open-drain;
|
||||
};
|
||||
gpio2 {
|
||||
pins = "GPIO2";
|
||||
bias-pull-down;
|
||||
input-enable;
|
||||
};
|
||||
gpio3 {
|
||||
pins = "GPIO3";
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
hwspinlock@0 {
|
||||
|
|
|
@ -42,26 +42,6 @@ int sandbox_gpio_get_value(struct udevice *dev, unsigned int offset);
|
|||
*/
|
||||
int sandbox_gpio_set_value(struct udevice *dev, unsigned int offset, int value);
|
||||
|
||||
/**
|
||||
* Set or reset the simulated open drain mode of a GPIO (used only in sandbox
|
||||
* test code)
|
||||
*
|
||||
* @param gp GPIO number
|
||||
* @param value value to set (0 for enabled open drain mode, non-zero for
|
||||
* disabled)
|
||||
* @return -1 on error, 0 if ok
|
||||
*/
|
||||
int sandbox_gpio_set_open_drain(struct udevice *dev, unsigned offset, int value);
|
||||
|
||||
/**
|
||||
* Return the state of the simulated open drain mode of a GPIO (used only in
|
||||
* sandbox test code)
|
||||
*
|
||||
* @param gp GPIO number
|
||||
* @return -1 on error, 0 if GPIO is input, >0 if output
|
||||
*/
|
||||
int sandbox_gpio_get_open_drain(struct udevice *dev, unsigned offset);
|
||||
|
||||
/**
|
||||
* Return the simulated direction of a GPIO (used only in sandbox test code)
|
||||
*
|
||||
|
@ -82,4 +62,24 @@ int sandbox_gpio_get_direction(struct udevice *dev, unsigned int offset);
|
|||
int sandbox_gpio_set_direction(struct udevice *dev, unsigned int offset,
|
||||
int output);
|
||||
|
||||
/**
|
||||
* Return the simulated flags of a GPIO (used only in sandbox test code)
|
||||
*
|
||||
* @param dev device to use
|
||||
* @param offset GPIO offset within bank
|
||||
* @return dir_flags: bitfield accesses by GPIOD_ defines
|
||||
*/
|
||||
ulong sandbox_gpio_get_dir_flags(struct udevice *dev, unsigned int offset);
|
||||
|
||||
/**
|
||||
* Set the simulated flags of a GPIO (used only in sandbox test code)
|
||||
*
|
||||
* @param dev device to use
|
||||
* @param offset GPIO offset within bank
|
||||
* @param flags dir_flags: bitfield accesses by GPIOD_ defines
|
||||
* @return -1 on error, 0 if ok
|
||||
*/
|
||||
int sandbox_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
|
||||
ulong flags);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Copyright 2015 Timesys Corporation.
|
||||
* Copyright 2015 General Electric Company
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Copyright 2015 Timesys Corporation.
|
||||
* Copyright 2015 General Electric Company
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Based on:
|
||||
* Copyright (C) 2013 Boundary Devices
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Copyright (C) 2011 Freescale Semiconductor, Inc.
|
||||
* Jason Liu <r64343@freescale.com>
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Copyright (C) 2011 Freescale Semiconductor, Inc.
|
||||
* Jason Liu <r64343@freescale.com>
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Boundary Devices
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Boundary Devices
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Boundary Devices
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Boundary Devices
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Boundary Devices
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Boundary Devices
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2016 Stefan Roese <sr@denx.de>
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -28,7 +28,7 @@ CONFIGURING
|
|||
|
||||
|
||||
Please refer to u-boot README (general info, u-boot-x-x-x/README),
|
||||
to u-boot-x-x-x/doc/README.COBRA5272 and
|
||||
to u-boot-x-x-x/board/cobra5272/README and
|
||||
to the comments in u-boot-x-x-x/include/configs/cobra5272.h
|
||||
|
||||
Configuring u-boot is done by commenting/uncommenting preprocessor defines.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright 2018 NXP
|
||||
*
|
||||
* Refer doc/README.imx8image for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imx8image.txt for more details about how-to configure
|
||||
* and create imx8image boot image
|
||||
*/
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ Changed files:
|
|||
- arch/m68k/cpu/mcf5227x/config.mk config make
|
||||
- arch/m68k/cpu/mcf5227x/start.S start up assembly code
|
||||
|
||||
- doc/README.m52277evb This readme file
|
||||
- board/freescale/m52277evb/README This readme file
|
||||
|
||||
- drivers/serial/mcfuart.c ColdFire common UART driver
|
||||
- drivers/rtc/mcfrtc.c Realtime clock Driver
|
||||
|
|
|
@ -23,7 +23,7 @@ Changed files:
|
|||
- arch/m68k/cpu/mcf532x/config.mk config make
|
||||
- arch/m68k/cpu/mcf532x/start.S start up assembly code
|
||||
|
||||
- doc/README.m53017evb This readme file
|
||||
- board/freescale/m53017evb/README his readme file
|
||||
|
||||
- drivers/net/mcffec.c ColdFire common FEC driver
|
||||
- drivers/net/mcfmii.c ColdFire common Mii driver
|
||||
|
|
|
@ -23,7 +23,7 @@ Changed files:
|
|||
- arch/m68k/cpu/mcf532x/config.mk config make
|
||||
- arch/m68k/cpu/mcf532x/start.S start up assembly code
|
||||
|
||||
- doc/README.m5373evb This readme file
|
||||
- board/freescale/m5373evb/README This readme file
|
||||
|
||||
- drivers/net/mcffec.c ColdFire common FEC driver
|
||||
- drivers/serial/mcfuart.c ColdFire common UART driver
|
||||
|
|
|
@ -26,7 +26,7 @@ Changed files:
|
|||
- arch/m68k/cpu/mcf5445x/config.mk config make
|
||||
- arch/m68k/cpu/mcf5445x/start.S start up assembly code
|
||||
|
||||
- doc/README.m54455evb This readme file
|
||||
- board/freescale/m54455evb/README This readme file
|
||||
|
||||
- drivers/net/mcffec.c ColdFire common FEC driver
|
||||
- drivers/serial/mcfuart.c ColdFire common UART driver
|
||||
|
|
|
@ -24,7 +24,7 @@ Changed files:
|
|||
- arch/m68k/cpu/mcf547x_8x/config.mk config make
|
||||
- arch/m68k/cpu/mcf547x_8x/start.S start up assembly code
|
||||
|
||||
- doc/README.m5475evb This readme file
|
||||
- board/freescale/m547xevb/README This readme file
|
||||
|
||||
- drivers/dma/MCD_dmaApi.c DMA API functions
|
||||
- drivers/dma/MCD_tasks.c DMA Tasks
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* (C) Copyright 2009
|
||||
* Stefano Babic DENX Software Engineering sbabic@denx.de.
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* (C Copyright 2009
|
||||
* Stefano Babic DENX Software Engineering sbabic@denx.de.
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* (C) Copyright 2009
|
||||
* Stefano Babic DENX Software Engineering sbabic@denx.de.
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* (C Copyright 2009
|
||||
* Stefano Babic DENX Software Engineering sbabic@denx.de.
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Copyright (C) 2011 Freescale Semiconductor, Inc.
|
||||
* Jason Liu <r64343@freescale.com>
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* (C) Copyright 2009
|
||||
* Stefano Babic DENX Software Engineering sbabic@denx.de.
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Copyright (C) 2011-2014 Freescale Semiconductor, Inc.
|
||||
* Jason Liu <r64343@freescale.com>
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Copyright (C) 2014 Freescale Semiconductor, Inc.
|
||||
* Jason Liu <r64343@freescale.com>
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright (C) 2015 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Copyright 2015 Timesys Corporation.
|
||||
* Copyright 2015 General Electric Company
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Copyright (C) 2011 Freescale Semiconductor, Inc.
|
||||
* Jason Liu <r64343@freescale.com>
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* M53 DRAM init values
|
||||
* Copyright (C) 2012-2013 Marek Vasut <marex@denx.de>
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright 2015 3ADEV <http://www.3adev.com>
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Seco USA Inc
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright 2018 NXP
|
||||
*
|
||||
* Refer doc/README.imx8image for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imx8image.txt for more details about how-to configure
|
||||
* and create imx8image boot image
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright (C) 2015 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright 2019 Toradex
|
||||
*
|
||||
* Refer doc/README.imx8image for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imx8image.txt for more details about how-to configure
|
||||
* and create imx8image boot image
|
||||
*/
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Copyright (C) 2016 Freescale Semiconductor, Inc.
|
||||
* Copyright (C) 2018 Toradex AG
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright 2019 Toradex
|
||||
*
|
||||
* Refer doc/README.imx8image for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imx8image.txt for more details about how-to configure
|
||||
* and create imx8image boot image
|
||||
*/
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Copyright (C) 2015 Freescale Semiconductor, Inc.
|
||||
* 2015 Toradex AG
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright 2014 Toradex, Inc.
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Copyright (C) 2013 Boundary Devices
|
||||
* Copyright (C) 2013, 2014 Markus Niebel <Markus.Niebel@tq-group.com>
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*/
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright (C) 2014 - 2015 Markus Niebel <Markus.Niebel@tq-group.com>
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright (C) 2013, 2014 Markus Niebel <Markus.Niebel@tq-group.com>
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright (C) 2013, 2014 Markus Niebel <Markus.Niebel@tq-group.com>
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Copyright (C) 2016 NXP Semiconductors
|
||||
*
|
||||
* Refer doc/README.imximage for more details about how-to configure
|
||||
* Refer doc/imx/mkimage/imximage.txt for more details about how-to configure
|
||||
* and create imximage boot image
|
||||
*
|
||||
* The syntax is taken as close as possible with the kwbimage
|
||||
|
|
|
@ -472,6 +472,17 @@ static int reserve_uboot(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* reserve after start_addr_sp the requested size and make the stack pointer
|
||||
* 16-byte aligned, this alignment is needed for cast on the reserved memory
|
||||
* ref = x86_64 ABI: https://reviews.llvm.org/D30049: 16 bytes
|
||||
* = ARMv8 Instruction Set Overview: quad word, 16 bytes
|
||||
*/
|
||||
static unsigned long reserve_stack_aligned(size_t size)
|
||||
{
|
||||
return ALIGN_DOWN(gd->start_addr_sp - size, 16);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_NONCACHED_MEMORY
|
||||
static int reserve_noncached(void)
|
||||
{
|
||||
|
@ -497,7 +508,7 @@ static int reserve_noncached(void)
|
|||
/* reserve memory for malloc() area */
|
||||
static int reserve_malloc(void)
|
||||
{
|
||||
gd->start_addr_sp = gd->start_addr_sp - TOTAL_MALLOC_LEN;
|
||||
gd->start_addr_sp = reserve_stack_aligned(TOTAL_MALLOC_LEN);
|
||||
debug("Reserving %dk for malloc() at: %08lx\n",
|
||||
TOTAL_MALLOC_LEN >> 10, gd->start_addr_sp);
|
||||
#ifdef CONFIG_SYS_NONCACHED_MEMORY
|
||||
|
@ -511,7 +522,7 @@ static int reserve_malloc(void)
|
|||
static int reserve_board(void)
|
||||
{
|
||||
if (!gd->bd) {
|
||||
gd->start_addr_sp -= sizeof(bd_t);
|
||||
gd->start_addr_sp = reserve_stack_aligned(sizeof(bd_t));
|
||||
gd->bd = (bd_t *)map_sysmem(gd->start_addr_sp, sizeof(bd_t));
|
||||
memset(gd->bd, '\0', sizeof(bd_t));
|
||||
debug("Reserving %zu Bytes for Board Info at: %08lx\n",
|
||||
|
@ -530,7 +541,7 @@ static int setup_machine(void)
|
|||
|
||||
static int reserve_global_data(void)
|
||||
{
|
||||
gd->start_addr_sp -= sizeof(gd_t);
|
||||
gd->start_addr_sp = reserve_stack_aligned(sizeof(gd_t));
|
||||
gd->new_gd = (gd_t *)map_sysmem(gd->start_addr_sp, sizeof(gd_t));
|
||||
debug("Reserving %zu Bytes for Global Data at: %08lx\n",
|
||||
sizeof(gd_t), gd->start_addr_sp);
|
||||
|
@ -548,7 +559,7 @@ static int reserve_fdt(void)
|
|||
if (gd->fdt_blob) {
|
||||
gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32);
|
||||
|
||||
gd->start_addr_sp -= gd->fdt_size;
|
||||
gd->start_addr_sp = reserve_stack_aligned(gd->fdt_size);
|
||||
gd->new_fdt = map_sysmem(gd->start_addr_sp, gd->fdt_size);
|
||||
debug("Reserving %lu Bytes for FDT at: %08lx\n",
|
||||
gd->fdt_size, gd->start_addr_sp);
|
||||
|
@ -563,7 +574,7 @@ static int reserve_bootstage(void)
|
|||
#ifdef CONFIG_BOOTSTAGE
|
||||
int size = bootstage_get_size();
|
||||
|
||||
gd->start_addr_sp -= size;
|
||||
gd->start_addr_sp = reserve_stack_aligned(size);
|
||||
gd->new_bootstage = map_sysmem(gd->start_addr_sp, size);
|
||||
debug("Reserving %#x Bytes for bootstage at: %08lx\n", size,
|
||||
gd->start_addr_sp);
|
||||
|
@ -580,8 +591,7 @@ __weak int arch_reserve_stacks(void)
|
|||
static int reserve_stacks(void)
|
||||
{
|
||||
/* make stack pointer 16-byte aligned */
|
||||
gd->start_addr_sp -= 16;
|
||||
gd->start_addr_sp &= ~0xf;
|
||||
gd->start_addr_sp = reserve_stack_aligned(16);
|
||||
|
||||
/*
|
||||
* let the architecture-specific code tailor gd->start_addr_sp and
|
||||
|
@ -593,8 +603,7 @@ static int reserve_stacks(void)
|
|||
static int reserve_bloblist(void)
|
||||
{
|
||||
#ifdef CONFIG_BLOBLIST
|
||||
gd->start_addr_sp &= ~0xf;
|
||||
gd->start_addr_sp -= CONFIG_BLOBLIST_SIZE;
|
||||
gd->start_addr_sp = reserve_stack_aligned(CONFIG_BLOBLIST_SIZE);
|
||||
gd->new_bloblist = map_sysmem(gd->start_addr_sp, CONFIG_BLOBLIST_SIZE);
|
||||
#endif
|
||||
|
||||
|
|
42
doc/README.gpio
Normal file
42
doc/README.gpio
Normal file
|
@ -0,0 +1,42 @@
|
|||
|
||||
GPIO hog (CONFIG_GPIO_HOG)
|
||||
--------
|
||||
|
||||
All the GPIO hog are initialized in gpio_hog_probe_all() function called in
|
||||
board_r.c just before board_late_init() but you can also acces directly to
|
||||
the gpio with gpio_hog_lookup_name().
|
||||
|
||||
|
||||
Example, for the device tree:
|
||||
|
||||
tca6416@20 {
|
||||
compatible = "ti,tca6416";
|
||||
reg = <0x20>;
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
|
||||
env_reset {
|
||||
gpio-hog;
|
||||
input;
|
||||
gpios = <6 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
boot_rescue {
|
||||
gpio-hog;
|
||||
input;
|
||||
line-name = "foo-bar-gpio";
|
||||
gpios = <7 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
You can than access the gpio in your board code with:
|
||||
|
||||
struct gpio_desc *desc;
|
||||
int ret;
|
||||
|
||||
ret = gpio_hog_lookup_name("boot_rescue", &desc);
|
||||
if (ret)
|
||||
return;
|
||||
if (dm_gpio_get_value(desc) == 1)
|
||||
printf("\nBooting into Rescue System\n");
|
||||
else if (dm_gpio_get_value(desc) == 0)
|
||||
printf("\nBoot normal\n");
|
|
@ -4,19 +4,12 @@ Specifying GPIO information for devices
|
|||
1) gpios property
|
||||
-----------------
|
||||
|
||||
Nodes that makes use of GPIOs should specify them using one or more
|
||||
properties, each containing a 'gpio-list':
|
||||
|
||||
gpio-list ::= <single-gpio> [gpio-list]
|
||||
single-gpio ::= <gpio-phandle> <gpio-specifier>
|
||||
gpio-phandle : phandle to gpio controller node
|
||||
gpio-specifier : Array of #gpio-cells specifying specific gpio
|
||||
(controller specific)
|
||||
|
||||
GPIO properties should be named "[<name>-]gpios", with <name> being the purpose
|
||||
of this GPIO for the device. While a non-existent <name> is considered valid
|
||||
for compatibility reasons (resolving to the "gpios" property), it is not allowed
|
||||
for new bindings.
|
||||
for new bindings. Also, GPIO properties named "[<name>-]gpio" are valid and old
|
||||
bindings use it, but are only supported for compatibility reasons and should not
|
||||
be used for newer bindings since it has been deprecated.
|
||||
|
||||
GPIO properties can contain one or more GPIO phandles, but only in exceptional
|
||||
cases should they contain more than one. If your device uses several GPIOs with
|
||||
|
@ -31,30 +24,28 @@ The following example could be used to describe GPIO pins used as device enable
|
|||
and bit-banged data signals:
|
||||
|
||||
gpio1: gpio1 {
|
||||
gpio-controller
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
gpio2: gpio2 {
|
||||
gpio-controller
|
||||
#gpio-cells = <1>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
[...]
|
||||
|
||||
enable-gpios = <&gpio2 2>;
|
||||
data-gpios = <&gpio1 12 0>,
|
||||
<&gpio1 13 0>,
|
||||
<&gpio1 14 0>,
|
||||
<&gpio1 15 0>;
|
||||
|
||||
Note that gpio-specifier length is controller dependent. In the
|
||||
above example, &gpio1 uses 2 cells to specify a gpio, while &gpio2
|
||||
only uses one.
|
||||
In the above example, &gpio1 uses 2 cells to specify a gpio. The first cell is
|
||||
a local offset to the GPIO line and the second cell represent consumer flags,
|
||||
such as if the consumer desire the line to be active low (inverted) or open
|
||||
drain. This is the recommended practice.
|
||||
|
||||
gpio-specifier may encode: bank, pin position inside the bank,
|
||||
whether pin is open-drain and whether pin is logically inverted.
|
||||
Exact meaning of each specifier cell is controller specific, and must
|
||||
be documented in the device tree binding for the device. Use the macros
|
||||
defined in include/dt-bindings/gpio/gpio.h whenever possible:
|
||||
The exact meaning of each specifier cell is controller specific, and must be
|
||||
documented in the device tree binding for the device, but it is strongly
|
||||
recommended to use the two-cell approach.
|
||||
|
||||
Most controllers are specifying a generic flag bitfield in the last cell, so
|
||||
for these, use the macros defined in
|
||||
include/dt-bindings/gpio/gpio.h whenever possible:
|
||||
|
||||
Example of a node using GPIOs:
|
||||
|
||||
|
@ -65,6 +56,30 @@ Example of a node using GPIOs:
|
|||
GPIO_ACTIVE_HIGH is 0, so in this example gpio-specifier is "18 0" and encodes
|
||||
GPIO pin number, and GPIO flags as accepted by the "qe_pio_e" gpio-controller.
|
||||
|
||||
Optional standard bitfield specifiers for the last cell:
|
||||
|
||||
- Bit 0: 0 means active high, 1 means active low
|
||||
- Bit 1: 0 mean push-pull wiring, see:
|
||||
https://en.wikipedia.org/wiki/Push-pull_output
|
||||
1 means single-ended wiring, see:
|
||||
https://en.wikipedia.org/wiki/Single-ended_triode
|
||||
- Bit 2: 0 means open-source, 1 means open drain, see:
|
||||
https://en.wikipedia.org/wiki/Open_collector
|
||||
- Bit 3: 0 means the output should be maintained during sleep/low-power mode
|
||||
1 means the output state can be lost during sleep/low-power mode
|
||||
- Bit 4: 0 means no pull-up resistor should be enabled
|
||||
1 means a pull-up resistor should be enabled
|
||||
This setting only applies to hardware with a simple on/off
|
||||
control for pull-up configuration. If the hardware has more
|
||||
elaborate pull-up configuration, it should be represented
|
||||
using a pin control binding.
|
||||
- Bit 5: 0 means no pull-down resistor should be enabled
|
||||
1 means a pull-down resistor should be enabled
|
||||
This setting only applies to hardware with a simple on/off
|
||||
control for pull-down configuration. If the hardware has more
|
||||
elaborate pull-down configuration, it should be represented
|
||||
using a pin control binding.
|
||||
|
||||
1.1) GPIO specifier best practices
|
||||
----------------------------------
|
||||
|
||||
|
@ -116,6 +131,80 @@ Every GPIO controller node must contain both an empty "gpio-controller"
|
|||
property, and a #gpio-cells integer property, which indicates the number of
|
||||
cells in a gpio-specifier.
|
||||
|
||||
Some system-on-chips (SoCs) use the concept of GPIO banks. A GPIO bank is an
|
||||
instance of a hardware IP core on a silicon die, usually exposed to the
|
||||
programmer as a coherent range of I/O addresses. Usually each such bank is
|
||||
exposed in the device tree as an individual gpio-controller node, reflecting
|
||||
the fact that the hardware was synthesized by reusing the same IP block a
|
||||
few times over.
|
||||
|
||||
Optionally, a GPIO controller may have a "ngpios" property. This property
|
||||
indicates the number of in-use slots of available slots for GPIOs. The
|
||||
typical example is something like this: the hardware register is 32 bits
|
||||
wide, but only 18 of the bits have a physical counterpart. The driver is
|
||||
generally written so that all 32 bits can be used, but the IP block is reused
|
||||
in a lot of designs, some using all 32 bits, some using 18 and some using
|
||||
12. In this case, setting "ngpios = <18>;" informs the driver that only the
|
||||
first 18 GPIOs, at local offset 0 .. 17, are in use.
|
||||
|
||||
If these GPIOs do not happen to be the first N GPIOs at offset 0...N-1, an
|
||||
additional set of tuples is needed to specify which GPIOs are unusable, with
|
||||
the gpio-reserved-ranges binding. This property indicates the start and size
|
||||
of the GPIOs that can't be used.
|
||||
|
||||
Optionally, a GPIO controller may have a "gpio-line-names" property. This is
|
||||
an array of strings defining the names of the GPIO lines going out of the
|
||||
GPIO controller. This name should be the most meaningful producer name
|
||||
for the system, such as a rail name indicating the usage. Package names
|
||||
such as pin name are discouraged: such lines have opaque names (since they
|
||||
are by definition generic purpose) and such names are usually not very
|
||||
helpful. For example "MMC-CD", "Red LED Vdd" and "ethernet reset" are
|
||||
reasonable line names as they describe what the line is used for. "GPIO0"
|
||||
is not a good name to give to a GPIO line. Placeholders are discouraged:
|
||||
rather use the "" (blank string) if the use of the GPIO line is undefined
|
||||
in your design. The names are assigned starting from line offset 0 from
|
||||
left to right from the passed array. An incomplete array (where the number
|
||||
of passed named are less than ngpios) will still be used up until the last
|
||||
provided valid line index.
|
||||
|
||||
Example:
|
||||
|
||||
gpio-controller@00000000 {
|
||||
compatible = "foo";
|
||||
reg = <0x00000000 0x1000>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
ngpios = <18>;
|
||||
gpio-reserved-ranges = <0 4>, <12 2>;
|
||||
gpio-line-names = "MMC-CD", "MMC-WP", "VDD eth", "RST eth", "LED R",
|
||||
"LED G", "LED B", "Col A", "Col B", "Col C", "Col D",
|
||||
"Row A", "Row B", "Row C", "Row D", "NMI button",
|
||||
"poweroff", "reset";
|
||||
}
|
||||
|
||||
The GPIO chip may contain GPIO hog definitions. GPIO hogging is a mechanism
|
||||
providing automatic GPIO request and configuration as part of the
|
||||
gpio-controller's driver probe function.
|
||||
|
||||
Each GPIO hog definition is represented as a child node of the GPIO controller.
|
||||
Required properties:
|
||||
- gpio-hog: A property specifying that this child node represents a GPIO hog.
|
||||
- gpios: Store the GPIO information (id, flags, ...) for each GPIO to
|
||||
affect. Shall contain an integer multiple of the number of cells
|
||||
specified in its parent node (GPIO controller node).
|
||||
Only one of the following properties scanned in the order shown below.
|
||||
This means that when multiple properties are present they will be searched
|
||||
in the order presented below and the first match is taken as the intended
|
||||
configuration.
|
||||
- input: A property specifying to set the GPIO direction as input.
|
||||
- output-low A property specifying to set the GPIO direction as output with
|
||||
the value low.
|
||||
- output-high A property specifying to set the GPIO direction as output with
|
||||
the value high.
|
||||
|
||||
Optional properties:
|
||||
- line-name: The GPIO label name. If not present the node name is used.
|
||||
|
||||
Example of two SOC GPIO banks defined as gpio-controller nodes:
|
||||
|
||||
qe_pio_a: gpio-controller@1400 {
|
||||
|
@ -137,46 +226,40 @@ Example of two SOC GPIO banks defined as gpio-controller nodes:
|
|||
|
||||
Some or all of the GPIOs provided by a GPIO controller may be routed to pins
|
||||
on the package via a pin controller. This allows muxing those pins between
|
||||
GPIO and other functions.
|
||||
GPIO and other functions. It is a fairly common practice among silicon
|
||||
engineers.
|
||||
|
||||
2.2) Ordinary (numerical) GPIO ranges
|
||||
-------------------------------------
|
||||
|
||||
It is useful to represent which GPIOs correspond to which pins on which pin
|
||||
controllers. The gpio-ranges property described below represents this, and
|
||||
contains information structures as follows:
|
||||
controllers. The gpio-ranges property described below represents this with
|
||||
a discrete set of ranges mapping pins from the pin controller local number space
|
||||
to pins in the GPIO controller local number space.
|
||||
|
||||
gpio-range-list ::= <single-gpio-range> [gpio-range-list]
|
||||
single-gpio-range ::= <numeric-gpio-range> | <named-gpio-range>
|
||||
numeric-gpio-range ::=
|
||||
<pinctrl-phandle> <gpio-base> <pinctrl-base> <count>
|
||||
named-gpio-range ::= <pinctrl-phandle> <gpio-base> '<0 0>'
|
||||
pinctrl-phandle : phandle to pin controller node
|
||||
gpio-base : Base GPIO ID in the GPIO controller
|
||||
pinctrl-base : Base pinctrl pin ID in the pin controller
|
||||
count : The number of GPIOs/pins in this range
|
||||
The format is: <[pin controller phandle], [GPIO controller offset],
|
||||
[pin controller offset], [number of pins]>;
|
||||
|
||||
The "pin controller node" mentioned above must conform to the bindings
|
||||
described in ../pinctrl/pinctrl-bindings.txt.
|
||||
The GPIO controller offset pertains to the GPIO controller node containing the
|
||||
range definition.
|
||||
|
||||
In case named gpio ranges are used (ranges with both <pinctrl-base> and
|
||||
<count> set to 0), the property gpio-ranges-group-names contains one string
|
||||
for every single-gpio-range in gpio-ranges:
|
||||
gpiorange-names-list ::= <gpiorange-name> [gpiorange-names-list]
|
||||
gpiorange-name : Name of the pingroup associated to the GPIO range in
|
||||
the respective pin controller.
|
||||
The pin controller node referenced by the phandle must conform to the bindings
|
||||
described in pinctrl/pinctrl-bindings.txt.
|
||||
|
||||
Elements of gpiorange-names-list corresponding to numeric ranges contain
|
||||
the empty string. Elements of gpiorange-names-list corresponding to named
|
||||
ranges contain the name of a pin group defined in the respective pin
|
||||
controller. The number of pins/GPIOs in the range is the number of pins in
|
||||
that pin group.
|
||||
Each offset runs from 0 to N. It is perfectly fine to pile any number of
|
||||
ranges with just one pin-to-GPIO line mapping if the ranges are concocted, but
|
||||
in practice these ranges are often lumped in discrete sets.
|
||||
|
||||
Previous versions of this binding required all pin controller nodes that
|
||||
were referenced by any gpio-ranges property to contain a property named
|
||||
#gpio-range-cells with value <3>. This requirement is now deprecated.
|
||||
However, that property may still exist in older device trees for
|
||||
compatibility reasons, and would still be required even in new device
|
||||
trees that need to be compatible with older software.
|
||||
Example:
|
||||
|
||||
Example 1:
|
||||
gpio-ranges = <&foo 0 20 10>, <&bar 10 50 20>;
|
||||
|
||||
This means:
|
||||
- pins 20..29 on pin controller "foo" is mapped to GPIO line 0..9 and
|
||||
- pins 50..69 on pin controller "bar" is mapped to GPIO line 10..29
|
||||
|
||||
|
||||
Verbose example:
|
||||
|
||||
qe_pio_e: gpio-controller@1460 {
|
||||
#gpio-cells = <2>;
|
||||
|
@ -187,12 +270,33 @@ Example 1:
|
|||
};
|
||||
|
||||
Here, a single GPIO controller has GPIOs 0..9 routed to pin controller
|
||||
pinctrl1's pins 20..29, and GPIOs 10..19 routed to pin controller pinctrl2's
|
||||
pins 50..59.
|
||||
pinctrl1's pins 20..29, and GPIOs 10..29 routed to pin controller pinctrl2's
|
||||
pins 50..69.
|
||||
|
||||
Example 2:
|
||||
|
||||
gpio_pio_i: gpio-controller@14B0 {
|
||||
2.3) GPIO ranges from named pin groups
|
||||
--------------------------------------
|
||||
|
||||
It is also possible to use pin groups for gpio ranges when pin groups are the
|
||||
easiest and most convenient mapping.
|
||||
|
||||
Both both <pinctrl-base> and <count> must set to 0 when using named pin groups
|
||||
names.
|
||||
|
||||
The property gpio-ranges-group-names must contain exactly one string for each
|
||||
range.
|
||||
|
||||
Elements of gpio-ranges-group-names must contain the name of a pin group
|
||||
defined in the respective pin controller. The number of pins/GPIO lines in the
|
||||
range is the number of pins in that pin group. The number of pins of that
|
||||
group is defined int the implementation and not in the device tree.
|
||||
|
||||
If numerical and named pin groups are mixed, the string corresponding to a
|
||||
numerical pin range in gpio-ranges-group-names must be empty.
|
||||
|
||||
Example:
|
||||
|
||||
gpio_pio_i: gpio-controller@14b0 {
|
||||
#gpio-cells = <2>;
|
||||
compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank";
|
||||
reg = <0x1480 0x18>;
|
||||
|
@ -207,66 +311,14 @@ Example 2:
|
|||
"bar";
|
||||
};
|
||||
|
||||
Here, three GPIO ranges are defined wrt. two pin controllers. pinctrl1 GPIO
|
||||
ranges are defined using pin numbers whereas the GPIO ranges wrt. pinctrl2
|
||||
are named "foo" and "bar".
|
||||
Here, three GPIO ranges are defined referring to two pin controllers.
|
||||
|
||||
3) GPIO hog definitions
|
||||
-----------------------
|
||||
pinctrl1 GPIO ranges are defined using pin numbers whereas the GPIO ranges
|
||||
in pinctrl2 are defined using the pin groups named "foo" and "bar".
|
||||
|
||||
The GPIO chip may contain GPIO hog definitions. GPIO hogging is a mechanism
|
||||
providing automatic GPIO request and configuration as part of the
|
||||
gpio-controller's driver probe function.
|
||||
|
||||
Each GPIO hog definition is represented as a child node of the GPIO controller.
|
||||
Required properties:
|
||||
- gpio-hog: A property specifying that this child node represents a GPIO hog.
|
||||
- gpios: Store the GPIO information (id, flags) for the GPIO to
|
||||
affect.
|
||||
|
||||
! Not yet support more than one gpio !
|
||||
|
||||
Only one of the following properties scanned in the order shown below.
|
||||
- input: A property specifying to set the GPIO direction as input.
|
||||
- output-low A property specifying to set the GPIO direction as output with
|
||||
the value low.
|
||||
- output-high A property specifying to set the GPIO direction as output with
|
||||
the value high.
|
||||
|
||||
Optional properties:
|
||||
- line-name: The GPIO label name. If not present the node name is used.
|
||||
|
||||
Example:
|
||||
|
||||
tca6416@20 {
|
||||
compatible = "ti,tca6416";
|
||||
reg = <0x20>;
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
|
||||
env_reset {
|
||||
gpio-hog;
|
||||
input;
|
||||
gpios = <6 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
boot_rescue {
|
||||
gpio-hog;
|
||||
input;
|
||||
line-name = "foo-bar-gpio";
|
||||
gpios = <7 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
For the above Example you can than access the gpio in your boardcode
|
||||
with:
|
||||
|
||||
struct gpio_desc *desc;
|
||||
int ret;
|
||||
|
||||
ret = gpio_hog_lookup_name("boot_rescue", &desc);
|
||||
if (ret)
|
||||
return;
|
||||
if (dm_gpio_get_value(desc) == 1)
|
||||
printf("\nBooting into Rescue System\n");
|
||||
else if (dm_gpio_get_value(desc) == 0)
|
||||
printf("\nBoot normal\n");
|
||||
Previous versions of this binding required all pin controller nodes that
|
||||
were referenced by any gpio-ranges property to contain a property named
|
||||
#gpio-range-cells with value <3>. This requirement is now deprecated.
|
||||
However, that property may still exist in older device trees for
|
||||
compatibility reasons, and would still be required even in new device
|
||||
trees that need to be compatible with older software.
|
||||
|
|
|
@ -20,7 +20,7 @@ Required properties:
|
|||
<LVDS_OUTPUT_DUAL>, This describes the output face.
|
||||
|
||||
- display-timings : described by
|
||||
doc/devicetree/device-tree-bindings/video/display-timing.txt.
|
||||
doc/device-tree-bindings/video/display-timing.txt.
|
||||
|
||||
Example:
|
||||
lvds: lvds@ff96c000 {
|
||||
|
|
|
@ -22,7 +22,7 @@ described in the manual. It is a replacement for Freescale's
|
|||
MFGTOOLS.
|
||||
|
||||
The host side utilities are typically capable to interpret the i.MX
|
||||
specific image header (see doc/README.imximage). There are extensions
|
||||
specific image header (see doc/imx/mkimage/imximage.txt). There are extensions
|
||||
for imx_loader's imx_usb utility which allow to interpret the U-Boot
|
||||
specific legacy image format (see mkimage(1)). Also the U-Boot side
|
||||
support beside the i.MX specific header the U-Boot legacy header.
|
||||
|
|
|
@ -171,6 +171,38 @@ const void *of_get_property(const struct device_node *np, const char *name,
|
|||
return pp ? pp->value : NULL;
|
||||
}
|
||||
|
||||
const struct property *of_get_first_property(const struct device_node *np)
|
||||
{
|
||||
if (!np)
|
||||
return NULL;
|
||||
|
||||
return np->properties;
|
||||
}
|
||||
|
||||
const struct property *of_get_next_property(const struct device_node *np,
|
||||
const struct property *property)
|
||||
{
|
||||
if (!np)
|
||||
return NULL;
|
||||
|
||||
return property->next;
|
||||
}
|
||||
|
||||
const void *of_get_property_by_prop(const struct device_node *np,
|
||||
const struct property *property,
|
||||
const char **name,
|
||||
int *lenp)
|
||||
{
|
||||
if (!np || !property)
|
||||
return NULL;
|
||||
if (name)
|
||||
*name = property->name;
|
||||
if (lenp)
|
||||
*lenp = property->length;
|
||||
|
||||
return property->value;
|
||||
}
|
||||
|
||||
static const char *of_prop_next_string(struct property *prop, const char *cur)
|
||||
{
|
||||
const void *curv = cur;
|
||||
|
|
|
@ -571,6 +571,54 @@ const void *ofnode_get_property(ofnode node, const char *propname, int *lenp)
|
|||
propname, lenp);
|
||||
}
|
||||
|
||||
int ofnode_get_first_property(ofnode node, struct ofprop *prop)
|
||||
{
|
||||
prop->node = node;
|
||||
|
||||
if (ofnode_is_np(node)) {
|
||||
prop->prop = of_get_first_property(ofnode_to_np(prop->node));
|
||||
if (!prop->prop)
|
||||
return -FDT_ERR_NOTFOUND;
|
||||
} else {
|
||||
prop->offset =
|
||||
fdt_first_property_offset(gd->fdt_blob,
|
||||
ofnode_to_offset(prop->node));
|
||||
if (prop->offset < 0)
|
||||
return prop->offset;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ofnode_get_next_property(struct ofprop *prop)
|
||||
{
|
||||
if (ofnode_is_np(prop->node)) {
|
||||
prop->prop = of_get_next_property(ofnode_to_np(prop->node),
|
||||
prop->prop);
|
||||
if (!prop->prop)
|
||||
return -FDT_ERR_NOTFOUND;
|
||||
} else {
|
||||
prop->offset = fdt_next_property_offset(gd->fdt_blob,
|
||||
prop->offset);
|
||||
if (prop->offset < 0)
|
||||
return prop->offset;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const void *ofnode_get_property_by_prop(const struct ofprop *prop,
|
||||
const char **propname, int *lenp)
|
||||
{
|
||||
if (ofnode_is_np(prop->node))
|
||||
return of_get_property_by_prop(ofnode_to_np(prop->node),
|
||||
prop->prop, propname, lenp);
|
||||
else
|
||||
return fdt_getprop_by_offset(gd->fdt_blob,
|
||||
prop->offset,
|
||||
propname, lenp);
|
||||
}
|
||||
|
||||
bool ofnode_is_available(ofnode node)
|
||||
{
|
||||
if (ofnode_is_np(node))
|
||||
|
|
|
@ -255,6 +255,22 @@ const void *dev_read_prop(const struct udevice *dev, const char *propname,
|
|||
return ofnode_get_property(dev_ofnode(dev), propname, lenp);
|
||||
}
|
||||
|
||||
int dev_read_first_prop(const struct udevice *dev, struct ofprop *prop)
|
||||
{
|
||||
return ofnode_get_first_property(dev_ofnode(dev), prop);
|
||||
}
|
||||
|
||||
int dev_read_next_prop(struct ofprop *prop)
|
||||
{
|
||||
return ofnode_get_next_property(prop);
|
||||
}
|
||||
|
||||
const void *dev_read_prop_by_prop(struct ofprop *prop,
|
||||
const char **propname, int *lenp)
|
||||
{
|
||||
return ofnode_get_property_by_prop(prop, propname, lenp);
|
||||
}
|
||||
|
||||
int dev_read_alias_seq(const struct udevice *dev, int *devnump)
|
||||
{
|
||||
ofnode node = dev_ofnode(dev);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <dm/device_compat.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <dm/lists.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
|
@ -18,6 +19,22 @@
|
|||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/**
|
||||
* gpio_desc_init() - Initialize the GPIO descriptor
|
||||
*
|
||||
* @desc: GPIO descriptor to initialize
|
||||
* @dev: GPIO device
|
||||
* @offset: Offset of device GPIO
|
||||
*/
|
||||
static void gpio_desc_init(struct gpio_desc *desc,
|
||||
struct udevice *dev,
|
||||
uint offset)
|
||||
{
|
||||
desc->dev = dev;
|
||||
desc->offset = offset;
|
||||
desc->flags = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gpio_to_device() - Convert global GPIO number to device, number
|
||||
*
|
||||
|
@ -41,9 +58,7 @@ static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
|
|||
uc_priv = dev_get_uclass_priv(dev);
|
||||
if (gpio >= uc_priv->gpio_base &&
|
||||
gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
|
||||
desc->dev = dev;
|
||||
desc->offset = gpio - uc_priv->gpio_base;
|
||||
desc->flags = 0;
|
||||
gpio_desc_init(desc, dev, gpio - uc_priv->gpio_base);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -85,8 +100,7 @@ int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc)
|
|||
if (!dev)
|
||||
return ret ? ret : -EINVAL;
|
||||
|
||||
desc->dev = dev;
|
||||
desc->offset = offset;
|
||||
gpio_desc_init(desc, dev, offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -127,8 +141,27 @@ int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc,
|
|||
if (args->args_count < 2)
|
||||
return 0;
|
||||
|
||||
desc->flags = 0;
|
||||
if (args->args[1] & GPIO_ACTIVE_LOW)
|
||||
desc->flags = GPIOD_ACTIVE_LOW;
|
||||
desc->flags |= GPIOD_ACTIVE_LOW;
|
||||
|
||||
/*
|
||||
* need to test 2 bits for gpio output binding:
|
||||
* OPEN_DRAIN (0x6) = SINGLE_ENDED (0x2) | LINE_OPEN_DRAIN (0x4)
|
||||
* OPEN_SOURCE (0x2) = SINGLE_ENDED (0x2) | LINE_OPEN_SOURCE (0x0)
|
||||
*/
|
||||
if (args->args[1] & GPIO_SINGLE_ENDED) {
|
||||
if (args->args[1] & GPIO_LINE_OPEN_DRAIN)
|
||||
desc->flags |= GPIOD_OPEN_DRAIN;
|
||||
else
|
||||
desc->flags |= GPIOD_OPEN_SOURCE;
|
||||
}
|
||||
|
||||
if (args->args[1] & GPIO_PULL_UP)
|
||||
desc->flags |= GPIOD_PULL_UP;
|
||||
|
||||
if (args->args[1] & GPIO_PULL_DOWN)
|
||||
desc->flags |= GPIOD_PULL_DOWN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -463,18 +496,24 @@ int gpio_direction_output(unsigned gpio, int value)
|
|||
desc.offset, value);
|
||||
}
|
||||
|
||||
int dm_gpio_get_value(const struct gpio_desc *desc)
|
||||
static int _gpio_get_value(const struct gpio_desc *desc)
|
||||
{
|
||||
int value;
|
||||
|
||||
value = gpio_get_ops(desc->dev)->get_value(desc->dev, desc->offset);
|
||||
|
||||
return desc->flags & GPIOD_ACTIVE_LOW ? !value : value;
|
||||
}
|
||||
|
||||
int dm_gpio_get_value(const struct gpio_desc *desc)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = check_reserved(desc, "get_value");
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
value = gpio_get_ops(desc->dev)->get_value(desc->dev, desc->offset);
|
||||
|
||||
return desc->flags & GPIOD_ACTIVE_LOW ? !value : value;
|
||||
return _gpio_get_value(desc);
|
||||
}
|
||||
|
||||
int dm_gpio_set_value(const struct gpio_desc *desc, int value)
|
||||
|
@ -491,71 +530,128 @@ int dm_gpio_set_value(const struct gpio_desc *desc, int value)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int dm_gpio_get_open_drain(struct gpio_desc *desc)
|
||||
/* check dir flags invalid configuration */
|
||||
static int check_dir_flags(ulong flags)
|
||||
{
|
||||
struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
|
||||
int ret;
|
||||
if ((flags & GPIOD_IS_OUT) && (flags & GPIOD_IS_IN)) {
|
||||
log_debug("%s: flags 0x%lx has GPIOD_IS_OUT and GPIOD_IS_IN\n",
|
||||
__func__, flags);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = check_reserved(desc, "get_open_drain");
|
||||
if (ret)
|
||||
return ret;
|
||||
if ((flags & GPIOD_PULL_UP) && (flags & GPIOD_PULL_DOWN)) {
|
||||
log_debug("%s: flags 0x%lx has GPIOD_PULL_UP and GPIOD_PULL_DOWN\n",
|
||||
__func__, flags);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ops->set_open_drain)
|
||||
return ops->get_open_drain(desc->dev, desc->offset);
|
||||
else
|
||||
return -ENOSYS;
|
||||
if ((flags & GPIOD_OPEN_DRAIN) && (flags & GPIOD_OPEN_SOURCE)) {
|
||||
log_debug("%s: flags 0x%lx has GPIOD_OPEN_DRAIN and GPIOD_OPEN_SOURCE\n",
|
||||
__func__, flags);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dm_gpio_set_open_drain(struct gpio_desc *desc, int value)
|
||||
static int _dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
|
||||
{
|
||||
struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
|
||||
int ret;
|
||||
struct udevice *dev = desc->dev;
|
||||
struct dm_gpio_ops *ops = gpio_get_ops(dev);
|
||||
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
|
||||
int ret = 0;
|
||||
|
||||
ret = check_dir_flags(flags);
|
||||
if (ret) {
|
||||
dev_dbg(dev,
|
||||
"%s error: set_dir_flags for gpio %s%d has invalid dir flags 0x%lx\n",
|
||||
desc->dev->name,
|
||||
uc_priv->bank_name ? uc_priv->bank_name : "",
|
||||
desc->offset, flags);
|
||||
|
||||
ret = check_reserved(desc, "set_open_drain");
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ops->set_open_drain)
|
||||
ret = ops->set_open_drain(desc->dev, desc->offset, value);
|
||||
else
|
||||
return 0; /* feature not supported -> ignore setting */
|
||||
/* GPIOD_ are directly managed by driver in set_dir_flags*/
|
||||
if (ops->set_dir_flags) {
|
||||
ret = ops->set_dir_flags(dev, desc->offset, flags);
|
||||
} else {
|
||||
if (flags & GPIOD_IS_OUT) {
|
||||
ret = ops->direction_output(dev, desc->offset,
|
||||
GPIOD_FLAGS_OUTPUT(flags));
|
||||
} else if (flags & GPIOD_IS_IN) {
|
||||
ret = ops->direction_input(dev, desc->offset);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
|
||||
{
|
||||
struct udevice *dev = desc->dev;
|
||||
struct dm_gpio_ops *ops = gpio_get_ops(dev);
|
||||
int ret;
|
||||
|
||||
ret = check_reserved(desc, "set_dir_flags");
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* combine the requested flags (for IN/OUT) and the descriptor flags */
|
||||
flags |= desc->flags;
|
||||
ret = _dm_gpio_set_dir_flags(desc, flags);
|
||||
|
||||
/* update the descriptor flags */
|
||||
if (ret)
|
||||
desc->flags = flags;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dm_gpio_set_dir(struct gpio_desc *desc)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = check_reserved(desc, "set_dir");
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (flags & GPIOD_IS_OUT) {
|
||||
int value = flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0;
|
||||
|
||||
if (flags & GPIOD_ACTIVE_LOW)
|
||||
value = !value;
|
||||
ret = ops->direction_output(dev, desc->offset, value);
|
||||
} else if (flags & GPIOD_IS_IN) {
|
||||
ret = ops->direction_input(dev, desc->offset);
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
/*
|
||||
* Update desc->flags here, so that GPIO_ACTIVE_LOW is honoured in
|
||||
* futures
|
||||
*/
|
||||
desc->flags = flags;
|
||||
|
||||
return 0;
|
||||
return _dm_gpio_set_dir_flags(desc, desc->flags);
|
||||
}
|
||||
|
||||
int dm_gpio_set_dir(struct gpio_desc *desc)
|
||||
int dm_gpio_get_dir_flags(struct gpio_desc *desc, ulong *flags)
|
||||
{
|
||||
return dm_gpio_set_dir_flags(desc, desc->flags);
|
||||
struct udevice *dev = desc->dev;
|
||||
int ret, value;
|
||||
struct dm_gpio_ops *ops = gpio_get_ops(dev);
|
||||
ulong dir_flags;
|
||||
|
||||
ret = check_reserved(desc, "get_dir_flags");
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* GPIOD_ are directly provided by driver except GPIOD_ACTIVE_LOW */
|
||||
if (ops->get_dir_flags) {
|
||||
ret = ops->get_dir_flags(dev, desc->offset, &dir_flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* GPIOD_ACTIVE_LOW is saved in desc->flags */
|
||||
value = dir_flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0;
|
||||
if (desc->flags & GPIOD_ACTIVE_LOW)
|
||||
value = !value;
|
||||
dir_flags &= ~(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE);
|
||||
dir_flags |= (desc->flags & GPIOD_ACTIVE_LOW);
|
||||
if (value)
|
||||
dir_flags |= GPIOD_IS_OUT_ACTIVE;
|
||||
} else {
|
||||
dir_flags = desc->flags;
|
||||
/* only GPIOD_IS_OUT_ACTIVE is provided by uclass */
|
||||
dir_flags &= ~GPIOD_IS_OUT_ACTIVE;
|
||||
if ((desc->flags & GPIOD_IS_OUT) && _gpio_get_value(desc))
|
||||
dir_flags |= GPIOD_IS_OUT_ACTIVE;
|
||||
}
|
||||
*flags = dir_flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -804,9 +900,7 @@ static int gpio_request_tail(int ret, const char *nodename,
|
|||
struct gpio_desc *desc, int flags,
|
||||
bool add_index, struct udevice *gpio_dev)
|
||||
{
|
||||
desc->dev = gpio_dev;
|
||||
desc->offset = 0;
|
||||
desc->flags = 0;
|
||||
gpio_desc_init(desc, gpio_dev, 0);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
|
@ -830,7 +924,7 @@ static int gpio_request_tail(int ret, const char *nodename,
|
|||
debug("%s: dm_gpio_requestf failed\n", __func__);
|
||||
goto err;
|
||||
}
|
||||
ret = dm_gpio_set_dir_flags(desc, flags | desc->flags);
|
||||
ret = dm_gpio_set_dir_flags(desc, flags);
|
||||
if (ret) {
|
||||
debug("%s: dm_gpio_set_dir failed\n", __func__);
|
||||
goto err;
|
||||
|
@ -1053,14 +1147,14 @@ static int gpio_post_bind(struct udevice *dev)
|
|||
ops->get_value += gd->reloc_off;
|
||||
if (ops->set_value)
|
||||
ops->set_value += gd->reloc_off;
|
||||
if (ops->get_open_drain)
|
||||
ops->get_open_drain += gd->reloc_off;
|
||||
if (ops->set_open_drain)
|
||||
ops->set_open_drain += gd->reloc_off;
|
||||
if (ops->get_function)
|
||||
ops->get_function += gd->reloc_off;
|
||||
if (ops->xlate)
|
||||
ops->xlate += gd->reloc_off;
|
||||
if (ops->set_dir_flags)
|
||||
ops->set_dir_flags += gd->reloc_off;
|
||||
if (ops->get_dir_flags)
|
||||
ops->get_dir_flags += gd->reloc_off;
|
||||
|
||||
reloc_done++;
|
||||
}
|
||||
|
|
|
@ -133,26 +133,6 @@ static int mpc8xxx_gpio_get_value(struct udevice *dev, uint gpio)
|
|||
return !!mpc8xxx_gpio_get_val(data->base, gpio_mask(gpio));
|
||||
}
|
||||
|
||||
static int mpc8xxx_gpio_get_open_drain(struct udevice *dev, uint gpio)
|
||||
{
|
||||
struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
|
||||
|
||||
return !!mpc8xxx_gpio_open_drain_val(data->base, gpio_mask(gpio));
|
||||
}
|
||||
|
||||
static int mpc8xxx_gpio_set_open_drain(struct udevice *dev, uint gpio,
|
||||
int value)
|
||||
{
|
||||
struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
|
||||
|
||||
if (value)
|
||||
mpc8xxx_gpio_open_drain_on(data->base, gpio_mask(gpio));
|
||||
else
|
||||
mpc8xxx_gpio_open_drain_off(data->base, gpio_mask(gpio));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpc8xxx_gpio_get_function(struct udevice *dev, uint gpio)
|
||||
{
|
||||
struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
|
||||
|
@ -229,8 +209,6 @@ static const struct dm_gpio_ops gpio_mpc8xxx_ops = {
|
|||
.direction_output = mpc8xxx_gpio_direction_output,
|
||||
.get_value = mpc8xxx_gpio_get_value,
|
||||
.set_value = mpc8xxx_gpio_set_value,
|
||||
.get_open_drain = mpc8xxx_gpio_get_open_drain,
|
||||
.set_open_drain = mpc8xxx_gpio_set_open_drain,
|
||||
.get_function = mpc8xxx_gpio_get_function,
|
||||
};
|
||||
|
||||
|
|
|
@ -8,43 +8,44 @@
|
|||
#include <fdtdec.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <dm/device_compat.h>
|
||||
#include <dm/lists.h>
|
||||
#include <dm/of.h>
|
||||
#include <dm/pinctrl.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/gpio/sandbox-gpio.h>
|
||||
|
||||
/* Flags for each GPIO */
|
||||
#define GPIOF_OUTPUT (1 << 0) /* Currently set as an output */
|
||||
#define GPIOF_HIGH (1 << 1) /* Currently set high */
|
||||
#define GPIOF_ODR (1 << 2) /* Currently set to open drain mode */
|
||||
|
||||
struct gpio_state {
|
||||
const char *label; /* label given by requester */
|
||||
u8 flags; /* flags (GPIOF_...) */
|
||||
ulong dir_flags; /* dir_flags (GPIOD_...) */
|
||||
};
|
||||
|
||||
/* Access routines for GPIO state */
|
||||
static u8 *get_gpio_flags(struct udevice *dev, unsigned offset)
|
||||
/* Access routines for GPIO dir flags */
|
||||
static ulong *get_gpio_dir_flags(struct udevice *dev, unsigned int offset)
|
||||
{
|
||||
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
|
||||
struct gpio_state *state = dev_get_priv(dev);
|
||||
|
||||
if (offset >= uc_priv->gpio_count) {
|
||||
static u8 invalid_flags;
|
||||
static ulong invalid_dir_flags;
|
||||
printf("sandbox_gpio: error: invalid gpio %u\n", offset);
|
||||
return &invalid_flags;
|
||||
return &invalid_dir_flags;
|
||||
}
|
||||
|
||||
return &state[offset].flags;
|
||||
return &state[offset].dir_flags;
|
||||
|
||||
}
|
||||
|
||||
static int get_gpio_flag(struct udevice *dev, unsigned offset, int flag)
|
||||
static int get_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag)
|
||||
{
|
||||
return (*get_gpio_flags(dev, offset) & flag) != 0;
|
||||
return (*get_gpio_dir_flags(dev, offset) & flag) != 0;
|
||||
}
|
||||
|
||||
static int set_gpio_flag(struct udevice *dev, unsigned offset, int flag,
|
||||
static int set_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag,
|
||||
int value)
|
||||
{
|
||||
u8 *gpio = get_gpio_flags(dev, offset);
|
||||
ulong *gpio = get_gpio_dir_flags(dev, offset);
|
||||
|
||||
if (value)
|
||||
*gpio |= flag;
|
||||
|
@ -60,34 +61,40 @@ static int set_gpio_flag(struct udevice *dev, unsigned offset, int flag,
|
|||
|
||||
int sandbox_gpio_get_value(struct udevice *dev, unsigned offset)
|
||||
{
|
||||
if (get_gpio_flag(dev, offset, GPIOF_OUTPUT))
|
||||
if (get_gpio_flag(dev, offset, GPIOD_IS_OUT))
|
||||
debug("sandbox_gpio: get_value on output gpio %u\n", offset);
|
||||
return get_gpio_flag(dev, offset, GPIOF_HIGH);
|
||||
return get_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE);
|
||||
}
|
||||
|
||||
int sandbox_gpio_set_value(struct udevice *dev, unsigned offset, int value)
|
||||
{
|
||||
return set_gpio_flag(dev, offset, GPIOF_HIGH, value);
|
||||
}
|
||||
|
||||
int sandbox_gpio_get_open_drain(struct udevice *dev, unsigned offset)
|
||||
{
|
||||
return get_gpio_flag(dev, offset, GPIOF_ODR);
|
||||
}
|
||||
|
||||
int sandbox_gpio_set_open_drain(struct udevice *dev, unsigned offset, int value)
|
||||
{
|
||||
return set_gpio_flag(dev, offset, GPIOF_ODR, value);
|
||||
return set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE, value);
|
||||
}
|
||||
|
||||
int sandbox_gpio_get_direction(struct udevice *dev, unsigned offset)
|
||||
{
|
||||
return get_gpio_flag(dev, offset, GPIOF_OUTPUT);
|
||||
return get_gpio_flag(dev, offset, GPIOD_IS_OUT);
|
||||
}
|
||||
|
||||
int sandbox_gpio_set_direction(struct udevice *dev, unsigned offset, int output)
|
||||
{
|
||||
return set_gpio_flag(dev, offset, GPIOF_OUTPUT, output);
|
||||
set_gpio_flag(dev, offset, GPIOD_IS_OUT, output);
|
||||
set_gpio_flag(dev, offset, GPIOD_IS_IN, !(output));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ulong sandbox_gpio_get_dir_flags(struct udevice *dev, unsigned int offset)
|
||||
{
|
||||
return *get_gpio_dir_flags(dev, offset);
|
||||
}
|
||||
|
||||
int sandbox_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
|
||||
ulong flags)
|
||||
{
|
||||
*get_gpio_dir_flags(dev, offset) = flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -134,33 +141,14 @@ static int sb_gpio_set_value(struct udevice *dev, unsigned offset, int value)
|
|||
return sandbox_gpio_set_value(dev, offset, value);
|
||||
}
|
||||
|
||||
/* read GPIO ODR value of port 'offset' */
|
||||
static int sb_gpio_get_open_drain(struct udevice *dev, unsigned offset)
|
||||
{
|
||||
debug("%s: offset:%u\n", __func__, offset);
|
||||
|
||||
return sandbox_gpio_get_open_drain(dev, offset);
|
||||
}
|
||||
|
||||
/* write GPIO ODR value to port 'offset' */
|
||||
static int sb_gpio_set_open_drain(struct udevice *dev, unsigned offset, int value)
|
||||
{
|
||||
debug("%s: offset:%u, value = %d\n", __func__, offset, value);
|
||||
|
||||
if (!sandbox_gpio_get_direction(dev, offset)) {
|
||||
printf("sandbox_gpio: error: set_open_drain on input gpio %u\n",
|
||||
offset);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sandbox_gpio_set_open_drain(dev, offset, value);
|
||||
}
|
||||
|
||||
static int sb_gpio_get_function(struct udevice *dev, unsigned offset)
|
||||
{
|
||||
if (get_gpio_flag(dev, offset, GPIOF_OUTPUT))
|
||||
if (get_gpio_flag(dev, offset, GPIOD_IS_OUT))
|
||||
return GPIOF_OUTPUT;
|
||||
return GPIOF_INPUT;
|
||||
if (get_gpio_flag(dev, offset, GPIOD_IS_IN))
|
||||
return GPIOF_INPUT;
|
||||
|
||||
return GPIOF_INPUT; /*GPIO is not configurated */
|
||||
}
|
||||
|
||||
static int sb_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
|
||||
|
@ -169,27 +157,54 @@ static int sb_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
|
|||
desc->offset = args->args[0];
|
||||
if (args->args_count < 2)
|
||||
return 0;
|
||||
if (args->args[1] & GPIO_ACTIVE_LOW)
|
||||
desc->flags |= GPIOD_ACTIVE_LOW;
|
||||
if (args->args[1] & 2)
|
||||
/* treat generic binding with gpio uclass */
|
||||
gpio_xlate_offs_flags(dev, desc, args);
|
||||
|
||||
/* sandbox test specific, not defined in gpio.h */
|
||||
if (args->args[1] & GPIO_IN)
|
||||
desc->flags |= GPIOD_IS_IN;
|
||||
if (args->args[1] & 4)
|
||||
|
||||
if (args->args[1] & GPIO_OUT)
|
||||
desc->flags |= GPIOD_IS_OUT;
|
||||
if (args->args[1] & 8)
|
||||
|
||||
if (args->args[1] & GPIO_OUT_ACTIVE)
|
||||
desc->flags |= GPIOD_IS_OUT_ACTIVE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sb_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
|
||||
ulong flags)
|
||||
{
|
||||
ulong *dir_flags;
|
||||
|
||||
debug("%s: offset:%u, dir_flags = %lx\n", __func__, offset, flags);
|
||||
|
||||
dir_flags = get_gpio_dir_flags(dev, offset);
|
||||
|
||||
*dir_flags = flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sb_gpio_get_dir_flags(struct udevice *dev, unsigned int offset,
|
||||
ulong *flags)
|
||||
{
|
||||
debug("%s: offset:%u\n", __func__, offset);
|
||||
*flags = *get_gpio_dir_flags(dev, offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dm_gpio_ops gpio_sandbox_ops = {
|
||||
.direction_input = sb_gpio_direction_input,
|
||||
.direction_output = sb_gpio_direction_output,
|
||||
.get_value = sb_gpio_get_value,
|
||||
.set_value = sb_gpio_set_value,
|
||||
.get_open_drain = sb_gpio_get_open_drain,
|
||||
.set_open_drain = sb_gpio_set_open_drain,
|
||||
.get_function = sb_gpio_get_function,
|
||||
.xlate = sb_gpio_xlate,
|
||||
.set_dir_flags = sb_gpio_set_dir_flags,
|
||||
.get_dir_flags = sb_gpio_get_dir_flags,
|
||||
};
|
||||
|
||||
static int sandbox_gpio_ofdata_to_platdata(struct udevice *dev)
|
||||
|
@ -237,3 +252,198 @@ U_BOOT_DRIVER(gpio_sandbox) = {
|
|||
.remove = gpio_sandbox_remove,
|
||||
.ops = &gpio_sandbox_ops,
|
||||
};
|
||||
|
||||
/* pincontrol: used only to check GPIO pin configuration (pinmux command) */
|
||||
|
||||
struct sb_pinctrl_priv {
|
||||
int pinctrl_ngpios;
|
||||
struct list_head gpio_dev;
|
||||
};
|
||||
|
||||
struct sb_gpio_bank {
|
||||
struct udevice *gpio_dev;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
static int sb_populate_gpio_dev_list(struct udevice *dev)
|
||||
{
|
||||
struct sb_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
struct udevice *gpio_dev;
|
||||
struct udevice *child;
|
||||
struct sb_gpio_bank *gpio_bank;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* parse pin-controller sub-nodes (ie gpio bank nodes) and fill
|
||||
* a list with all gpio device reference which belongs to the
|
||||
* current pin-controller. This list is used to find pin_name and
|
||||
* pin muxing
|
||||
*/
|
||||
list_for_each_entry(child, &dev->child_head, sibling_node) {
|
||||
ret = uclass_get_device_by_name(UCLASS_GPIO, child->name,
|
||||
&gpio_dev);
|
||||
if (ret < 0)
|
||||
continue;
|
||||
|
||||
gpio_bank = malloc(sizeof(*gpio_bank));
|
||||
if (!gpio_bank) {
|
||||
dev_err(dev, "Not enough memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
gpio_bank->gpio_dev = gpio_dev;
|
||||
list_add_tail(&gpio_bank->list, &priv->gpio_dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sb_pinctrl_get_pins_count(struct udevice *dev)
|
||||
{
|
||||
struct sb_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
struct gpio_dev_priv *uc_priv;
|
||||
struct sb_gpio_bank *gpio_bank;
|
||||
|
||||
/*
|
||||
* if get_pins_count has already been executed once on this
|
||||
* pin-controller, no need to run it again
|
||||
*/
|
||||
if (priv->pinctrl_ngpios)
|
||||
return priv->pinctrl_ngpios;
|
||||
|
||||
if (list_empty(&priv->gpio_dev))
|
||||
sb_populate_gpio_dev_list(dev);
|
||||
/*
|
||||
* walk through all banks to retrieve the pin-controller
|
||||
* pins number
|
||||
*/
|
||||
list_for_each_entry(gpio_bank, &priv->gpio_dev, list) {
|
||||
uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev);
|
||||
|
||||
priv->pinctrl_ngpios += uc_priv->gpio_count;
|
||||
}
|
||||
|
||||
return priv->pinctrl_ngpios;
|
||||
}
|
||||
|
||||
static struct udevice *sb_pinctrl_get_gpio_dev(struct udevice *dev,
|
||||
unsigned int selector,
|
||||
unsigned int *idx)
|
||||
{
|
||||
struct sb_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
struct sb_gpio_bank *gpio_bank;
|
||||
struct gpio_dev_priv *uc_priv;
|
||||
int pin_count = 0;
|
||||
|
||||
if (list_empty(&priv->gpio_dev))
|
||||
sb_populate_gpio_dev_list(dev);
|
||||
|
||||
/* look up for the bank which owns the requested pin */
|
||||
list_for_each_entry(gpio_bank, &priv->gpio_dev, list) {
|
||||
uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev);
|
||||
|
||||
if (selector < (pin_count + uc_priv->gpio_count)) {
|
||||
/*
|
||||
* we found the bank, convert pin selector to
|
||||
* gpio bank index
|
||||
*/
|
||||
*idx = selector - pin_count;
|
||||
|
||||
return gpio_bank->gpio_dev;
|
||||
}
|
||||
pin_count += uc_priv->gpio_count;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *sb_pinctrl_get_pin_name(struct udevice *dev,
|
||||
unsigned int selector)
|
||||
{
|
||||
struct gpio_dev_priv *uc_priv;
|
||||
struct udevice *gpio_dev;
|
||||
unsigned int gpio_idx;
|
||||
static char pin_name[PINNAME_SIZE];
|
||||
|
||||
/* look up for the bank which owns the requested pin */
|
||||
gpio_dev = sb_pinctrl_get_gpio_dev(dev, selector, &gpio_idx);
|
||||
if (!gpio_dev) {
|
||||
snprintf(pin_name, PINNAME_SIZE, "Error");
|
||||
} else {
|
||||
uc_priv = dev_get_uclass_priv(gpio_dev);
|
||||
|
||||
snprintf(pin_name, PINNAME_SIZE, "%s%d",
|
||||
uc_priv->bank_name,
|
||||
gpio_idx);
|
||||
}
|
||||
|
||||
return pin_name;
|
||||
}
|
||||
|
||||
static char *get_dir_flags_string(ulong flags)
|
||||
{
|
||||
if (flags & GPIOD_OPEN_DRAIN)
|
||||
return "drive-open-drain";
|
||||
if (flags & GPIOD_OPEN_SOURCE)
|
||||
return "drive-open-source";
|
||||
if (flags & GPIOD_PULL_UP)
|
||||
return "bias-pull-up";
|
||||
if (flags & GPIOD_PULL_DOWN)
|
||||
return "bias-pull-down";
|
||||
return ".";
|
||||
}
|
||||
|
||||
static int sb_pinctrl_get_pin_muxing(struct udevice *dev,
|
||||
unsigned int selector,
|
||||
char *buf, int size)
|
||||
{
|
||||
struct udevice *gpio_dev;
|
||||
unsigned int gpio_idx;
|
||||
ulong dir_flags;
|
||||
int function;
|
||||
|
||||
/* look up for the bank which owns the requested pin */
|
||||
gpio_dev = sb_pinctrl_get_gpio_dev(dev, selector, &gpio_idx);
|
||||
if (!gpio_dev) {
|
||||
snprintf(buf, size, "Error");
|
||||
} else {
|
||||
function = sb_gpio_get_function(gpio_dev, gpio_idx);
|
||||
dir_flags = *get_gpio_dir_flags(gpio_dev, gpio_idx);
|
||||
|
||||
snprintf(buf, size, "gpio %s %s",
|
||||
function == GPIOF_OUTPUT ? "output" : "input",
|
||||
get_dir_flags_string(dir_flags));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sandbox_pinctrl_probe(struct udevice *dev)
|
||||
{
|
||||
struct sb_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
|
||||
INIT_LIST_HEAD(&priv->gpio_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct pinctrl_ops sandbox_pinctrl_gpio_ops = {
|
||||
.get_pin_name = sb_pinctrl_get_pin_name,
|
||||
.get_pins_count = sb_pinctrl_get_pins_count,
|
||||
.get_pin_muxing = sb_pinctrl_get_pin_muxing,
|
||||
};
|
||||
|
||||
static const struct udevice_id sandbox_pinctrl_gpio_match[] = {
|
||||
{ .compatible = "sandbox,pinctrl-gpio" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sandbox_pinctrl_gpio) = {
|
||||
.name = "sandbox_pinctrl_gpio",
|
||||
.id = UCLASS_PINCTRL,
|
||||
.of_match = sandbox_pinctrl_gpio_match,
|
||||
.ops = &sandbox_pinctrl_gpio_ops,
|
||||
.bind = dm_scan_fdt_dev,
|
||||
.probe = sandbox_pinctrl_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct sb_pinctrl_priv),
|
||||
};
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
#include <linux/compat.h>
|
||||
#include <dm/pinctrl.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/**
|
||||
* pinctrl_pin_name_to_selector() - return the pin selector for a pin
|
||||
*
|
||||
|
@ -244,18 +242,14 @@ static int pinctrl_generic_set_state_one(struct udevice *dev,
|
|||
struct udevice *config,
|
||||
bool is_group, unsigned selector)
|
||||
{
|
||||
const void *fdt = gd->fdt_blob;
|
||||
int node_offset = dev_of_offset(config);
|
||||
const char *propname;
|
||||
const void *value;
|
||||
int prop_offset, len, func_selector, param, ret;
|
||||
struct ofprop property;
|
||||
int len, func_selector, param, ret;
|
||||
u32 arg, default_val;
|
||||
|
||||
for (prop_offset = fdt_first_property_offset(fdt, node_offset);
|
||||
prop_offset > 0;
|
||||
prop_offset = fdt_next_property_offset(fdt, prop_offset)) {
|
||||
value = fdt_getprop_by_offset(fdt, prop_offset,
|
||||
&propname, &len);
|
||||
dev_for_each_property(property, config) {
|
||||
value = dev_read_prop_by_prop(&property, &propname, &len);
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -299,19 +293,17 @@ static int pinctrl_generic_set_state_one(struct udevice *dev,
|
|||
static int pinctrl_generic_set_state_subnode(struct udevice *dev,
|
||||
struct udevice *config)
|
||||
{
|
||||
const void *fdt = gd->fdt_blob;
|
||||
int node = dev_of_offset(config);
|
||||
const char *subnode_target_type = "pins";
|
||||
bool is_group = false;
|
||||
const char *name;
|
||||
int strings_count, selector, i, ret;
|
||||
|
||||
strings_count = fdt_stringlist_count(fdt, node, subnode_target_type);
|
||||
strings_count = dev_read_string_count(config, subnode_target_type);
|
||||
if (strings_count < 0) {
|
||||
subnode_target_type = "groups";
|
||||
is_group = true;
|
||||
strings_count = fdt_stringlist_count(fdt, node,
|
||||
subnode_target_type);
|
||||
strings_count = dev_read_string_count(config,
|
||||
subnode_target_type);
|
||||
if (strings_count < 0) {
|
||||
/* skip this node; may contain config child nodes */
|
||||
return 0;
|
||||
|
@ -319,10 +311,10 @@ static int pinctrl_generic_set_state_subnode(struct udevice *dev,
|
|||
}
|
||||
|
||||
for (i = 0; i < strings_count; i++) {
|
||||
name = fdt_stringlist_get(fdt, node, subnode_target_type, i,
|
||||
NULL);
|
||||
if (!name)
|
||||
return -EINVAL;
|
||||
ret = dev_read_string_index(config, subnode_target_type, i,
|
||||
&name);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (is_group)
|
||||
selector = pinctrl_group_name_to_selector(dev, name);
|
||||
|
|
|
@ -14,7 +14,11 @@ static const char * const sandbox_pins[] = {
|
|||
"SDA",
|
||||
"TX",
|
||||
"RX",
|
||||
"W1"
|
||||
"W1",
|
||||
"GPIO0",
|
||||
"GPIO1",
|
||||
"GPIO2",
|
||||
"GPIO3",
|
||||
};
|
||||
|
||||
static const char * const sandbox_pins_muxing[] = {
|
||||
|
@ -23,6 +27,10 @@ static const char * const sandbox_pins_muxing[] = {
|
|||
"Uart TX",
|
||||
"Uart RX",
|
||||
"1-wire gpio",
|
||||
"gpio",
|
||||
"gpio",
|
||||
"gpio",
|
||||
"gpio",
|
||||
};
|
||||
|
||||
static const char * const sandbox_groups[] = {
|
||||
|
@ -38,6 +46,10 @@ static const char * const sandbox_functions[] = {
|
|||
"serial",
|
||||
"spi",
|
||||
"w1",
|
||||
"gpio",
|
||||
"gpio",
|
||||
"gpio",
|
||||
"gpio",
|
||||
};
|
||||
|
||||
static const struct pinconf_param sandbox_conf_params[] = {
|
||||
|
@ -54,6 +66,10 @@ static const struct pinconf_param sandbox_conf_params[] = {
|
|||
{ "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
|
||||
};
|
||||
|
||||
/* bitfield used to save param and value of each pin/selector */
|
||||
static unsigned int sandbox_pins_param[ARRAY_SIZE(sandbox_pins)];
|
||||
static unsigned int sandbox_pins_value[ARRAY_SIZE(sandbox_pins)];
|
||||
|
||||
static int sandbox_get_pins_count(struct udevice *dev)
|
||||
{
|
||||
return ARRAY_SIZE(sandbox_pins);
|
||||
|
@ -68,8 +84,25 @@ static int sandbox_get_pin_muxing(struct udevice *dev,
|
|||
unsigned int selector,
|
||||
char *buf, int size)
|
||||
{
|
||||
const struct pinconf_param *p;
|
||||
int i;
|
||||
|
||||
snprintf(buf, size, "%s", sandbox_pins_muxing[selector]);
|
||||
|
||||
if (sandbox_pins_param[selector]) {
|
||||
for (i = 0, p = sandbox_conf_params;
|
||||
i < ARRAY_SIZE(sandbox_conf_params);
|
||||
i++, p++) {
|
||||
if ((sandbox_pins_param[selector] & BIT(p->param)) &&
|
||||
(!!(sandbox_pins_value[selector] & BIT(p->param)) ==
|
||||
p->default_value)) {
|
||||
strncat(buf, " ", size);
|
||||
strncat(buf, p->property, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
strncat(buf, ".", size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -102,6 +135,9 @@ static int sandbox_pinmux_set(struct udevice *dev, unsigned pin_selector,
|
|||
pin_selector, sandbox_get_pin_name(dev, pin_selector),
|
||||
func_selector, sandbox_get_function_name(dev, func_selector));
|
||||
|
||||
sandbox_pins_param[pin_selector] = 0;
|
||||
sandbox_pins_value[pin_selector] = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -123,6 +159,12 @@ static int sandbox_pinconf_set(struct udevice *dev, unsigned pin_selector,
|
|||
pin_selector, sandbox_get_pin_name(dev, pin_selector),
|
||||
param, argument);
|
||||
|
||||
sandbox_pins_param[pin_selector] |= BIT(param);
|
||||
if (argument)
|
||||
sandbox_pins_value[pin_selector] |= BIT(param);
|
||||
else
|
||||
sandbox_pins_value[pin_selector] &= ~BIT(param);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
#include <linux/libfdt.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
struct single_pdata {
|
||||
fdt_addr_t base; /* first configuration register */
|
||||
int offset; /* index of last configuration register */
|
||||
|
@ -118,13 +116,11 @@ static int single_configure_bits(struct udevice *dev,
|
|||
static int single_set_state(struct udevice *dev,
|
||||
struct udevice *config)
|
||||
{
|
||||
const void *fdt = gd->fdt_blob;
|
||||
const struct single_fdt_pin_cfg *prop;
|
||||
const struct single_fdt_bits_cfg *prop_bits;
|
||||
int len;
|
||||
|
||||
prop = fdt_getprop(fdt, dev_of_offset(config), "pinctrl-single,pins",
|
||||
&len);
|
||||
prop = dev_read_prop(dev, "pinctrl-single,pins", &len);
|
||||
|
||||
if (prop) {
|
||||
dev_dbg(dev, "configuring pins for %s\n", config->name);
|
||||
|
@ -137,9 +133,7 @@ static int single_set_state(struct udevice *dev,
|
|||
}
|
||||
|
||||
/* pinctrl-single,pins not found so check for pinctrl-single,bits */
|
||||
prop_bits = fdt_getprop(fdt, dev_of_offset(config),
|
||||
"pinctrl-single,bits",
|
||||
&len);
|
||||
prop_bits = dev_read_prop(dev, "pinctrl-single,bits", &len);
|
||||
if (prop_bits) {
|
||||
dev_dbg(dev, "configuring pins for %s\n", config->name);
|
||||
if (len % sizeof(struct single_fdt_bits_cfg)) {
|
||||
|
@ -161,27 +155,24 @@ static int single_ofdata_to_platdata(struct udevice *dev)
|
|||
int res;
|
||||
struct single_pdata *pdata = dev->platdata;
|
||||
|
||||
pdata->width = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
|
||||
"pinctrl-single,register-width", 0);
|
||||
pdata->width =
|
||||
dev_read_u32_default(dev, "pinctrl-single,register-width", 0);
|
||||
|
||||
res = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev),
|
||||
"reg", of_reg, 2);
|
||||
res = dev_read_u32_array(dev, "reg", of_reg, 2);
|
||||
if (res)
|
||||
return res;
|
||||
pdata->offset = of_reg[1] - pdata->width / 8;
|
||||
|
||||
addr = devfdt_get_addr(dev);
|
||||
addr = dev_read_addr(dev);
|
||||
if (addr == FDT_ADDR_T_NONE) {
|
||||
dev_dbg(dev, "no valid base register address\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
pdata->base = addr;
|
||||
|
||||
pdata->mask = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
|
||||
"pinctrl-single,function-mask",
|
||||
0xffffffff);
|
||||
pdata->bits_per_mux = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
|
||||
"pinctrl-single,bit-per-mux");
|
||||
pdata->mask = dev_read_u32_default(dev, "pinctrl-single,function-mask",
|
||||
0xffffffff);
|
||||
pdata->bits_per_mux = dev_read_bool(dev, "pinctrl-single,bit-per-mux");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -9,39 +9,47 @@
|
|||
#include <malloc.h>
|
||||
#include <linux/lzo.h>
|
||||
#include <linux/zstd.h>
|
||||
#include <linux/compat.h>
|
||||
#include <u-boot/zlib.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
/* Header for each segment, LE32, recording the compressed size */
|
||||
#define LZO_LEN 4
|
||||
static u32 decompress_lzo(const u8 *cbuf, u32 clen, u8 *dbuf, u32 dlen)
|
||||
{
|
||||
u32 tot_len, in_len, res;
|
||||
u32 tot_len, tot_in, in_len, res;
|
||||
size_t out_len;
|
||||
int ret;
|
||||
|
||||
if (clen < 4)
|
||||
if (clen < LZO_LEN)
|
||||
return -1;
|
||||
|
||||
tot_len = le32_to_cpu(get_unaligned((u32 *)cbuf));
|
||||
cbuf += 4;
|
||||
clen -= 4;
|
||||
tot_len -= 4;
|
||||
tot_in = 0;
|
||||
cbuf += LZO_LEN;
|
||||
clen -= LZO_LEN;
|
||||
tot_len -= LZO_LEN;
|
||||
tot_in += LZO_LEN;
|
||||
|
||||
if (tot_len == 0 && dlen)
|
||||
return -1;
|
||||
if (tot_len < 4)
|
||||
if (tot_len < LZO_LEN)
|
||||
return -1;
|
||||
|
||||
res = 0;
|
||||
|
||||
while (tot_len > 4) {
|
||||
in_len = le32_to_cpu(get_unaligned((u32 *)cbuf));
|
||||
cbuf += 4;
|
||||
clen -= 4;
|
||||
while (tot_len > LZO_LEN) {
|
||||
u32 rem_page;
|
||||
|
||||
if (in_len > clen || tot_len < 4 + in_len)
|
||||
in_len = le32_to_cpu(get_unaligned((u32 *)cbuf));
|
||||
cbuf += LZO_LEN;
|
||||
clen -= LZO_LEN;
|
||||
|
||||
if (in_len > clen || tot_len < LZO_LEN + in_len)
|
||||
return -1;
|
||||
|
||||
tot_len -= 4 + in_len;
|
||||
tot_len -= (LZO_LEN + in_len);
|
||||
tot_in += (LZO_LEN + in_len);
|
||||
|
||||
out_len = dlen;
|
||||
ret = lzo1x_decompress_safe(cbuf, in_len, dbuf, &out_len);
|
||||
|
@ -54,6 +62,18 @@ static u32 decompress_lzo(const u8 *cbuf, u32 clen, u8 *dbuf, u32 dlen)
|
|||
dlen -= out_len;
|
||||
|
||||
res += out_len;
|
||||
|
||||
/*
|
||||
* If the 4 bytes header does not fit to the rest of the page we
|
||||
* have to move to next one, or we read some garbage.
|
||||
*/
|
||||
rem_page = PAGE_SIZE - (tot_in % PAGE_SIZE);
|
||||
if (rem_page < LZO_LEN) {
|
||||
cbuf += rem_page;
|
||||
tot_in += rem_page;
|
||||
clen -= rem_page;
|
||||
tot_len -= rem_page;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "btrfs.h"
|
||||
#include <memalign.h>
|
||||
#include <linux/compat.h>
|
||||
|
||||
#define BTRFS_SUPER_FLAG_SUPP (BTRFS_HEADER_FLAG_WRITTEN \
|
||||
| BTRFS_HEADER_FLAG_RELOC \
|
||||
|
@ -232,6 +233,13 @@ int btrfs_read_superblock(void)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (sb->sectorsize != PAGE_SIZE) {
|
||||
printf(
|
||||
"%s: Unsupported sector size (%u), only supports %u as sector size\n",
|
||||
__func__, sb->sectorsize, PAGE_SIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (btrfs_info.sb.num_devices != 1) {
|
||||
printf("%s: Unsupported number of devices (%lli). This driver "
|
||||
"only supports filesystem on one device.\n", __func__,
|
||||
|
|
|
@ -117,11 +117,14 @@ struct udevice;
|
|||
struct gpio_desc {
|
||||
struct udevice *dev; /* Device, NULL for invalid GPIO */
|
||||
unsigned long flags;
|
||||
#define GPIOD_REQUESTED (1 << 0) /* Requested/claimed */
|
||||
#define GPIOD_IS_OUT (1 << 1) /* GPIO is an output */
|
||||
#define GPIOD_IS_IN (1 << 2) /* GPIO is an input */
|
||||
#define GPIOD_ACTIVE_LOW (1 << 3) /* value has active low */
|
||||
#define GPIOD_IS_OUT_ACTIVE (1 << 4) /* set output active */
|
||||
#define GPIOD_IS_OUT BIT(1) /* GPIO is an output */
|
||||
#define GPIOD_IS_IN BIT(2) /* GPIO is an input */
|
||||
#define GPIOD_ACTIVE_LOW BIT(3) /* GPIO is active when value is low */
|
||||
#define GPIOD_IS_OUT_ACTIVE BIT(4) /* set output active */
|
||||
#define GPIOD_OPEN_DRAIN BIT(5) /* GPIO is open drain type */
|
||||
#define GPIOD_OPEN_SOURCE BIT(6) /* GPIO is open source type */
|
||||
#define GPIOD_PULL_UP BIT(7) /* GPIO has pull-up enabled */
|
||||
#define GPIOD_PULL_DOWN BIT(8) /* GPIO has pull-down enabled */
|
||||
|
||||
uint offset; /* GPIO offset within the device */
|
||||
/*
|
||||
|
@ -130,6 +133,12 @@ struct gpio_desc {
|
|||
*/
|
||||
};
|
||||
|
||||
/* helper to compute the value of the gpio output */
|
||||
#define GPIOD_FLAGS_OUTPUT_MASK (GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE)
|
||||
#define GPIOD_FLAGS_OUTPUT(flags) \
|
||||
(((((flags) & GPIOD_FLAGS_OUTPUT_MASK) == GPIOD_IS_OUT_ACTIVE) || \
|
||||
(((flags) & GPIOD_FLAGS_OUTPUT_MASK) == GPIOD_ACTIVE_LOW)))
|
||||
|
||||
/**
|
||||
* dm_gpio_is_valid() - Check if a GPIO is valid
|
||||
*
|
||||
|
@ -254,8 +263,6 @@ struct dm_gpio_ops {
|
|||
int value);
|
||||
int (*get_value)(struct udevice *dev, unsigned offset);
|
||||
int (*set_value)(struct udevice *dev, unsigned offset, int value);
|
||||
int (*get_open_drain)(struct udevice *dev, unsigned offset);
|
||||
int (*set_open_drain)(struct udevice *dev, unsigned offset, int value);
|
||||
/**
|
||||
* get_function() Get the GPIO function
|
||||
*
|
||||
|
@ -290,6 +297,37 @@ struct dm_gpio_ops {
|
|||
*/
|
||||
int (*xlate)(struct udevice *dev, struct gpio_desc *desc,
|
||||
struct ofnode_phandle_args *args);
|
||||
|
||||
/**
|
||||
* set_dir_flags() - Set GPIO dir flags
|
||||
*
|
||||
* This function should set up the GPIO configuration according to the
|
||||
* information provide by the direction flags bitfield.
|
||||
*
|
||||
* This method is optional.
|
||||
*
|
||||
* @dev: GPIO device
|
||||
* @offset: GPIO offset within that device
|
||||
* @flags: GPIO configuration to use
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int (*set_dir_flags)(struct udevice *dev, unsigned int offset,
|
||||
ulong flags);
|
||||
|
||||
/**
|
||||
* get_dir_flags() - Get GPIO dir flags
|
||||
*
|
||||
* This function return the GPIO direction flags used.
|
||||
*
|
||||
* This method is optional.
|
||||
*
|
||||
* @dev: GPIO device
|
||||
* @offset: GPIO offset within that device
|
||||
* @flags: place to put the used direction flags by GPIO
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int (*get_dir_flags)(struct udevice *dev, unsigned int offset,
|
||||
ulong *flags);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -586,43 +624,10 @@ int dm_gpio_get_value(const struct gpio_desc *desc);
|
|||
|
||||
int dm_gpio_set_value(const struct gpio_desc *desc, int value);
|
||||
|
||||
/**
|
||||
* dm_gpio_get_open_drain() - Check if open-drain-mode of a GPIO is active
|
||||
*
|
||||
* This checks if open-drain-mode for a GPIO is enabled or not. This method is
|
||||
* optional.
|
||||
*
|
||||
* @desc: GPIO description containing device, offset and flags,
|
||||
* previously returned by gpio_request_by_name()
|
||||
* @return Value of open drain mode for GPIO (0 for inactive, 1 for active) or
|
||||
* -ve on error
|
||||
*/
|
||||
int dm_gpio_get_open_drain(struct gpio_desc *desc);
|
||||
|
||||
/**
|
||||
* dm_gpio_set_open_drain() - Switch open-drain-mode of a GPIO on or off
|
||||
*
|
||||
* This enables or disables open-drain mode for a GPIO. This method is
|
||||
* optional; if the driver does not support it, nothing happens when the method
|
||||
* is called.
|
||||
*
|
||||
* In open-drain mode, instead of actively driving the output (Push-pull
|
||||
* output), the GPIO's pin is connected to the collector (for a NPN transistor)
|
||||
* or the drain (for a MOSFET) of a transistor, respectively. The pin then
|
||||
* either forms an open circuit or a connection to ground, depending on the
|
||||
* state of the transistor.
|
||||
*
|
||||
* @desc: GPIO description containing device, offset and flags,
|
||||
* previously returned by gpio_request_by_name()
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int dm_gpio_set_open_drain(struct gpio_desc *desc, int value);
|
||||
|
||||
/**
|
||||
* dm_gpio_set_dir() - Set the direction for a GPIO
|
||||
*
|
||||
* This sets up the direction according tot the provided flags. It will do
|
||||
* nothing unless the direction is actually specified.
|
||||
* This sets up the direction according to the GPIO flags: desc->flags.
|
||||
*
|
||||
* @desc: GPIO description containing device, offset and flags,
|
||||
* previously returned by gpio_request_by_name()
|
||||
|
@ -631,11 +636,10 @@ int dm_gpio_set_open_drain(struct gpio_desc *desc, int value);
|
|||
int dm_gpio_set_dir(struct gpio_desc *desc);
|
||||
|
||||
/**
|
||||
* dm_gpio_set_dir_flags() - Set direction using specific flags
|
||||
* dm_gpio_set_dir_flags() - Set direction using description and added flags
|
||||
*
|
||||
* This is like dm_gpio_set_dir() except that the flags value is provided
|
||||
* instead of being used from desc->flags. This is needed because in many
|
||||
* cases the GPIO description does not include direction information.
|
||||
* This sets up the direction according to the provided flags and the GPIO
|
||||
* description (desc->flags) which include direction information.
|
||||
* Note that desc->flags is updated by this function.
|
||||
*
|
||||
* @desc: GPIO description containing device, offset and flags,
|
||||
|
@ -645,6 +649,18 @@ int dm_gpio_set_dir(struct gpio_desc *desc);
|
|||
*/
|
||||
int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags);
|
||||
|
||||
/**
|
||||
* dm_gpio_get_dir_flags() - Get direction flags
|
||||
*
|
||||
* read the current direction flags
|
||||
*
|
||||
* @desc: GPIO description containing device, offset and flags,
|
||||
* previously returned by gpio_request_by_name()
|
||||
* @flags: place to put the used flags
|
||||
* @return 0 if OK, -ve on error, in which case desc->flags is not updated
|
||||
*/
|
||||
int dm_gpio_get_dir_flags(struct gpio_desc *desc, ulong *flags);
|
||||
|
||||
/**
|
||||
* gpio_get_number() - Get the global GPIO number of a GPIO
|
||||
*
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
/*
|
||||
* sbc8548 board configuration file
|
||||
* Please refer to doc/README.sbc8548 for more info.
|
||||
* Please refer to board/sbc8548/README for more info.
|
||||
*/
|
||||
#ifndef __CONFIG_H
|
||||
#define __CONFIG_H
|
||||
|
|
|
@ -103,6 +103,46 @@ struct property *of_find_property(const struct device_node *np,
|
|||
const void *of_get_property(const struct device_node *np, const char *name,
|
||||
int *lenp);
|
||||
|
||||
/**
|
||||
* of_get_first_property()- get to the pointer of the first property
|
||||
*
|
||||
* Get pointer to the first property of the node, it is used to iterate
|
||||
* and read all the property with of_get_next_property_by_prop().
|
||||
*
|
||||
* @np: Pointer to device node
|
||||
* @return pointer to property or NULL if not found
|
||||
*/
|
||||
const struct property *of_get_first_property(const struct device_node *np);
|
||||
|
||||
/**
|
||||
* of_get_next_property() - get to the pointer of the next property
|
||||
*
|
||||
* Get pointer to the next property of the node, it is used to iterate
|
||||
* and read all the property with of_get_property_by_prop().
|
||||
*
|
||||
* @np: Pointer to device node
|
||||
* @property: pointer of the current property
|
||||
* @return pointer to next property or NULL if not found
|
||||
*/
|
||||
const struct property *of_get_next_property(const struct device_node *np,
|
||||
const struct property *property);
|
||||
|
||||
/**
|
||||
* of_get_property_by_prop() - get a property value of a node property
|
||||
*
|
||||
* Get value for the property identified by node and property pointer.
|
||||
*
|
||||
* @node: node to read
|
||||
* @property: pointer of the property to read
|
||||
* @propname: place to property name on success
|
||||
* @lenp: place to put length on success
|
||||
* @return pointer to property value or NULL if error
|
||||
*/
|
||||
const void *of_get_property_by_prop(const struct device_node *np,
|
||||
const struct property *property,
|
||||
const char **name,
|
||||
int *lenp);
|
||||
|
||||
/**
|
||||
* of_device_is_compatible() - Check if the node matches given constraints
|
||||
* @device: pointer to node
|
||||
|
|
|
@ -58,6 +58,31 @@ struct ofnode_phandle_args {
|
|||
uint32_t args[OF_MAX_PHANDLE_ARGS];
|
||||
};
|
||||
|
||||
/**
|
||||
* ofprop - reference to a property of a device tree node
|
||||
*
|
||||
* This struct hold the reference on one property of one node,
|
||||
* using struct ofnode and an offset within the flat device tree or either
|
||||
* a pointer to a struct property in the live device tree.
|
||||
*
|
||||
* Thus we can reference arguments in both the live tree and the flat tree.
|
||||
*
|
||||
* The property reference can also hold a null reference. This corresponds to
|
||||
* a struct property NULL pointer or an offset of -1.
|
||||
*
|
||||
* @node: Pointer to device node
|
||||
* @offset: Pointer into flat device tree, used for flat tree.
|
||||
* @prop: Pointer to property, used for live treee.
|
||||
*/
|
||||
|
||||
struct ofprop {
|
||||
ofnode node;
|
||||
union {
|
||||
int offset;
|
||||
const struct property *prop;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* _ofnode_to_np() - convert an ofnode to a live DT node pointer
|
||||
*
|
||||
|
@ -595,7 +620,7 @@ int ofnode_decode_display_timing(ofnode node, int index,
|
|||
struct display_timing *config);
|
||||
|
||||
/**
|
||||
* ofnode_get_property()- - get a pointer to the value of a node property
|
||||
* ofnode_get_property() - get a pointer to the value of a node property
|
||||
*
|
||||
* @node: node to read
|
||||
* @propname: property to read
|
||||
|
@ -604,6 +629,42 @@ int ofnode_decode_display_timing(ofnode node, int index,
|
|||
*/
|
||||
const void *ofnode_get_property(ofnode node, const char *propname, int *lenp);
|
||||
|
||||
/**
|
||||
* ofnode_get_first_property()- get the reference of the first property
|
||||
*
|
||||
* Get reference to the first property of the node, it is used to iterate
|
||||
* and read all the property with ofnode_get_property_by_prop().
|
||||
*
|
||||
* @node: node to read
|
||||
* @prop: place to put argument reference
|
||||
* @return 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found
|
||||
*/
|
||||
int ofnode_get_first_property(ofnode node, struct ofprop *prop);
|
||||
|
||||
/**
|
||||
* ofnode_get_next_property() - get the reference of the next property
|
||||
*
|
||||
* Get reference to the next property of the node, it is used to iterate
|
||||
* and read all the property with ofnode_get_property_by_prop().
|
||||
*
|
||||
* @prop: reference of current argument and place to put reference of next one
|
||||
* @return 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found
|
||||
*/
|
||||
int ofnode_get_next_property(struct ofprop *prop);
|
||||
|
||||
/**
|
||||
* ofnode_get_property_by_prop() - get a pointer to the value of a property
|
||||
*
|
||||
* Get value for the property identified by the provided reference.
|
||||
*
|
||||
* @prop: reference on property
|
||||
* @propname: If non-NULL, place to property name on success,
|
||||
* @lenp: If non-NULL, place to put length on success
|
||||
* @return 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found
|
||||
*/
|
||||
const void *ofnode_get_property_by_prop(const struct ofprop *prop,
|
||||
const char **propname, int *lenp);
|
||||
|
||||
/**
|
||||
* ofnode_is_available() - check if a node is marked available
|
||||
*
|
||||
|
|
|
@ -494,6 +494,42 @@ int dev_read_phandle(const struct udevice *dev);
|
|||
const void *dev_read_prop(const struct udevice *dev, const char *propname,
|
||||
int *lenp);
|
||||
|
||||
/**
|
||||
* dev_read_first_prop()- get the reference of the first property
|
||||
*
|
||||
* Get reference to the first property of the node, it is used to iterate
|
||||
* and read all the property with dev_read_prop_by_prop().
|
||||
*
|
||||
* @dev: device to check
|
||||
* @prop: place to put argument reference
|
||||
* @return 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found
|
||||
*/
|
||||
int dev_read_first_prop(const struct udevice *dev, struct ofprop *prop);
|
||||
|
||||
/**
|
||||
* ofnode_get_next_property() - get the reference of the next property
|
||||
*
|
||||
* Get reference to the next property of the node, it is used to iterate
|
||||
* and read all the property with dev_read_prop_by_prop().
|
||||
*
|
||||
* @prop: reference of current argument and place to put reference of next one
|
||||
* @return 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found
|
||||
*/
|
||||
int dev_read_next_prop(struct ofprop *prop);
|
||||
|
||||
/**
|
||||
* dev_read_prop_by_prop() - get a pointer to the value of a property
|
||||
*
|
||||
* Get value for the property identified by the provided reference.
|
||||
*
|
||||
* @prop: reference on property
|
||||
* @propname: If non-NULL, place to property name on success,
|
||||
* @lenp: If non-NULL, place to put length on success
|
||||
* @return 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found
|
||||
*/
|
||||
const void *dev_read_prop_by_prop(struct ofprop *prop,
|
||||
const char **propname, int *lenp);
|
||||
|
||||
/**
|
||||
* dev_read_alias_seq() - Get the alias sequence number of a node
|
||||
*
|
||||
|
@ -860,6 +896,23 @@ static inline const void *dev_read_prop(const struct udevice *dev,
|
|||
return ofnode_get_property(dev_ofnode(dev), propname, lenp);
|
||||
}
|
||||
|
||||
static inline int dev_read_first_prop(const struct udevice *dev, struct ofprop *prop)
|
||||
{
|
||||
return ofnode_get_first_property(dev_ofnode(dev), prop);
|
||||
}
|
||||
|
||||
static inline int dev_read_next_prop(struct ofprop *prop)
|
||||
{
|
||||
return ofnode_get_next_property(prop);
|
||||
}
|
||||
|
||||
static inline const void *dev_read_prop_by_prop(struct ofprop *prop,
|
||||
const char **propname,
|
||||
int *lenp)
|
||||
{
|
||||
return ofnode_get_property_by_prop(prop, propname, lenp);
|
||||
}
|
||||
|
||||
static inline int dev_read_alias_seq(const struct udevice *dev, int *devnump)
|
||||
{
|
||||
return fdtdec_get_alias_seq(gd->fdt_blob, dev->uclass->uc_drv->name,
|
||||
|
@ -941,4 +994,18 @@ static inline int dev_read_alias_highest_id(const char *stem)
|
|||
ofnode_valid(subnode); \
|
||||
subnode = ofnode_next_subnode(subnode))
|
||||
|
||||
/**
|
||||
* dev_for_each_property() - Helper function to iterate through property
|
||||
*
|
||||
* This creates a for() loop which works through the property in a device's
|
||||
* device-tree node.
|
||||
*
|
||||
* @prop: struct ofprop holding the current property
|
||||
* @dev: device to use for interation (struct udevice *)
|
||||
*/
|
||||
#define dev_for_each_property(prop, dev) \
|
||||
for (int ret_prop = dev_read_first_prop(dev, &prop); \
|
||||
!ret_prop; \
|
||||
ret_prop = dev_read_next_prop(&prop))
|
||||
|
||||
#endif
|
||||
|
|
|
@ -33,4 +33,10 @@
|
|||
#define GPIO_PERSISTENT 0
|
||||
#define GPIO_TRANSITORY 8
|
||||
|
||||
/* Bit 4 express pull up */
|
||||
#define GPIO_PULL_UP 16
|
||||
|
||||
/* Bit 5 express pull down */
|
||||
#define GPIO_PULL_DOWN 32
|
||||
|
||||
#endif
|
||||
|
|
24
include/dt-bindings/gpio/sandbox-gpio.h
Normal file
24
include/dt-bindings/gpio/sandbox-gpio.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* This header provides constants for binding sandbox,gpio
|
||||
*
|
||||
*/
|
||||
#ifndef _DT_BINDINGS_GPIO_SANDBOX_GPIO_H
|
||||
#define _DT_BINDINGS_GPIO_SANDBOX_GPIO_H
|
||||
|
||||
/*
|
||||
* Add a specific binding for sandbox gpio.
|
||||
* The value need to be after the generic defines of
|
||||
* dt-bindings/gpio/gpio.h
|
||||
*/
|
||||
|
||||
/* Bit 16 express GPIO input mode */
|
||||
#define GPIO_IN 0x10000
|
||||
|
||||
/* Bit 17 express GPIO output mode */
|
||||
#define GPIO_OUT 0x20000
|
||||
|
||||
/* Bit 18 express GPIO output is active */
|
||||
#define GPIO_OUT_ACTIVE 0x40000
|
||||
|
||||
#endif
|
|
@ -31,8 +31,9 @@ obj-y += irq.o
|
|||
obj-$(CONFIG_LED) += led.o
|
||||
obj-$(CONFIG_DM_MAILBOX) += mailbox.o
|
||||
obj-$(CONFIG_DM_MMC) += mmc.o
|
||||
obj-y += ofnode.o
|
||||
obj-y += fdtdec.o
|
||||
obj-y += ofnode.o
|
||||
obj-y += ofread.o
|
||||
obj-$(CONFIG_OSD) += osd.o
|
||||
obj-$(CONFIG_DM_VIDEO) += panel.o
|
||||
obj-$(CONFIG_DM_PCI) += pci.o
|
||||
|
|
|
@ -24,9 +24,9 @@ static int dm_test_gpio(struct unit_test_state *uts)
|
|||
char buf[80];
|
||||
|
||||
/*
|
||||
* We expect to get 3 banks. One is anonymous (just numbered) and
|
||||
* comes from platdata. The other two are named a (20 gpios)
|
||||
* and b (10 gpios) and come from the device tree. See
|
||||
* We expect to get 4 banks. One is anonymous (just numbered) and
|
||||
* comes from platdata. The other are named a (20 gpios),
|
||||
* b (10 gpios) and c (10 gpios) and come from the device tree. See
|
||||
* test/dm/test.dts.
|
||||
*/
|
||||
ut_assertok(gpio_lookup_name("b4", &dev, &offset, &gpio));
|
||||
|
@ -74,11 +74,16 @@ static int dm_test_gpio(struct unit_test_state *uts)
|
|||
ut_asserteq(1, ops->get_value(dev, offset));
|
||||
|
||||
/* Make it an open drain output, and reset it */
|
||||
ut_asserteq(0, sandbox_gpio_get_open_drain(dev, offset));
|
||||
ut_assertok(ops->set_open_drain(dev, offset, 1));
|
||||
ut_asserteq(1, sandbox_gpio_get_open_drain(dev, offset));
|
||||
ut_assertok(ops->set_open_drain(dev, offset, 0));
|
||||
ut_asserteq(0, sandbox_gpio_get_open_drain(dev, offset));
|
||||
ut_asserteq(GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE,
|
||||
sandbox_gpio_get_dir_flags(dev, offset));
|
||||
ut_assertok(ops->set_dir_flags(dev, offset,
|
||||
GPIOD_IS_OUT | GPIOD_OPEN_DRAIN));
|
||||
ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_DRAIN,
|
||||
sandbox_gpio_get_dir_flags(dev, offset));
|
||||
ut_assertok(ops->set_dir_flags(dev, offset,
|
||||
GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE));
|
||||
ut_asserteq(GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE,
|
||||
sandbox_gpio_get_dir_flags(dev, offset));
|
||||
|
||||
/* Make it an input */
|
||||
ut_assertok(ops->direction_input(dev, offset));
|
||||
|
@ -215,11 +220,14 @@ static int dm_test_gpio_phandles(struct unit_test_state *uts)
|
|||
desc_list2,
|
||||
ARRAY_SIZE(desc_list2),
|
||||
0));
|
||||
ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_a, 4, NULL));
|
||||
ut_assertok(gpio_free_list(dev, desc_list, 3));
|
||||
ut_asserteq(GPIOF_UNUSED, gpio_get_function(gpio_a, 4, NULL));
|
||||
ut_asserteq(3, gpio_request_list_by_name(dev, "test-gpios", desc_list,
|
||||
ARRAY_SIZE(desc_list),
|
||||
GPIOD_IS_OUT |
|
||||
GPIOD_IS_OUT_ACTIVE));
|
||||
ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_a, 4, NULL));
|
||||
ut_asserteq_ptr(gpio_a, desc_list[0].dev);
|
||||
ut_asserteq(1, desc_list[0].offset);
|
||||
ut_asserteq_ptr(gpio_a, desc_list[1].dev);
|
||||
|
@ -229,10 +237,14 @@ static int dm_test_gpio_phandles(struct unit_test_state *uts)
|
|||
ut_asserteq(1, dm_gpio_get_value(desc_list));
|
||||
ut_assertok(gpio_free_list(dev, desc_list, 3));
|
||||
|
||||
ut_asserteq(GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE,
|
||||
sandbox_gpio_get_dir_flags(gpio_a, 1));
|
||||
ut_asserteq(6, gpio_request_list_by_name(dev, "test2-gpios", desc_list,
|
||||
ARRAY_SIZE(desc_list), 0));
|
||||
/* This was set to output previously, so still will be */
|
||||
ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_a, 1, NULL));
|
||||
|
||||
/* This was set to output previously but flags resetted to 0 = INPUT */
|
||||
ut_asserteq(0, sandbox_gpio_get_dir_flags(gpio_a, 1));
|
||||
ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_a, 1, NULL));
|
||||
|
||||
/* Active low should invert the input value */
|
||||
ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_b, 6, NULL));
|
||||
|
@ -244,7 +256,42 @@ static int dm_test_gpio_phandles(struct unit_test_state *uts)
|
|||
ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_b, 9, NULL));
|
||||
ut_asserteq(1, dm_gpio_get_value(&desc_list[5]));
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_gpio_phandles, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||
|
||||
/* Check the gpio pin configuration get from device tree information */
|
||||
static int dm_test_gpio_get_dir_flags(struct unit_test_state *uts)
|
||||
{
|
||||
struct gpio_desc desc_list[6];
|
||||
struct udevice *dev;
|
||||
ulong flags;
|
||||
|
||||
ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
|
||||
|
||||
ut_asserteq(6, gpio_request_list_by_name(dev, "test3-gpios", desc_list,
|
||||
ARRAY_SIZE(desc_list), 0));
|
||||
|
||||
ut_assertok(dm_gpio_get_dir_flags(&desc_list[0], &flags));
|
||||
ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_DRAIN, flags);
|
||||
|
||||
ut_assertok(dm_gpio_get_dir_flags(&desc_list[1], &flags));
|
||||
ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_SOURCE, flags);
|
||||
|
||||
ut_assertok(dm_gpio_get_dir_flags(&desc_list[2], &flags));
|
||||
ut_asserteq(GPIOD_IS_OUT, flags);
|
||||
|
||||
ut_assertok(dm_gpio_get_dir_flags(&desc_list[3], &flags));
|
||||
ut_asserteq(GPIOD_IS_IN | GPIOD_PULL_UP, flags);
|
||||
|
||||
ut_assertok(dm_gpio_get_dir_flags(&desc_list[4], &flags));
|
||||
ut_asserteq(GPIOD_IS_IN | GPIOD_PULL_DOWN, flags);
|
||||
|
||||
ut_assertok(dm_gpio_get_dir_flags(&desc_list[5], &flags));
|
||||
ut_asserteq(GPIOD_IS_IN, flags);
|
||||
|
||||
ut_assertok(gpio_free_list(dev, desc_list, 6));
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_gpio_get_dir_flags, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||
|
|
50
test/dm/ofread.c
Normal file
50
test/dm/ofread.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <dm/test.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
static int dm_test_ofnode_get_property_by_prop(struct unit_test_state *uts)
|
||||
{
|
||||
ofnode node;
|
||||
struct ofprop prop;
|
||||
const void *value;
|
||||
const char *propname;
|
||||
int res, len, count = 0;
|
||||
|
||||
node = ofnode_path("/cros-ec/flash");
|
||||
for (res = ofnode_get_first_property(node, &prop);
|
||||
!res;
|
||||
res = ofnode_get_next_property(&prop)) {
|
||||
value = ofnode_get_property_by_prop(&prop, &propname, &len);
|
||||
ut_assertnonnull(value);
|
||||
switch (count) {
|
||||
case 0:
|
||||
ut_asserteq_str("image-pos", propname);
|
||||
ut_asserteq(4, len);
|
||||
break;
|
||||
case 1:
|
||||
ut_asserteq_str("size", propname);
|
||||
ut_asserteq(4, len);
|
||||
break;
|
||||
case 2:
|
||||
ut_asserteq_str("erase-value", propname);
|
||||
ut_asserteq(4, len);
|
||||
break;
|
||||
case 3:
|
||||
/* only for platdata */
|
||||
ut_asserteq_str("name", propname);
|
||||
ut_asserteq(6, len);
|
||||
ut_asserteq_str("flash", value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_ofnode_get_property_by_prop,
|
||||
DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
|
@ -286,7 +286,7 @@ static int dm_test_alias_highest_id(struct unit_test_state *uts)
|
|||
ut_asserteq(5, ret);
|
||||
|
||||
ret = dev_read_alias_highest_id("gpio");
|
||||
ut_asserteq(2, ret);
|
||||
ut_asserteq(3, ret);
|
||||
|
||||
ret = dev_read_alias_highest_id("pci");
|
||||
ut_asserteq(2, ret);
|
||||
|
|
|
@ -22,11 +22,21 @@ def test_pinmux_usage_2(u_boot_console):
|
|||
def test_pinmux_status_all(u_boot_console):
|
||||
"""Test that 'pinmux status -a' displays pin's muxing."""
|
||||
output = u_boot_console.run_command('pinmux status -a')
|
||||
assert ('SCL : I2C SCL' in output)
|
||||
assert ('SDA : I2C SDA' in output)
|
||||
assert ('TX : Uart TX' in output)
|
||||
assert ('RX : Uart RX' in output)
|
||||
assert ('W1 : 1-wire gpio' in output)
|
||||
|
||||
assert ('pinctrl-gpio:' in output)
|
||||
assert ('a5 : gpio output .' in output)
|
||||
assert ('a6 : gpio output .' in output)
|
||||
|
||||
assert ('pinctrl:' in output)
|
||||
assert ('SCL : I2C SCL.' in output)
|
||||
assert ('SDA : I2C SDA.' in output)
|
||||
assert ('TX : Uart TX.' in output)
|
||||
assert ('RX : Uart RX.' in output)
|
||||
assert ('W1 : 1-wire gpio.' in output)
|
||||
assert ('GPIO0 : gpio bias-pull-up input-disable.' in output)
|
||||
assert ('GPIO1 : gpio drive-open-drain.' in output)
|
||||
assert ('GPIO2 : gpio bias-pull-down input-enable.' in output)
|
||||
assert ('GPIO3 : gpio bias-disable.' in output)
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_pinmux')
|
||||
@pytest.mark.boardspec('sandbox')
|
||||
|
@ -59,8 +69,16 @@ def test_pinmux_status(u_boot_console):
|
|||
"""Test that 'pinmux status' displays selected pincontroller's pin
|
||||
muxing descriptions."""
|
||||
output = u_boot_console.run_command('pinmux status')
|
||||
assert ('SCL : I2C SCL' in output)
|
||||
assert ('SDA : I2C SDA' in output)
|
||||
assert ('TX : Uart TX' in output)
|
||||
assert ('RX : Uart RX' in output)
|
||||
assert ('W1 : 1-wire gpio' in output)
|
||||
|
||||
assert (not 'pinctrl-gpio:' in output)
|
||||
assert (not 'pinctrl:' in output)
|
||||
|
||||
assert ('SCL : I2C SCL.' in output)
|
||||
assert ('SDA : I2C SDA.' in output)
|
||||
assert ('TX : Uart TX.' in output)
|
||||
assert ('RX : Uart RX.' in output)
|
||||
assert ('W1 : 1-wire gpio.' in output)
|
||||
assert ('GPIO0 : gpio bias-pull-up input-disable.' in output)
|
||||
assert ('GPIO1 : gpio drive-open-drain.' in output)
|
||||
assert ('GPIO2 : gpio bias-pull-down input-enable.' in output)
|
||||
assert ('GPIO3 : gpio bias-disable.' in output)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue