Types of raw data include acceleration and magnetism, so base address should vary with raw data types rightly. The function for data acquisition is incorrect because of not considering msb data and lsb data. Acceleration raw data is 14 bits and magnetism raw data is 16 bits, data reprocessing is necessary accordingly. Rewrite the function for data acquisition. Base data register address is configured correctly varied with acceleration and magnetism raw data, and data reprocessing method is added. Fixes: 84e5ddd5c46e ("iio: imu: Add support for the FXOS8700 IMU") Fixes: c9a8417a13ed ("iio: imu: fxos8700: Fix alignment for DMA safety") Signed-off-by: Carlos Song <carlos.song@xxxxxxx> Reviewed-by: Haibo Chen <haibo.chen@xxxxxxx> --- drivers/iio/imu/fxos8700_core.c | 39 +++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/drivers/iio/imu/fxos8700_core.c b/drivers/iio/imu/fxos8700_core.c index 423cfe526f2a..a69122799892 100644 --- a/drivers/iio/imu/fxos8700_core.c +++ b/drivers/iio/imu/fxos8700_core.c @@ -162,12 +162,10 @@ #define FXOS8700_DEVICE_ID 0xC7 #define FXOS8700_PRE_DEVICE_ID 0xC4 -#define FXOS8700_DATA_BUF_SIZE 3 struct fxos8700_data { struct regmap *regmap; struct iio_trigger *trig; - __be16 buf[FXOS8700_DATA_BUF_SIZE] __aligned(IIO_DMA_MINALIGN); }; /* Regmap info */ @@ -391,25 +389,42 @@ static int fxos8700_get_scale(struct fxos8700_data *data, } static int fxos8700_get_data(struct fxos8700_data *data, int chan_type, - int axis, int *val) + int axis, int *val) { - u8 base, reg; + u8 base, offset; + __be16 buf; + s16 tmp; int ret; enum fxos8700_sensor type = fxos8700_to_sensor(chan_type); - base = type ? FXOS8700_OUT_X_MSB : FXOS8700_M_OUT_X_MSB; + /* + * FXOS8700_M_OUT_X_MSB is magnetic X-axis output data register address. + * FXOS8700_OUT_X_MSB is acceler X-axis output data register address. + * Type is 1 for FXOS8700_MAGN, 0 for FXOS8700_ACCEL. + */ + base = type ? FXOS8700_M_OUT_X_MSB : FXOS8700_OUT_X_MSB; - /* Block read 6 bytes of device output registers to avoid data loss */ - ret = regmap_bulk_read(data->regmap, base, data->buf, - FXOS8700_DATA_BUF_SIZE); + /* Convert axis to offset index */ + offset = axis - IIO_MOD_X; + + ret = regmap_bulk_read(data->regmap, base + offset, &buf, 2); if (ret) return ret; - /* 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(buf); + + /* + * Accel raw data is 14 bit, magn raw data is 16 bit, value should be + * extended to 32 bit. + */ + if (!type) + tmp = tmp >> 2; - /* Convert to native endianness */ - *val = sign_extend32(be16_to_cpu(data->buf[reg]), 15); + *val = sign_extend32(tmp, 15); return 0; } -- 2.34.1