~mil/sxmo-devel

sxmo-utils: LEDs: Add support for rgb multi-intensity device (OnePlus 6) v4 PROPOSED

Zach DeCook: 1
 LEDs: Add support for rgb multi-intensity device (OnePlus 6)

 7 files changed, 97 insertions(+), 18 deletions(-)
#1049652 test.yml success
Hey Anjan ~

We already added brightnessctl dependency when light has been dropped.
So using it to manage led is a no cost choice.

I don't know about multi-intensity devices, I don't own any :(
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~mil/sxmo-devel/patches/44149/mbox | git am -3
Learn more about email & git

[PATCH sxmo-utils v4] LEDs: Add support for rgb multi-intensity device (OnePlus 6) Export this patch

---
 .../default_hooks/sxmo_hook_contextmenu.sh    |   2 +-
 configs/udev/90-sxmo.rules                    |   2 +
 scripts/core/sxmo_flashtoggle.sh              |   2 +-
 scripts/core/sxmo_led.sh                      | 103 +++++++++++++++---
 scripts/deviceprofiles/README.md              |   2 +
 .../sxmo_deviceprofile_oneplus,enchilada.sh   |   2 +-
 .../sxmo_deviceprofile_oneplus,fajita.sh      |   2 +-
 7 files changed, 97 insertions(+), 18 deletions(-)

diff --git a/configs/default_hooks/sxmo_hook_contextmenu.sh b/configs/default_hooks/sxmo_hook_contextmenu.sh
index cc3273f..89a0463 100755
--- a/configs/default_hooks/sxmo_hook_contextmenu.sh
+++ b/configs/default_hooks/sxmo_hook_contextmenu.sh
@@ -672,7 +672,7 @@ case "$WMCLASS" in
			$(
				if [ -z "$SXMO_DISABLE_LEDS" ]; then
					printf "%s Flashlight " "$icon_fll"
					sxmo_led.sh get white | grep -vq ^100$ &&
					sxmo_led.sh get white | grep -vq ^100.00$ &&
						printf %b "$icon_tof" ||  printf %b "$icon_ton";
					printf %b "^ 1 ^ sxmo_flashtoggle.sh"
				fi
diff --git a/configs/udev/90-sxmo.rules b/configs/udev/90-sxmo.rules
index e5ac382..2f469ca 100644
--- a/configs/udev/90-sxmo.rules
+++ b/configs/udev/90-sxmo.rules
@@ -22,3 +22,5 @@ ACTION=="add", SUBSYSTEM=="backlight", RUN+="/bin/chgrp video /sys/class/backlig
ACTION=="add", SUBSYSTEM=="backlight", RUN+="/bin/chmod g+w /sys/class/backlight/%k/brightness"
ACTION=="add", SUBSYSTEM=="leds", RUN+="/bin/chgrp video /sys/class/leds/%k/brightness"
ACTION=="add", SUBSYSTEM=="leds", RUN+="/bin/chmod g+w /sys/class/leds/%k/brightness"
ACTION=="add", SUBSYSTEM=="leds", RUN+="/bin/chgrp video /sys/class/leds/%k/multi_intensity"
ACTION=="add", SUBSYSTEM=="leds", RUN+="/bin/chmod g+w /sys/class/leds/%k/multi_intensity"
diff --git a/scripts/core/sxmo_flashtoggle.sh b/scripts/core/sxmo_flashtoggle.sh
index 7fe835f..ca7e62a 100755
--- a/scripts/core/sxmo_flashtoggle.sh
+++ b/scripts/core/sxmo_flashtoggle.sh
@@ -2,7 +2,7 @@
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2022 Sxmo Contributors

if sxmo_led.sh get white | grep -vq ^100$; then
if sxmo_led.sh get white | grep -vq ^100.00$; then
	sxmo_led.sh set white 100
else
	sxmo_led.sh set white 0
diff --git a/scripts/core/sxmo_led.sh b/scripts/core/sxmo_led.sh
index 82ee540..5c24863 100755
--- a/scripts/core/sxmo_led.sh
+++ b/scripts/core/sxmo_led.sh
@@ -13,7 +13,11 @@ get_type() {
	# Defaults
	if [ -z "$type" ]; then
		case $1 in
			red|green|blue) type="indicator" ;;
			red|green|blue)
				if [ -z "$SXMO_LED_RGB_TYPE" ]; then
					type="indicator"
				fi
				;;
			white) type="flash" ;;
		esac
	fi
