Skip to content

Commit dde67eb

Browse files
committed
i2c: add i2c_get_device_id() to get the standard i2c device id
Can be used during probe to double check that the probed device is what is expected. Loosely based on code from Adrian Fiergolski <[email protected]>. Tested-by: Adrian Fiergolski <[email protected]> Reviewed-by: Wolfram Sang <[email protected]> Signed-off-by: Peter Rosin <[email protected]>
1 parent 4a3928c commit dde67eb

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

drivers/i2c/i2c-core-base.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@
5858
#define I2C_ADDR_7BITS_MAX 0x77
5959
#define I2C_ADDR_7BITS_COUNT (I2C_ADDR_7BITS_MAX + 1)
6060

61+
#define I2C_ADDR_DEVICE_ID 0x7c
62+
6163
/*
6264
* core_lock protects i2c_adapter_idr, and guarantees that device detection,
6365
* deletion of detected devices, and attach_adapter calls are serialized
@@ -1968,6 +1970,37 @@ int i2c_transfer_buffer_flags(const struct i2c_client *client, char *buf,
19681970
}
19691971
EXPORT_SYMBOL(i2c_transfer_buffer_flags);
19701972

1973+
/**
1974+
* i2c_get_device_id - get manufacturer, part id and die revision of a device
1975+
* @client: The device to query
1976+
* @id: The queried information
1977+
*
1978+
* Returns negative errno on error, zero on success.
1979+
*/
1980+
int i2c_get_device_id(const struct i2c_client *client,
1981+
struct i2c_device_identity *id)
1982+
{
1983+
struct i2c_adapter *adap = client->adapter;
1984+
union i2c_smbus_data raw_id;
1985+
int ret;
1986+
1987+
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_I2C_BLOCK))
1988+
return -EOPNOTSUPP;
1989+
1990+
raw_id.block[0] = 3;
1991+
ret = i2c_smbus_xfer(adap, I2C_ADDR_DEVICE_ID, 0,
1992+
I2C_SMBUS_READ, client->addr << 1,
1993+
I2C_SMBUS_I2C_BLOCK_DATA, &raw_id);
1994+
if (ret)
1995+
return ret;
1996+
1997+
id->manufacturer_id = (raw_id.block[1] << 4) | (raw_id.block[2] >> 4);
1998+
id->part_id = ((raw_id.block[2] & 0xf) << 5) | (raw_id.block[3] >> 3);
1999+
id->die_revision = raw_id.block[3] & 0x7;
2000+
return 0;
2001+
}
2002+
EXPORT_SYMBOL_GPL(i2c_get_device_id);
2003+
19712004
/* ----------------------------------------------------
19722005
* the i2c address scanning function
19732006
* Will not work for 10-bit addresses!

include/linux/i2c.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ struct i2c_algorithm;
4747
struct i2c_adapter;
4848
struct i2c_client;
4949
struct i2c_driver;
50+
struct i2c_device_identity;
5051
union i2c_smbus_data;
5152
struct i2c_board_info;
5253
enum i2c_slave_event;
@@ -186,8 +187,37 @@ extern s32 i2c_smbus_write_i2c_block_data(const struct i2c_client *client,
186187
extern s32
187188
i2c_smbus_read_i2c_block_data_or_emulated(const struct i2c_client *client,
188189
u8 command, u8 length, u8 *values);
190+
int i2c_get_device_id(const struct i2c_client *client,
191+
struct i2c_device_identity *id);
189192
#endif /* I2C */
190193

194+
/**
195+
* struct i2c_device_identity - i2c client device identification
196+
* @manufacturer_id: 0 - 4095, database maintained by NXP
197+
* @part_id: 0 - 511, according to manufacturer
198+
* @die_revision: 0 - 7, according to manufacturer
199+
*/
200+
struct i2c_device_identity {
201+
u16 manufacturer_id;
202+
#define I2C_DEVICE_ID_NXP_SEMICONDUCTORS 0
203+
#define I2C_DEVICE_ID_NXP_SEMICONDUCTORS_1 1
204+
#define I2C_DEVICE_ID_NXP_SEMICONDUCTORS_2 2
205+
#define I2C_DEVICE_ID_NXP_SEMICONDUCTORS_3 3
206+
#define I2C_DEVICE_ID_RAMTRON_INTERNATIONAL 4
207+
#define I2C_DEVICE_ID_ANALOG_DEVICES 5
208+
#define I2C_DEVICE_ID_STMICROELECTRONICS 6
209+
#define I2C_DEVICE_ID_ON_SEMICONDUCTOR 7
210+
#define I2C_DEVICE_ID_SPRINTEK_CORPORATION 8
211+
#define I2C_DEVICE_ID_ESPROS_PHOTONICS_AG 9
212+
#define I2C_DEVICE_ID_FUJITSU_SEMICONDUCTOR 10
213+
#define I2C_DEVICE_ID_FLIR 11
214+
#define I2C_DEVICE_ID_O2MICRO 12
215+
#define I2C_DEVICE_ID_ATMEL 13
216+
#define I2C_DEVICE_ID_NONE 0xffff
217+
u16 part_id;
218+
u8 die_revision;
219+
};
220+
191221
enum i2c_alert_protocol {
192222
I2C_PROTOCOL_SMBUS_ALERT,
193223
I2C_PROTOCOL_SMBUS_HOST_NOTIFY,

0 commit comments

Comments
 (0)