soc: arm: atmel_sam0: improve radio off handling for samr3x

Improve the radio off code, mainly:

- Compile the file only if necessary, ie, LORA radio not in use
- Use pin information from DT, so that we do not need to hardcode pins
  and can switch to dt-spec APIs.
- Improve error handling, includes, etc.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
This commit is contained in:
Gerard Marull-Paretas 2023-04-26 17:42:24 +02:00 committed by Fabio Baltieri
commit 6dde0056fc
4 changed files with 49 additions and 34 deletions

View file

@ -13,8 +13,9 @@ zephyr_sources_ifdef(CONFIG_SOC_SERIES_SAMD20 soc_samd2x.c)
zephyr_sources_ifdef(CONFIG_SOC_SERIES_SAMD21 soc_samd2x.c) zephyr_sources_ifdef(CONFIG_SOC_SERIES_SAMD21 soc_samd2x.c)
zephyr_sources_ifdef(CONFIG_SOC_SERIES_SAMR21 soc_samd2x.c) zephyr_sources_ifdef(CONFIG_SOC_SERIES_SAMR21 soc_samd2x.c)
zephyr_sources_ifdef(CONFIG_SOC_SERIES_SAML21 soc_saml2x.c) zephyr_sources_ifdef(CONFIG_SOC_SERIES_SAML21 soc_saml2x.c)
zephyr_sources_ifdef(CONFIG_SOC_SERIES_SAMR34 soc_saml2x.c soc_samr34.c) zephyr_sources_ifdef(CONFIG_SOC_SERIES_SAMR34 soc_saml2x.c)
zephyr_sources_ifdef(CONFIG_SOC_SERIES_SAMR35 soc_saml2x.c soc_samr34.c) zephyr_sources_ifdef(CONFIG_SOC_SERIES_SAMR35 soc_saml2x.c)
zephyr_sources_ifdef(CONFIG_SOC_ATMEL_SAMR3X_RADIO_OFF_SETUP soc_samr3x_radio_off.c)
zephyr_sources_ifdef(CONFIG_SOC_SERIES_SAMD51 soc_samd5x.c) zephyr_sources_ifdef(CONFIG_SOC_SERIES_SAMD51 soc_samd5x.c)
zephyr_sources_ifdef(CONFIG_SOC_SERIES_SAME51 soc_samd5x.c) zephyr_sources_ifdef(CONFIG_SOC_SERIES_SAME51 soc_samd5x.c)

View file

@ -72,3 +72,15 @@ config SOC_ATMEL_SAML_OSC16M_AS_MAIN
endchoice endchoice
endif # SOC_SERIES_SAML21 || SOC_SERIES_SAMR34 || SOC_SERIES_SAMR35 endif # SOC_SERIES_SAML21 || SOC_SERIES_SAMR34 || SOC_SERIES_SAMR35
config SOC_ATMEL_SAMR3X_RADIO_OFF_SETUP
bool "Configure LoRa radio pins if not in use"
default y if !LORA
depends on SOC_SERIES_SAMR34 || SOC_SERIES_SAMR35
help
As detailed in DS70005356C, LoRa radio SPI pins do not have pull-ups,
so when the radio is not in use, it's important that CS is kept high,
to avoid unexpected behavior and increased current consumption. To
further reduce power consumption, radio can be kept in reset state by
keeping nRST pin low. When enabling this option, both CS and nRST will
be configured high and low, respectively.

View file

@ -1,32 +0,0 @@
/*
* Copyright (c) 2021 Argentum Systems Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/init.h>
#include <zephyr/drivers/gpio.h>
#include <soc.h>
#if !(ATMEL_SAM0_DT_SERCOM_CHECK(4, atmel_sam0_spi) && CONFIG_SPI_SAM0)
/* When the radio is not in use, it's important that #CS is set high, to avoid
* unexpected behavior and increased current consumption... see Chapter 10 of
* DS70005356C. We also hold the radio in reset.
*/
static int soc_pinconf_init(void)
{
const struct device *const portb = DEVICE_DT_GET(DT_NODELABEL(portb));
if (!device_is_ready(portb)) {
return -ENODEV;
}
gpio_pin_configure(portb, 31, GPIO_OUTPUT_HIGH);
gpio_pin_configure(portb, 15, GPIO_OUTPUT_LOW);
return 0;
}
SYS_INIT(soc_pinconf_init, PRE_KERNEL_2, 0);
#endif

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2021 Argentum Systems Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/devicetree.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/init.h>
static int radio_off_setup(void)
{
int ret;
const struct gpio_dt_spec reset = GPIO_DT_SPEC_GET(DT_NODELABEL(lora), reset_gpios);
const struct gpio_dt_spec cs = GPIO_DT_SPEC_GET(DT_NODELABEL(sercom4), cs_gpios);
if (!gpio_is_ready_dt(&reset) || !gpio_is_ready_dt(&cs)) {
return -ENODEV;
}
ret = gpio_pin_configure_dt(&reset, GPIO_OUTPUT_ACTIVE);
if (ret < 0) {
return ret;
}
ret = gpio_pin_configure_dt(&cs, GPIO_OUTPUT_INACTIVE);
if (ret < 0) {
return ret;
}
return 0;
}
SYS_INIT(radio_off_setup, PRE_KERNEL_2, 0);