Expose the per-chip unique identifier so it can be used to identify the sensor producing the measurements. Signed-off-by: Peter A. Bigot <pab@xxxxxxxxxxx> --- Documentation/hwmon/sht21 | 6 ++-- drivers/hwmon/sht21.c | 92 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 94 insertions(+), 4 deletions(-) diff --git a/Documentation/hwmon/sht21 b/Documentation/hwmon/sht21 index db17fda..a0db761 100644 --- a/Documentation/hwmon/sht21 +++ b/Documentation/hwmon/sht21 @@ -16,6 +16,7 @@ Supported chips: Author: Urs Fleisch <urs.fleisch@xxxxxxxxxxxxx> + Peter A. Bigot <pab@xxxxxxxxxxx> Description ----------- @@ -35,6 +36,7 @@ sysfs-Interface temp1_input - temperature input humidity1_input - humidity input +eic1_input - Electronic Identification Code Notes ----- @@ -45,5 +47,5 @@ humidity and 66 ms for temperature. To keep self heating below 0.1 degree Celsius, the device should not be active for more than 10% of the time, e.g. maximum two measurements per second at the given resolution. -Different resolutions, the on-chip heater, using the CRC checksum and reading -the serial number are not supported yet. +Different resolutions, the on-chip heater, and using the CRC checksum +are not supported yet. diff --git a/drivers/hwmon/sht21.c b/drivers/hwmon/sht21.c index 84cdb1c..530350b 100644 --- a/drivers/hwmon/sht21.c +++ b/drivers/hwmon/sht21.c @@ -1,6 +1,7 @@ /* Sensirion SHT21 humidity and temperature sensor driver * * Copyright (C) 2010 Urs Fleisch <urs.fleisch@xxxxxxxxxxxxx> + * Copyright (C) 2016 Peter A. Bigot <pab@xxxxxxxxxxx> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,6 +36,10 @@ #define SHT21_TRIG_T_MEASUREMENT_HM 0xe3 #define SHT21_TRIG_RH_MEASUREMENT_HM 0xe5 +/* Valid flags */ +#define SHT21_MEASUREMENT_VALID 0x01 +#define SHT21_EIC_VALID 0x02 + /** * struct sht21 - SHT21 device specific data * @hwmon_dev: device registered with hwmon @@ -43,6 +48,7 @@ * @last_update: time of last update (jiffies) * @temperature: cached temperature measurement value * @humidity: cached humidity measurement value + * @eic: cached electronic identification code */ struct sht21 { struct i2c_client *client; @@ -51,6 +57,7 @@ struct sht21 { unsigned long last_update; int temperature; int humidity; + u8 eic[8]; }; /** @@ -101,7 +108,8 @@ static int sht21_update_measurements(struct device *dev) * SHT2x should not be active for more than 10% of the time - e.g. * maximum two measurements per second at 12bit accuracy shall be made. */ - if (time_after(jiffies, sht21->last_update + HZ / 2) || !sht21->valid) { + if (time_after(jiffies, sht21->last_update + HZ / 2) + || !(SHT21_MEASUREMENT_VALID & sht21->valid)) { ret = i2c_smbus_read_word_swapped(client, SHT21_TRIG_T_MEASUREMENT_HM); if (ret < 0) @@ -113,7 +121,7 @@ static int sht21_update_measurements(struct device *dev) goto out; sht21->humidity = sht21_rh_ticks_to_per_cent_mille(ret); sht21->last_update = jiffies; - sht21->valid = 1; + sht21->valid |= SHT21_MEASUREMENT_VALID; } out: mutex_unlock(&sht21->lock); @@ -165,15 +173,95 @@ static ssize_t sht21_show_humidity(struct device *dev, return sprintf(buf, "%d\n", sht21->humidity); } +/** + * sht21_show_eic() - show Electronic Identification Code in sysfs + * @dev: device + * @attr: device attribute + * @buf: sysfs buffer (PAGE_SIZE) where measurement values are written to + * + * Will be called on read access to eic1_input sysfs attribute. + * Returns number of bytes written into buffer, negative errno on error. + */ +static ssize_t sht21_show_eic(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct sht21 *sht21 = dev_get_drvdata(dev); + struct i2c_client *client = sht21->client; + int ret = 0; + int i; + char *bp = buf; + mutex_lock(&sht21->lock); + if (!(SHT21_EIC_VALID & sht21->valid)) { + u8 tx[4]; + u8 rx[8]; + struct i2c_msg msgs[2] = { + { + .addr = client->addr, + .flags = 0, + .len = 0, + .buf = tx, + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = 0, + .buf = rx, + }, + }; + u8 *dp = tx; + *dp++ = 0xFA; + *dp++ = 0x0F; + msgs[0].len = dp-tx; + msgs[1].len = 8; + ret = i2c_transfer(client->adapter, msgs, 2); + if (ret < 0) + goto out; + sht21->eic[2] = rx[0]; + sht21->eic[3] = rx[2]; + sht21->eic[4] = rx[4]; + sht21->eic[5] = rx[6]; + dp = tx; + *dp++ = 0xFC; + *dp++ = 0xC9; + msgs[0].len = dp-tx; + msgs[1].len = 6; + ret = i2c_transfer(client->adapter, msgs, 2); + if (ret < 0) + goto out; + sht21->eic[0] = rx[3]; + sht21->eic[1] = rx[4]; + sht21->eic[6] = rx[0]; + sht21->eic[7] = rx[1]; + sht21->valid |= SHT21_EIC_VALID; + } + + for (i = 0; i < sizeof(sht21->eic); ++i) { + ret = sprintf(bp, "%02x", sht21->eic[i]); + if (ret < 0) + goto out; + bp += ret; + } +out: + mutex_unlock(&sht21->lock); + if (ret >= 0) { + *bp++ = '\n'; + ret = bp - buf; + } + return ret; +} + /* sysfs attributes */ static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, sht21_show_temperature, NULL, 0); static SENSOR_DEVICE_ATTR(humidity1_input, S_IRUGO, sht21_show_humidity, NULL, 0); +static SENSOR_DEVICE_ATTR(eic1_input, S_IRUGO, sht21_show_eic, NULL, 0); static struct attribute *sht21_attrs[] = { &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_humidity1_input.dev_attr.attr, + &sensor_dev_attr_eic1_input.dev_attr.attr, NULL }; -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-hwmon" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html