Message ID | 20210126095036.6429-3-m.szyprowski@samsung.com |
---|---|
State | Superseded |
Headers | show |
Series | VIM3: add support for checking 'Function' button state | expand |
On 1/26/21 10:50 AM, Marek Szyprowski wrote: > Add a simple Analog to Digital Converter device based button driver. This > driver binds to the 'adc-keys' device tree node. > > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> > --- > drivers/button/Kconfig | 8 ++ > drivers/button/Makefile | 1 + > drivers/button/button-adc.c | 156 ++++++++++++++++++++++++++++++++++++ > 3 files changed, 165 insertions(+) > create mode 100644 drivers/button/button-adc.c > > diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig > index 6b3ec7e55d..6db3c5e93a 100644 > --- a/drivers/button/Kconfig > +++ b/drivers/button/Kconfig > @@ -9,6 +9,14 @@ config BUTTON > can provide access to board-specific buttons. Use of the device tree > for configuration is encouraged. > > +config BUTTON_ADC > + bool "Button adc" > + depends on BUTTON > + help > + Enable support for buttons which are connected to Analog to Digital > + Converter device. The ADC driver must use driver model. Buttons are > + configured using the device tree. > + > config BUTTON_GPIO > bool "Button gpio" > depends on BUTTON > diff --git a/drivers/button/Makefile b/drivers/button/Makefile > index fcc10ebe8d..bbd18af149 100644 > --- a/drivers/button/Makefile > +++ b/drivers/button/Makefile > @@ -3,4 +3,5 @@ > # Copyright (C) 2020 Philippe Reynes <philippe.reynes@softathome.com> > > obj-$(CONFIG_BUTTON) += button-uclass.o > +obj-$(CONFIG_BUTTON_ADC) += button-adc.o > obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o > diff --git a/drivers/button/button-adc.c b/drivers/button/button-adc.c > new file mode 100644 > index 0000000000..1901d59a0e > --- /dev/null > +++ b/drivers/button/button-adc.c > @@ -0,0 +1,156 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2021 Samsung Electronics Co., Ltd. > + * http://www.samsung.com > + * Author: Marek Szyprowski <m.szyprowski@samsung.com> > + */ > + > +#include <common.h> > +#include <adc.h> > +#include <button.h> > +#include <log.h> > +#include <dm.h> > +#include <dm/lists.h> > +#include <dm/of_access.h> > +#include <dm/uclass-internal.h> > + > +/** > + * struct button_adc_priv - private data for button-adc driver. > + * > + * @adc: Analog to Digital Converter device to which button is connected. > + * @channel: channel of the ADC device to probe the button state. > + * @min: minimal raw ADC sample value to consider button as pressed. > + * @max: maximal raw ADC sample value to consider button as pressed. > + */ > +struct button_adc_priv { > + struct udevice *adc; > + int channel; > + int min; > + int max; > +}; > + > +static enum button_state_t button_adc_get_state(struct udevice *dev) > +{ > + struct button_adc_priv *priv = dev_get_priv(dev); > + unsigned int val; > + int ret; > + > + ret = adc_start_channel(priv->adc, priv->channel); > + if (ret) > + return ret; > + > + ret = adc_channel_data(priv->adc, priv->channel, &val); > + if (ret) > + return ret; > + > + if (ret == 0) > + return (val >= priv->min && val < priv->max) ? > + BUTTON_ON : BUTTON_OFF; > + > + return ret; > +} > + > +static int button_adc_probe(struct udevice *dev) > +{ > + struct button_uc_plat *uc_plat = dev_get_uclass_plat(dev); > + struct button_adc_priv *priv = dev_get_priv(dev); > + struct ofnode_phandle_args args; > + u32 treshold, up_treshold, t; > + unsigned int mask; > + ofnode node; > + int ret, vdd; > + > + /* Ignore the top-level button node */ > + if (!uc_plat->label) > + return 0; > + > + ret = dev_read_phandle_with_args(dev->parent, "io-channels", > + "#io-channel-cells", 0, 0, &args); > + if (ret) > + return ret; > + > + ret = uclass_get_device_by_ofnode(UCLASS_ADC, args.node, &priv->adc); > + if (ret) > + return ret; > + > + ret = ofnode_read_u32(dev_ofnode(dev->parent), > + "keyup-threshold-microvolt", &up_treshold); > + if (ret) > + return ret; > + > + ret = ofnode_read_u32(dev_ofnode(dev), "press-threshold-microvolt", > + &treshold); > + if (ret) > + return ret; > + > + dev_for_each_subnode(node, dev->parent) { > + ret = ofnode_read_u32(dev_ofnode(dev), > + "press-threshold-microvolt", &t); > + if (ret) > + return ret; > + > + if (t > treshold) > + up_treshold = t; Linux' Documentation/devicetree/bindings/input/adc-keys.txt describes that one virtual key is created per sub-node. If I read your code correctly, this is not what you are implementing. Instead you only define a single key per adc-keys node. Why are your deviating from the bindings document? Best regards Heinrich > + } > + > + ret = adc_vdd_value(priv->adc, &vdd); > + if (ret) > + return ret; > + > + ret = adc_data_mask(priv->adc, &mask); > + if (ret) > + return ret; > + > + priv->channel = args.args[0]; > + priv->min = mask * (treshold / 1000) / (vdd / 1000); > + priv->max = mask * (up_treshold / 1000) / (vdd / 1000); > + > + return ret; > +} > + > +static int button_adc_bind(struct udevice *parent) > +{ > + struct udevice *dev; > + ofnode node; > + int ret; > + > + dev_for_each_subnode(node, parent) { > + struct button_uc_plat *uc_plat; > + const char *label; > + > + label = ofnode_read_string(node, "label"); > + if (!label) { > + debug("%s: node %s has no label\n", __func__, > + ofnode_get_name(node)); > + return -EINVAL; > + } > + ret = device_bind_driver_to_node(parent, "button_adc", > + ofnode_get_name(node), > + node, &dev); > + if (ret) > + return ret; > + uc_plat = dev_get_uclass_plat(dev); > + uc_plat->label = label; > + } > + > + return 0; > +} > + > +static const struct button_ops button_adc_ops = { > + .get_state = button_adc_get_state, > +}; > + > +static const struct udevice_id button_adc_ids[] = { > + { .compatible = "adc-keys" }, > + { } > +}; > + > +U_BOOT_DRIVER(button_adc) = { > + .name = "button_adc", > + .id = UCLASS_BUTTON, > + .of_match = button_adc_ids, > + .ops = &button_adc_ops, > + .priv_auto = sizeof(struct button_adc_priv), > + .bind = button_adc_bind, > + .probe = button_adc_probe, > +}; >
Hi Heinrich, On 26.01.2021 12:10, Heinrich Schuchardt wrote: > On 1/26/21 10:50 AM, Marek Szyprowski wrote: >> Add a simple Analog to Digital Converter device based button driver. >> This >> driver binds to the 'adc-keys' device tree node. >> >> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> >> --- >> drivers/button/Kconfig | 8 ++ >> drivers/button/Makefile | 1 + >> drivers/button/button-adc.c | 156 ++++++++++++++++++++++++++++++++++++ >> 3 files changed, 165 insertions(+) >> create mode 100644 drivers/button/button-adc.c >> >> diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig >> index 6b3ec7e55d..6db3c5e93a 100644 >> --- a/drivers/button/Kconfig >> +++ b/drivers/button/Kconfig >> @@ -9,6 +9,14 @@ config BUTTON >> can provide access to board-specific buttons. Use of the >> device tree >> for configuration is encouraged. >> >> +config BUTTON_ADC >> + bool "Button adc" >> + depends on BUTTON >> + help >> + Enable support for buttons which are connected to Analog to >> Digital >> + Converter device. The ADC driver must use driver model. >> Buttons are >> + configured using the device tree. >> + >> config BUTTON_GPIO >> bool "Button gpio" >> depends on BUTTON >> diff --git a/drivers/button/Makefile b/drivers/button/Makefile >> index fcc10ebe8d..bbd18af149 100644 >> --- a/drivers/button/Makefile >> +++ b/drivers/button/Makefile >> @@ -3,4 +3,5 @@ >> # Copyright (C) 2020 Philippe Reynes <philippe.reynes@softathome.com> >> >> obj-$(CONFIG_BUTTON) += button-uclass.o >> +obj-$(CONFIG_BUTTON_ADC) += button-adc.o >> obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o >> diff --git a/drivers/button/button-adc.c b/drivers/button/button-adc.c >> new file mode 100644 >> index 0000000000..1901d59a0e >> --- /dev/null >> +++ b/drivers/button/button-adc.c >> @@ -0,0 +1,156 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +/* >> + * Copyright (C) 2021 Samsung Electronics Co., Ltd. >> + * http://www.samsung.com >> + * Author: Marek Szyprowski <m.szyprowski@samsung.com> >> + */ >> + >> +#include <common.h> >> +#include <adc.h> >> +#include <button.h> >> +#include <log.h> >> +#include <dm.h> >> +#include <dm/lists.h> >> +#include <dm/of_access.h> >> +#include <dm/uclass-internal.h> >> + >> +/** >> + * struct button_adc_priv - private data for button-adc driver. >> + * >> + * @adc: Analog to Digital Converter device to which button is >> connected. >> + * @channel: channel of the ADC device to probe the button state. >> + * @min: minimal raw ADC sample value to consider button as pressed. >> + * @max: maximal raw ADC sample value to consider button as pressed. >> + */ >> +struct button_adc_priv { >> + struct udevice *adc; >> + int channel; >> + int min; >> + int max; >> +}; >> + >> +static enum button_state_t button_adc_get_state(struct udevice *dev) >> +{ >> + struct button_adc_priv *priv = dev_get_priv(dev); >> + unsigned int val; >> + int ret; >> + >> + ret = adc_start_channel(priv->adc, priv->channel); >> + if (ret) >> + return ret; >> + >> + ret = adc_channel_data(priv->adc, priv->channel, &val); >> + if (ret) >> + return ret; >> + >> + if (ret == 0) >> + return (val >= priv->min && val < priv->max) ? >> + BUTTON_ON : BUTTON_OFF; >> + >> + return ret; >> +} >> + >> +static int button_adc_probe(struct udevice *dev) >> +{ >> + struct button_uc_plat *uc_plat = dev_get_uclass_plat(dev); >> + struct button_adc_priv *priv = dev_get_priv(dev); >> + struct ofnode_phandle_args args; >> + u32 treshold, up_treshold, t; >> + unsigned int mask; >> + ofnode node; >> + int ret, vdd; >> + >> + /* Ignore the top-level button node */ >> + if (!uc_plat->label) >> + return 0; >> + >> + ret = dev_read_phandle_with_args(dev->parent, "io-channels", >> + "#io-channel-cells", 0, 0, &args); >> + if (ret) >> + return ret; >> + >> + ret = uclass_get_device_by_ofnode(UCLASS_ADC, args.node, >> &priv->adc); >> + if (ret) >> + return ret; >> + >> + ret = ofnode_read_u32(dev_ofnode(dev->parent), >> + "keyup-threshold-microvolt", &up_treshold); >> + if (ret) >> + return ret; >> + >> + ret = ofnode_read_u32(dev_ofnode(dev), "press-threshold-microvolt", >> + &treshold); >> + if (ret) >> + return ret; >> + >> + dev_for_each_subnode(node, dev->parent) { >> + ret = ofnode_read_u32(dev_ofnode(dev), >> + "press-threshold-microvolt", &t); >> + if (ret) >> + return ret; >> + >> + if (t > treshold) >> + up_treshold = t; > > Linux' Documentation/devicetree/bindings/input/adc-keys.txt describes > that one virtual key is created per sub-node. > > If I read your code correctly, this is not what you are implementing. > Instead you only define a single key per adc-keys node. > > Why are your deviating from the bindings document? No I don't. button_adc_bind() binds to the root node with 'adc-keys' compatible, while the dev_for_each_subnode() loop instantiates driver for each subnode, so the button_adc_probe() is called for each defined key. I've copied this pattern from gpio-keys driver. >> ... Here is the related code: >> +static int button_adc_bind(struct udevice *parent) >> +{ >> + struct udevice *dev; >> + ofnode node; >> + int ret; >> + >> + dev_for_each_subnode(node, parent) { >> + struct button_uc_plat *uc_plat; >> + const char *label; >> + >> + label = ofnode_read_string(node, "label"); >> + if (!label) { >> + debug("%s: node %s has no label\n", __func__, >> + ofnode_get_name(node)); >> + return -EINVAL; >> + } >> + ret = device_bind_driver_to_node(parent, "button_adc", >> + ofnode_get_name(node), >> + node, &dev); >> + if (ret) >> + return ret; >> + uc_plat = dev_get_uclass_plat(dev); >> + uc_plat->label = label; >> + } >> + >> + return 0; >> +} >> + >> +static const struct button_ops button_adc_ops = { >> + .get_state = button_adc_get_state, >> +}; >> + >> +static const struct udevice_id button_adc_ids[] = { >> + { .compatible = "adc-keys" }, >> + { } >> +}; >> + >> +U_BOOT_DRIVER(button_adc) = { >> + .name = "button_adc", >> + .id = UCLASS_BUTTON, >> + .of_match = button_adc_ids, >> + .ops = &button_adc_ops, >> + .priv_auto = sizeof(struct button_adc_priv), >> + .bind = button_adc_bind, >> + .probe = button_adc_probe, >> +}; >> > > Best regards -- Marek Szyprowski, PhD Samsung R&D Institute Poland
On 26.01.21 12:25, Marek Szyprowski wrote: > Hi Heinrich, > > On 26.01.2021 12:10, Heinrich Schuchardt wrote: >> On 1/26/21 10:50 AM, Marek Szyprowski wrote: >>> Add a simple Analog to Digital Converter device based button driver. >>> This >>> driver binds to the 'adc-keys' device tree node. >>> >>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> >>> --- >>> drivers/button/Kconfig | 8 ++ >>> drivers/button/Makefile | 1 + >>> drivers/button/button-adc.c | 156 ++++++++++++++++++++++++++++++++++++ >>> 3 files changed, 165 insertions(+) >>> create mode 100644 drivers/button/button-adc.c >>> >>> diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig >>> index 6b3ec7e55d..6db3c5e93a 100644 >>> --- a/drivers/button/Kconfig >>> +++ b/drivers/button/Kconfig >>> @@ -9,6 +9,14 @@ config BUTTON >>> can provide access to board-specific buttons. Use of the >>> device tree >>> for configuration is encouraged. >>> >>> +config BUTTON_ADC >>> + bool "Button adc" >>> + depends on BUTTON >>> + help >>> + Enable support for buttons which are connected to Analog to >>> Digital >>> + Converter device. The ADC driver must use driver model. >>> Buttons are >>> + configured using the device tree. >>> + >>> config BUTTON_GPIO >>> bool "Button gpio" >>> depends on BUTTON >>> diff --git a/drivers/button/Makefile b/drivers/button/Makefile >>> index fcc10ebe8d..bbd18af149 100644 >>> --- a/drivers/button/Makefile >>> +++ b/drivers/button/Makefile >>> @@ -3,4 +3,5 @@ >>> # Copyright (C) 2020 Philippe Reynes <philippe.reynes@softathome.com> >>> >>> obj-$(CONFIG_BUTTON) += button-uclass.o >>> +obj-$(CONFIG_BUTTON_ADC) += button-adc.o >>> obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o >>> diff --git a/drivers/button/button-adc.c b/drivers/button/button-adc.c >>> new file mode 100644 >>> index 0000000000..1901d59a0e >>> --- /dev/null >>> +++ b/drivers/button/button-adc.c >>> @@ -0,0 +1,156 @@ >>> +// SPDX-License-Identifier: GPL-2.0 >>> +/* >>> + * Copyright (C) 2021 Samsung Electronics Co., Ltd. >>> + * http://www.samsung.com >>> + * Author: Marek Szyprowski <m.szyprowski@samsung.com> >>> + */ >>> + >>> +#include <common.h> >>> +#include <adc.h> >>> +#include <button.h> >>> +#include <log.h> >>> +#include <dm.h> >>> +#include <dm/lists.h> >>> +#include <dm/of_access.h> >>> +#include <dm/uclass-internal.h> >>> + >>> +/** >>> + * struct button_adc_priv - private data for button-adc driver. >>> + * >>> + * @adc: Analog to Digital Converter device to which button is >>> connected. >>> + * @channel: channel of the ADC device to probe the button state. >>> + * @min: minimal raw ADC sample value to consider button as pressed. >>> + * @max: maximal raw ADC sample value to consider button as pressed. >>> + */ >>> +struct button_adc_priv { >>> + struct udevice *adc; >>> + int channel; >>> + int min; >>> + int max; >>> +}; >>> + >>> +static enum button_state_t button_adc_get_state(struct udevice *dev) >>> +{ >>> + struct button_adc_priv *priv = dev_get_priv(dev); >>> + unsigned int val; >>> + int ret; >>> + >>> + ret = adc_start_channel(priv->adc, priv->channel); >>> + if (ret) >>> + return ret; >>> + >>> + ret = adc_channel_data(priv->adc, priv->channel, &val); >>> + if (ret) >>> + return ret; >>> + >>> + if (ret == 0) >>> + return (val >= priv->min && val < priv->max) ? >>> + BUTTON_ON : BUTTON_OFF; >>> + >>> + return ret; >>> +} >>> + >>> +static int button_adc_probe(struct udevice *dev) >>> +{ >>> + struct button_uc_plat *uc_plat = dev_get_uclass_plat(dev); >>> + struct button_adc_priv *priv = dev_get_priv(dev); >>> + struct ofnode_phandle_args args; >>> + u32 treshold, up_treshold, t; >>> + unsigned int mask; >>> + ofnode node; >>> + int ret, vdd; >>> + >>> + /* Ignore the top-level button node */ >>> + if (!uc_plat->label) >>> + return 0; >>> + >>> + ret = dev_read_phandle_with_args(dev->parent, "io-channels", >>> + "#io-channel-cells", 0, 0, &args); >>> + if (ret) >>> + return ret; >>> + >>> + ret = uclass_get_device_by_ofnode(UCLASS_ADC, args.node, >>> &priv->adc); >>> + if (ret) >>> + return ret; >>> + >>> + ret = ofnode_read_u32(dev_ofnode(dev->parent), >>> + "keyup-threshold-microvolt", &up_treshold); >>> + if (ret) >>> + return ret; >>> + >>> + ret = ofnode_read_u32(dev_ofnode(dev), "press-threshold-microvolt", >>> + &treshold); >>> + if (ret) >>> + return ret; >>> + >>> + dev_for_each_subnode(node, dev->parent) { >>> + ret = ofnode_read_u32(dev_ofnode(dev), >>> + "press-threshold-microvolt", &t); >>> + if (ret) >>> + return ret; >>> + >>> + if (t > treshold) >>> + up_treshold = t; >> >> Linux' Documentation/devicetree/bindings/input/adc-keys.txt describes >> that one virtual key is created per sub-node. >> >> If I read your code correctly, this is not what you are implementing. >> Instead you only define a single key per adc-keys node. >> >> Why are your deviating from the bindings document? > > No I don't. button_adc_bind() binds to the root node with 'adc-keys' > compatible, while the dev_for_each_subnode() loop instantiates driver > for each subnode, so the button_adc_probe() is called for each defined > key. I've copied this pattern from gpio-keys driver. > > >> ... > > Here is the related code: Thanks for pointing this out. To really test the driver we would need an emulated device on the sandbox where we can set the voltage and see which button is activated. I assume this can be added to test/dm/adc.c. Best regards Heinrich > >>> +static int button_adc_bind(struct udevice *parent) >>> +{ >>> + struct udevice *dev; >>> + ofnode node; >>> + int ret; >>> + >>> + dev_for_each_subnode(node, parent) { >>> + struct button_uc_plat *uc_plat; >>> + const char *label; >>> + >>> + label = ofnode_read_string(node, "label"); >>> + if (!label) { >>> + debug("%s: node %s has no label\n", __func__, >>> + ofnode_get_name(node)); >>> + return -EINVAL; >>> + } >>> + ret = device_bind_driver_to_node(parent, "button_adc", >>> + ofnode_get_name(node), >>> + node, &dev); >>> + if (ret) >>> + return ret; >>> + uc_plat = dev_get_uclass_plat(dev); >>> + uc_plat->label = label; >>> + } >>> + >>> + return 0; >>> +} >>> + >>> +static const struct button_ops button_adc_ops = { >>> + .get_state = button_adc_get_state, >>> +}; >>> + >>> +static const struct udevice_id button_adc_ids[] = { >>> + { .compatible = "adc-keys" }, >>> + { } >>> +}; >>> + >>> +U_BOOT_DRIVER(button_adc) = { >>> + .name = "button_adc", >>> + .id = UCLASS_BUTTON, >>> + .of_match = button_adc_ids, >>> + .ops = &button_adc_ops, >>> + .priv_auto = sizeof(struct button_adc_priv), >>> + .bind = button_adc_bind, >>> + .probe = button_adc_probe, >>> +}; >>> >> >> > Best regards >
Hi, On Tue, 26 Jan 2021 at 06:03, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > On 26.01.21 12:25, Marek Szyprowski wrote: > > Hi Heinrich, > > > > On 26.01.2021 12:10, Heinrich Schuchardt wrote: > >> On 1/26/21 10:50 AM, Marek Szyprowski wrote: > >>> Add a simple Analog to Digital Converter device based button driver. > >>> This > >>> driver binds to the 'adc-keys' device tree node. > >>> > >>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> > >>> --- > >>> drivers/button/Kconfig | 8 ++ > >>> drivers/button/Makefile | 1 + > >>> drivers/button/button-adc.c | 156 ++++++++++++++++++++++++++++++++++++ > >>> 3 files changed, 165 insertions(+) > >>> create mode 100644 drivers/button/button-adc.c > >>> > >>> diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig > >>> index 6b3ec7e55d..6db3c5e93a 100644 > >>> --- a/drivers/button/Kconfig > >>> +++ b/drivers/button/Kconfig > >>> @@ -9,6 +9,14 @@ config BUTTON > >>> can provide access to board-specific buttons. Use of the > >>> device tree > >>> for configuration is encouraged. > >>> > >>> +config BUTTON_ADC > >>> + bool "Button adc" > >>> + depends on BUTTON > >>> + help > >>> + Enable support for buttons which are connected to Analog to > >>> Digital > >>> + Converter device. The ADC driver must use driver model. > >>> Buttons are > >>> + configured using the device tree. > >>> + > >>> config BUTTON_GPIO > >>> bool "Button gpio" > >>> depends on BUTTON > >>> diff --git a/drivers/button/Makefile b/drivers/button/Makefile > >>> index fcc10ebe8d..bbd18af149 100644 > >>> --- a/drivers/button/Makefile > >>> +++ b/drivers/button/Makefile > >>> @@ -3,4 +3,5 @@ > >>> # Copyright (C) 2020 Philippe Reynes <philippe.reynes@softathome.com> > >>> > >>> obj-$(CONFIG_BUTTON) += button-uclass.o > >>> +obj-$(CONFIG_BUTTON_ADC) += button-adc.o > >>> obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o > >>> diff --git a/drivers/button/button-adc.c b/drivers/button/button-adc.c > >>> new file mode 100644 > >>> index 0000000000..1901d59a0e > >>> --- /dev/null > >>> +++ b/drivers/button/button-adc.c > >>> @@ -0,0 +1,156 @@ > >>> +// SPDX-License-Identifier: GPL-2.0 > >>> +/* > >>> + * Copyright (C) 2021 Samsung Electronics Co., Ltd. > >>> + * http://www.samsung.com > >>> + * Author: Marek Szyprowski <m.szyprowski@samsung.com> > >>> + */ > >>> + > >>> +#include <common.h> > >>> +#include <adc.h> > >>> +#include <button.h> > >>> +#include <log.h> > >>> +#include <dm.h> > >>> +#include <dm/lists.h> > >>> +#include <dm/of_access.h> > >>> +#include <dm/uclass-internal.h> > >>> + > >>> +/** > >>> + * struct button_adc_priv - private data for button-adc driver. > >>> + * > >>> + * @adc: Analog to Digital Converter device to which button is > >>> connected. > >>> + * @channel: channel of the ADC device to probe the button state. > >>> + * @min: minimal raw ADC sample value to consider button as pressed. > >>> + * @max: maximal raw ADC sample value to consider button as pressed. > >>> + */ > >>> +struct button_adc_priv { > >>> + struct udevice *adc; > >>> + int channel; > >>> + int min; > >>> + int max; > >>> +}; > >>> + > >>> +static enum button_state_t button_adc_get_state(struct udevice *dev) > >>> +{ > >>> + struct button_adc_priv *priv = dev_get_priv(dev); > >>> + unsigned int val; > >>> + int ret; > >>> + > >>> + ret = adc_start_channel(priv->adc, priv->channel); > >>> + if (ret) > >>> + return ret; > >>> + > >>> + ret = adc_channel_data(priv->adc, priv->channel, &val); > >>> + if (ret) > >>> + return ret; > >>> + > >>> + if (ret == 0) > >>> + return (val >= priv->min && val < priv->max) ? > >>> + BUTTON_ON : BUTTON_OFF; > >>> + > >>> + return ret; > >>> +} > >>> + > >>> +static int button_adc_probe(struct udevice *dev) > >>> +{ > >>> + struct button_uc_plat *uc_plat = dev_get_uclass_plat(dev); > >>> + struct button_adc_priv *priv = dev_get_priv(dev); > >>> + struct ofnode_phandle_args args; > >>> + u32 treshold, up_treshold, t; > >>> + unsigned int mask; > >>> + ofnode node; > >>> + int ret, vdd; > >>> + > >>> + /* Ignore the top-level button node */ > >>> + if (!uc_plat->label) > >>> + return 0; > >>> + > >>> + ret = dev_read_phandle_with_args(dev->parent, "io-channels", > >>> + "#io-channel-cells", 0, 0, &args); > >>> + if (ret) > >>> + return ret; > >>> + > >>> + ret = uclass_get_device_by_ofnode(UCLASS_ADC, args.node, > >>> &priv->adc); > >>> + if (ret) > >>> + return ret; > >>> + > >>> + ret = ofnode_read_u32(dev_ofnode(dev->parent), > >>> + "keyup-threshold-microvolt", &up_treshold); > >>> + if (ret) > >>> + return ret; > >>> + > >>> + ret = ofnode_read_u32(dev_ofnode(dev), "press-threshold-microvolt", > >>> + &treshold); > >>> + if (ret) > >>> + return ret; > >>> + > >>> + dev_for_each_subnode(node, dev->parent) { > >>> + ret = ofnode_read_u32(dev_ofnode(dev), > >>> + "press-threshold-microvolt", &t); > >>> + if (ret) > >>> + return ret; > >>> + > >>> + if (t > treshold) > >>> + up_treshold = t; > >> > >> Linux' Documentation/devicetree/bindings/input/adc-keys.txt describes > >> that one virtual key is created per sub-node. > >> > >> If I read your code correctly, this is not what you are implementing. > >> Instead you only define a single key per adc-keys node. > >> > >> Why are your deviating from the bindings document? > > > > No I don't. button_adc_bind() binds to the root node with 'adc-keys' > > compatible, while the dev_for_each_subnode() loop instantiates driver > > for each subnode, so the button_adc_probe() is called for each defined > > key. I've copied this pattern from gpio-keys driver. > > > > >> ... > > > > Here is the related code: > > Thanks for pointing this out. > > To really test the driver we would need an emulated device on the > sandbox where we can set the voltage and see which button is activated. > > I assume this can be added to test/dm/adc.c. Yes please! Regards, Simon
Hi Simon, On 01.02.2021 21:38, Simon Glass wrote: > On Tue, 26 Jan 2021 at 06:03, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: >> On 26.01.21 12:25, Marek Szyprowski wrote: >>> On 26.01.2021 12:10, Heinrich Schuchardt wrote: >>>> On 1/26/21 10:50 AM, Marek Szyprowski wrote: >>>>> Add a simple Analog to Digital Converter device based button driver. >>>>> This >>>>> driver binds to the 'adc-keys' device tree node. >>>>> >>>>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> >>>>> --- >>>>> drivers/button/Kconfig | 8 ++ >>>>> drivers/button/Makefile | 1 + >>>>> drivers/button/button-adc.c | 156 ++++++++++++++++++++++++++++++++++++ >>>>> 3 files changed, 165 insertions(+) >>>>> create mode 100644 drivers/button/button-adc.c >>>>> >>>>> diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig >>>>> index 6b3ec7e55d..6db3c5e93a 100644 >>>>> --- a/drivers/button/Kconfig >>>>> +++ b/drivers/button/Kconfig >>>>> @@ -9,6 +9,14 @@ config BUTTON >>>>> can provide access to board-specific buttons. Use of the >>>>> device tree >>>>> for configuration is encouraged. >>>>> >>>>> +config BUTTON_ADC >>>>> + bool "Button adc" >>>>> + depends on BUTTON >>>>> + help >>>>> + Enable support for buttons which are connected to Analog to >>>>> Digital >>>>> + Converter device. The ADC driver must use driver model. >>>>> Buttons are >>>>> + configured using the device tree. >>>>> + >>>>> config BUTTON_GPIO >>>>> bool "Button gpio" >>>>> depends on BUTTON >>>>> diff --git a/drivers/button/Makefile b/drivers/button/Makefile >>>>> index fcc10ebe8d..bbd18af149 100644 >>>>> --- a/drivers/button/Makefile >>>>> +++ b/drivers/button/Makefile >>>>> @@ -3,4 +3,5 @@ >>>>> # Copyright (C) 2020 Philippe Reynes <philippe.reynes@softathome.com> >>>>> >>>>> obj-$(CONFIG_BUTTON) += button-uclass.o >>>>> +obj-$(CONFIG_BUTTON_ADC) += button-adc.o >>>>> obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o >>>>> diff --git a/drivers/button/button-adc.c b/drivers/button/button-adc.c >>>>> new file mode 100644 >>>>> index 0000000000..1901d59a0e >>>>> --- /dev/null >>>>> +++ b/drivers/button/button-adc.c >>>>> @@ -0,0 +1,156 @@ >>>>> +// SPDX-License-Identifier: GPL-2.0 >>>>> +/* >>>>> + * Copyright (C) 2021 Samsung Electronics Co., Ltd. >>>>> + * http://www.samsung.com >>>>> + * Author: Marek Szyprowski <m.szyprowski@samsung.com> >>>>> + */ >>>>> + >>>>> +#include <common.h> >>>>> +#include <adc.h> >>>>> +#include <button.h> >>>>> +#include <log.h> >>>>> +#include <dm.h> >>>>> +#include <dm/lists.h> >>>>> +#include <dm/of_access.h> >>>>> +#include <dm/uclass-internal.h> >>>>> + >>>>> +/** >>>>> + * struct button_adc_priv - private data for button-adc driver. >>>>> + * >>>>> + * @adc: Analog to Digital Converter device to which button is >>>>> connected. >>>>> + * @channel: channel of the ADC device to probe the button state. >>>>> + * @min: minimal raw ADC sample value to consider button as pressed. >>>>> + * @max: maximal raw ADC sample value to consider button as pressed. >>>>> + */ >>>>> +struct button_adc_priv { >>>>> + struct udevice *adc; >>>>> + int channel; >>>>> + int min; >>>>> + int max; >>>>> +}; >>>>> + >>>>> +static enum button_state_t button_adc_get_state(struct udevice *dev) >>>>> +{ >>>>> + struct button_adc_priv *priv = dev_get_priv(dev); >>>>> + unsigned int val; >>>>> + int ret; >>>>> + >>>>> + ret = adc_start_channel(priv->adc, priv->channel); >>>>> + if (ret) >>>>> + return ret; >>>>> + >>>>> + ret = adc_channel_data(priv->adc, priv->channel, &val); >>>>> + if (ret) >>>>> + return ret; >>>>> + >>>>> + if (ret == 0) >>>>> + return (val >= priv->min && val < priv->max) ? >>>>> + BUTTON_ON : BUTTON_OFF; >>>>> + >>>>> + return ret; >>>>> +} >>>>> + >>>>> +static int button_adc_probe(struct udevice *dev) >>>>> +{ >>>>> + struct button_uc_plat *uc_plat = dev_get_uclass_plat(dev); >>>>> + struct button_adc_priv *priv = dev_get_priv(dev); >>>>> + struct ofnode_phandle_args args; >>>>> + u32 treshold, up_treshold, t; >>>>> + unsigned int mask; >>>>> + ofnode node; >>>>> + int ret, vdd; >>>>> + >>>>> + /* Ignore the top-level button node */ >>>>> + if (!uc_plat->label) >>>>> + return 0; >>>>> + >>>>> + ret = dev_read_phandle_with_args(dev->parent, "io-channels", >>>>> + "#io-channel-cells", 0, 0, &args); >>>>> + if (ret) >>>>> + return ret; >>>>> + >>>>> + ret = uclass_get_device_by_ofnode(UCLASS_ADC, args.node, >>>>> &priv->adc); >>>>> + if (ret) >>>>> + return ret; >>>>> + >>>>> + ret = ofnode_read_u32(dev_ofnode(dev->parent), >>>>> + "keyup-threshold-microvolt", &up_treshold); >>>>> + if (ret) >>>>> + return ret; >>>>> + >>>>> + ret = ofnode_read_u32(dev_ofnode(dev), "press-threshold-microvolt", >>>>> + &treshold); >>>>> + if (ret) >>>>> + return ret; >>>>> + >>>>> + dev_for_each_subnode(node, dev->parent) { >>>>> + ret = ofnode_read_u32(dev_ofnode(dev), >>>>> + "press-threshold-microvolt", &t); >>>>> + if (ret) >>>>> + return ret; >>>>> + >>>>> + if (t > treshold) >>>>> + up_treshold = t; >>>> Linux' Documentation/devicetree/bindings/input/adc-keys.txt describes >>>> that one virtual key is created per sub-node. >>>> >>>> If I read your code correctly, this is not what you are implementing. >>>> Instead you only define a single key per adc-keys node. >>>> >>>> Why are your deviating from the bindings document? >>> No I don't. button_adc_bind() binds to the root node with 'adc-keys' >>> compatible, while the dev_for_each_subnode() loop instantiates driver >>> for each subnode, so the button_adc_probe() is called for each defined >>> key. I've copied this pattern from gpio-keys driver. >>> >>> >> ... >>> >>> Here is the related code: >> Thanks for pointing this out. >> >> To really test the driver we would need an emulated device on the >> sandbox where we can set the voltage and see which button is activated. >> >> I assume this can be added to test/dm/adc.c. > Yes please! Could you give me a bit more hints or point where to start? I've tried to build sandbox, but it fails for v2021.01 release (I've did make sandbox_defconfig && make all). I assume I would need to add adc and adc-keys devices to some sandbox dts and some code triggering and checking the key values, but that's all I know now. Best regards -- Marek Szyprowski, PhD Samsung R&D Institute Poland
Hi Marek, On Thu, 4 Feb 2021 at 03:36, Marek Szyprowski <m.szyprowski@samsung.com> wrote: > > Hi Simon, > > On 01.02.2021 21:38, Simon Glass wrote: > > On Tue, 26 Jan 2021 at 06:03, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > >> On 26.01.21 12:25, Marek Szyprowski wrote: > >>> On 26.01.2021 12:10, Heinrich Schuchardt wrote: > >>>> On 1/26/21 10:50 AM, Marek Szyprowski wrote: > >>>>> Add a simple Analog to Digital Converter device based button driver. > >>>>> This > >>>>> driver binds to the 'adc-keys' device tree node. > >>>>> > >>>>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> > >>>>> --- > >>>>> drivers/button/Kconfig | 8 ++ > >>>>> drivers/button/Makefile | 1 + > >>>>> drivers/button/button-adc.c | 156 ++++++++++++++++++++++++++++++++++++ > >>>>> 3 files changed, 165 insertions(+) > >>>>> create mode 100644 drivers/button/button-adc.c > >>>>> > >>>>> diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig > >>>>> index 6b3ec7e55d..6db3c5e93a 100644 > >>>>> --- a/drivers/button/Kconfig > >>>>> +++ b/drivers/button/Kconfig > >>>>> @@ -9,6 +9,14 @@ config BUTTON > >>>>> can provide access to board-specific buttons. Use of the > >>>>> device tree > >>>>> for configuration is encouraged. > >>>>> > >>>>> +config BUTTON_ADC > >>>>> + bool "Button adc" > >>>>> + depends on BUTTON > >>>>> + help > >>>>> + Enable support for buttons which are connected to Analog to > >>>>> Digital > >>>>> + Converter device. The ADC driver must use driver model. > >>>>> Buttons are > >>>>> + configured using the device tree. > >>>>> + > >>>>> config BUTTON_GPIO > >>>>> bool "Button gpio" > >>>>> depends on BUTTON > >>>>> diff --git a/drivers/button/Makefile b/drivers/button/Makefile > >>>>> index fcc10ebe8d..bbd18af149 100644 > >>>>> --- a/drivers/button/Makefile > >>>>> +++ b/drivers/button/Makefile > >>>>> @@ -3,4 +3,5 @@ > >>>>> # Copyright (C) 2020 Philippe Reynes <philippe.reynes@softathome.com> > >>>>> > >>>>> obj-$(CONFIG_BUTTON) += button-uclass.o > >>>>> +obj-$(CONFIG_BUTTON_ADC) += button-adc.o > >>>>> obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o > >>>>> diff --git a/drivers/button/button-adc.c b/drivers/button/button-adc.c > >>>>> new file mode 100644 > >>>>> index 0000000000..1901d59a0e > >>>>> --- /dev/null > >>>>> +++ b/drivers/button/button-adc.c > >>>>> @@ -0,0 +1,156 @@ > >>>>> +// SPDX-License-Identifier: GPL-2.0 > >>>>> +/* > >>>>> + * Copyright (C) 2021 Samsung Electronics Co., Ltd. > >>>>> + * http://www.samsung.com > >>>>> + * Author: Marek Szyprowski <m.szyprowski@samsung.com> > >>>>> + */ > >>>>> + > >>>>> +#include <common.h> > >>>>> +#include <adc.h> > >>>>> +#include <button.h> > >>>>> +#include <log.h> > >>>>> +#include <dm.h> > >>>>> +#include <dm/lists.h> > >>>>> +#include <dm/of_access.h> > >>>>> +#include <dm/uclass-internal.h> > >>>>> + > >>>>> +/** > >>>>> + * struct button_adc_priv - private data for button-adc driver. > >>>>> + * > >>>>> + * @adc: Analog to Digital Converter device to which button is > >>>>> connected. > >>>>> + * @channel: channel of the ADC device to probe the button state. > >>>>> + * @min: minimal raw ADC sample value to consider button as pressed. > >>>>> + * @max: maximal raw ADC sample value to consider button as pressed. > >>>>> + */ > >>>>> +struct button_adc_priv { > >>>>> + struct udevice *adc; > >>>>> + int channel; > >>>>> + int min; > >>>>> + int max; > >>>>> +}; > >>>>> + > >>>>> +static enum button_state_t button_adc_get_state(struct udevice *dev) > >>>>> +{ > >>>>> + struct button_adc_priv *priv = dev_get_priv(dev); > >>>>> + unsigned int val; > >>>>> + int ret; > >>>>> + > >>>>> + ret = adc_start_channel(priv->adc, priv->channel); > >>>>> + if (ret) > >>>>> + return ret; > >>>>> + > >>>>> + ret = adc_channel_data(priv->adc, priv->channel, &val); > >>>>> + if (ret) > >>>>> + return ret; > >>>>> + > >>>>> + if (ret == 0) > >>>>> + return (val >= priv->min && val < priv->max) ? > >>>>> + BUTTON_ON : BUTTON_OFF; > >>>>> + > >>>>> + return ret; > >>>>> +} > >>>>> + > >>>>> +static int button_adc_probe(struct udevice *dev) > >>>>> +{ > >>>>> + struct button_uc_plat *uc_plat = dev_get_uclass_plat(dev); > >>>>> + struct button_adc_priv *priv = dev_get_priv(dev); > >>>>> + struct ofnode_phandle_args args; > >>>>> + u32 treshold, up_treshold, t; > >>>>> + unsigned int mask; > >>>>> + ofnode node; > >>>>> + int ret, vdd; > >>>>> + > >>>>> + /* Ignore the top-level button node */ > >>>>> + if (!uc_plat->label) > >>>>> + return 0; > >>>>> + > >>>>> + ret = dev_read_phandle_with_args(dev->parent, "io-channels", > >>>>> + "#io-channel-cells", 0, 0, &args); > >>>>> + if (ret) > >>>>> + return ret; > >>>>> + > >>>>> + ret = uclass_get_device_by_ofnode(UCLASS_ADC, args.node, > >>>>> &priv->adc); > >>>>> + if (ret) > >>>>> + return ret; > >>>>> + > >>>>> + ret = ofnode_read_u32(dev_ofnode(dev->parent), > >>>>> + "keyup-threshold-microvolt", &up_treshold); > >>>>> + if (ret) > >>>>> + return ret; > >>>>> + > >>>>> + ret = ofnode_read_u32(dev_ofnode(dev), "press-threshold-microvolt", > >>>>> + &treshold); > >>>>> + if (ret) > >>>>> + return ret; > >>>>> + > >>>>> + dev_for_each_subnode(node, dev->parent) { > >>>>> + ret = ofnode_read_u32(dev_ofnode(dev), > >>>>> + "press-threshold-microvolt", &t); > >>>>> + if (ret) > >>>>> + return ret; > >>>>> + > >>>>> + if (t > treshold) > >>>>> + up_treshold = t; > >>>> Linux' Documentation/devicetree/bindings/input/adc-keys.txt describes > >>>> that one virtual key is created per sub-node. > >>>> > >>>> If I read your code correctly, this is not what you are implementing. > >>>> Instead you only define a single key per adc-keys node. > >>>> > >>>> Why are your deviating from the bindings document? > >>> No I don't. button_adc_bind() binds to the root node with 'adc-keys' > >>> compatible, while the dev_for_each_subnode() loop instantiates driver > >>> for each subnode, so the button_adc_probe() is called for each defined > >>> key. I've copied this pattern from gpio-keys driver. > >>> > >>> >> ... > >>> > >>> Here is the related code: > >> Thanks for pointing this out. > >> > >> To really test the driver we would need an emulated device on the > >> sandbox where we can set the voltage and see which button is activated. > >> > >> I assume this can be added to test/dm/adc.c. > > Yes please! > > Could you give me a bit more hints or point where to start? I've tried > to build sandbox, but it fails for v2021.01 release (I've did make > sandbox_defconfig && make all). I assume I would need to add adc and > adc-keys devices to some sandbox dts and some code triggering and > checking the key values, but that's all I know now. Well you do need to be able to build sandbox or you will get nowhere...what error did you get? Once we understand what went wrong we can update the docs. Maybe it is missing a dependency. BTW for testing there is a series with more docs at u-boot-dm/test-working that might be useful. You can add your node to sandbox.dtsi and then run U-Boot with -T to get the test devicetree. Something like: $ ./u-boot -T (U-Boot starts) > ut dm adc_multi_channel_shot (test runs) You just need to probe your device and then button_get_state() on it. BTW I think all of the code in your probe() method should move to of_to_plat(). It has nothing to do with probing the device and is all about reading from the devicetree. Regards, Simon
Hi Simon, On 06.02.2021 17:21, Simon Glass wrote: > On Thu, 4 Feb 2021 at 03:36, Marek Szyprowski <m.szyprowski@samsung.com> wrote: >> ... >> Could you give me a bit more hints or point where to start? I've tried >> to build sandbox, but it fails for v2021.01 release (I've did make >> sandbox_defconfig && make all). I assume I would need to add adc and >> adc-keys devices to some sandbox dts and some code triggering and >> checking the key values, but that's all I know now. > Well you do need to be able to build sandbox or you will get > nowhere...what error did you get? Once we understand what went wrong > we can update the docs. Maybe it is missing a dependency. $ gcc --version gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0 Copyright (C) 2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ git checkout v2021.01 $ make sandbox_defconfig # # configuration written to .config # $ make scripts/kconfig/conf --syncconfig Kconfig CFG u-boot.cfg GEN include/autoconf.mk GEN include/autoconf.mk.dep CFGCHK u-boot.cfg UPD include/generated/timestamp_autogenerated.h HOSTCC tools/mkenvimage.o HOSTLD tools/mkenvimage HOSTCC tools/fit_image.o HOSTCC tools/image-host.o HOSTCC tools/dumpimage.o HOSTLD tools/dumpimage HOSTCC tools/mkimage.o HOSTLD tools/mkimage HOSTLD tools/fit_info HOSTLD tools/fit_check_sign ... CC arch/sandbox/cpu/cpu.o In file included from include/common.h:26:0, from arch/sandbox/cpu/cpu.c:6: include/asm/global_data.h:112:58: warning: call-clobbered register used for global register variable #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r9") ^ include/dm/of.h:86:1: note: in expansion of macro ‘DECLARE_GLOBAL_DATA_PTR’ DECLARE_GLOBAL_DATA_PTR; ^~~~~~~~~~~~~~~~~~~~~~~ In file included from arch/sandbox/cpu/cpu.c:18:0: ./arch/sandbox/include/asm/state.h:98:30: error: ‘CONFIG_SANDBOX_SPI_MAX_BUS’ undeclared here (not in a function); did you mean ‘CONFIG_SANDBOX_SPI’? struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS] ^~~~~~~~~~~~~~~~~~~~~~~~~~ CONFIG_SANDBOX_SPI ./arch/sandbox/include/asm/state.h:99:7: error: ‘CONFIG_SANDBOX_SPI_MAX_CS’ undeclared here (not in a function); did you mean ‘CONFIG_SANDBOX_SPI_MAX_BUS’? [CONFIG_SANDBOX_SPI_MAX_CS]; ^~~~~~~~~~~~~~~~~~~~~~~~~ CONFIG_SANDBOX_SPI_MAX_BUS arch/sandbox/cpu/cpu.c: In function ‘is_in_sandbox_mem’: arch/sandbox/cpu/cpu.c:83:41: error: ‘volatile struct arch_global_data’ has no member named ‘ram_buf’ return (const uint8_t *)ptr >= gd->arch.ram_buf && ^ arch/sandbox/cpu/cpu.c:84:34: error: ‘volatile struct arch_global_data’ has no member named ‘ram_buf’ (const uint8_t *)ptr < gd->arch.ram_buf + gd->ram_size; ^ arch/sandbox/cpu/cpu.c: At top level: arch/sandbox/cpu/cpu.c:97:7: error: redefinition of ‘phys_to_virt’ void *phys_to_virt(phys_addr_t paddr) ^~~~~~~~~~~~ In file included from include/asm/io.h:495:0, from arch/sandbox/cpu/cpu.c:15: include/asm-generic/io.h:30:21: note: previous definition of ‘phys_to_virt’ was here static inline void *phys_to_virt(phys_addr_t paddr) ^~~~~~~~~~~~ arch/sandbox/cpu/cpu.c: In function ‘phys_to_virt’: arch/sandbox/cpu/cpu.c:104:27: error: ‘volatile struct arch_global_data’ has no member named ‘ram_buf’ return (void *)(gd->arch.ram_buf + paddr); ^ In file included from include/linux/posix_types.h:4:0, from include/linux/types.h:4, from include/time.h:7, from include/common.h:18, from arch/sandbox/cpu/cpu.c:6: include/linux/stddef.h:17:33: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) ^ include/linux/kernel.h:274:29: note: in expansion of macro ‘offsetof’ (type *)( (char *)__mptr - offsetof(type,member) );}) ^~~~~~~~ include/linux/list.h:327:2: note: in expansion of macro ‘container_of’ container_of(ptr, type, member) ^~~~~~~~~~~~ include/linux/list.h:424:13: note: in expansion of macro ‘list_entry’ for (pos = list_entry((head)->next, typeof(*pos), member); \ ^~~~~~~~~~ arch/sandbox/cpu/cpu.c:111:2: note: in expansion of macro ‘list_for_each_entry’ list_for_each_entry(mentry, &state->mapmem_head, sibling_node) { ^~~~~~~~~~~~~~~~~~~ include/linux/stddef.h:17:33: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) ^ include/linux/kernel.h:274:29: note: in expansion of macro ‘offsetof’ (type *)( (char *)__mptr - offsetof(type,member) );}) ^~~~~~~~ include/linux/list.h:327:2: note: in expansion of macro ‘container_of’ container_of(ptr, type, member) ^~~~~~~~~~~~ include/linux/list.h:426:13: note: in expansion of macro ‘list_entry’ pos = list_entry(pos->member.next, typeof(*pos), member)) ^~~~~~~~~~ arch/sandbox/cpu/cpu.c:111:2: note: in expansion of macro ‘list_for_each_entry’ list_for_each_entry(mentry, &state->mapmem_head, sibling_node) { ^~~~~~~~~~~~~~~~~~~ arch/sandbox/cpu/cpu.c: In function ‘find_tag’: include/linux/stddef.h:17:33: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) ^ include/linux/kernel.h:274:29: note: in expansion of macro ‘offsetof’ (type *)( (char *)__mptr - offsetof(type,member) );}) ^~~~~~~~ include/linux/list.h:327:2: note: in expansion of macro ‘container_of’ container_of(ptr, type, member) ^~~~~~~~~~~~ include/linux/list.h:424:13: note: in expansion of macro ‘list_entry’ for (pos = list_entry((head)->next, typeof(*pos), member); \ ^~~~~~~~~~ arch/sandbox/cpu/cpu.c:132:2: note: in expansion of macro ‘list_for_each_entry’ list_for_each_entry(mentry, &state->mapmem_head, sibling_node) { ^~~~~~~~~~~~~~~~~~~ include/linux/stddef.h:17:33: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) ^ include/linux/kernel.h:274:29: note: in expansion of macro ‘offsetof’ (type *)( (char *)__mptr - offsetof(type,member) );}) ^~~~~~~~ include/linux/list.h:327:2: note: in expansion of macro ‘container_of’ container_of(ptr, type, member) ^~~~~~~~~~~~ include/linux/list.h:426:13: note: in expansion of macro ‘list_entry’ pos = list_entry(pos->member.next, typeof(*pos), member)) ^~~~~~~~~~ arch/sandbox/cpu/cpu.c:132:2: note: in expansion of macro ‘list_for_each_entry’ list_for_each_entry(mentry, &state->mapmem_head, sibling_node) { ^~~~~~~~~~~~~~~~~~~ arch/sandbox/cpu/cpu.c: At top level: arch/sandbox/cpu/cpu.c:142:13: error: redefinition of ‘virt_to_phys’ phys_addr_t virt_to_phys(void *ptr) ^~~~~~~~~~~~ In file included from include/asm/io.h:495:0, from arch/sandbox/cpu/cpu.c:15: include/asm-generic/io.h:46:27: note: previous definition of ‘virt_to_phys’ was here static inline phys_addr_t virt_to_phys(void *vaddr) ^~~~~~~~~~~~ arch/sandbox/cpu/cpu.c: In function ‘virt_to_phys’: arch/sandbox/cpu/cpu.c:151:49: error: ‘volatile struct arch_global_data’ has no member named ‘ram_buf’ return (phys_addr_t)((uint8_t *)ptr - gd->arch.ram_buf); ^ arch/sandbox/cpu/cpu.c: At top level: arch/sandbox/cpu/cpu.c:165:7: error: redefinition of ‘map_physmem’ void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) ^~~~~~~~~~~ In file included from include/asm/io.h:495:0, from arch/sandbox/cpu/cpu.c:15: include/asm-generic/io.h:86:21: note: previous definition of ‘map_physmem’ was here static inline void *map_physmem(phys_addr_t paddr, unsigned long len, ^~~~~~~~~~~ arch/sandbox/cpu/cpu.c: In function ‘map_physmem’: arch/sandbox/cpu/cpu.c:172:25: warning: implicit declaration of function ‘pci_map_physmem’; did you mean ‘map_physmem’? [-Wimplicit-function-declaration] if (enable_pci_map && !pci_map_physmem(paddr, &len, &map_dev, &ptr)) { ^~~~~~~~~~~~~~~ map_physmem arch/sandbox/cpu/cpu.c: At top level: arch/sandbox/cpu/cpu.c:185:6: error: conflicting types for ‘unmap_physmem’ void unmap_physmem(const void *ptr, unsigned long flags) ^~~~~~~~~~~~~ In file included from include/asm/io.h:495:0, from arch/sandbox/cpu/cpu.c:15: include/asm-generic/io.h:103:20: note: previous definition of ‘unmap_physmem’ was here static inline void unmap_physmem(void *vaddr, unsigned long flags) ^~~~~~~~~~~~~ arch/sandbox/cpu/cpu.c: In function ‘unmap_physmem’: arch/sandbox/cpu/cpu.c:189:3: warning: implicit declaration of function ‘pci_unmap_physmem’; did you mean ‘unmap_physmem’? [-Wimplicit-function-declaration] pci_unmap_physmem(ptr, map_len, map_dev); ^~~~~~~~~~~~~~~~~ unmap_physmem arch/sandbox/cpu/cpu.c: In function ‘map_to_sysmem’: arch/sandbox/cpu/cpu.c:204:30: error: ‘volatile struct arch_global_data’ has no member named ‘ram_buf’ return (u8 *)ptr - gd->arch.ram_buf; ^ arch/sandbox/cpu/cpu.c: At top level: arch/sandbox/cpu/cpu.c:233:50: warning: ‘enum sandboxio_size_t’ declared inside parameter list will not be visible outside of this definition or declaration unsigned int sandbox_read(const void *addr, enum sandboxio_size_t size) ^~~~~~~~~~~~~~~~ arch/sandbox/cpu/cpu.c:233:67: error: parameter 2 (‘size’) has incomplete type unsigned int sandbox_read(const void *addr, enum sandboxio_size_t size) ^~~~ arch/sandbox/cpu/cpu.c:233:14: warning: function declaration isn’t a prototype [-Wstrict-prototypes] unsigned int sandbox_read(const void *addr, enum sandboxio_size_t size) ^~~~~~~~~~~~ arch/sandbox/cpu/cpu.c: In function ‘sandbox_read’: arch/sandbox/cpu/cpu.c:241:7: error: ‘SB_SIZE_8’ undeclared (first use in this function); did you mean ‘PCI_SIZE_8’? case SB_SIZE_8: ^~~~~~~~~ PCI_SIZE_8 arch/sandbox/cpu/cpu.c:241:7: note: each undeclared identifier is reported only once for each function it appears in arch/sandbox/cpu/cpu.c:243:7: error: ‘SB_SIZE_16’ undeclared (first use in this function); did you mean ‘SB_SIZE_8’? case SB_SIZE_16: ^~~~~~~~~~ SB_SIZE_8 arch/sandbox/cpu/cpu.c:245:7: error: ‘SB_SIZE_32’ undeclared (first use in this function); did you mean ‘SB_SIZE_16’? case SB_SIZE_32: ^~~~~~~~~~ SB_SIZE_16 arch/sandbox/cpu/cpu.c:247:7: error: ‘SB_SIZE_64’ undeclared (first use in this function); did you mean ‘SB_SIZE_32’? case SB_SIZE_64: ^~~~~~~~~~ SB_SIZE_32 arch/sandbox/cpu/cpu.c: At top level: arch/sandbox/cpu/cpu.c:254:55: warning: ‘enum sandboxio_size_t’ declared inside parameter list will not be visible outside of this definition or declaration void sandbox_write(void *addr, unsigned int val, enum sandboxio_size_t size) ^~~~~~~~~~~~~~~~ arch/sandbox/cpu/cpu.c:254:72: error: parameter 3 (‘size’) has incomplete type void sandbox_write(void *addr, unsigned int val, enum sandboxio_size_t size) ^~~~ arch/sandbox/cpu/cpu.c:254:6: warning: function declaration isn’t a prototype [-Wstrict-prototypes] void sandbox_write(void *addr, unsigned int val, enum sandboxio_size_t size) ^~~~~~~~~~~~~ arch/sandbox/cpu/cpu.c: In function ‘sandbox_write’: arch/sandbox/cpu/cpu.c:262:7: error: ‘SB_SIZE_8’ undeclared (first use in this function); did you mean ‘PCI_SIZE_8’? case SB_SIZE_8: ^~~~~~~~~ PCI_SIZE_8 arch/sandbox/cpu/cpu.c:265:7: error: ‘SB_SIZE_16’ undeclared (first use in this function); did you mean ‘SB_SIZE_8’? case SB_SIZE_16: ^~~~~~~~~~ SB_SIZE_8 arch/sandbox/cpu/cpu.c:268:7: error: ‘SB_SIZE_32’ undeclared (first use in this function); did you mean ‘SB_SIZE_16’? case SB_SIZE_32: ^~~~~~~~~~ SB_SIZE_16 arch/sandbox/cpu/cpu.c:271:7: error: ‘SB_SIZE_64’ undeclared (first use in this function); did you mean ‘SB_SIZE_32’? case SB_SIZE_64: ^~~~~~~~~~ SB_SIZE_32 arch/sandbox/cpu/cpu.c: In function ‘sandbox_read_fdt_from_file’: arch/sandbox/cpu/cpu.c:306:9: warning: implicit declaration of function ‘map_sysmem’; did you mean ‘map_physmem’? [-Wimplicit-function-declaration] blob = map_sysmem(CONFIG_SYS_FDT_LOAD_ADDR, 0); ^~~~~~~~~~ map_physmem arch/sandbox/cpu/cpu.c:306:7: warning: assignment makes pointer from integer without a cast [-Wint-conversion] blob = map_sysmem(CONFIG_SYS_FDT_LOAD_ADDR, 0); ^ arch/sandbox/cpu/cpu.c: In function ‘is_in_sandbox_mem’: arch/sandbox/cpu/cpu.c:85:1: warning: control reaches end of non-void function [-Wreturn-type] } ^ scripts/Makefile.build:265: recipe for target 'arch/sandbox/cpu/cpu.o' failed make[1]: *** [arch/sandbox/cpu/cpu.o] Error 1 Makefile:1784: recipe for target 'arch/sandbox/cpu' failed make: *** [arch/sandbox/cpu] Error 2 Best regards -- Marek Szyprowski, PhD Samsung R&D Institute Poland
HI Marek, On Mon, 8 Feb 2021 at 09:10, Marek Szyprowski <m.szyprowski@samsung.com> wrote: > > Hi Simon, > > On 06.02.2021 17:21, Simon Glass wrote: > > On Thu, 4 Feb 2021 at 03:36, Marek Szyprowski <m.szyprowski@samsung.com> wrote: > >> ... > >> Could you give me a bit more hints or point where to start? I've tried > >> to build sandbox, but it fails for v2021.01 release (I've did make > >> sandbox_defconfig && make all). I assume I would need to add adc and > >> adc-keys devices to some sandbox dts and some code triggering and > >> checking the key values, but that's all I know now. > > Well you do need to be able to build sandbox or you will get > > nowhere...what error did you get? Once we understand what went wrong > > we can update the docs. Maybe it is missing a dependency. > > $ gcc --version > gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0 > Copyright (C) 2017 Free Software Foundation, Inc. > This is free software; see the source for copying conditions. There is NO > warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. > > $ git checkout v2021.01 > > $ make sandbox_defconfig > # > # configuration written to .config > # > > $ make > scripts/kconfig/conf --syncconfig Kconfig > CFG u-boot.cfg > GEN include/autoconf.mk > GEN include/autoconf.mk.dep > CFGCHK u-boot.cfg > UPD include/generated/timestamp_autogenerated.h > HOSTCC tools/mkenvimage.o > HOSTLD tools/mkenvimage > HOSTCC tools/fit_image.o > HOSTCC tools/image-host.o > HOSTCC tools/dumpimage.o > HOSTLD tools/dumpimage > HOSTCC tools/mkimage.o > HOSTLD tools/mkimage > HOSTLD tools/fit_info > HOSTLD tools/fit_check_sign > > ... > > CC arch/sandbox/cpu/cpu.o > In file included from include/common.h:26:0, > from arch/sandbox/cpu/cpu.c:6: > include/asm/global_data.h:112:58: warning: call-clobbered register used > for global register variable > #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r9") > ^ > include/dm/of.h:86:1: note: in expansion of macro ‘DECLARE_GLOBAL_DATA_PTR’ > DECLARE_GLOBAL_DATA_PTR; This is pretty mysterious. Are you sure you are using an x86_64 machine? Regards, Simon
On 2/8/21 6:08 PM, Simon Glass wrote: > HI Marek, > > On Mon, 8 Feb 2021 at 09:10, Marek Szyprowski <m.szyprowski@samsung.com> wrote: >> >> Hi Simon, >> >> On 06.02.2021 17:21, Simon Glass wrote: >>> On Thu, 4 Feb 2021 at 03:36, Marek Szyprowski <m.szyprowski@samsung.com> wrote: >>>> ... >>>> Could you give me a bit more hints or point where to start? I've tried >>>> to build sandbox, but it fails for v2021.01 release (I've did make >>>> sandbox_defconfig && make all). I assume I would need to add adc and >>>> adc-keys devices to some sandbox dts and some code triggering and >>>> checking the key values, but that's all I know now. >>> Well you do need to be able to build sandbox or you will get >>> nowhere...what error did you get? Once we understand what went wrong >>> we can update the docs. Maybe it is missing a dependency. >> >> $ gcc --version >> gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0 >> Copyright (C) 2017 Free Software Foundation, Inc. >> This is free software; see the source for copying conditions. There is NO >> warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. >> >> $ git checkout v2021.01 >> >> $ make sandbox_defconfig >> # >> # configuration written to .config >> # >> >> $ make >> scripts/kconfig/conf --syncconfig Kconfig >> CFG u-boot.cfg >> GEN include/autoconf.mk >> GEN include/autoconf.mk.dep >> CFGCHK u-boot.cfg >> UPD include/generated/timestamp_autogenerated.h >> HOSTCC tools/mkenvimage.o >> HOSTLD tools/mkenvimage >> HOSTCC tools/fit_image.o >> HOSTCC tools/image-host.o >> HOSTCC tools/dumpimage.o >> HOSTLD tools/dumpimage >> HOSTCC tools/mkimage.o >> HOSTLD tools/mkimage >> HOSTLD tools/fit_info >> HOSTLD tools/fit_check_sign >> >> ... >> >> CC arch/sandbox/cpu/cpu.o >> In file included from include/common.h:26:0, >> from arch/sandbox/cpu/cpu.c:6: >> include/asm/global_data.h:112:58: warning: call-clobbered register used >> for global register variable >> #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r9") >> ^ >> include/dm/of.h:86:1: note: in expansion of macro ‘DECLARE_GLOBAL_DATA_PTR’ >> DECLARE_GLOBAL_DATA_PTR; > > This is pretty mysterious. Are you sure you are using an x86_64 machine? r9 relates to ARMv7. You have to unset CROSS_COMPILE when you build the sandbox. The sandbox runs fine on aarch64. There are a bunch of errors currently when building on 32bit architectures. Simon has a lot of patches pending. Best regards Heinrich
On 2/8/21 6:56 PM, Heinrich Schuchardt wrote: > On 2/8/21 6:08 PM, Simon Glass wrote: >> HI Marek, >> >> On Mon, 8 Feb 2021 at 09:10, Marek Szyprowski >> <m.szyprowski@samsung.com> wrote: >>> >>> Hi Simon, >>> >>> On 06.02.2021 17:21, Simon Glass wrote: >>>> On Thu, 4 Feb 2021 at 03:36, Marek Szyprowski >>>> <m.szyprowski@samsung.com> wrote: >>>>> ... >>>>> Could you give me a bit more hints or point where to start? I've tried >>>>> to build sandbox, but it fails for v2021.01 release (I've did make >>>>> sandbox_defconfig && make all). I assume I would need to add adc and >>>>> adc-keys devices to some sandbox dts and some code triggering and >>>>> checking the key values, but that's all I know now. >>>> Well you do need to be able to build sandbox or you will get >>>> nowhere...what error did you get? Once we understand what went wrong >>>> we can update the docs. Maybe it is missing a dependency. >>> >>> $ gcc --version >>> gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0 >>> Copyright (C) 2017 Free Software Foundation, Inc. >>> This is free software; see the source for copying conditions. There >>> is NO >>> warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR >>> PURPOSE. >>> >>> $ git checkout v2021.01 >>> >>> $ make sandbox_defconfig >>> # >>> # configuration written to .config >>> # >>> >>> $ make >>> scripts/kconfig/conf --syncconfig Kconfig >>> CFG u-boot.cfg >>> GEN include/autoconf.mk >>> GEN include/autoconf.mk.dep >>> CFGCHK u-boot.cfg >>> UPD include/generated/timestamp_autogenerated.h >>> HOSTCC tools/mkenvimage.o >>> HOSTLD tools/mkenvimage >>> HOSTCC tools/fit_image.o >>> HOSTCC tools/image-host.o >>> HOSTCC tools/dumpimage.o >>> HOSTLD tools/dumpimage >>> HOSTCC tools/mkimage.o >>> HOSTLD tools/mkimage >>> HOSTLD tools/fit_info >>> HOSTLD tools/fit_check_sign >>> >>> ... >>> >>> CC arch/sandbox/cpu/cpu.o >>> In file included from include/common.h:26:0, >>> from arch/sandbox/cpu/cpu.c:6: >>> include/asm/global_data.h:112:58: warning: call-clobbered register used >>> for global register variable >>> #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm >>> ("r9") >>> ^ >>> include/dm/of.h:86:1: note: in expansion of macro >>> ‘DECLARE_GLOBAL_DATA_PTR’ >>> DECLARE_GLOBAL_DATA_PTR; >> >> This is pretty mysterious. Are you sure you are using an x86_64 machine? > > r9 relates to ARMv7. > > You have to unset CROSS_COMPILE when you build the sandbox. > > The sandbox runs fine on aarch64. > > There are a bunch of errors currently when building on 32bit > architectures. Simon has a lot of patches pending. Hello Simon, it was your patch 091401131085 ("command: Remove the cmd_tbl_t typedef") 2020-05-10 that broke building the sandbox on ARMv7. Once your 32bit corrections are merged we should try to add cross-compiling the sandbox for aarch64 and armv7 to Gitlab CI. Best regards Heinrich
Hi Heinrich, On Mon, 8 Feb 2021 at 15:18, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > On 2/8/21 6:56 PM, Heinrich Schuchardt wrote: > > On 2/8/21 6:08 PM, Simon Glass wrote: > >> HI Marek, > >> > >> On Mon, 8 Feb 2021 at 09:10, Marek Szyprowski > >> <m.szyprowski@samsung.com> wrote: > >>> > >>> Hi Simon, > >>> > >>> On 06.02.2021 17:21, Simon Glass wrote: > >>>> On Thu, 4 Feb 2021 at 03:36, Marek Szyprowski > >>>> <m.szyprowski@samsung.com> wrote: > >>>>> ... > >>>>> Could you give me a bit more hints or point where to start? I've tried > >>>>> to build sandbox, but it fails for v2021.01 release (I've did make > >>>>> sandbox_defconfig && make all). I assume I would need to add adc and > >>>>> adc-keys devices to some sandbox dts and some code triggering and > >>>>> checking the key values, but that's all I know now. > >>>> Well you do need to be able to build sandbox or you will get > >>>> nowhere...what error did you get? Once we understand what went wrong > >>>> we can update the docs. Maybe it is missing a dependency. > >>> > >>> $ gcc --version > >>> gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0 > >>> Copyright (C) 2017 Free Software Foundation, Inc. > >>> This is free software; see the source for copying conditions. There > >>> is NO > >>> warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR > >>> PURPOSE. > >>> > >>> $ git checkout v2021.01 > >>> > >>> $ make sandbox_defconfig > >>> # > >>> # configuration written to .config > >>> # > >>> > >>> $ make > >>> scripts/kconfig/conf --syncconfig Kconfig > >>> CFG u-boot.cfg > >>> GEN include/autoconf.mk > >>> GEN include/autoconf.mk.dep > >>> CFGCHK u-boot.cfg > >>> UPD include/generated/timestamp_autogenerated.h > >>> HOSTCC tools/mkenvimage.o > >>> HOSTLD tools/mkenvimage > >>> HOSTCC tools/fit_image.o > >>> HOSTCC tools/image-host.o > >>> HOSTCC tools/dumpimage.o > >>> HOSTLD tools/dumpimage > >>> HOSTCC tools/mkimage.o > >>> HOSTLD tools/mkimage > >>> HOSTLD tools/fit_info > >>> HOSTLD tools/fit_check_sign > >>> > >>> ... > >>> > >>> CC arch/sandbox/cpu/cpu.o > >>> In file included from include/common.h:26:0, > >>> from arch/sandbox/cpu/cpu.c:6: > >>> include/asm/global_data.h:112:58: warning: call-clobbered register used > >>> for global register variable > >>> #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm > >>> ("r9") > >>> ^ > >>> include/dm/of.h:86:1: note: in expansion of macro > >>> ‘DECLARE_GLOBAL_DATA_PTR’ > >>> DECLARE_GLOBAL_DATA_PTR; > >> > >> This is pretty mysterious. Are you sure you are using an x86_64 machine? > > > > r9 relates to ARMv7. > > > > You have to unset CROSS_COMPILE when you build the sandbox. > > > > The sandbox runs fine on aarch64. > > > > There are a bunch of errors currently when building on 32bit > > architectures. Simon has a lot of patches pending. > > Hello Simon, > > it was your patch > > 091401131085 ("command: Remove the cmd_tbl_t typedef") 2020-05-10 > > that broke building the sandbox on ARMv7. Oh dear. > > Once your 32bit corrections are merged we should try to add > cross-compiling the sandbox for aarch64 and armv7 to Gitlab CI. Yes, what we don't test doesn't work :-) Regards, Simon
Hi Simon, On 08.02.2021 18:08, Simon Glass wrote: > On Mon, 8 Feb 2021 at 09:10, Marek Szyprowski <m.szyprowski@samsung.com> wrote: >> On 06.02.2021 17:21, Simon Glass wrote: >>> On Thu, 4 Feb 2021 at 03:36, Marek Szyprowski <m.szyprowski@samsung.com> wrote: >>>> ... >>>> Could you give me a bit more hints or point where to start? I've tried >>>> to build sandbox, but it fails for v2021.01 release (I've did make >>>> sandbox_defconfig && make all). I assume I would need to add adc and >>>> adc-keys devices to some sandbox dts and some code triggering and >>>> checking the key values, but that's all I know now. >>> Well you do need to be able to build sandbox or you will get >>> nowhere...what error did you get? Once we understand what went wrong >>> we can update the docs. Maybe it is missing a dependency. >> $ gcc --version >> gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0 >> Copyright (C) 2017 Free Software Foundation, Inc. >> This is free software; see the source for copying conditions. There is NO >> warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. >> >> $ git checkout v2021.01 >> >> $ make sandbox_defconfig >> # >> # configuration written to .config >> # >> >> $ make >> scripts/kconfig/conf --syncconfig Kconfig >> CFG u-boot.cfg >> GEN include/autoconf.mk >> GEN include/autoconf.mk.dep >> CFGCHK u-boot.cfg >> UPD include/generated/timestamp_autogenerated.h >> HOSTCC tools/mkenvimage.o >> HOSTLD tools/mkenvimage >> HOSTCC tools/fit_image.o >> HOSTCC tools/image-host.o >> HOSTCC tools/dumpimage.o >> HOSTLD tools/dumpimage >> HOSTCC tools/mkimage.o >> HOSTLD tools/mkimage >> HOSTLD tools/fit_info >> HOSTLD tools/fit_check_sign >> >> ... >> >> CC arch/sandbox/cpu/cpu.o >> In file included from include/common.h:26:0, >> from arch/sandbox/cpu/cpu.c:6: >> include/asm/global_data.h:112:58: warning: call-clobbered register used >> for global register variable >> #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r9") >> ^ >> include/dm/of.h:86:1: note: in expansion of macro ‘DECLARE_GLOBAL_DATA_PTR’ >> DECLARE_GLOBAL_DATA_PTR; > This is pretty mysterious. Are you sure you are using an x86_64 machine? I've finally found what caused the issue on my build system. It is x86_64 machine, but after some old cross-builds I had an 'asm' symlink in u-boot/include directory pointing to arch/arm directory. I'm quite surprised that it has not been removed by make clean/distclean/mrproper combo. Best regards -- Marek Szyprowski, PhD Samsung R&D Institute Poland
Hi Marek, On Tue, 9 Feb 2021 at 01:43, Marek Szyprowski <m.szyprowski@samsung.com> wrote: > > Hi Simon, > > On 08.02.2021 18:08, Simon Glass wrote: > > On Mon, 8 Feb 2021 at 09:10, Marek Szyprowski <m.szyprowski@samsung.com> wrote: > >> On 06.02.2021 17:21, Simon Glass wrote: > >>> On Thu, 4 Feb 2021 at 03:36, Marek Szyprowski <m.szyprowski@samsung.com> wrote: > >>>> ... > >>>> Could you give me a bit more hints or point where to start? I've tried > >>>> to build sandbox, but it fails for v2021.01 release (I've did make > >>>> sandbox_defconfig && make all). I assume I would need to add adc and > >>>> adc-keys devices to some sandbox dts and some code triggering and > >>>> checking the key values, but that's all I know now. > >>> Well you do need to be able to build sandbox or you will get > >>> nowhere...what error did you get? Once we understand what went wrong > >>> we can update the docs. Maybe it is missing a dependency. > >> $ gcc --version > >> gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0 > >> Copyright (C) 2017 Free Software Foundation, Inc. > >> This is free software; see the source for copying conditions. There is NO > >> warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. > >> > >> $ git checkout v2021.01 > >> > >> $ make sandbox_defconfig > >> # > >> # configuration written to .config > >> # > >> > >> $ make > >> scripts/kconfig/conf --syncconfig Kconfig > >> CFG u-boot.cfg > >> GEN include/autoconf.mk > >> GEN include/autoconf.mk.dep > >> CFGCHK u-boot.cfg > >> UPD include/generated/timestamp_autogenerated.h > >> HOSTCC tools/mkenvimage.o > >> HOSTLD tools/mkenvimage > >> HOSTCC tools/fit_image.o > >> HOSTCC tools/image-host.o > >> HOSTCC tools/dumpimage.o > >> HOSTLD tools/dumpimage > >> HOSTCC tools/mkimage.o > >> HOSTLD tools/mkimage > >> HOSTLD tools/fit_info > >> HOSTLD tools/fit_check_sign > >> > >> ... > >> > >> CC arch/sandbox/cpu/cpu.o > >> In file included from include/common.h:26:0, > >> from arch/sandbox/cpu/cpu.c:6: > >> include/asm/global_data.h:112:58: warning: call-clobbered register used > >> for global register variable > >> #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r9") > >> ^ > >> include/dm/of.h:86:1: note: in expansion of macro ‘DECLARE_GLOBAL_DATA_PTR’ > >> DECLARE_GLOBAL_DATA_PTR; > > This is pretty mysterious. Are you sure you are using an x86_64 machine? > > I've finally found what caused the issue on my build system. It is > x86_64 machine, but after some old cross-builds I had an 'asm' symlink > in u-boot/include directory pointing to arch/arm directory. I'm quite > surprised that it has not been removed by make clean/distclean/mrproper > combo. OK. I wonder if this is after building a U-Boot from 2013? I will send a patch. Regards, Simon
diff --git a/drivers/button/Kconfig b/drivers/button/Kconfig index 6b3ec7e55d..6db3c5e93a 100644 --- a/drivers/button/Kconfig +++ b/drivers/button/Kconfig @@ -9,6 +9,14 @@ config BUTTON can provide access to board-specific buttons. Use of the device tree for configuration is encouraged. +config BUTTON_ADC + bool "Button adc" + depends on BUTTON + help + Enable support for buttons which are connected to Analog to Digital + Converter device. The ADC driver must use driver model. Buttons are + configured using the device tree. + config BUTTON_GPIO bool "Button gpio" depends on BUTTON diff --git a/drivers/button/Makefile b/drivers/button/Makefile index fcc10ebe8d..bbd18af149 100644 --- a/drivers/button/Makefile +++ b/drivers/button/Makefile @@ -3,4 +3,5 @@ # Copyright (C) 2020 Philippe Reynes <philippe.reynes@softathome.com> obj-$(CONFIG_BUTTON) += button-uclass.o +obj-$(CONFIG_BUTTON_ADC) += button-adc.o obj-$(CONFIG_BUTTON_GPIO) += button-gpio.o diff --git a/drivers/button/button-adc.c b/drivers/button/button-adc.c new file mode 100644 index 0000000000..1901d59a0e --- /dev/null +++ b/drivers/button/button-adc.c @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2021 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * Author: Marek Szyprowski <m.szyprowski@samsung.com> + */ + +#include <common.h> +#include <adc.h> +#include <button.h> +#include <log.h> +#include <dm.h> +#include <dm/lists.h> +#include <dm/of_access.h> +#include <dm/uclass-internal.h> + +/** + * struct button_adc_priv - private data for button-adc driver. + * + * @adc: Analog to Digital Converter device to which button is connected. + * @channel: channel of the ADC device to probe the button state. + * @min: minimal raw ADC sample value to consider button as pressed. + * @max: maximal raw ADC sample value to consider button as pressed. + */ +struct button_adc_priv { + struct udevice *adc; + int channel; + int min; + int max; +}; + +static enum button_state_t button_adc_get_state(struct udevice *dev) +{ + struct button_adc_priv *priv = dev_get_priv(dev); + unsigned int val; + int ret; + + ret = adc_start_channel(priv->adc, priv->channel); + if (ret) + return ret; + + ret = adc_channel_data(priv->adc, priv->channel, &val); + if (ret) + return ret; + + if (ret == 0) + return (val >= priv->min && val < priv->max) ? + BUTTON_ON : BUTTON_OFF; + + return ret; +} + +static int button_adc_probe(struct udevice *dev) +{ + struct button_uc_plat *uc_plat = dev_get_uclass_plat(dev); + struct button_adc_priv *priv = dev_get_priv(dev); + struct ofnode_phandle_args args; + u32 treshold, up_treshold, t; + unsigned int mask; + ofnode node; + int ret, vdd; + + /* Ignore the top-level button node */ + if (!uc_plat->label) + return 0; + + ret = dev_read_phandle_with_args(dev->parent, "io-channels", + "#io-channel-cells", 0, 0, &args); + if (ret) + return ret; + + ret = uclass_get_device_by_ofnode(UCLASS_ADC, args.node, &priv->adc); + if (ret) + return ret; + + ret = ofnode_read_u32(dev_ofnode(dev->parent), + "keyup-threshold-microvolt", &up_treshold); + if (ret) + return ret; + + ret = ofnode_read_u32(dev_ofnode(dev), "press-threshold-microvolt", + &treshold); + if (ret) + return ret; + + dev_for_each_subnode(node, dev->parent) { + ret = ofnode_read_u32(dev_ofnode(dev), + "press-threshold-microvolt", &t); + if (ret) + return ret; + + if (t > treshold) + up_treshold = t; + } + + ret = adc_vdd_value(priv->adc, &vdd); + if (ret) + return ret; + + ret = adc_data_mask(priv->adc, &mask); + if (ret) + return ret; + + priv->channel = args.args[0]; + priv->min = mask * (treshold / 1000) / (vdd / 1000); + priv->max = mask * (up_treshold / 1000) / (vdd / 1000); + + return ret; +} + +static int button_adc_bind(struct udevice *parent) +{ + struct udevice *dev; + ofnode node; + int ret; + + dev_for_each_subnode(node, parent) { + struct button_uc_plat *uc_plat; + const char *label; + + label = ofnode_read_string(node, "label"); + if (!label) { + debug("%s: node %s has no label\n", __func__, + ofnode_get_name(node)); + return -EINVAL; + } + ret = device_bind_driver_to_node(parent, "button_adc", + ofnode_get_name(node), + node, &dev); + if (ret) + return ret; + uc_plat = dev_get_uclass_plat(dev); + uc_plat->label = label; + } + + return 0; +} + +static const struct button_ops button_adc_ops = { + .get_state = button_adc_get_state, +}; + +static const struct udevice_id button_adc_ids[] = { + { .compatible = "adc-keys" }, + { } +}; + +U_BOOT_DRIVER(button_adc) = { + .name = "button_adc", + .id = UCLASS_BUTTON, + .of_match = button_adc_ids, + .ops = &button_adc_ops, + .priv_auto = sizeof(struct button_adc_priv), + .bind = button_adc_bind, + .probe = button_adc_probe, +};
Add a simple Analog to Digital Converter device based button driver. This driver binds to the 'adc-keys' device tree node. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> --- drivers/button/Kconfig | 8 ++ drivers/button/Makefile | 1 + drivers/button/button-adc.c | 156 ++++++++++++++++++++++++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 drivers/button/button-adc.c -- 2.17.1