summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorCrestez Dan Leonard <leonard.crestez@intel.com>2016-04-20 16:15:11 +0300
committerJonathan Cameron <jic23@kernel.org>2016-04-25 20:19:15 +0100
commitcec0154556f8fe6d3a7f5d370f715283888d1c02 (patch)
tree7a082b20a86aee92d75492aaf804d5d5dafc0764 /drivers
parent7bdd3181596d3d95ef39849bc3ef8e5b91cb6ae1 (diff)
downloadlinux-cec0154556f8fe6d3a7f5d370f715283888d1c02.tar.gz
linux-cec0154556f8fe6d3a7f5d370f715283888d1c02.tar.bz2
linux-cec0154556f8fe6d3a7f5d370f715283888d1c02.zip
iio: inv_mpu6050: Check WHO_AM_I register on probe
This can be used to distinguish mpu6500. This is a warning rather than an error because the differences are mostly irrelevant and it's nice to avoid breaking users with slightly incorrect ACPI/DT. Signed-off-by: Crestez Dan Leonard <leonard.crestez@intel.com> Acked-by: Ge Gao <ggao@invensense.com> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/iio/imu/inv_mpu6050/inv_mpu_core.c15
-rw-r--r--drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h8
2 files changed, 23 insertions, 0 deletions
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
index 84d5b6939e6a..4152f2fcf598 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
@@ -91,16 +91,19 @@ static const struct inv_mpu6050_chip_config chip_config_6050 = {
/* Indexed by enum inv_devices */
static const struct inv_mpu6050_hw hw_info[] = {
{
+ .whoami = INV_MPU6050_WHOAMI_VALUE,
.name = "MPU6050",
.reg = &reg_set_6050,
.config = &chip_config_6050,
},
{
+ .whoami = INV_MPU6500_WHOAMI_VALUE,
.name = "MPU6500",
.reg = &reg_set_6500,
.config = &chip_config_6050,
},
{
+ .whoami = INV_MPU6000_WHOAMI_VALUE,
.name = "MPU6000",
.reg = &reg_set_6050,
.config = &chip_config_6050,
@@ -749,6 +752,7 @@ static const struct iio_info mpu_info = {
static int inv_check_and_setup_chip(struct inv_mpu6050_state *st)
{
int result;
+ unsigned int regval;
st->hw = &hw_info[st->chip_type];
st->reg = hw_info[st->chip_type].reg;
@@ -759,6 +763,17 @@ static int inv_check_and_setup_chip(struct inv_mpu6050_state *st)
if (result)
return result;
msleep(INV_MPU6050_POWER_UP_TIME);
+
+ /* check chip self-identification */
+ result = regmap_read(st->map, INV_MPU6050_REG_WHOAMI, &regval);
+ if (result)
+ return result;
+ if (regval != st->hw->whoami) {
+ dev_warn(regmap_get_device(st->map),
+ "whoami mismatch got %#02x expected %#02hhx for %s\n",
+ regval, st->hw->whoami, st->hw->name);
+ }
+
/*
* toggle power state. After reset, the sleep bit could be on
* or off depending on the OTP settings. Toggling power would
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
index 26b63993ba00..fb45cc76e4e4 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
@@ -93,11 +93,13 @@ struct inv_mpu6050_chip_config {
/**
* struct inv_mpu6050_hw - Other important hardware information.
+ * @whoami: Self identification byte from WHO_AM_I register
* @name: name of the chip.
* @reg: register map of the chip.
* @config: configuration of the chip.
*/
struct inv_mpu6050_hw {
+ u8 whoami;
u8 *name;
const struct inv_mpu6050_reg_map *reg;
const struct inv_mpu6050_chip_config *config;
@@ -215,6 +217,12 @@ struct inv_mpu6050_state {
#define INV_MPU6050_MIN_FIFO_RATE 4
#define INV_MPU6050_ONE_K_HZ 1000
+#define INV_MPU6050_REG_WHOAMI 117
+
+#define INV_MPU6000_WHOAMI_VALUE 0x68
+#define INV_MPU6050_WHOAMI_VALUE 0x68
+#define INV_MPU6500_WHOAMI_VALUE 0x70
+
/* scan element definition */
enum inv_mpu6050_scan {
INV_MPU6050_SCAN_ACCL_X,