driver: bmi160: Add magic sequence to unlock

If init() is interrupted while we are setting the link to the compass,
the BMI160 may be in paging mode and will only answer to registers 7Eh
and 7Fh. Other registers access will return 00h.
To get out of this state, run the sequence to move back from the paging
mode in the error handler. If successful, a subsequent call to init()
will work.

BRANCH=smaug
BUG=chrome-os-partner:45722
TEST=use a special firmware that exists in the middle of the compass
init sequence. Check that the FIFO and all other registers return 0.
Issue 'accelinit 1' (to reset the Gyro): the command succeeds and the
accelerometer is operational again (double tap works).
Check the sequence can be issued after sysjump to RW/RO.

Change-Id: I3455a8cbdcf1c88699ae90f7c09e4438e1268d47
Signed-off-by: Gwendal Grignou <gwendal@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/308184
Reviewed-by: Alec Berg <alecaberg@chromium.org>
This commit is contained in:
Gwendal Grignou
2015-10-20 11:23:33 -07:00
committed by chrome-bot
parent df038776b4
commit 8238dfa27d

View File

@@ -1074,8 +1074,19 @@ static int init(const struct motion_sensor_t *s)
if (ret)
return EC_ERROR_UNKNOWN;
if (tmp != BMI160_CHIP_ID_MAJOR)
if (tmp != BMI160_CHIP_ID_MAJOR) {
/* The device may be lock on paging mode. Try to unlock it. */
raw_write8(s->addr, BMI160_CMD_REG,
BMI160_CMD_EXT_MODE_EN_B0);
raw_write8(s->addr, BMI160_CMD_REG,
BMI160_CMD_EXT_MODE_EN_B1);
raw_write8(s->addr, BMI160_CMD_REG,
BMI160_CMD_EXT_MODE_EN_B2);
raw_write8(s->addr, BMI160_CMD_EXT_MODE_ADDR,
BMI160_CMD_PAGING_EN);
raw_write8(s->addr, BMI160_CMD_EXT_MODE_ADDR, 0);
return EC_ERROR_ACCESS_DENIED;
}
if (s->type == MOTIONSENSE_TYPE_ACCEL) {