overlay-jedi: Userspace power sequence for Rolling Wireless LTE module
1.Add lte_power_control enable flags
2.Control power sequence (gpios) from userspace upstart script
BUG=b:440194776
TEST=emerge-jedi lte_power_control
Change-Id: I4cc4a27b58991fe47c59ea332c4a5b2a376d3914
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/overlays/board-overlays/+/6869511
Commit-Queue: zhao wang <wangzhao5@huaqin.corp-partner.google.com>
Reviewed-by: Oscar Liu <oscarliu@google.com>
Reviewed-by: Knox Chiou <knoxchiou@chromium.org>
Tested-by: zhao wang <wangzhao5@huaqin.corp-partner.google.com>
Reviewed-by: Zhengqiao Xia <xiazhengqiao@huaqin.corp-partner.google.com>
diff --git a/overlay-jedi/chromeos-base/chromeos-bsp-jedi/chromeos-bsp-jedi-9999.ebuild b/overlay-jedi/chromeos-base/chromeos-bsp-jedi/chromeos-bsp-jedi-9999.ebuild
index d91ab6f..de09d3d 100644
--- a/overlay-jedi/chromeos-base/chromeos-bsp-jedi/chromeos-bsp-jedi-9999.ebuild
+++ b/overlay-jedi/chromeos-base/chromeos-bsp-jedi/chromeos-bsp-jedi-9999.ebuild
@@ -24,6 +24,7 @@
RDEPEND="
chromeos-base/chromeos-config
chromeos-base/chromeos-bsp-baseboard-skywalker
+ chromeos-base/lte_power_control
"
DEPEND="
${RDEPEND}
diff --git a/overlay-jedi/chromeos-base/lte_power_control/files/lte_power_control b/overlay-jedi/chromeos-base/lte_power_control/files/lte_power_control
new file mode 100644
index 0000000..1d18975
--- /dev/null
+++ b/overlay-jedi/chromeos-base/lte_power_control/files/lte_power_control
@@ -0,0 +1,153 @@
+#!/bin/bash
+# Copyright 2025 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Init gpio for Rolling Wireless LTE module
+
+readonly GPIO_DIR="/sys/class/gpio"
+
+declare -A RW135
+
+# RW135 GPIO Device and offset values
+RW135["GPIO_DEVICE"]="10005000.pinctrl"
+RW135["LTE_W_DISABLE_OFFSET"]=148
+RW135["LTE_SAR_DETECT_OFFSET"]=124
+RW135["LTE_EN_OFFSET"]=121
+RW135["LTE_PWR_OFF_OFFSET"]=147
+RW135["LTE_RESET_OFFSET"]=10
+RW135["DISABLE_RESET_SLEEP"]=0.02
+RW135["DISABLE_PWR_SLEEP"]=0.1
+RW135["SLEEP_AFTER_ENABLE"]=0.002
+RW135["SLEEP_AFTER_ENABLE_PWR"]=0.014
+
+declare -A RW101
+
+# RW101 GPIO Device and offset values
+RW101["GPIO_DEVICE"]="10005000.pinctrl"
+RW101["LTE_W_DISABLE_OFFSET"]=148
+RW101["LTE_SAR_DETECT_OFFSET"]=124
+RW101["LTE_EN_OFFSET"]=121
+RW101["LTE_PWR_OFF_OFFSET"]=147
+RW101["LTE_RESET_OFFSET"]=10
+RW101["DISABLE_RESET_SLEEP"]=0.02
+RW101["DISABLE_PWR_SLEEP"]=0.1
+RW101["SLEEP_AFTER_ENABLE"]=0.002
+RW101["SLEEP_AFTER_ENABLE_PWR"]=0.014
+
+get_gpio_base() {
+ local GPIO_DEVICE="${1}"
+ dir_list=$(find /sys/class/gpio -type l -name "gpiochip*")
+ for d in ${dir_list}; do
+ DEVICE=$(basename "$(readlink "${d}/device")")
+ if [ "${DEVICE}" = "${GPIO_DEVICE}" ]; then
+ BASE=$(cat "${d}/base")
+ break
+ fi
+ done
+ if [ -z "${BASE}" ]; then
+ # Base not set, exiting.
+ exit 0
+ fi
+ echo "${BASE}"
+}
+
+disable_modem() {
+ local -n MODEM=${1}
+ local BASE
+ BASE=$(get_gpio_base "${MODEM[GPIO_DEVICE]}")
+ # lte-w-disable
+ disable_gpio $((BASE + MODEM["LTE_W_DISABLE_OFFSET"]))
+
+ # sar-detect
+ disable_gpio $((BASE + MODEM["LTE_SAR_DETECT_OFFSET"]))
+
+ # reset and sleep 20ms
+ disable_gpio $((BASE + MODEM["LTE_RESET_OFFSET"]))
+ sleep "${MODEM[DISABLE_RESET_SLEEP]}"
+
+ # poweroff and sleep 100ms
+ disable_gpio $((BASE + MODEM["LTE_PWR_OFF_OFFSET"]))
+ sleep "${MODEM[DISABLE_PWR_SLEEP]}"
+
+ # m2-power
+ disable_gpio $((BASE + MODEM["LTE_EN_OFFSET"]))
+}
+
+enable_modem() {
+ local -n MODEM=${1}
+ local BASE
+ BASE=$(get_gpio_base "${MODEM[GPIO_DEVICE]}")
+ # lte-w-disable
+ echo $((BASE + MODEM["LTE_W_DISABLE_OFFSET"]))
+ enable_gpio $((BASE + MODEM["LTE_W_DISABLE_OFFSET"]))
+
+ # sar-detect"
+ enable_gpio $((BASE + MODEM["LTE_SAR_DETECT_OFFSET"]))
+
+ # m2-power and sleep 2ms
+ enable_gpio $((BASE + MODEM["LTE_EN_OFFSET"]))
+ sleep "${MODEM[SLEEP_AFTER_ENABLE]}"
+
+ # poweroff and sleep 14ms
+ enable_gpio $((BASE + MODEM["LTE_PWR_OFF_OFFSET"]))
+ sleep "${MODEM[SLEEP_AFTER_ENABLE_PWR]}"
+
+ #reset
+ enable_gpio $((BASE + MODEM["LTE_RESET_OFFSET"]))
+}
+
+set_gpio() {
+ local gpio="$1"
+ local gpio_level="$2"
+ local gpio_path
+ gpio_path="${GPIO_DIR}/gpio${gpio}"
+ if [ ! -e "${gpio_path}" ]; then
+ echo "${gpio}" > "${GPIO_DIR}/export"
+ ret="$?"
+ if [ "${ret}" -ne 0 ]; then
+ exit 1
+ fi
+ fi
+ echo "${gpio_level}" > "${gpio_path}/direction"
+ echo "${gpio}" > "${GPIO_DIR}/unexport"
+}
+
+disable_gpio() {
+ local gpio="$1"
+ set_gpio "${gpio}" "low"
+}
+
+enable_gpio() {
+ local gpio="$1"
+ set_gpio "${gpio}" "high"
+}
+
+main() {
+ local fw
+ fw=$(cros_config /modem firmware-variant)
+ if [ -z "${fw}" ]; then
+ exit 0
+ fi
+
+ if [ "$1" = "on" ]; then
+ case ${fw#*_} in
+ "rw135")
+ enable_modem RW135
+ ;;
+ "rw101")
+ enable_modem RW101
+ ;;
+ esac
+ else
+ case ${fw#*_} in
+ "rw135")
+ disable_modem RW135
+ ;;
+ "rw101")
+ disable_modem RW101
+ ;;
+ esac
+ fi
+}
+main "$@"
diff --git a/overlay-jedi/chromeos-base/lte_power_control/files/lte_power_off.conf b/overlay-jedi/chromeos-base/lte_power_control/files/lte_power_off.conf
new file mode 100644
index 0000000..3a91096
--- /dev/null
+++ b/overlay-jedi/chromeos-base/lte_power_control/files/lte_power_off.conf
@@ -0,0 +1,13 @@
+# Copyright 2025 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+description "Shutdown gpio power sequence for Rolling Wireless LTE module"
+author "chromium-os-dev@chromium.org"
+
+oom score -100
+
+start on starting halt or starting reboot
+task
+
+exec lte_power_control off
diff --git a/overlay-jedi/chromeos-base/lte_power_control/files/lte_power_on.conf b/overlay-jedi/chromeos-base/lte_power_control/files/lte_power_on.conf
new file mode 100644
index 0000000..a017285
--- /dev/null
+++ b/overlay-jedi/chromeos-base/lte_power_control/files/lte_power_on.conf
@@ -0,0 +1,16 @@
+# Copyright 2025 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+description "Init gpio power sequence for Rolling Wireless LTE module"
+author "chromium-os-dev@chromium.org"
+
+respawn
+respawn limit 3 10
+
+oom score -100
+
+start on starting boot-services
+task
+
+exec lte_power_control on
diff --git a/overlay-jedi/chromeos-base/lte_power_control/lte_power_control-0.0.1-r1.ebuild b/overlay-jedi/chromeos-base/lte_power_control/lte_power_control-0.0.1-r1.ebuild
new file mode 120000
index 0000000..ae32d5c
--- /dev/null
+++ b/overlay-jedi/chromeos-base/lte_power_control/lte_power_control-0.0.1-r1.ebuild
@@ -0,0 +1 @@
+lte_power_control-0.0.1.ebuild
\ No newline at end of file
diff --git a/overlay-jedi/chromeos-base/lte_power_control/lte_power_control-0.0.1.ebuild b/overlay-jedi/chromeos-base/lte_power_control/lte_power_control-0.0.1.ebuild
new file mode 100644
index 0000000..e4a456e
--- /dev/null
+++ b/overlay-jedi/chromeos-base/lte_power_control/lte_power_control-0.0.1.ebuild
@@ -0,0 +1,20 @@
+# Copyright 2025 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+EAPI=7
+
+DESCRIPTION="Init power sequence for Rolling Wireless LTE module"
+
+LICENSE="BSD-Google"
+SLOT="0"
+KEYWORDS="-* arm64 arm"
+IUSE=""
+S="${WORKDIR}"
+
+src_install() {
+ dosbin "${FILESDIR}"/lte_power_control
+ insinto /etc/init
+ doins "${FILESDIR}"/lte_power_on.conf
+ doins "${FILESDIR}"/lte_power_off.conf
+}