aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter A. Bigot <pab@pabigot.com>2016-12-24 08:22:44 -0500
committerGuenter Roeck <linux@roeck-us.net>2017-01-02 13:19:45 -0500
commit53e678d75e7c22b251c6981ff8364b5c42c5eac4 (patch)
tree2886d135b167d53686c839802d655b5a312cce25
parent5343aed12f262c87372c4f20b744756837240dc9 (diff)
hwmon: (sht21) Add Electronic Identification Code retrieval
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@pabigot.com> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r--Documentation/hwmon/sht215
-rw-r--r--drivers/hwmon/sht21.c92
2 files changed, 93 insertions, 4 deletions
diff --git a/Documentation/hwmon/sht21 b/Documentation/hwmon/sht21
index db17fda45c3e..47f4765db256 100644
--- a/Documentation/hwmon/sht21
+++ b/Documentation/hwmon/sht21
@@ -35,6 +35,7 @@ sysfs-Interface
35 35
36temp1_input - temperature input 36temp1_input - temperature input
37humidity1_input - humidity input 37humidity1_input - humidity input
38eic - Electronic Identification Code
38 39
39Notes 40Notes
40----- 41-----
@@ -45,5 +46,5 @@ humidity and 66 ms for temperature. To keep self heating below 0.1 degree
45Celsius, the device should not be active for more than 10% of the time, 46Celsius, the device should not be active for more than 10% of the time,
46e.g. maximum two measurements per second at the given resolution. 47e.g. maximum two measurements per second at the given resolution.
47 48
48Different resolutions, the on-chip heater, using the CRC checksum and reading 49Different resolutions, the on-chip heater, and using the CRC checksum
49the serial number are not supported yet. 50are not supported yet.
diff --git a/drivers/hwmon/sht21.c b/drivers/hwmon/sht21.c
index 84cdb1cf0fb4..06706d288355 100644
--- a/drivers/hwmon/sht21.c
+++ b/drivers/hwmon/sht21.c
@@ -34,23 +34,29 @@
34/* I2C command bytes */ 34/* I2C command bytes */
35#define SHT21_TRIG_T_MEASUREMENT_HM 0xe3 35#define SHT21_TRIG_T_MEASUREMENT_HM 0xe3
36#define SHT21_TRIG_RH_MEASUREMENT_HM 0xe5 36#define SHT21_TRIG_RH_MEASUREMENT_HM 0xe5
37#define SHT21_READ_SNB_CMD1 0xFA
38#define SHT21_READ_SNB_CMD2 0x0F
39#define SHT21_READ_SNAC_CMD1 0xFC
40#define SHT21_READ_SNAC_CMD2 0xC9
37 41
38/** 42/**
39 * struct sht21 - SHT21 device specific data 43 * struct sht21 - SHT21 device specific data
40 * @hwmon_dev: device registered with hwmon 44 * @hwmon_dev: device registered with hwmon
41 * @lock: mutex to protect measurement values 45 * @lock: mutex to protect measurement values
42 * @valid: only 0 before first measurement is taken
43 * @last_update: time of last update (jiffies) 46 * @last_update: time of last update (jiffies)
44 * @temperature: cached temperature measurement value 47 * @temperature: cached temperature measurement value
45 * @humidity: cached humidity measurement value 48 * @humidity: cached humidity measurement value
49 * @valid: only 0 before first measurement is taken
50 * @eic: cached electronic identification code text
46 */ 51 */
47struct sht21 { 52struct sht21 {
48 struct i2c_client *client; 53 struct i2c_client *client;
49 struct mutex lock; 54 struct mutex lock;
50 char valid;
51 unsigned long last_update; 55 unsigned long last_update;
52 int temperature; 56 int temperature;
53 int humidity; 57 int humidity;
58 char valid;
59 char eic[18];
54}; 60};
55 61
56/** 62/**
@@ -165,15 +171,97 @@ static ssize_t sht21_show_humidity(struct device *dev,
165 return sprintf(buf, "%d\n", sht21->humidity); 171 return sprintf(buf, "%d\n", sht21->humidity);
166} 172}
167 173
174static ssize_t eic_read(struct sht21 *sht21)
175{
176 struct i2c_client *client = sht21->client;
177 u8 tx[2];
178 u8 rx[8];
179 u8 eic[8];
180 struct i2c_msg msgs[2] = {
181 {
182 .addr = client->addr,
183 .flags = 0,
184 .len = 2,
185 .buf = tx,
186 },
187 {
188 .addr = client->addr,
189 .flags = I2C_M_RD,
190 .len = 8,
191 .buf = rx,
192 },
193 };
194 int ret;
195
196 tx[0] = SHT21_READ_SNB_CMD1;
197 tx[1] = SHT21_READ_SNB_CMD2;
198 ret = i2c_transfer(client->adapter, msgs, 2);
199 if (ret < 0)
200 goto out;
201 eic[2] = rx[0];
202 eic[3] = rx[2];
203 eic[4] = rx[4];
204 eic[5] = rx[6];
205
206 tx[0] = SHT21_READ_SNAC_CMD1;
207 tx[1] = SHT21_READ_SNAC_CMD2;
208 msgs[1].len = 6;
209 ret = i2c_transfer(client->adapter, msgs, 2);
210 if (ret < 0)
211 goto out;
212 eic[0] = rx[3];
213 eic[1] = rx[4];
214 eic[6] = rx[0];
215 eic[7] = rx[1];
216
217 ret = snprintf(sht21->eic, sizeof(sht21->eic),
218 "%02x%02x%02x%02x%02x%02x%02x%02x\n",
219 eic[0], eic[1], eic[2], eic[3],
220 eic[4], eic[5], eic[6], eic[7]);
221out:
222 if (ret < 0)
223 sht21->eic[0] = 0;
224
225 return ret;
226}
227
228/**
229 * eic_show() - show Electronic Identification Code in sysfs
230 * @dev: device
231 * @attr: device attribute
232 * @buf: sysfs buffer (PAGE_SIZE) where EIC is written
233 *
234 * Will be called on read access to eic sysfs attribute.
235 * Returns number of bytes written into buffer, negative errno on error.
236 */
237static ssize_t eic_show(struct device *dev,
238 struct device_attribute *attr,
239 char *buf)
240{
241 struct sht21 *sht21 = dev_get_drvdata(dev);
242 int ret;
243
244 ret = sizeof(sht21->eic) - 1;
245 mutex_lock(&sht21->lock);
246 if (!sht21->eic[0])
247 ret = eic_read(sht21);
248 if (ret > 0)
249 memcpy(buf, sht21->eic, ret);
250 mutex_unlock(&sht21->lock);
251 return ret;
252}
253
168/* sysfs attributes */ 254/* sysfs attributes */
169static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, sht21_show_temperature, 255static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, sht21_show_temperature,
170 NULL, 0); 256 NULL, 0);
171static SENSOR_DEVICE_ATTR(humidity1_input, S_IRUGO, sht21_show_humidity, 257static SENSOR_DEVICE_ATTR(humidity1_input, S_IRUGO, sht21_show_humidity,
172 NULL, 0); 258 NULL, 0);
259static DEVICE_ATTR_RO(eic);
173 260
174static struct attribute *sht21_attrs[] = { 261static struct attribute *sht21_attrs[] = {
175 &sensor_dev_attr_temp1_input.dev_attr.attr, 262 &sensor_dev_attr_temp1_input.dev_attr.attr,
176 &sensor_dev_attr_humidity1_input.dev_attr.attr, 263 &sensor_dev_attr_humidity1_input.dev_attr.attr,
264 &dev_attr_eic.attr,
177 NULL 265 NULL
178}; 266};
179 267