From 49e70bd5f5cccc5d28caaa5c92bbd5d6f5691e2c Mon Sep 17 00:00:00 2001
From: Alistair Francis <alistair@alistair23.me>
Date: Mon, 25 Nov 2024 19:40:50 +1000
Subject: [PATCH] temp/iio-sensor-proxy: Support set_polling (MR 5853)

In order to reduce the power usage when using sensors let's implement
set_polling as described [1]. The patch was linked in the MR that adds
libssc support [2] and is from [3].

An alternative implementation is also avaliable [4], but that seems to
have GLib threading issues [5].

1: https://gitlab.postmarketos.org/postmarketOS/pmaports/-/issues/2455#note_453587
2: https://gitlab.freedesktop.org/hadess/iio-sensor-proxy/-/merge_requests/381#note_2567822
3: https://gitlab.freedesktop.org/verdre/iio-sensor-proxy/-/commit/7a7a5f3ea04ff4c134f3dbbbc005b8c26d0af300
4: https://gitlab.freedesktop.org/verdre/iio-sensor-proxy/-/commit/74a5860474b6e79cd6e3be13d1ff8dd9cd810b8b
5: https://mastodon.social/@verdre/113390737074625004

Signed-off-by: Alistair Francis <alistair@alistair23.me>
[ci:skip-build]: already built successfully in CI
---
 ...s-ssc-implement-set_polling-function.patch | 431 ++++++++++++++++++
 temp/iio-sensor-proxy/APKBUILD                |   4 +-
 2 files changed, 434 insertions(+), 1 deletion(-)
 create mode 100644 temp/iio-sensor-proxy/0009-drivers-ssc-implement-set_polling-function.patch

