Skip to content

Commit 9d61c18

Browse files
NXP-CarlosSongjic23
authored andcommitted
iio: imu: fxos8700: fix ACCEL measurement range selection
When device is in active mode, it fails to set an ACCEL full-scale range(2g/4g/8g) in FXOS8700_XYZ_DATA_CFG. This is not align with the datasheet, but it is a fxos8700 chip behavior. Keep the device in standby mode before setting ACCEL full-scale range into FXOS8700_XYZ_DATA_CFG in chip initialization phase and setting scale phase. Fixes: 84e5ddd ("iio: imu: Add support for the FXOS8700 IMU") Signed-off-by: Carlos Song <[email protected]> Link: https://lore.kernel.org/r/[email protected] Cc: <[email protected]> Signed-off-by: Jonathan Cameron <[email protected]>
1 parent a53f945 commit 9d61c18

File tree

1 file changed

+34
-7
lines changed

1 file changed

+34
-7
lines changed

drivers/iio/imu/fxos8700_core.c

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,8 @@ static int fxos8700_set_active_mode(struct fxos8700_data *data,
345345
static int fxos8700_set_scale(struct fxos8700_data *data,
346346
enum fxos8700_sensor t, int uscale)
347347
{
348-
int i;
348+
int i, ret, val;
349+
bool active_mode;
349350
static const int scale_num = ARRAY_SIZE(fxos8700_accel_scale);
350351
struct device *dev = regmap_get_device(data->regmap);
351352

@@ -354,15 +355,38 @@ static int fxos8700_set_scale(struct fxos8700_data *data,
354355
return -EINVAL;
355356
}
356357

358+
/*
359+
* When device is in active mode, it failed to set an ACCEL
360+
* full-scale range(2g/4g/8g) in FXOS8700_XYZ_DATA_CFG.
361+
* This is not align with the datasheet, but it is a fxos8700
362+
* chip behavier. Set the device in standby mode before setting
363+
* an ACCEL full-scale range.
364+
*/
365+
ret = regmap_read(data->regmap, FXOS8700_CTRL_REG1, &val);
366+
if (ret)
367+
return ret;
368+
369+
active_mode = val & FXOS8700_ACTIVE;
370+
if (active_mode) {
371+
ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1,
372+
val & ~FXOS8700_ACTIVE);
373+
if (ret)
374+
return ret;
375+
}
376+
357377
for (i = 0; i < scale_num; i++)
358378
if (fxos8700_accel_scale[i].uscale == uscale)
359379
break;
360380

361381
if (i == scale_num)
362382
return -EINVAL;
363383

364-
return regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG,
384+
ret = regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG,
365385
fxos8700_accel_scale[i].bits);
386+
if (ret)
387+
return ret;
388+
return regmap_write(data->regmap, FXOS8700_CTRL_REG1,
389+
active_mode);
366390
}
367391

368392
static int fxos8700_get_scale(struct fxos8700_data *data,
@@ -631,14 +655,17 @@ static int fxos8700_chip_init(struct fxos8700_data *data, bool use_spi)
631655
if (ret)
632656
return ret;
633657

634-
/* Max ODR (800Hz individual or 400Hz hybrid), active mode */
635-
ret = regmap_write(data->regmap, FXOS8700_CTRL_REG1,
636-
FXOS8700_CTRL_ODR_MAX | FXOS8700_ACTIVE);
658+
/*
659+
* Set max full-scale range (+/-8G) for ACCEL sensor in chip
660+
* initialization then activate the device.
661+
*/
662+
ret = regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG, MODE_8G);
637663
if (ret)
638664
return ret;
639665

640-
/* Set for max full-scale range (+/-8G) */
641-
return regmap_write(data->regmap, FXOS8700_XYZ_DATA_CFG, MODE_8G);
666+
/* Max ODR (800Hz individual or 400Hz hybrid), active mode */
667+
return regmap_write(data->regmap, FXOS8700_CTRL_REG1,
668+
FXOS8700_CTRL_ODR_MAX | FXOS8700_ACTIVE);
642669
}
643670

644671
static void fxos8700_chip_uninit(void *data)

0 commit comments

Comments
 (0)