Skip to content

Commit

Permalink
mpu6050: Add check of WHO_AM_I register value
Browse files Browse the repository at this point in the history
Most of i2c chips have a special read-only register with unique id.
So the easiest way to communicate with the device is to read that register.
It should be accessibe even during power off modes and so failing to read it
means no communication with the device. Reading non-expected value will indicate
wrong adress or data size used, or incorrect device connected (other revision).

Reading small amounts of data is easiest done using i2c_smbus_read_byte()
or similar functions. Why smbus? Because they are wrappers to i2c_transfer()
function and have internal device address as a parameter. This eliminates need
to fill i2c_transfer structure for each small read or write.
Using i2c_transfer() should be considered for large blocks of data and gives
a performance boost over i2c_smbus wrappers.

Signed-off-by: Andriy.Khulap <[email protected]>
  • Loading branch information
an1kh committed Nov 9, 2017
1 parent 1dccbeb commit 83e27dd
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
33 changes: 33 additions & 0 deletions mpu6050/mpu6050-regs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef _MPU6050_REGS_H
#define _MPU6050_REGS_H

/* Registed addresses */
#define REG_CONFIG 0x1A
#define REG_GYRO_CONFIG 0x1B
#define REG_ACCEL_CONFIG 0x1C
#define REG_FIFO_EN 0x23
#define REG_INT_PIN_CFG 0x37
#define REG_INT_ENABLE 0x38
#define REG_ACCEL_XOUT_H 0x3B
#define REG_ACCEL_XOUT_L 0x3C
#define REG_ACCEL_YOUT_H 0x3D
#define REG_ACCEL_YOUT_L 0x3E
#define REG_ACCEL_ZOUT_H 0x3F
#define REG_ACCEL_ZOUT_L 0x40
#define REG_TEMP_OUT_H 0x41
#define REG_TEMP_OUT_L 0x42
#define REG_GYRO_XOUT_H 0x43
#define REG_GYRO_XOUT_L 0x44
#define REG_GYRO_YOUT_H 0x45
#define REG_GYRO_YOUT_L 0x46
#define REG_GYRO_ZOUT_H 0x47
#define REG_GYRO_ZOUT_L 0x48
#define REG_USER_CTRL 0x6A
#define REG_PWR_MGMT_1 0x6B
#define REG_PWR_MGMT_2 0x6C
#define REG_WHO_AM_I 0x75

/* Register values */
#define MPU6050_WHO_AM_I 0x68

#endif /* _MPU6050_REGS_H */
23 changes: 23 additions & 0 deletions mpu6050/mpu6050.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,34 @@
#include <linux/i2c.h>
#include <linux/i2c-dev.h>

#include "mpu6050-regs.h"

static int mpu6050_probe(struct i2c_client *drv_client,
const struct i2c_device_id *id)
{
int ret;

dev_info(&drv_client->dev,
"i2c client address is 0x%X\n", drv_client->addr);

/* Read who_am_i register */
ret = i2c_smbus_read_byte_data(drv_client, REG_WHO_AM_I);
if (IS_ERR_VALUE(ret)) {
dev_err(&drv_client->dev,
"i2c_smbus_read_byte_data() failed with error: %d\n",
ret);
return ret;
}
if (ret != MPU6050_WHO_AM_I) {
dev_err(&drv_client->dev,
"wrong i2c device found: expected 0x%X, found 0x%X\n",
MPU6050_WHO_AM_I, ret);
return -1;
}
dev_info(&drv_client->dev,
"i2c mpu6050 device found, WHO_AM_I register value = 0x%X\n",
ret);

dev_info(&drv_client->dev, "i2c driver probed\n");
return 0;
}
Expand Down

0 comments on commit 83e27dd

Please sign in to comment.