iio: cros_ec: Expose hwfifo_timeout
Expose EC minimal interrupt period through buffer/hwfifo_timeout: - Maximal timeout is limited to 65s. - When timeout for all sensors is set to 0, EC will not send events, even if the sensor sampling rate is greater than 0. Rename frequency to sampling_frequency to match IIO ABI. Signed-off-by: Gwendal Grignou <gwendal@chromium.org> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
This commit is contained in:
parent
2861be4ca9
commit
6562793b55
@ -236,6 +236,8 @@ static int cros_ec_sensors_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
iio_buffer_set_attrs(indio_dev->buffer, cros_ec_sensor_fifo_attributes);
|
||||
|
||||
indio_dev->info = &ec_sensors_info;
|
||||
state = iio_priv(indio_dev);
|
||||
for (channel = state->channels, i = CROS_EC_SENSOR_X;
|
||||
@ -247,7 +249,6 @@ static int cros_ec_sensors_probe(struct platform_device *pdev)
|
||||
BIT(IIO_CHAN_INFO_CALIBSCALE);
|
||||
channel->info_mask_shared_by_all =
|
||||
BIT(IIO_CHAN_INFO_SCALE) |
|
||||
BIT(IIO_CHAN_INFO_FREQUENCY) |
|
||||
BIT(IIO_CHAN_INFO_SAMP_FREQ);
|
||||
channel->info_mask_shared_by_all_available =
|
||||
BIT(IIO_CHAN_INFO_SAMP_FREQ);
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <linux/iio/common/cros_ec_sensors_core.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/iio/kfifo_buf.h>
|
||||
#include <linux/iio/sysfs.h>
|
||||
#include <linux/iio/trigger_consumer.h>
|
||||
#include <linux/iio/triggered_buffer.h>
|
||||
#include <linux/kernel.h>
|
||||
@ -83,6 +84,77 @@ static void get_default_min_max_freq(enum motionsensor_type type,
|
||||
}
|
||||
}
|
||||
|
||||
static int cros_ec_sensor_set_ec_rate(struct cros_ec_sensors_core_state *st,
|
||||
int rate)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (rate > U16_MAX)
|
||||
rate = U16_MAX;
|
||||
|
||||
mutex_lock(&st->cmd_lock);
|
||||
st->param.cmd = MOTIONSENSE_CMD_EC_RATE;
|
||||
st->param.ec_rate.data = rate;
|
||||
ret = cros_ec_motion_send_host_cmd(st, 0);
|
||||
mutex_unlock(&st->cmd_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t cros_ec_sensor_set_report_latency(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
{
|
||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||
struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
|
||||
int integer, fract, ret;
|
||||
int latency;
|
||||
|
||||
ret = iio_str_to_fixpoint(buf, 100000, &integer, &fract);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* EC rate is in ms. */
|
||||
latency = integer * 1000 + fract / 1000;
|
||||
ret = cros_ec_sensor_set_ec_rate(st, latency);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t cros_ec_sensor_get_report_latency(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||
struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
|
||||
int latency, ret;
|
||||
|
||||
mutex_lock(&st->cmd_lock);
|
||||
st->param.cmd = MOTIONSENSE_CMD_EC_RATE;
|
||||
st->param.ec_rate.data = EC_MOTION_SENSE_NO_VALUE;
|
||||
|
||||
ret = cros_ec_motion_send_host_cmd(st, 0);
|
||||
latency = st->resp->ec_rate.ret;
|
||||
mutex_unlock(&st->cmd_lock);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return sprintf(buf, "%d.%06u\n",
|
||||
latency / 1000,
|
||||
(latency % 1000) * 1000);
|
||||
}
|
||||
|
||||
static IIO_DEVICE_ATTR(hwfifo_timeout, 0644,
|
||||
cros_ec_sensor_get_report_latency,
|
||||
cros_ec_sensor_set_report_latency, 0);
|
||||
|
||||
const struct attribute *cros_ec_sensor_fifo_attributes[] = {
|
||||
&iio_dev_attr_hwfifo_timeout.dev_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(cros_ec_sensor_fifo_attributes);
|
||||
|
||||
int cros_ec_sensors_push_data(struct iio_dev *indio_dev,
|
||||
s16 *data,
|
||||
s64 timestamp)
|
||||
@ -631,18 +703,6 @@ int cros_ec_sensors_core_read(struct cros_ec_sensors_core_state *st,
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
st->param.cmd = MOTIONSENSE_CMD_EC_RATE;
|
||||
st->param.ec_rate.data =
|
||||
EC_MOTION_SENSE_NO_VALUE;
|
||||
|
||||
ret = cros_ec_motion_send_host_cmd(st, 0);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
*val = st->resp->ec_rate.ret;
|
||||
ret = IIO_VAL_INT;
|
||||
break;
|
||||
case IIO_CHAN_INFO_FREQUENCY:
|
||||
st->param.cmd = MOTIONSENSE_CMD_SENSOR_ODR;
|
||||
st->param.sensor_odr.data =
|
||||
EC_MOTION_SENSE_NO_VALUE;
|
||||
@ -712,7 +772,7 @@ int cros_ec_sensors_core_write(struct cros_ec_sensors_core_state *st,
|
||||
int ret;
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_FREQUENCY:
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
st->param.cmd = MOTIONSENSE_CMD_SENSOR_ODR;
|
||||
st->param.sensor_odr.data = val;
|
||||
|
||||
@ -721,15 +781,6 @@ int cros_ec_sensors_core_write(struct cros_ec_sensors_core_state *st,
|
||||
|
||||
ret = cros_ec_motion_send_host_cmd(st, 0);
|
||||
break;
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
st->param.cmd = MOTIONSENSE_CMD_EC_RATE;
|
||||
st->param.ec_rate.data = val;
|
||||
|
||||
ret = cros_ec_motion_send_host_cmd(st, 0);
|
||||
if (ret)
|
||||
break;
|
||||
st->curr_sampl_freq = val;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
|
@ -183,6 +183,8 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
iio_buffer_set_attrs(indio_dev->buffer, cros_ec_sensor_fifo_attributes);
|
||||
|
||||
indio_dev->info = &cros_ec_light_prox_info;
|
||||
state = iio_priv(indio_dev);
|
||||
state->core.type = state->core.resp->info.type;
|
||||
@ -191,8 +193,7 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev)
|
||||
|
||||
/* Common part */
|
||||
channel->info_mask_shared_by_all =
|
||||
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
|
||||
BIT(IIO_CHAN_INFO_FREQUENCY);
|
||||
BIT(IIO_CHAN_INFO_SAMP_FREQ);
|
||||
channel->info_mask_shared_by_all_available =
|
||||
BIT(IIO_CHAN_INFO_SAMP_FREQ);
|
||||
channel->scan_type.realbits = CROS_EC_SENSOR_BITS;
|
||||
|
@ -140,6 +140,8 @@ static int cros_ec_baro_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
iio_buffer_set_attrs(indio_dev->buffer, cros_ec_sensor_fifo_attributes);
|
||||
|
||||
indio_dev->info = &cros_ec_baro_info;
|
||||
state = iio_priv(indio_dev);
|
||||
state->core.type = state->core.resp->info.type;
|
||||
@ -149,8 +151,7 @@ static int cros_ec_baro_probe(struct platform_device *pdev)
|
||||
channel->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
|
||||
channel->info_mask_shared_by_all =
|
||||
BIT(IIO_CHAN_INFO_SCALE) |
|
||||
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
|
||||
BIT(IIO_CHAN_INFO_FREQUENCY);
|
||||
BIT(IIO_CHAN_INFO_SAMP_FREQ);
|
||||
channel->info_mask_shared_by_all_available =
|
||||
BIT(IIO_CHAN_INFO_SAMP_FREQ);
|
||||
channel->scan_type.realbits = CROS_EC_SENSOR_BITS;
|
||||
|
@ -50,7 +50,6 @@ typedef irqreturn_t (*cros_ec_sensors_capture_t)(int irq, void *p);
|
||||
* the timestamp. The timestamp is always last and
|
||||
* is always 8-byte aligned.
|
||||
* @read_ec_sensors_data: function used for accessing sensors values
|
||||
* @cuur_sampl_freq: current sampling period
|
||||
*/
|
||||
struct cros_ec_sensors_core_state {
|
||||
struct cros_ec_device *ec;
|
||||
@ -73,8 +72,6 @@ struct cros_ec_sensors_core_state {
|
||||
int (*read_ec_sensors_data)(struct iio_dev *indio_dev,
|
||||
unsigned long scan_mask, s16 *data);
|
||||
|
||||
int curr_sampl_freq;
|
||||
|
||||
/* Table of known available frequencies : 0, Min and Max in mHz */
|
||||
int frequencies[3];
|
||||
};
|
||||
@ -116,5 +113,6 @@ int cros_ec_sensors_core_write(struct cros_ec_sensors_core_state *st,
|
||||
|
||||
/* List of extended channel specification for all sensors */
|
||||
extern const struct iio_chan_spec_ext_info cros_ec_sensors_ext_info[];
|
||||
extern const struct attribute *cros_ec_sensor_fifo_attributes[];
|
||||
|
||||
#endif /* __CROS_EC_SENSORS_CORE_H */
|
||||
|
Loading…
Reference in New Issue
Block a user