Commit a53f9458 authored by Carlos Song's avatar Carlos Song Committed by Jonathan Cameron
Browse files

iio: imu: fxos8700: fix IMU data bits returned to user space



ACCEL output data registers contain the X-axis, Y-axis, and Z-axis
14-bit left-justified sample data and MAGN output data registers
contain the X-axis, Y-axis, and Z-axis 16-bit sample data. The ACCEL
raw register output data should be divided by 4 before sent to
userspace.

Apply a 2 bits signed right shift to the raw data from ACCEL output
data register but keep that from MAGN sensor as the origin.

Fixes: 84e5ddd5 ("iio: imu: Add support for the FXOS8700 IMU")
Signed-off-by: default avatarCarlos Song <carlos.song@nxp.com>
Link: https://lore.kernel.org/r/20221208071911.2405922-5-carlos.song@nxp.com


Cc: <Stable@vger.kernel.org>
Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 37a94d86
Loading
Loading
Loading
Loading
+27 −1
Original line number Diff line number Diff line
@@ -394,6 +394,7 @@ static int fxos8700_get_data(struct fxos8700_data *data, int chan_type,
			     int axis, int *val)
{
	u8 base, reg;
	s16 tmp;
	int ret;

	/*
@@ -421,8 +422,33 @@ static int fxos8700_get_data(struct fxos8700_data *data, int chan_type,
	/* Convert axis to buffer index */
	reg = axis - IIO_MOD_X;

	/*
	 * Convert to native endianness. The accel data and magn data
	 * are signed, so a forced type conversion is needed.
	 */
	tmp = be16_to_cpu(data->buf[reg]);

	/*
	 * ACCEL output data registers contain the X-axis, Y-axis, and Z-axis
	 * 14-bit left-justified sample data and MAGN output data registers
	 * contain the X-axis, Y-axis, and Z-axis 16-bit sample data. Apply
	 * a signed 2 bits right shift to the readback raw data from ACCEL
	 * output data register and keep that from MAGN sensor as the origin.
	 * Value should be extended to 32 bit.
	 */
	switch (chan_type) {
	case IIO_ACCEL:
		tmp = tmp >> 2;
		break;
	case IIO_MAGN:
		/* Nothing to do */
		break;
	default:
		return -EINVAL;
	}

	/* Convert to native endianness */
	*val = sign_extend32(be16_to_cpu(data->buf[reg]), 15);
	*val = sign_extend32(tmp, 15);

	return 0;
}