From: Jonathan Cameron <jic23@jic23.retrosnub.co.uk>
To: Fabien Lahoudere <fabien.lahoudere@collabora.com>
Cc: linux-iio@vger.kernel.org, Gwendal Grignou <gwendal@chromium.org>
Subject: Re: [RFC 1/1] iio: common: cros_ec_sensors: add extra sensor API
Date: Sun, 5 May 2019 16:36:47 +0100 [thread overview]
Message-ID: <20190505163647.4f961a0d@archlinux> (raw)
In-Reply-To: <f30612908370460d61904450d6f7c5224082898e.1556873525.git.fabien.lahoudere@collabora.com>
On Fri, 3 May 2019 12:54:46 +0200
Fabien Lahoudere <fabien.lahoudere@collabora.com> wrote:
> From: Gwendal Grignou <gwendal@chromium.org>
>
> Version 3 of the EC protocol provides min and max frequencies and fifo
> size for EC sensors.
> The driver allows EC to set parameters for version 3 and set default values
> for earlier versions.
> The sysfs entries are read only and cannot be used to impact on values.
>
> Signed-off-by: Gwendal Grignou <gwendal@chromium.org>
> Signed-off-by: Fabien Lahoudere <fabien.lahoudere@collabora.com>
Mostly changes in here will follow from comments on the cover letter
but a few other things inline.
Thanks,
Jonathan
> ---
> .../ABI/testing/sysfs-bus-iio-cros-ec | 24 ++++
> .../cros_ec_sensors/cros_ec_sensors_core.c | 126 +++++++++++++++++-
> .../linux/iio/common/cros_ec_sensors_core.h | 7 +
> include/linux/mfd/cros_ec_commands.h | 21 +++
> 4 files changed, 177 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-iio-cros-ec b/Documentation/ABI/testing/sysfs-bus-iio-cros-ec
> index 0e95c2ca105c..85d266f4a57e 100644
> --- a/Documentation/ABI/testing/sysfs-bus-iio-cros-ec
> +++ b/Documentation/ABI/testing/sysfs-bus-iio-cros-ec
> @@ -26,3 +26,27 @@ Description:
> driver and represents the sensor ID as exposed by the EC. This
> ID is used by the Android sensor service hardware abstraction
> layer (sensor HAL) through the Android container on ChromeOS.
> +
> +What: /sys/bus/iio/devices/iio:deviceX/min_frequency
> +Date: April 2019
> +KernelVersion: 5.0
> +Contact: linux-iio@vger.kernel.org
> +Description:
> + This attribute is exposed by CrOS EC sensors. It defines the
> + minimum frequency used by the sensor.
> +
> +What: /sys/bus/iio/devices/iio:deviceX/max_frequency
> +Date: April 2019
> +KernelVersion: 5.0
> +Contact: linux-iio@vger.kernel.org
> +Description:
> + This attribute is exposed by CrOS EC sensors. It defines the
> + maximum frequency used by the sensor.
> +
See reply to the cover letter on these. Bonus points if you implement them
with the read_avail callback.
> +What: /sys/bus/iio/devices/iio:deviceX/max_events
> +Date: April 2019
> +KernelVersion: 5.0
> +Contact: linux-iio@vger.kernel.org
> +Description:
> + This attribute is exposed by CrOS EC sensors. It defines the
> + maximum number of events in the fifo.
Why does userspace care?
> 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 719a0df5aeeb..84908a4085ef 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
> @@ -19,12 +19,84 @@
> #include <linux/slab.h>
> #include <linux/platform_device.h>
>
> +/*
> + * Hard coded to the first device to support sensor fifo. The EC has a 2048
> + * byte fifo and will trigger an interrupt when fifo is 2/3 full.
> + */
> +#define CROS_EC_FIFO_SIZE (2048 * 2 / 3)
> +
> static char *cros_ec_loc[] = {
> [MOTIONSENSE_LOC_BASE] = "base",
> [MOTIONSENSE_LOC_LID] = "lid",
> [MOTIONSENSE_LOC_MAX] = "unknown",
> };
>
> +static void get_default_min_max_freq_and_fifo_size(enum motionsensor_type type,
> + u32 *min_freq,
> + u32 *max_freq,
> + u32 *max_fifo_events)
> +{
> + /* we don't know fifo size, set to size previously used by sensor HAL */
> + *max_fifo_events = CROS_EC_FIFO_SIZE;
> +
> + switch (type) {
> + case MOTIONSENSE_TYPE_ACCEL:
> + case MOTIONSENSE_TYPE_GYRO:
> + *min_freq = 12500;
> + *max_freq = 100000;
> + break;
> + case MOTIONSENSE_TYPE_MAG:
> + *min_freq = 5000;
> + *max_freq = 25000;
> + break;
> + case MOTIONSENSE_TYPE_PROX:
> + case MOTIONSENSE_TYPE_LIGHT:
> + *min_freq = 100;
> + *max_freq = 50000;
> + break;
> + case MOTIONSENSE_TYPE_BARO:
> + *min_freq = 250;
> + *max_freq = 20000;
> + break;
> + case MOTIONSENSE_TYPE_ACTIVITY:
> + default:
> + *max_fifo_events = 0;
> + *min_freq = 0;
> + *max_freq = 0;
> + break;
> + }
> +}
> +
> +static int cros_ec_get_host_cmd_version_mask(struct cros_ec_device *ec_dev,
> + u16 cmd_offset, u16 cmd, u32 *mask)
> +{
> + struct {
> + struct cros_ec_command msg;
> + union {
> + struct ec_params_get_cmd_versions params;
> + struct ec_response_get_cmd_versions resp;
> + };
> + } __packed buf;
> + struct ec_params_get_cmd_versions *params = &buf.params;
> + struct ec_response_get_cmd_versions *resp = &buf.resp;
> + struct cros_ec_command *msg = &buf.msg;
> + int ret;
> +
> + memset(&buf, 0, sizeof(buf));
> + msg->command = EC_CMD_GET_CMD_VERSIONS + cmd_offset;
> + msg->insize = sizeof(*resp);
> + msg->outsize = sizeof(*params);
You could, I think, use c99 structure initialization to set these neatly
and avoid the need for the memset being explicit.
> + params->cmd = cmd;
> + ret = cros_ec_cmd_xfer_status(ec_dev, msg);
> + if (ret >= 0) {
> + if (msg->result == EC_RES_SUCCESS)
> + *mask = resp->version_mask;
> + else
> + *mask = 0;
> + }
> + return ret;
> +}
> +
> int cros_ec_sensors_core_init(struct platform_device *pdev,
> struct iio_dev *indio_dev,
> bool physical_device)
> @@ -33,6 +105,8 @@ int cros_ec_sensors_core_init(struct platform_device *pdev,
> struct cros_ec_sensors_core_state *state = iio_priv(indio_dev);
> struct cros_ec_dev *ec = dev_get_drvdata(pdev->dev.parent);
> struct cros_ec_sensor_platform *sensor_platform = dev_get_platdata(dev);
> + u32 ver_mask;
> + int ret;
>
> platform_set_drvdata(pdev, indio_dev);
>
> @@ -47,8 +121,16 @@ int cros_ec_sensors_core_init(struct platform_device *pdev,
>
> mutex_init(&state->cmd_lock);
>
> + /* determine what version of MOTIONSENSE CMD EC has */
> + ret = cros_ec_get_host_cmd_version_mask(state->ec,
> + ec->cmd_offset,
> + EC_CMD_MOTION_SENSE_CMD,
> + &ver_mask);
> + if (ret < 0 || ver_mask == 0)
> + return -ENODEV;
> +
> /* Set up the host command structure. */
> - state->msg->version = 2;
> + state->msg->version = fls(ver_mask) - 1;
> state->msg->command = EC_CMD_MOTION_SENSE_CMD + ec->cmd_offset;
> state->msg->outsize = sizeof(struct ec_params_motion_sense);
>
> @@ -66,6 +148,20 @@ int cros_ec_sensors_core_init(struct platform_device *pdev,
> }
> state->type = state->resp->info.type;
> state->loc = state->resp->info.location;
> + if (state->msg->version < 3) {
> + get_default_min_max_freq_and_fifo_size(
> + state->resp->info.type,
> + &state->min_freq,
> + &state->max_freq,
> + &state->fifo_max_event_count);
> + } else {
> + state->min_freq =
> + state->resp->info_3.min_frequency;
> + state->max_freq =
> + state->resp->info_3.max_frequency;
> + state->fifo_max_event_count =
> + state->resp->info_3.fifo_max_event_count;
> + }
> }
>
> return 0;
> @@ -134,6 +230,19 @@ static ssize_t cros_ec_sensors_loc(struct iio_dev *indio_dev,
> return snprintf(buf, PAGE_SIZE, "%s\n", cros_ec_loc[st->loc]);
> }
>
> +#define DEVICE_STATE_INT_ATTR(_name, _var) \
> +static ssize_t cros_ec_sensors_##_name(struct iio_dev *indio_dev, \
> + uintptr_t private, const struct iio_chan_spec *chan, \
> + char *buf) \
> +{ \
> + struct cros_ec_sensors_core_state *st = iio_priv(indio_dev); \
> + return snprintf(buf, PAGE_SIZE, "%d\n", st->_var); \
> +}
> +
> +DEVICE_STATE_INT_ATTR(min_freq, min_freq);
> +DEVICE_STATE_INT_ATTR(max_freq, max_freq);
> +DEVICE_STATE_INT_ATTR(max_events, fifo_max_event_count);
> +
> const struct iio_chan_spec_ext_info cros_ec_sensors_ext_info[] = {
> {
> .name = "calibrate",
> @@ -145,6 +254,21 @@ const struct iio_chan_spec_ext_info cros_ec_sensors_ext_info[] = {
> .shared = IIO_SHARED_BY_ALL,
> .read = cros_ec_sensors_loc
> },
> + {
> + .name = "min_frequency",
> + .shared = IIO_SHARED_BY_ALL,
> + .read = cros_ec_sensors_min_freq
> + },
> + {
> + .name = "max_frequency",
> + .shared = IIO_SHARED_BY_ALL,
> + .read = cros_ec_sensors_max_freq
> + },
> + {
> + .name = "max_events",
> + .shared = IIO_SHARED_BY_ALL,
> + .read = cros_ec_sensors_max_events
> + },
> { },
> };
> EXPORT_SYMBOL_GPL(cros_ec_sensors_ext_info);
> diff --git a/include/linux/iio/common/cros_ec_sensors_core.h b/include/linux/iio/common/cros_ec_sensors_core.h
> index ce16445411ac..4742a9637a85 100644
> --- a/include/linux/iio/common/cros_ec_sensors_core.h
> +++ b/include/linux/iio/common/cros_ec_sensors_core.h
> @@ -78,6 +78,13 @@ struct cros_ec_sensors_core_state {
> unsigned long scan_mask, s16 *data);
>
> int curr_sampl_freq;
> +
> + /* Min and Max Sampling Frequency in mHz */
> + u32 min_freq;
> + u32 max_freq;
> +
> + /* event fifo size represented in number of events */
> + u32 fifo_max_event_count;
> };
>
> /**
> diff --git a/include/linux/mfd/cros_ec_commands.h b/include/linux/mfd/cros_ec_commands.h
> index 43bee4f7d137..7fbf29416a0b 100644
> --- a/include/linux/mfd/cros_ec_commands.h
> +++ b/include/linux/mfd/cros_ec_commands.h
> @@ -1714,6 +1714,27 @@ struct ec_response_motion_sense {
> uint8_t chip;
> } info;
>
> + /* Used for MOTIONSENSE_CMD_INFO version 3 */
> + struct __ec_todo_unpacked {
> + /* Should be element of enum motionsensor_type. */
> + u8 type;
> +
> + /* Should be element of enum motionsensor_location. */
> + u8 location;
> +
> + /* Should be element of enum motionsensor_chip. */
> + u8 chip;
> +
> + /* Minimum sensor sampling frequency */
> + u32 min_frequency;
> +
> + /* Maximum sensor sampling frequency */
> + u32 max_frequency;
> +
> + /* Max number of sensor events that could be in fifo */
> + u32 fifo_max_event_count;
> + } info_3;
> +
> /* Used for MOTIONSENSE_CMD_DATA */
> struct ec_response_motion_sensor_data data;
>
next prev parent reply other threads:[~2019-05-05 15:36 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-03 10:54 [RFC 0/1] Add new sysfs ABI for chromebook devices Fabien Lahoudere
2019-05-03 10:54 ` [RFC 1/1] iio: common: cros_ec_sensors: add extra sensor API Fabien Lahoudere
2019-05-05 15:36 ` Jonathan Cameron [this message]
2019-05-25 0:28 ` Gwendal Grignou
2019-05-27 9:18 ` Jonathan Cameron
2019-05-30 4:28 ` Gwendal Grignou
2019-05-05 15:32 ` [RFC 0/1] Add new sysfs ABI for chromebook devices Jonathan Cameron
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190505163647.4f961a0d@archlinux \
--to=jic23@jic23.retrosnub.co.uk \
--cc=fabien.lahoudere@collabora.com \
--cc=gwendal@chromium.org \
--cc=linux-iio@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).