diff --git a/temp/iio-sensor-proxy/0009-drivers-ssc-implement-set_polling-function.patch b/temp/iio-sensor-proxy/0009-drivers-ssc-implement-set_polling-function.patch
new file mode 100644
index 00000000000..9090d48b8da
--- /dev/null
+++ b/temp/iio-sensor-proxy/0009-drivers-ssc-implement-set_polling-function.patch
@@ -0,0 +1,431 @@
+Patch-Source: https://gitlab.freedesktop.org/verdre/iio-sensor-proxy/-/commit/74a5860474b6e79cd6e3be13d1ff8dd9cd810b8b
+---
+From 7a7a5f3ea04ff4c134f3dbbbc005b8c26d0af300 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
+Date: Thu, 11 Jul 2024 23:19:34 +0200
+Subject: [PATCH] drivers/ssc: Implement set_polling function
+
+Seems like ssc doesn't like when ssc_sensor_*_open_sync() isn't called right
+after ssc_sensor_*_new_sync(), so move the call to new_sync() into
+set_polling(), too.
+---
+ src/drv-ssc-accel.c     | 73 ++++++++++++++++++++-------------------
+ src/drv-ssc-compass.c   | 75 ++++++++++++++++++++++-------------------
+ src/drv-ssc-light.c     | 72 ++++++++++++++++++++-------------------
+ src/drv-ssc-proximity.c | 73 ++++++++++++++++++++-------------------
+ 4 files changed, 155 insertions(+), 138 deletions(-)
+
+diff --git a/src/drv-ssc-accel.c b/src/drv-ssc-accel.c
+index 26364db..be26308 100644
+--- a/src/drv-ssc-accel.c
++++ b/src/drv-ssc-accel.c
+@@ -57,7 +57,7 @@ measurement_cb (SSCSensorAccelerometer *sensor, gfloat accel_x, gfloat accel_y,
+ 	DrvData *drv_data = (DrvData *) sensor_device->priv;
+ 	AccelReadings readings;
+ 	AccelVec3 tmp;
+-
++			g_debug ("recvd measure from accel");
+ 	tmp.x = accel_x;
+ 	tmp.y = accel_y;
+ 	tmp.z = accel_z;
+@@ -78,7 +78,6 @@ ssc_accelerometer_open (GUdevDevice *device)
+ {
+ 	SensorDevice *sensor_device;
+ 	DrvData *drv_data;
+-	g_autoptr (GError) error = NULL;
+ 
+ 	sensor_device = g_new0 (SensorDevice, 1);
+ 	sensor_device->priv = g_new0 (DrvData, 1);
+@@ -89,45 +88,50 @@ ssc_accelerometer_open (GUdevDevice *device)
+ 	drv_data->location = setup_accel_location (device);
+ 	set_accel_scale (&drv_data->scale, 1.0);
+ 
+-	/* Create sensor */
+-	drv_data->sensor = ssc_sensor_accelerometer_new_sync (NULL, &error);
+-	if (!drv_data->sensor) {
+-		g_warning ("Creating SSC accelerometer sensor failed: %s", error ? error->message : "UNKNOWN");
+-		return NULL;
+-	}
+-	g_object_get (drv_data->sensor,
+-                      SSC_SENSOR_NAME, &sensor_device->name,
+-		      NULL);
+-
+-	/* Start listening for measurements */
+-	drv_data->measurement_id = g_signal_connect (drv_data->sensor,
+-			                             "measurement",
+-						     G_CALLBACK (measurement_cb),
+-						     sensor_device);
+-
+-	/* Enable sensor */
+-	if (!ssc_sensor_accelerometer_open_sync (drv_data->sensor, NULL, &error)) {
+-		g_warning ("Opening SSC accelerometer sensor failed: %s", error ? error->message : "UNKNOWN");
+-		g_object_unref (sensor_device);
+-		return NULL;
+-	}
+-
+ 	return sensor_device;
+ }
+ 
+ static void
+-ssc_accelerometer_close (SensorDevice *sensor_device)
++ssc_accelerometer_set_polling (SensorDevice *sensor_device,
++			       gboolean state)
+ {
+-	g_autoptr (GError) error = NULL;
+ 	DrvData *drv_data = (DrvData *) sensor_device->priv;
++	g_autoptr (GError) error = NULL;
++	if (state) {
++		/* Create sensor */
++		drv_data->sensor = ssc_sensor_accelerometer_new_sync (NULL, &error);
++		if (!drv_data->sensor) {
++			g_warning ("Creating SSC accelerometer sensor failed: %s", error ? error->message : "UNKNOWN");
++			return;
++		}
++
++		/* Start listening for measurements */
++		drv_data->measurement_id = g_signal_connect (drv_data->sensor,
++					                     "measurement",
++							     G_CALLBACK (measurement_cb),
++							     sensor_device);
++
++		/* Enable sensor */
++		if (!ssc_sensor_accelerometer_open_sync (drv_data->sensor, NULL, &error)) {
++			g_warning ("Opening SSC accelerometer sensor failed: %s", error ? error->message : "UNKNOWN");
++			g_object_unref (sensor_device);
++			return;
++		}
++	} else {
++		/* Stop listening for measurements */
++		g_warn_if_fail (drv_data->measurement_id > 0);
++		g_signal_handler_disconnect (drv_data->sensor, drv_data->measurement_id);
++
++		/* Disable sensor */
++		if (!ssc_sensor_accelerometer_close_sync (drv_data->sensor, NULL, &error))
++			g_warning ("Closing SSC accelerometer sensor failed: %s", error ? error->message : "UNKNOWN");
++	}
++}
+ 
+-	/* Stop listening for measurements */
+-	g_warn_if_fail (drv_data->measurement_id > 0);
+-	g_signal_handler_disconnect (drv_data->sensor, drv_data->measurement_id);
+-
+-	/* Disable sensor */
+-	if (!ssc_sensor_accelerometer_close_sync (drv_data->sensor, NULL, &error))
+-		g_warning ("Closing SSC accelerometer sensor failed: %s", error ? error->message : "UNKNOWN");
++static void
++ssc_accelerometer_close (SensorDevice *sensor_device)
++{
++	DrvData *drv_data = (DrvData *) sensor_device->priv;
+ 
+ 	g_clear_object (&drv_data->sensor);
+ 	g_clear_pointer (&drv_data->mount_matrix, g_free);
+@@ -141,5 +145,6 @@ SensorDriver ssc_accel = {
+ 
+ 	.discover = ssc_accelerometer_discover,
+ 	.open = ssc_accelerometer_open,
++	.set_polling = ssc_accelerometer_set_polling,
+ 	.close = ssc_accelerometer_close,
+ };
+diff --git a/src/drv-ssc-compass.c b/src/drv-ssc-compass.c
+index 5e65c15..6dd032a 100644
+--- a/src/drv-ssc-compass.c
++++ b/src/drv-ssc-compass.c
+@@ -61,52 +61,57 @@ static SensorDevice *
+ ssc_compass_open (GUdevDevice *device)
+ {
+ 	SensorDevice *sensor_device;
+-	DrvData *drv_data;
+-	g_autoptr (GError) error = NULL;
+ 
+ 	sensor_device = g_new0 (SensorDevice, 1);
+ 	sensor_device->priv = g_new0 (DrvData, 1);
+-	drv_data = (DrvData *) sensor_device->priv;
+-
+-	/* Create sensor */
+-	drv_data->sensor = ssc_sensor_compass_new_sync (NULL, &error);
+-	if (!drv_data->sensor) {
+-		g_warning ("Creating SSC compass sensor failed: %s", error ? error->message : "UNKNOWN");
+-		return NULL;
+-	}
+-	g_object_get (drv_data->sensor,
+-                      SSC_SENSOR_NAME, &sensor_device->name,
+-		      NULL);
+-
+-	/* Start listening for measurements */
+-	drv_data->measurement_id = g_signal_connect (drv_data->sensor,
+-			                             "measurement",
+-						     G_CALLBACK (measurement_cb),
+-						     sensor_device);
+-
+-	/* Enable sensor */
+-	if (!ssc_sensor_compass_open_sync (drv_data->sensor, NULL, &error)) {
+-		g_warning ("Opening SSC compass sensor failed: %s", error ? error->message : "UNKNOWN");
+-		g_object_unref (sensor_device);
+-		return NULL;
+-	}
+ 
+ 	return sensor_device;
+ }
+ 
+ static void
+-ssc_compass_close (SensorDevice *sensor_device)
++ssc_compass_set_polling (SensorDevice *sensor_device,
++			 gboolean state)
+ {
+-	g_autoptr (GError) error = NULL;
+ 	DrvData *drv_data = (DrvData *) sensor_device->priv;
++	g_autoptr (GError) error = NULL;
++	if (state) {
++		/* Create sensor */
++		drv_data->sensor = ssc_sensor_compass_new_sync (NULL, &error);
++		if (!drv_data->sensor) {
++			g_warning ("Creating SSC compass sensor failed: %s", error ? error->message : "UNKNOWN");
++			return;
++		}
++		g_object_get (drv_data->sensor,
++		              SSC_SENSOR_NAME, &sensor_device->name,
++			      NULL);
++
++		/* Start listening for measurements */
++		drv_data->measurement_id = g_signal_connect (drv_data->sensor,
++					                     "measurement",
++							     G_CALLBACK (measurement_cb),
++							     sensor_device);
++
++		/* Enable sensor */
++		if (!ssc_sensor_compass_open_sync (drv_data->sensor, NULL, &error)) {
++			g_warning ("Opening SSC compass sensor failed: %s", error ? error->message : "UNKNOWN");
++			g_object_unref (sensor_device);
++			return;
++		}
++	} else {
++		/* Stop listening for measurements */
++		g_warn_if_fail (drv_data->measurement_id > 0);
++		g_signal_handler_disconnect (drv_data->sensor, drv_data->measurement_id);
++
++		/* Disable sensor */
++		if (!ssc_sensor_compass_close_sync (drv_data->sensor, NULL, &error))
++			g_warning ("Closing SSC compass sensor failed: %s", error ? error->message : "UNKNOWN");
++	}
++}
+ 
+-	/* Stop listening for measurements */
+-	g_warn_if_fail (drv_data->measurement_id > 0);
+-	g_signal_handler_disconnect (drv_data->sensor, drv_data->measurement_id);
+-
+-	/* Disable sensor */
+-	if (!ssc_sensor_compass_close_sync (drv_data->sensor, NULL, &error))
+-		g_warning ("Closing SSC compass sensor failed: %s", error ? error->message : "UNKNOWN");
++static void
++ssc_compass_close (SensorDevice *sensor_device)
++{
++	DrvData *drv_data = (DrvData *) sensor_device->priv;
+ 
+ 	g_clear_object (&drv_data->sensor);
+ 	g_clear_pointer (&sensor_device->priv, g_free);
+diff --git a/src/drv-ssc-light.c b/src/drv-ssc-light.c
+index e5ad8dd..892b7d0 100644
+--- a/src/drv-ssc-light.c
++++ b/src/drv-ssc-light.c
+@@ -61,53 +61,56 @@ static SensorDevice *
+ ssc_light_open (GUdevDevice *device)
+ {
+ 	SensorDevice *sensor_device;
+-	DrvData *drv_data;
+-	g_autoptr (GError) error = NULL;
+ 
+ 	sensor_device = g_new0 (SensorDevice, 1);
+ 	sensor_device->priv = g_new0 (DrvData, 1);
+-	drv_data = (DrvData *) sensor_device->priv;
+-
+-	/* Create sensor */
+-	drv_data->sensor = ssc_sensor_light_new_sync (NULL, &error);
+-	if (!drv_data->sensor) {
+-		g_warning ("Creating SSC light sensor failed: %s", error ? error->message : "UNKNOWN");
+-		return NULL;
+-	}
+-	g_object_get (drv_data->sensor,
+-                      SSC_SENSOR_NAME, &sensor_device->name,
+-		      NULL);
+-
+-	/* Start listening for measurements */
+-	drv_data->measurement_id = g_signal_connect (drv_data->sensor,
+-			                             "measurement",
+-						     G_CALLBACK (measurement_cb),
+-						     sensor_device);
+-
+-	/* Enable sensor */
+-	if (!ssc_sensor_light_open_sync (drv_data->sensor, NULL, &error)) {
+-		g_warning ("Opening SSC light sensor failed: %s", error ? error->message : "UNKNOWN");
+-		g_object_unref (sensor_device);
+-		return NULL;
+-	}
+ 
+ 	return sensor_device;
+ }
+ 
++static void
++ssc_light_set_polling (SensorDevice *sensor_device,
++		       gboolean state)
++{
++	DrvData *drv_data = (DrvData *) sensor_device->priv;
++	g_autoptr (GError) error = NULL;
++	if (state) {
++		/* Create sensor */
++		drv_data->sensor = ssc_sensor_light_new_sync (NULL, &error);
++		if (!drv_data->sensor) {
++			g_warning ("Creating SSC light sensor failed: %s", error ? error->message : "UNKNOWN");
++			return;
++		}
++
++		/* Start listening for measurements */
++		drv_data->measurement_id = g_signal_connect (drv_data->sensor,
++					                     "measurement",
++							     G_CALLBACK (measurement_cb),
++							     sensor_device);
++
++		/* Enable sensor */
++		if (!ssc_sensor_light_open_sync (drv_data->sensor, NULL, &error)) {
++			g_warning ("Opening SSC light sensor failed: %s", error ? error->message : "UNKNOWN");
++			g_object_unref (sensor_device);
++			return;
++		}
++	} else {
++		/* Stop listening for measurements */
++		g_warn_if_fail (drv_data->measurement_id > 0);
++		g_signal_handler_disconnect (drv_data->sensor, drv_data->measurement_id);
++
++		/* Disable sensor */
++		if (!ssc_sensor_light_close_sync (drv_data->sensor, NULL, &error))
++			g_warning ("Closing SSC light sensor failed: %s", error ? error->message : "UNKNOWN");
++	}
++}
++
+ static void
+ ssc_light_close (SensorDevice *sensor_device)
+ {
+ 	g_autoptr (GError) error = NULL;
+ 	DrvData *drv_data = (DrvData *) sensor_device->priv;
+ 
+-	/* Stop listening for measurements */
+-	g_warn_if_fail (drv_data->measurement_id > 0);
+-	g_signal_handler_disconnect (drv_data->sensor, drv_data->measurement_id);
+-
+-	/* Disable sensor */
+-	if (!ssc_sensor_light_close_sync (drv_data->sensor, NULL, &error))
+-		g_warning ("Closing SSC light sensor failed: %s", error ? error->message : "UNKNOWN");
+-
+ 	g_clear_object (&drv_data->sensor);
+ 	g_clear_pointer (&sensor_device->priv, g_free);
+ 	g_free (sensor_device);
+@@ -119,5 +122,6 @@ SensorDriver ssc_light = {
+ 
+ 	.discover = ssc_light_discover,
+ 	.open = ssc_light_open,
++	.set_polling = ssc_light_set_polling,
+ 	.close = ssc_light_close,
+ };
+diff --git a/src/drv-ssc-proximity.c b/src/drv-ssc-proximity.c
+index 0ec8b08..32659fb 100644
+--- a/src/drv-ssc-proximity.c
++++ b/src/drv-ssc-proximity.c
+@@ -60,52 +60,54 @@ static SensorDevice *
+ ssc_proximity_open (GUdevDevice *device)
+ {
+ 	SensorDevice *sensor_device;
+-	DrvData *drv_data;
+-	g_autoptr (GError) error = NULL;
+ 
+ 	sensor_device = g_new0 (SensorDevice, 1);
+ 	sensor_device->priv = g_new0 (DrvData, 1);
+-	drv_data = (DrvData *) sensor_device->priv;
+-
+-	/* Create sensor */
+-	drv_data->sensor = ssc_sensor_proximity_new_sync (NULL, &error);
+-	if (!drv_data->sensor) {
+-		g_warning ("Creating SSC proximity sensor failed: %s", error ? error->message : "UNKNOWN");
+-		return NULL;
+-	}
+-	g_object_get (drv_data->sensor,
+-                      SSC_SENSOR_NAME, &sensor_device->name,
+-		      NULL);
+-
+-	/* Start listening for measurements */
+-	drv_data->measurement_id = g_signal_connect (drv_data->sensor,
+-			                             "measurement",
+-						     G_CALLBACK (measurement_cb),
+-						     sensor_device);
+-
+-	/* Enable sensor */
+-	if (!ssc_sensor_proximity_open_sync (drv_data->sensor, NULL, &error)) {
+-		g_warning ("Opening SSC proximity sensor failed: %s", error ? error->message : "UNKNOWN");
+-		g_object_unref (sensor_device);
+-		return NULL;
+-	}
+ 
+ 	return sensor_device;
+ }
+ 
+ static void
+-ssc_proximity_close (SensorDevice *sensor_device)
++ssc_proximity_set_polling (SensorDevice *sensor_device,
++			   gboolean state)
+ {
+-	g_autoptr (GError) error = NULL;
+ 	DrvData *drv_data = (DrvData *) sensor_device->priv;
++	g_autoptr (GError) error = NULL;
++	if (state) {
++		/* Create sensor */
++		drv_data->sensor = ssc_sensor_proximity_new_sync (NULL, &error);
++		if (!drv_data->sensor) {
++			g_warning ("Creating SSC proximity sensor failed: %s", error ? error->message : "UNKNOWN");
++			return;
++		}
++
++		/* Start listening for measurements */
++		drv_data->measurement_id = g_signal_connect (drv_data->sensor,
++					                     "measurement",
++							     G_CALLBACK (measurement_cb),
++							     sensor_device);
++
++		/* Enable sensor */
++		if (!ssc_sensor_proximity_open_sync (drv_data->sensor, NULL, &error)) {
++			g_warning ("Opening SSC proximity sensor failed: %s", error ? error->message : "UNKNOWN");
++			g_object_unref (sensor_device);
++			return;
++		}
++	} else {
++		/* Stop listening for measurements */
++		g_warn_if_fail (drv_data->measurement_id > 0);
++		g_signal_handler_disconnect (drv_data->sensor, drv_data->measurement_id);
++
++		/* Disable sensor */
++		if (!ssc_sensor_proximity_close_sync (drv_data->sensor, NULL, &error))
++			g_warning ("Closing SSC proximity sensor failed: %s", error ? error->message : "UNKNOWN");
++	}
++}
+ 
+-	/* Stop listening for measurements */
+-	g_warn_if_fail (drv_data->measurement_id > 0);
+-	g_signal_handler_disconnect (drv_data->sensor, drv_data->measurement_id);
+-
+-	/* Disable sensor */
+-	if (!ssc_sensor_proximity_close_sync (drv_data->sensor, NULL, &error))
+-		g_warning ("Closing SSC proximity sensor failed: %s", error ? error->message : "UNKNOWN");
++static void
++ssc_proximity_close (SensorDevice *sensor_device)
++{
++	DrvData *drv_data = (DrvData *) sensor_device->priv;
+ 
+ 	g_clear_object (&drv_data->sensor);
+ 	g_clear_pointer (&sensor_device->priv, g_free);
+@@ -118,5 +120,6 @@ SensorDriver ssc_proximity = {
+ 
+ 	.discover = ssc_proximity_discover,
+ 	.open = ssc_proximity_open,
++	.set_polling = ssc_proximity_set_polling,
+ 	.close = ssc_proximity_close,
+ };
+-- 
+GitLab
+
diff --git a/temp/iio-sensor-proxy/APKBUILD b/temp/iio-sensor-proxy/APKBUILD
index 1117954a69d..c5f6c34c8a8 100644
--- a/temp/iio-sensor-proxy/APKBUILD
+++ b/temp/iio-sensor-proxy/APKBUILD
@@ -2,7 +2,7 @@
 
 pkgname=iio-sensor-proxy
 pkgver=9999
-pkgrel=5
+pkgrel=6
 pkgdesc="IIO sensors to D-Bus proxy"
 url="https://gitlab.freedesktop.org/hadess/iio-sensor-proxy"
 arch="aarch64"
@@ -29,6 +29,7 @@ source="https://gitlab.freedesktop.org/hadess/iio-sensor-proxy/-/archive/$_commi
 	0006-data-add-libssc-udev-rules.patch
 	0007-CI-add-libssc-build.patch
 	0008-data-iio-sensor-proxy.service.in-add-AF_QIPCRTR.patch
+	0009-drivers-ssc-implement-set_polling-function.patch
 	"
 # tests fail on armv7 and armhf, and it seems to be due to some weird issue
 # with pmaports qemu CI (not reproducible locally with `pmb build --arch
@@ -65,4 +66,5 @@ bb8e1496411c030062eeb1bb919c9680c32d9571587540368c663b6739e3c506d21ab90836a4e83b
 651d3281fe64fb72780bdfc4f3416af6f221c5c0aebf8b9a87d2cf6b5a31ebd0816199b45c97f24810807286a4a8839b6304a12cfc23b4191261a30efd3fbe2b  0006-data-add-libssc-udev-rules.patch
 bdb8831d89f389badd5de0eb52d9eca5dbdf045dbcfab18165d43798c9e329c3e68e3209b8ad1053916cfac6c54984dd47aa379c419d46f1c25ad6a57c2bd771  0007-CI-add-libssc-build.patch
 c778168de17f86e3d50b62a4905d3940e9d69bb919fe3b9b5fc8962d8fe9b7cdb48a57dd8128ded93ff08493f65a7f602e6e7ad295e6736c74c273a2c6399c35  0008-data-iio-sensor-proxy.service.in-add-AF_QIPCRTR.patch
+d7c0d67a664d900708a1a76edaac3fc05be567abe9c5d49b11d3181ebe932c3847de4f3f89291542fe7d7f0798bde2d5a504d23350a79d93a7afe57f959380ae  0009-drivers-ssc-implement-set_polling-function.patch
 "
-- 
GitLab