Commit dde67eb1beeb ("i2c: add i2c_get_device_id() to get the standard I2C device id") added a function to return the standard I2C device ID. Use that function to verify the device ID of a given device. Cc: Peter Rosin <peda@xxxxxxxxxx> Signed-off-by: Guenter Roeck <linux@xxxxxxxxxxxx> --- RFC: - Compile tested only - Should there also be I2C_DEVICE_PART_ID_ANY to enable maching against all parts from a given manufacturer ? drivers/i2c/i2c-core-base.c | 34 ++++++++++++++++++++++++++++++++++ include/linux/i2c.h | 3 +++ 2 files changed, 37 insertions(+) diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 16a3b73375a6..4e4372b064f6 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -2009,6 +2009,40 @@ int i2c_get_device_id(const struct i2c_client *client, } EXPORT_SYMBOL_GPL(i2c_get_device_id); +/** + * i2c_verify_device_id - verify device ID + * @client: The device to query + * @id: Expected device ID + * + * Returns negative errno on error, zero on success. + */ +int i2c_verify_device_id(const struct i2c_client *client, + const struct i2c_device_identity *id) +{ + struct i2c_device_identity real_id; + int ret; + + if (id->manufacturer_id == I2C_DEVICE_ID_NONE) + return 0; + + ret = i2c_get_device_id(client, &real_id); + if (ret < 0) + return ret; + + if (id->manufacturer_id != real_id.manufacturer_id || + id->part_id != real_id.part_id || + (id->die_revision != I2C_DEVICE_DIE_REVISION_ANY && + id->die_revision != real_id.die_revision)) { + dev_err(&client->dev, "unexpected device id %03x-%03x-%x\n", + real_id.manufacturer_id, real_id.part_id, + real_id.die_revision); + return -ENODEV; + } + + return 0; +} +EXPORT_SYMBOL_GPL(i2c_verify_device_id); + /* ---------------------------------------------------- * the i2c address scanning function * Will not work for 10-bit addresses! diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 44ad14e016b5..45bae9717ecb 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -189,6 +189,8 @@ i2c_smbus_read_i2c_block_data_or_emulated(const struct i2c_client *client, u8 command, u8 length, u8 *values); int i2c_get_device_id(const struct i2c_client *client, struct i2c_device_identity *id); +int i2c_verify_device_id(const struct i2c_client *client, + const struct i2c_device_identity *id); #endif /* I2C */ /** @@ -216,6 +218,7 @@ struct i2c_device_identity { #define I2C_DEVICE_ID_NONE 0xffff u16 part_id; u8 die_revision; +#define I2C_DEVICE_DIE_REVISION_ANY 0xff }; enum i2c_alert_protocol { -- 2.7.4