@@ -31,10 +35,20 @@ get_led() {
	[ $# -lt 1 ] && usage

	type="$(get_type "$color")";

	value="$(cat "/sys/class/leds/$color:$type/brightness")"
	if [ -n "$type" ]; then
		value="$(cat "/sys/class/leds/$color:$type/brightness")"
	elif [ -n "$SXMO_LED_RGB_TYPE" ]; then
		get_leds_rgb_raw
		value="$(eval echo '$'"$color")"
		color="rgb"
		type="$SXMO_LED_RGB_TYPE"
	else
		printf "unknown color: %s" "$color" >/dev/stderr
		exit 1
	fi
	max="$(cat "/sys/class/leds/$color:$type/max_brightness")"
	printf "scale=0; %s / %s * 100\n" "$value" "$max" | bc -l

	to_percent "$value" "$max"
}

set_led() {
@@ -55,11 +69,15 @@ set_led() {
	fi

	max="$(cat "/sys/class/leds/$color:$type/max_brightness")"
	brightness="$(echo "($percent / 100.0) * $max" | bc -l)"
	brightness="$(from_percent "$percent" "$max")"
	printf "%0.f\n" "$brightness" > "/sys/class/leds/$color:$type/brightness"
}

set_leds() {
	if [ "$1" != "white" ] && [ "$SXMO_LED_RGB_TYPE" ]; then
		set_leds_rgb "$@"
		return
	fi
	while [ "$#" -ge 2 ]; do
		set_led "$1" "$2" &
		shift 2
@@ -68,6 +86,66 @@ set_leds() {
	wait
}

set_leds_rgb() {
	# Fetch the current value of each of them before overwriting with parameters
	get_leds_rgb_raw
	max="$(cat "/sys/class/leds/rgb:${SXMO_LED_RGB_TYPE}/max_brightness")"
	while [ "$#" -ge 2 ]; do
		brightness="$(from_percent "$2" "$max")"
		eval "$1"="$brightness"
		shift 2
	done
	echo "$max" > "/sys/class/leds/rgb:${SXMO_LED_RGB_TYPE}/brightness"
	eval echo "$(sed 's/\(^\| \)/ \$/g' < "/sys/class/leds/rgb:${SXMO_LED_RGB_TYPE}/multi_index")" > \
		"/sys/class/leds/rgb:${SXMO_LED_RGB_TYPE}/multi_intensity"
}

store_leds() {
	if [ -n "$SXMO_LED_RGB_TYPE" ]; then
		store_leds_rgb
		return
	fi
	for color in green blue red white; do
		percent="$(get_led "$color")"
		eval "old_$color=$percent" # store old value
	done
}

to_percent() {
	value="${1:-0}"
	max="${2:-1}"
	# gets percent with two decimal places.
	printf "scale=2; %s * 100 / %s\n" "$value" "$max" | bc -l
}
from_percent() {
	percent="${1:-0}"
	max="${2:-1}"
	# Get brightness as an integer between 0 and $max, rounding at 0.5
	printf "%.f" "$(printf "scale=1; (%s * %s / 100) + 0.5\n" "$percent" "$max" | bc -l)"
}

store_leds_rgb() {
	get_leds_rgb_raw
	max="$(cat "/sys/class/leds/rgb:${SXMO_LED_RGB_TYPE}/max_brightness")"
	old_red="$(to_percent "${red:?}" "$max")"
	export old_red
	old_green="$(to_percent "${green:?}" "$max")"
	export old_green
	old_blue="$(to_percent "${blue:?}" "$max")"
	export old_blue
	unset green blue red
}
get_leds_rgb_raw() {
	# shellcheck disable=SC2046
	set -- $(cat "/sys/class/leds/rgb:${SXMO_LED_RGB_TYPE}/multi_intensity")
	i=1
	# shellcheck disable=SC2013
	for color in $(cat "/sys/class/leds/rgb:${SXMO_LED_RGB_TYPE}/multi_index"); do
		export "$color"="$(eval echo '$'$i)"
		i="$((i + 1))"
	done
}

finish_blinking() {
	sxmo_wakelock.sh unlock sxmo_playing_with_leds
	eval set_leds green '$'old_green blue '$'old_blue red '$'old_red ${white:+white '$'old_white}
@@ -75,14 +153,16 @@ finish_blinking() {
}

blink_leds() {
	for color in green blue red white; do
		percent="$(get_led "$color")"
		eval "old_$color=$percent" # store old value
	done
	store_leds

	sxmo_wakelock.sh lock sxmo_playing_with_leds 2s
	trap 'finish_blinking' TERM INT EXIT

	# shellcheck disable=SC2154
	set_leds green 0 blue 0 red 0 ${white:+white 0}

	sleep 0.1 # Make blink noticable

	while [ -n "$1" ]; do
		case "$1" in
			green|blue|red|white)
@@ -92,11 +172,6 @@ blink_leds() {
		esac
	done

	# shellcheck disable=SC2154
	set_leds green 0 blue 0 red 0 ${white:+white 0}

	sleep 0.1 # Make blink noticable

	set_leds green "${green:-0}" blue "${blue:-0}" red "${red:-0}" ${white:+white "${white:-0}"}

	sleep 0.1 # Make blink noticable
diff --git a/scripts/deviceprofiles/README.md b/scripts/deviceprofiles/README.md
index 116fdc7..dc97313 100644
--- a/scripts/deviceprofiles/README.md
+++ b/scripts/deviceprofiles/README.md
@@ -60,6 +60,8 @@ SXMO_LED_RED_TYPE		| LED device type, i.e., the part after the colon in the path

SXMO_LED_GREEN_TYPE		| LED device type, i.e., the part after the colon in the path: `/sys/class/leds/<color>:<type>` [default: status]

SXMO_LED_RGB_TYPE		| The type for a multi-intensity LED device (when defined, is an alternative to the RED, GREEN, and BLUE variables above). The part after the colon in the path: `/sys/class/leds/rgb:<type>`

SXMO_SWAY_SCALE		| Screen scale for hidpi screens. Can be fractional [SWAY-ONLY].

### Music-related
diff --git a/scripts/deviceprofiles/sxmo_deviceprofile_oneplus,enchilada.sh b/scripts/deviceprofiles/sxmo_deviceprofile_oneplus,enchilada.sh
index f41fd5d..02e8424 100755
--- a/scripts/deviceprofiles/sxmo_deviceprofile_oneplus,enchilada.sh
+++ b/scripts/deviceprofiles/sxmo_deviceprofile_oneplus,enchilada.sh
@@ -2,10 +2,10 @@
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2022 Sxmo Contributors

export SXMO_LED_RGB_TYPE="status"
export SXMO_VOLUME_BUTTON="1:1:Volume_keys"
export SXMO_POWER_BUTTON="0:0:pm8941_pwrkey"
export SXMO_MONITOR="DSI-1"
export SXMO_DISABLE_LEDS="1"
export SXMO_VIBRATE_DEV="/dev/input/by-path/platform-c440000.spmi-platform-c440000.spmi:pmic@3:haptics@c000-event"
export SXMO_VIBRATE_STRENGTH="5000"
export SXMO_SWAY_SCALE="3"
diff --git a/scripts/deviceprofiles/sxmo_deviceprofile_oneplus,fajita.sh b/scripts/deviceprofiles/sxmo_deviceprofile_oneplus,fajita.sh
index 65f5cb9..02e8424 100755
--- a/scripts/deviceprofiles/sxmo_deviceprofile_oneplus,fajita.sh
+++ b/scripts/deviceprofiles/sxmo_deviceprofile_oneplus,fajita.sh
@@ -2,7 +2,7 @@
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2022 Sxmo Contributors

export SXMO_DISABLE_LEDS="1"
export SXMO_LED_RGB_TYPE="status"
export SXMO_VOLUME_BUTTON="1:1:Volume_keys"
export SXMO_POWER_BUTTON="0:0:pm8941_pwrkey"
export SXMO_MONITOR="DSI-1"
-- 
2.42.0
sxmo-utils/patches/test.yml: SUCCESS in 45s

[LEDs: Add support for rgb multi-intensity device (OnePlus 6)][0] v4 from [Zach DeCook][1]

[0]: https://lists.sr.ht/~mil/sxmo-devel/patches/44149
[1]: mailto:zachdecook@librem.one

✓ #1049652 SUCCESS sxmo-utils/patches/test.yml https://builds.sr.ht/~mil/job/1049652
Hi!

Thank you for your patch. However, I wonder if supporting rgb
multi-intensity devices would be simpler using brightnessctl as
suggested here:

https://lists.sr.ht/~mil/sxmo-devel/patches/44136

I am not sure about the patch that adds brightnessctl but if
adding one more dependency allows us to support the one plus 6, I would
recommend merging in brightnessctl.

Thank you!
--
w:] www.momi.ca
pgp:] https://momi.ca/publickey.txt