Embedded controller return minimum and maximum frequencies, unfortunately
we have no way to know the step for all available frequencies.
Even if not complete, we can return a list of known values using the
standard read_avail callback (IIO_CHAN_INFO_SAMP_FREQ) to provide them to
userland.

Now cros_ec_* sensors provides frequencies values in sysfs like this:
"0 min max".

0 is always true to disable the sensor.

Signed-off-by: Fabien Lahoudere <[email protected]>
---
 .../cros_ec_sensors/cros_ec_sensors_core.c    | 22 +++++++++++++++++++
 .../linux/iio/common/cros_ec_sensors_core.h   |  4 +++-
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c 
b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
index 2ce077b576a4..8df82b675752 100644
--- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
+++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
@@ -10,6 +10,7 @@
 #include <linux/iio/buffer.h>
 #include <linux/iio/common/cros_ec_sensors_core.h>
 #include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
 #include <linux/iio/kfifo_buf.h>
 #include <linux/iio/trigger_consumer.h>
 #include <linux/iio/triggered_buffer.h>
@@ -86,6 +87,26 @@ static int cros_ec_get_host_cmd_version_mask(struct 
cros_ec_device *ec_dev,
        return ret;
 }
 
+static int cros_ec_read_avail(struct iio_dev *indio_dev,
+                             struct iio_chan_spec const *chan,
+                             const int **vals,
+                             int *type,
+                             int *length,
+                             long mask)
+{
+       struct cros_ec_sensors_core_state *state = iio_priv(indio_dev);
+
+       switch (mask) {
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               *length = 3;
+               *vals = (const int *)&state->frequency_range;
+               *type = IIO_VAL_INT;
+               return IIO_AVAIL_LIST;
+       }
+
+       return -EINVAL;
+}
+
 int cros_ec_sensors_core_init(struct platform_device *pdev,
                              int num_channels,
                              bool physical_device)
@@ -161,6 +182,7 @@ int cros_ec_sensors_core_init(struct platform_device *pdev,
                }
        }
 
+       state->info.read_avail = cros_ec_read_avail;
        indio_dev->info = &state->info;
 
        /* Timestamp channel */
diff --git a/include/linux/iio/common/cros_ec_sensors_core.h 
b/include/linux/iio/common/cros_ec_sensors_core.h
index 89937ad242ef..5fa9ba5332e0 100644
--- a/include/linux/iio/common/cros_ec_sensors_core.h
+++ b/include/linux/iio/common/cros_ec_sensors_core.h
@@ -140,7 +140,9 @@ int cros_ec_sensors_core_register(struct platform_device 
*pdev,
        channel[idx].scan_type.shift = 0;\
        channel[idx].scan_index = idx;\
        channel[idx].ext_info = cros_ec_sensors_ext_info;\
-       channel[idx].scan_type.sign = 'u';
+       channel[idx].scan_type.sign = 'u';\
+       channel[idx].info_mask_shared_by_all_available = \
+               BIT(IIO_CHAN_INFO_SAMP_FREQ);
 
 /**
  * cros_ec_motion_send_host_cmd() - send motion sense host command
-- 
2.20.1

Reply via email to