diff options
author | Devin Lu <devin.lu@quantatw.com> | 2018-12-27 11:03:04 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-01-25 04:09:07 -0800 |
commit | f2e78e4d9b670eb1427bb5fd89bb888bdcf91711 (patch) | |
tree | 946ea09eff010f0e190dbc0f235a0bbc141dec1f /driver | |
parent | 4ca73139635261ee1273fbe1767dcf06886d2208 (diff) | |
download | chrome-ec-f2e78e4d9b670eb1427bb5fd89bb888bdcf91711.tar.gz |
driver: lsm6dsm: add reboot at init time
Without this patch, the pass-through mode will get stuck after sysjump.
Force a reboot of the lsm6dsm accelerometer side at init() to allow
magnetometer initialization to complete.
BUG=b:115587004
BRANCH=octopus
TEST=execute "sysjump RW" then make sure magnetometer initial passed
and no errors as below:
[855.944737 Base Accel: MS Done Init type:0x0 range:2]
[855.947773 Base Accel ODR: 13000 - roundup 1 from config 1 [AP 0]]
[855.949904 Base Gyro: MS Done Init type:0x1 range:1000]
[855.952509 Base Gyro ODR: 0 - roundup 0 from config 0 [AP 0]]
sensorhub_check_and_rst: Base Accel type:0x0 WAIR error ret: 1
sensorhub_check_and_rst: Base Accel type:0x0 WAIR error ret: 1
sensorhub_check_and_rst: Base Accel type:0x0 WAIR error ret: 1
[855.993153 Base Mag: 3: init failed: 1]
Change-Id: I7870acb674457dfcf247a3fa231e82a7123303bf
Signed-off-by: Devin Lu <Devin.Lu@quantatw.com>
Reviewed-on: https://chromium-review.googlesource.com/1389994
Reviewed-by: Justin TerAvest <teravest@chromium.org>
Diffstat (limited to 'driver')
-rw-r--r-- | driver/accelgyro_lsm6dsm.c | 50 | ||||
-rw-r--r-- | driver/accelgyro_lsm6dsm.h | 1 |
2 files changed, 51 insertions, 0 deletions
diff --git a/driver/accelgyro_lsm6dsm.c b/driver/accelgyro_lsm6dsm.c index 59a46cdaac..b53755ada4 100644 --- a/driver/accelgyro_lsm6dsm.c +++ b/driver/accelgyro_lsm6dsm.c @@ -553,6 +553,7 @@ static int init(const struct motion_sensor_t *s) * struct stprivate_data *data = &lsm_data->a_data; */ struct stprivate_data *data = s->drv_data; + uint8_t ctrl_reg, reg_val = 0; ret = st_raw_read8(s->port, s->addr, LSM6DSM_WHO_AM_I_REG, &tmp); if (ret != EC_SUCCESS) @@ -571,12 +572,61 @@ static int init(const struct motion_sensor_t *s) if (s->type == MOTIONSENSE_TYPE_ACCEL) { mutex_lock(s->mutex); + /* Software reset procedure. */ + reg_val = LSM6DSM_ODR_TO_REG(LSM6DSM_ODR_MIN_VAL); + ctrl_reg = LSM6DSM_ODR_REG(MOTIONSENSE_TYPE_ACCEL); + + /* Power OFF gyro. */ + ret = st_raw_write8(s->port, s->addr, LSM6DSM_CTRL2_ADDR, 0); + if (ret != EC_SUCCESS) + goto err_unlock; + + /* Power ON Accel. */ + ret = st_raw_write8(s->port, s->addr, ctrl_reg, reg_val); + if (ret != EC_SUCCESS) + goto err_unlock; + /* Software reset. */ ret = st_raw_write8(s->port, s->addr, LSM6DSM_CTRL3_ADDR, LSM6DSM_SW_RESET); if (ret != EC_SUCCESS) goto err_unlock; +#ifdef CONFIG_MAG_LIS2MDL + /* + * TODO: Check for pass-through mode instead of magnetometer + * config. + */ + + /* + * Reboot to reload memory content as pass-through mode can get + * stuck. + * Direct to the AN: See "AN4987 - LSM6DSM: always-on 3D + * accelerometer and 3D gyroscope". + */ + + /* Power ON Accel. */ + ret = st_raw_write8(s->port, s->addr, ctrl_reg, reg_val); + if (ret != EC_SUCCESS) + goto err_unlock; + + ret = st_raw_write8(s->port, s->addr, LSM6DSM_CTRL3_ADDR, + LSM6DSM_BOOT); + if (ret != EC_SUCCESS) + goto err_unlock; + + /* + * Refer to AN4987, wait 15ms for accelerometer to doing full + * reboot. + */ + msleep(15); + + /* Power OFF Accel. */ + ret = st_raw_write8(s->port, s->addr, ctrl_reg, 0); + if (ret != EC_SUCCESS) + goto err_unlock; +#endif + /* * Output data not updated until have been read. * Prefer interrupt to be active low. diff --git a/driver/accelgyro_lsm6dsm.h b/driver/accelgyro_lsm6dsm.h index fd7f59c3b3..0d0480a9cb 100644 --- a/driver/accelgyro_lsm6dsm.h +++ b/driver/accelgyro_lsm6dsm.h @@ -46,6 +46,7 @@ #define LSM6DSM_PP_OD 0x10 #define LSM6DSM_H_L_ACTIVE 0x20 #define LSM6DSM_BDU 0x40 +#define LSM6DSM_BOOT 0x80 #define LSM6DSM_CTRL4_ADDR 0x13 #define LSM6DSM_INT2_ON_INT1_MASK 0x20 |