[PATCH 1/4] iio: imu: fxos8700: fix get data function error

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux