From 216012574efd99a78014895ebc1ebe0412da984b Mon Sep 17 00:00:00 2001 From: liquidraver <504870+liquidraver@users.noreply.github.com> Date: Fri, 14 Aug 2026 13:48:35 +0200 Subject: [PATCH] X1 barometrification --- .../adapters/sensors/ZephyrEnvSensors.cpp | 67 +++++++++++++------ zephcore/adapters/sensors/spa06.c | 9 +++ .../heltec_wireless_tracker_v2_procpu.dts | 11 +++ .../heltec_t096/heltec_t096_nrf52840.dts | 19 ++++++ .../nrf52840/lilygo_techo/lilygo_techo.dts | 12 +++- .../lilygo_timpulse_plus.dts | 8 +++ .../meshtracker_x1_nrf52840.dts | 44 ++++++++---- .../promicro_lr2021/promicro_lr2021.dts | 8 +++ .../promicro_sx1262/promicro_sx1262.dts | 8 +++ .../nrf52840/rak3401_1watt/rak3401_1watt.dts | 8 +++ .../rak_wismesh_tag/rak_wismesh_tag.dts | 8 +++ 11 files changed, 167 insertions(+), 35 deletions(-) diff --git a/zephcore/adapters/sensors/ZephyrEnvSensors.cpp b/zephcore/adapters/sensors/ZephyrEnvSensors.cpp index b1ffd8d..edd1da6 100644 --- a/zephcore/adapters/sensors/ZephyrEnvSensors.cpp +++ b/zephcore/adapters/sensors/ZephyrEnvSensors.cpp @@ -50,6 +50,31 @@ static const struct device *temp_humidity_dev = NULL; static const struct device *pressure_dev = NULL; static bool temp_dev_has_pressure = false; /* BME280/BME680 also have pressure */ static bool env_available = false; + +/* Is this sensor usable — bringing it up first if its node deferred init? + * + * A part behind a switched rail cannot be probed at POST_KERNEL. Regulators + * come up at priority 75 and sensors at 90, typically microseconds later, and a + * regulator-boot-on rail never applies its startup-delay-us (regulator_common_init + * takes the refcount-only branch, so regulator_delay() never runs). Such a node + * is marked zephyr,deferred-init and initialised from here instead, where the + * rail has had the whole boot to settle. See the i2c0 comment in the + * MeshTracker X1 DTS for the failure this prevents. + * + * Safe to call for every candidate on every board: do_device_init() marks a + * device initialized even when its init function failed, so device_init() + * answers -EALREADY for anything that already ran at POST_KERNEL and this + * reduces to a plain device_is_ready() check. */ +static bool sensor_ready(const struct device *dev) +{ + if (dev == NULL) { + return false; + } + if (!device_is_ready(dev)) { + (void)device_init(dev); + } + return device_is_ready(dev); +} #endif int env_sensors_init(void) @@ -63,7 +88,7 @@ int env_sensors_init(void) /* SHTC3 (e.g., RAK1901) */ dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(shtc3)); - if (dev && device_is_ready(dev)) { + if (sensor_ready(dev)) { temp_humidity_dev = dev; LOG_INF("Found temp/humidity sensor: %s (SHTC3)", dev->name); goto check_pressure; @@ -71,13 +96,13 @@ int env_sensors_init(void) /* Aosong AHT20/DHT20/AM2301B — same chip family, three compatible strings */ dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(aht20)); - if (!dev || !device_is_ready(dev)) { + if (!sensor_ready(dev)) { dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(dht20)); } - if (!dev || !device_is_ready(dev)) { + if (!sensor_ready(dev)) { dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(am2301b)); } - if (dev && device_is_ready(dev)) { + if (sensor_ready(dev)) { temp_humidity_dev = dev; LOG_INF("Found temp/humidity sensor: %s (AHT20/DHT20)", dev->name); goto check_pressure; @@ -85,7 +110,7 @@ int env_sensors_init(void) /* SHT4x */ dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(sht4x)); - if (dev && device_is_ready(dev)) { + if (sensor_ready(dev)) { temp_humidity_dev = dev; LOG_INF("Found temp/humidity sensor: %s (SHT4x)", dev->name); goto check_pressure; @@ -93,7 +118,7 @@ int env_sensors_init(void) /* SHT3xD */ dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(sht3xd)); - if (dev && device_is_ready(dev)) { + if (sensor_ready(dev)) { temp_humidity_dev = dev; LOG_INF("Found temp/humidity sensor: %s (SHT3xD)", dev->name); goto check_pressure; @@ -101,7 +126,7 @@ int env_sensors_init(void) /* BME280 — temperature + humidity + pressure */ dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(bme280)); - if (dev && device_is_ready(dev)) { + if (sensor_ready(dev)) { temp_humidity_dev = dev; temp_dev_has_pressure = true; LOG_INF("Found env sensor: %s (BME280 — temp/humidity/pressure)", dev->name); @@ -110,7 +135,7 @@ int env_sensors_init(void) /* BME680 — temperature + humidity + pressure (+ gas) */ dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(bme680)); - if (dev && device_is_ready(dev)) { + if (sensor_ready(dev)) { temp_humidity_dev = dev; temp_dev_has_pressure = true; LOG_INF("Found env sensor: %s (BME680 — temp/humidity/pressure)", dev->name); @@ -123,7 +148,7 @@ check_pressure: if (!temp_dev_has_pressure) { /* LPS22HB (e.g., RAK1902) */ dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(lps22hb)); - if (dev && device_is_ready(dev)) { + if (sensor_ready(dev)) { pressure_dev = dev; LOG_INF("Found pressure sensor: %s (LPS22HB)", dev->name); goto done; @@ -131,7 +156,7 @@ check_pressure: /* BMP280 — pressure + temperature (lower priority as temp source) */ dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(bmp280)); - if (dev && device_is_ready(dev)) { + if (sensor_ready(dev)) { pressure_dev = dev; LOG_INF("Found pressure sensor: %s (BMP280)", dev->name); goto done; @@ -139,7 +164,7 @@ check_pressure: /* BMP388 */ dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(bmp388)); - if (dev && device_is_ready(dev)) { + if (sensor_ready(dev)) { pressure_dev = dev; LOG_INF("Found pressure sensor: %s (BMP388)", dev->name); goto done; @@ -148,10 +173,10 @@ check_pressure: /* SPA06 — the two nodes are the same part at its two possible * addresses; the one that isn't there fails its ID check. */ dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(spa06)); - if (!dev || !device_is_ready(dev)) { + if (!sensor_ready(dev)) { dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(spa06_alt)); } - if (dev && device_is_ready(dev)) { + if (sensor_ready(dev)) { pressure_dev = dev; LOG_INF("Found pressure sensor: %s (SPA06)", dev->name); goto done; @@ -273,7 +298,7 @@ int power_sensors_init(void) /* INA3221 — 3-channel power monitor (check first — most channels) */ dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(ina3221)); - if (dev && device_is_ready(dev)) { + if (sensor_ready(dev)) { ina_dev = dev; ina_found = INA_3221; ina_num_channels = 3; @@ -284,7 +309,7 @@ int power_sensors_init(void) /* INA219 — standalone single-channel */ dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(ina219)); - if (dev && device_is_ready(dev)) { + if (sensor_ready(dev)) { ina_dev = dev; ina_found = INA_219; ina_num_channels = 1; @@ -295,22 +320,22 @@ int power_sensors_init(void) /* ina2xx unified family — try all supported variants */ dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(ina226)); - if (!dev || !device_is_ready(dev)) { + if (!sensor_ready(dev)) { dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(ina228)); } - if (!dev || !device_is_ready(dev)) { + if (!sensor_ready(dev)) { dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(ina230)); } - if (!dev || !device_is_ready(dev)) { + if (!sensor_ready(dev)) { dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(ina232)); } - if (!dev || !device_is_ready(dev)) { + if (!sensor_ready(dev)) { dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(ina236)); } - if (!dev || !device_is_ready(dev)) { + if (!sensor_ready(dev)) { dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(ina237)); } - if (dev && device_is_ready(dev)) { + if (sensor_ready(dev)) { ina_dev = dev; ina_found = INA_2XX; ina_num_channels = 1; diff --git a/zephcore/adapters/sensors/spa06.c b/zephcore/adapters/sensors/spa06.c index 3fc5562..bd49c84 100644 --- a/zephcore/adapters/sensors/spa06.c +++ b/zephcore/adapters/sensors/spa06.c @@ -171,11 +171,17 @@ static int spa06_init(const struct device *dev) int rc; if (!i2c_is_ready_dt(&cfg->bus)) { + LOG_ERR("I2C bus %s not ready", cfg->bus.bus->name); return -ENODEV; } + /* Probe failures stay at debug level: a board may declare the part at both + * of its possible addresses and let the absent one fail here. Everything + * past this point is a part that answered and then went wrong, so those + * are errors. */ rc = i2c_reg_read_byte_dt(&cfg->bus, SPA06_REG_ID, &id); if (rc < 0) { + LOG_DBG("no answer at 0x%02x (id read: %d)", cfg->bus.addr, rc); return -ENODEV; } if (id != SPA06_CHIP_ID) { @@ -185,6 +191,7 @@ static int spa06_init(const struct device *dev) rc = i2c_reg_write_byte_dt(&cfg->bus, SPA06_REG_RESET, SPA06_SOFT_RESET); if (rc < 0) { + LOG_ERR("SPA06 soft reset failed: %d", rc); return rc; } k_msleep(15); @@ -204,6 +211,7 @@ static int spa06_init(const struct device *dev) ready: rc = spa06_read_coefficients(dev); if (rc < 0) { + LOG_ERR("SPA06 coefficient read failed: %d", rc); return rc; } @@ -222,6 +230,7 @@ ready: SPA06_MEAS_CONT_BOTH); } if (rc < 0) { + LOG_ERR("SPA06 configuration failed: %d", rc); return rc; } diff --git a/zephcore/boards/esp32/heltec_wireless_tracker_v2/heltec_wireless_tracker_v2_procpu.dts b/zephcore/boards/esp32/heltec_wireless_tracker_v2/heltec_wireless_tracker_v2_procpu.dts index 793a083..aa6f098 100644 --- a/zephcore/boards/esp32/heltec_wireless_tracker_v2/heltec_wireless_tracker_v2_procpu.dts +++ b/zephcore/boards/esp32/heltec_wireless_tracker_v2/heltec_wireless_tracker_v2_procpu.dts @@ -85,6 +85,14 @@ enable-gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>; regulator-boot-on; regulator-always-on; + /* Documents the rail's requirement, but do not rely on it. It is + * inert twice over: regulator-boot-on sends regulator_common_init() + * down the refcount-only branch so regulator_delay() never runs, and + * regulator-always-on makes regulator_enable() return at its first + * line. The real settle time comes from the ST7735R driver's own + * mipi_dbi_reset() + exit-sleep delay at DISPLAY_INIT_PRIORITY 85; + * the GNSS side is safe because gnss-nmea-generic never probes the + * receiver, it just parses whatever the UART delivers. */ startup-delay-us = <10000>; }; @@ -112,6 +120,9 @@ enable-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>; regulator-boot-on; regulator-always-on; + /* Documents the FEM's requirement, but do not rely on it — inert for + * the same two reasons as vext above. Harmless because the FEM is a + * passive gain block with no bus to probe. */ startup-delay-us = <1000>; }; diff --git a/zephcore/boards/nrf52840/heltec_t096/heltec_t096_nrf52840.dts b/zephcore/boards/nrf52840/heltec_t096/heltec_t096_nrf52840.dts index 9d7964c..2a009f7 100644 --- a/zephcore/boards/nrf52840/heltec_t096/heltec_t096_nrf52840.dts +++ b/zephcore/boards/nrf52840/heltec_t096/heltec_t096_nrf52840.dts @@ -87,6 +87,14 @@ regulator-name = "gps-power"; enable-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; regulator-boot-on; + /* Documents the module's requirement, but do not rely on it: + * regulator-boot-on sends regulator_common_init() down the + * refcount-only branch, so regulator_delay() never runs and this + * value is inert. Harmless here because gnss-nmea-generic never + * probes the receiver — it attaches a UART and parses whatever + * arrives, so an unpowered module means no sentences yet, not a + * failed init. ZephyrGPSManager owns the rail at runtime via + * chosen { zephcore,gps-power }. */ startup-delay-us = <10000>; }; @@ -105,6 +113,11 @@ regulator-name = "vfem-enable"; enable-gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>; regulator-boot-on; + /* Documents the FEM's requirement, but do not rely on it: + * regulator-boot-on sends regulator_common_init() down the + * refcount-only branch, so regulator_delay() never runs and this + * value is inert. Harmless here because the FEM is a passive + * gain block with no bus to probe — nothing addresses it at init. */ startup-delay-us = <1000>; }; @@ -124,6 +137,12 @@ regulator-name = "tft-pwr-enable"; enable-gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>; regulator-boot-on; + /* Documents the panel's requirement, but do not rely on it: + * regulator-boot-on sends regulator_common_init() down the + * refcount-only branch, so regulator_delay() never runs and this + * value is inert. The real settle time comes from the ST7735R + * driver's own mipi_dbi_reset() + exit-sleep delay, at + * DISPLAY_INIT_PRIORITY 85 against this rail's 75. */ startup-delay-us = <10000>; }; diff --git a/zephcore/boards/nrf52840/lilygo_techo/lilygo_techo.dts b/zephcore/boards/nrf52840/lilygo_techo/lilygo_techo.dts index bf6e0d6..c9e900a 100644 --- a/zephcore/boards/nrf52840/lilygo_techo/lilygo_techo.dts +++ b/zephcore/boards/nrf52840/lilygo_techo/lilygo_techo.dts @@ -144,7 +144,17 @@ * 3. tcxo_enable (P0.21) — external TCXO for SX1262 * * These are all regulator-fixed with regulator-boot-on so Zephyr's - * regulator framework brings them up before the SX1262 driver init. */ + * regulator framework brings them up before the SX1262 driver init — + * REGULATOR_FIXED_INIT_PRIORITY 75 against LORA_INIT_PRIORITY 90. + * + * Ordering is all that guarantee covers. It does NOT mean a rail has + * settled: regulator-boot-on sends regulator_common_init() down the + * refcount-only branch, so regulator_delay() never runs and the + * startup-delay-us below is inert. The SX1262 is safe because its driver + * resets the part (5 ms NRESET pulse + 5 ms wait + BUSY poll) before any + * SPI traffic. Anything put behind these rails that does NOT + * reset-then-wait needs zephyr,deferred-init instead; see + * meshtracker_x1's i2c0 for what that failure looks like. */ pwr_enable: pwr-enable { compatible = "regulator-fixed"; diff --git a/zephcore/boards/nrf52840/lilygo_timpulse_plus/lilygo_timpulse_plus.dts b/zephcore/boards/nrf52840/lilygo_timpulse_plus/lilygo_timpulse_plus.dts index 50f40a9..008cbaf 100644 --- a/zephcore/boards/nrf52840/lilygo_timpulse_plus/lilygo_timpulse_plus.dts +++ b/zephcore/boards/nrf52840/lilygo_timpulse_plus/lilygo_timpulse_plus.dts @@ -125,6 +125,14 @@ regulator-name = "pwr-enable"; enable-gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>; regulator-boot-on; + /* Documents the LDO's requirement, but do not rely on it: + * regulator-boot-on sends regulator_common_init() down the + * refcount-only branch, so regulator_delay() never runs and this + * value is inert. What actually gives this rail time to settle is the + * priority-30 pin above — every consumer here (QSPI 41, OLED 85, + * SX1262 90) has real boot work between it and the rail, and the + * SX1262 and SSD1315 both reset-then-wait besides. The GPS, which + * does neither, is zephyr,deferred-init for that reason. */ startup-delay-us = <10000>; }; diff --git a/zephcore/boards/nrf52840/meshtracker_x1/meshtracker_x1_nrf52840.dts b/zephcore/boards/nrf52840/meshtracker_x1/meshtracker_x1_nrf52840.dts index 7491a1f..a2960d2 100644 --- a/zephcore/boards/nrf52840/meshtracker_x1/meshtracker_x1_nrf52840.dts +++ b/zephcore/boards/nrf52840/meshtracker_x1/meshtracker_x1_nrf52840.dts @@ -285,24 +285,42 @@ pinctrl-1 = <&i2c0_sleep>; pinctrl-names = "default", "sleep"; - /* Sealed enclosure — only these two parts are ever on this bus */ + /* Sealed enclosure — only these two parts are ever on this bus, and both + * sit behind the sensor_power switch. NEITHER can be probed at POST_KERNEL. + * + * sensor_power comes up at CONFIG_REGULATOR_FIXED_INIT_PRIORITY (75) and + * both drivers run at 90 — microseconds later, with nothing scheduled in + * between on this board. The node's startup-delay-us does not save them: + * with regulator-boot-on, regulator_common_init() takes the refcount-only + * branch and regulator_delay() never runs. Same trap as flash_power below. + * (vin-supply + regulator_enable() would not help either — that applies + * off-on-delay-us, and only on the 0->1 refcount transition.) + * + * So both nodes are deferred and the app owns their bring-up, by which + * time the rail has been up for seconds: + * SPA06 -> env_sensors_init() (adapters/sensors/ZephyrEnvSensors.cpp) + * DRV2605 -> haptic_init() (helpers/ui/haptic.c) + * + * Do not "simplify" one of these back to a normal probe. An earlier + * revision deferred only the DRV2605, and the SPA06 — which sorts after it + * within POST_KERNEL priority 90, since equal-priority devices order by DT + * dependency ordinal and drv2605@5a sorts before spa06@77 — silently lost + * the settling time it had been borrowing from the DRV2605's failing probe. + * The barometer had "worked" only by that accident, and went dead the day + * the haptic was fixed. */ spa06: spa06@77 { compatible = "goertek,spa06"; reg = <0x77>; + zephyr,deferred-init; }; - /* Deferred-init so haptic_init() owns the power-up sequence. - * - * Upstream's drv2605_init() spends DRV2605_POWER_UP_DELAY_US *before* - * drv2605_gpio_config() raises en-gpios, then reads the status register - * over I2C immediately after — so the part gets no settling time at all - * between EN rising and its first transaction, and NACKs. Deferring the - * node is what lets us assert EN and wait first; without it the driver - * has already run (and failed) by the time the app gets a say, and - * device_init() would just answer -EALREADY. - * - * Not a rail problem: the SPA06 shares this bus, this rail and this init - * priority and comes up fine. The enable pin is the only difference. */ + /* Deferring this one also lets haptic_init() assert EN and wait before the + * first transaction. Upstream's drv2605_init() spends its + * DRV2605_POWER_UP_DELAY_US *before* drv2605_gpio_config() raises en-gpios, + * then reads the status register over I2C immediately after — so the part + * gets no settling time at all between EN rising and being addressed, and + * NACKs. Without the deferral the driver has already run (and failed) by + * the time the app gets a say, and device_init() would answer -EALREADY. */ haptic: drv2605@5a { compatible = "ti,drv2605"; reg = <0x5a>; diff --git a/zephcore/boards/nrf52840/promicro_lr2021/promicro_lr2021.dts b/zephcore/boards/nrf52840/promicro_lr2021/promicro_lr2021.dts index c7df359..07da283 100644 --- a/zephcore/boards/nrf52840/promicro_lr2021/promicro_lr2021.dts +++ b/zephcore/boards/nrf52840/promicro_lr2021/promicro_lr2021.dts @@ -62,6 +62,14 @@ regulator-name = "vcc3v3-enable"; enable-gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>; regulator-boot-on; + /* Documents the module's requirement, but do not rely on it: + * regulator-boot-on sends regulator_common_init() down the + * refcount-only branch, so regulator_delay() never runs and this + * value is inert. The real settle time comes from lr20xx_hal_reset(), + * which the driver runs (with two retries, 10 ms apart) before any + * SPI traffic — and at LORA_INIT_PRIORITY 90 against this rail's 75. + * Anything put behind this rail that does NOT reset-then-wait needs + * zephyr,deferred-init instead; see meshtracker_x1's i2c0. */ startup-delay-us = <5000>; }; diff --git a/zephcore/boards/nrf52840/promicro_sx1262/promicro_sx1262.dts b/zephcore/boards/nrf52840/promicro_sx1262/promicro_sx1262.dts index be981e9..faf030d 100644 --- a/zephcore/boards/nrf52840/promicro_sx1262/promicro_sx1262.dts +++ b/zephcore/boards/nrf52840/promicro_sx1262/promicro_sx1262.dts @@ -63,6 +63,14 @@ regulator-name = "vcc3v3-enable"; enable-gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>; regulator-boot-on; + /* Documents the module's requirement, but do not rely on it: + * regulator-boot-on sends regulator_common_init() down the + * refcount-only branch, so regulator_delay() never runs and this + * value is inert. The real settle time comes from the SX126x driver's + * own reset (5 ms NRESET pulse + 5 ms wait + BUSY poll) before any + * SPI traffic, at LORA_INIT_PRIORITY 90 against this rail's 75. + * Anything put behind this rail that does NOT reset-then-wait needs + * zephyr,deferred-init instead; see meshtracker_x1's i2c0. */ startup-delay-us = <5000>; }; diff --git a/zephcore/boards/nrf52840/rak3401_1watt/rak3401_1watt.dts b/zephcore/boards/nrf52840/rak3401_1watt/rak3401_1watt.dts index c9b9a20..8af7387 100644 --- a/zephcore/boards/nrf52840/rak3401_1watt/rak3401_1watt.dts +++ b/zephcore/boards/nrf52840/rak3401_1watt/rak3401_1watt.dts @@ -93,6 +93,14 @@ regulator-name = "lora-pwr-enable"; enable-gpios = <&gpio0 21 GPIO_ACTIVE_HIGH>; regulator-boot-on; + /* Documents the FEM's requirement, but do not rely on it: + * regulator-boot-on sends regulator_common_init() down the + * refcount-only branch, so regulator_delay() never runs and this + * value is inert. The real settle time comes from the SX126x driver's + * own reset (5 ms NRESET pulse + 5 ms wait + BUSY poll) before any + * SPI traffic, at LORA_INIT_PRIORITY 90 against this rail's 75. + * Anything put behind this rail that does NOT reset-then-wait needs + * zephyr,deferred-init instead; see meshtracker_x1's i2c0. */ startup-delay-us = <10000>; }; diff --git a/zephcore/boards/nrf52840/rak_wismesh_tag/rak_wismesh_tag.dts b/zephcore/boards/nrf52840/rak_wismesh_tag/rak_wismesh_tag.dts index 546ddd0..33120de 100644 --- a/zephcore/boards/nrf52840/rak_wismesh_tag/rak_wismesh_tag.dts +++ b/zephcore/boards/nrf52840/rak_wismesh_tag/rak_wismesh_tag.dts @@ -120,6 +120,14 @@ regulator-name = "lora-pwr-enable"; enable-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; regulator-boot-on; + /* Documents the module's requirement, but do not rely on it: + * regulator-boot-on sends regulator_common_init() down the + * refcount-only branch, so regulator_delay() never runs and this + * value is inert. The real settle time comes from the SX126x driver's + * own reset (5 ms NRESET pulse + 5 ms wait + BUSY poll) before any + * SPI traffic, at LORA_INIT_PRIORITY 90 against this rail's 75. + * Anything put behind this rail that does NOT reset-then-wait needs + * zephyr,deferred-init instead; see meshtracker_x1's i2c0. */ startup-delay-us = <10000>; };