Commit ed1f2e85 authored by Gwendal Grignou's avatar Gwendal Grignou Committed by Jonathan Cameron

iio: cros_ec: Add calibscale for 3d MEMS

Add calibration scale support to accel, gyro and magnetometer.

Check on eve with current firmware, check reading calibscale returns 1.0,
check with newer firmware values are applied.
Signed-off-by: default avatarGwendal Grignou <gwendal@chromium.org>
Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 50e5bae0
...@@ -63,10 +63,35 @@ static int cros_ec_sensors_read(struct iio_dev *indio_dev, ...@@ -63,10 +63,35 @@ static int cros_ec_sensors_read(struct iio_dev *indio_dev,
/* Save values */ /* Save values */
for (i = CROS_EC_SENSOR_X; i < CROS_EC_SENSOR_MAX_AXIS; i++) for (i = CROS_EC_SENSOR_X; i < CROS_EC_SENSOR_MAX_AXIS; i++)
st->core.calib[i] = st->core.calib[i].offset =
st->core.resp->sensor_offset.offset[i]; st->core.resp->sensor_offset.offset[i];
ret = IIO_VAL_INT; ret = IIO_VAL_INT;
*val = st->core.calib[idx]; *val = st->core.calib[idx].offset;
break;
case IIO_CHAN_INFO_CALIBSCALE:
st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_SCALE;
st->core.param.sensor_offset.flags = 0;
ret = cros_ec_motion_send_host_cmd(&st->core, 0);
if (ret == -EPROTO) {
/* Reading calibscale is not supported on older EC. */
*val = 1;
*val2 = 0;
ret = IIO_VAL_INT_PLUS_MICRO;
break;
} else if (ret) {
break;
}
/* Save values */
for (i = CROS_EC_SENSOR_X; i < CROS_EC_SENSOR_MAX_AXIS; i++)
st->core.calib[i].scale =
st->core.resp->sensor_scale.scale[i];
*val = st->core.calib[idx].scale >> 15;
*val2 = ((st->core.calib[idx].scale & 0x7FFF) * 1000000LL) /
MOTION_SENSE_DEFAULT_SCALE;
ret = IIO_VAL_INT_PLUS_MICRO;
break; break;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_RANGE; st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_RANGE;
...@@ -134,7 +159,7 @@ static int cros_ec_sensors_write(struct iio_dev *indio_dev, ...@@ -134,7 +159,7 @@ static int cros_ec_sensors_write(struct iio_dev *indio_dev,
switch (mask) { switch (mask) {
case IIO_CHAN_INFO_CALIBBIAS: case IIO_CHAN_INFO_CALIBBIAS:
st->core.calib[idx] = val; st->core.calib[idx].offset = val;
/* Send to EC for each axis, even if not complete */ /* Send to EC for each axis, even if not complete */
st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_OFFSET; st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_OFFSET;
...@@ -142,10 +167,25 @@ static int cros_ec_sensors_write(struct iio_dev *indio_dev, ...@@ -142,10 +167,25 @@ static int cros_ec_sensors_write(struct iio_dev *indio_dev,
MOTION_SENSE_SET_OFFSET; MOTION_SENSE_SET_OFFSET;
for (i = CROS_EC_SENSOR_X; i < CROS_EC_SENSOR_MAX_AXIS; i++) for (i = CROS_EC_SENSOR_X; i < CROS_EC_SENSOR_MAX_AXIS; i++)
st->core.param.sensor_offset.offset[i] = st->core.param.sensor_offset.offset[i] =
st->core.calib[i]; st->core.calib[i].offset;
st->core.param.sensor_offset.temp = st->core.param.sensor_offset.temp =
EC_MOTION_SENSE_INVALID_CALIB_TEMP; EC_MOTION_SENSE_INVALID_CALIB_TEMP;
ret = cros_ec_motion_send_host_cmd(&st->core, 0);
break;
case IIO_CHAN_INFO_CALIBSCALE:
st->core.calib[idx].scale = val;
/* Send to EC for each axis, even if not complete */
st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_SCALE;
st->core.param.sensor_offset.flags =
MOTION_SENSE_SET_OFFSET;
for (i = CROS_EC_SENSOR_X; i < CROS_EC_SENSOR_MAX_AXIS; i++)
st->core.param.sensor_scale.scale[i] =
st->core.calib[i].scale;
st->core.param.sensor_scale.temp =
EC_MOTION_SENSE_INVALID_CALIB_TEMP;
ret = cros_ec_motion_send_host_cmd(&st->core, 0); ret = cros_ec_motion_send_host_cmd(&st->core, 0);
break; break;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
...@@ -206,7 +246,8 @@ static int cros_ec_sensors_probe(struct platform_device *pdev) ...@@ -206,7 +246,8 @@ static int cros_ec_sensors_probe(struct platform_device *pdev)
/* Common part */ /* Common part */
channel->info_mask_separate = channel->info_mask_separate =
BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_CALIBBIAS); BIT(IIO_CHAN_INFO_CALIBBIAS) |
BIT(IIO_CHAN_INFO_CALIBSCALE);
channel->info_mask_shared_by_all = channel->info_mask_shared_by_all =
BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_FREQUENCY) | BIT(IIO_CHAN_INFO_FREQUENCY) |
......
...@@ -118,7 +118,7 @@ static ssize_t cros_ec_sensors_calibrate(struct iio_dev *indio_dev, ...@@ -118,7 +118,7 @@ static ssize_t cros_ec_sensors_calibrate(struct iio_dev *indio_dev,
} else { } else {
/* Save values */ /* Save values */
for (i = CROS_EC_SENSOR_X; i < CROS_EC_SENSOR_MAX_AXIS; i++) for (i = CROS_EC_SENSOR_X; i < CROS_EC_SENSOR_MAX_AXIS; i++)
st->calib[i] = st->resp->perform_calib.offset[i]; st->calib[i].offset = st->resp->perform_calib.offset[i];
} }
mutex_unlock(&st->cmd_lock); mutex_unlock(&st->cmd_lock);
......
...@@ -88,9 +88,10 @@ static int cros_ec_light_prox_read(struct iio_dev *indio_dev, ...@@ -88,9 +88,10 @@ static int cros_ec_light_prox_read(struct iio_dev *indio_dev,
} }
/* Save values */ /* Save values */
st->core.calib[0] = st->core.resp->sensor_offset.offset[0]; st->core.calib[0].offset =
st->core.resp->sensor_offset.offset[0];
*val = st->core.calib[idx]; *val = st->core.calib[idx].offset;
break; break;
case IIO_CHAN_INFO_CALIBSCALE: case IIO_CHAN_INFO_CALIBSCALE:
/* /*
...@@ -134,11 +135,12 @@ static int cros_ec_light_prox_write(struct iio_dev *indio_dev, ...@@ -134,11 +135,12 @@ static int cros_ec_light_prox_write(struct iio_dev *indio_dev,
switch (mask) { switch (mask) {
case IIO_CHAN_INFO_CALIBBIAS: case IIO_CHAN_INFO_CALIBBIAS:
st->core.calib[idx] = val; st->core.calib[idx].offset = val;
/* Send to EC for each axis, even if not complete */ /* Send to EC for each axis, even if not complete */
st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_OFFSET; st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_OFFSET;
st->core.param.sensor_offset.flags = MOTION_SENSE_SET_OFFSET; st->core.param.sensor_offset.flags = MOTION_SENSE_SET_OFFSET;
st->core.param.sensor_offset.offset[0] = st->core.calib[0]; st->core.param.sensor_offset.offset[0] =
st->core.calib[0].offset;
st->core.param.sensor_offset.temp = st->core.param.sensor_offset.temp =
EC_MOTION_SENSE_INVALID_CALIB_TEMP; EC_MOTION_SENSE_INVALID_CALIB_TEMP;
if (cros_ec_motion_send_host_cmd(&st->core, 0)) if (cros_ec_motion_send_host_cmd(&st->core, 0))
...@@ -205,8 +207,6 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev) ...@@ -205,8 +207,6 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev)
channel->ext_info = cros_ec_sensors_ext_info; channel->ext_info = cros_ec_sensors_ext_info;
channel->scan_type.sign = 'u'; channel->scan_type.sign = 'u';
state->core.calib[0] = 0;
/* Sensor specific */ /* Sensor specific */
switch (state->core.type) { switch (state->core.type) {
case MOTIONSENSE_TYPE_LIGHT: case MOTIONSENSE_TYPE_LIGHT:
......
...@@ -152,8 +152,6 @@ static int cros_ec_baro_probe(struct platform_device *pdev) ...@@ -152,8 +152,6 @@ static int cros_ec_baro_probe(struct platform_device *pdev)
channel->ext_info = cros_ec_sensors_ext_info; channel->ext_info = cros_ec_sensors_ext_info;
channel->scan_type.sign = 'u'; channel->scan_type.sign = 'u';
state->core.calib[0] = 0;
/* Sensor specific */ /* Sensor specific */
switch (state->core.type) { switch (state->core.type) {
case MOTIONSENSE_TYPE_BARO: case MOTIONSENSE_TYPE_BARO:
......
...@@ -62,7 +62,10 @@ struct cros_ec_sensors_core_state { ...@@ -62,7 +62,10 @@ struct cros_ec_sensors_core_state {
enum motionsensor_type type; enum motionsensor_type type;
enum motionsensor_location loc; enum motionsensor_location loc;
s16 calib[CROS_EC_SENSOR_MAX_AXIS]; struct calib_data {
s16 offset;
u16 scale;
} calib[CROS_EC_SENSOR_MAX_AXIS];
u8 samples[CROS_EC_SAMPLE_SIZE]; u8 samples[CROS_EC_SAMPLE_SIZE];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment