1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * STTS751 sensor driver |
4 | * |
5 | * Copyright (C) 2016-2017 Istituto Italiano di Tecnologia - RBCS - EDL |
6 | * Robotics, Brain and Cognitive Sciences department |
7 | * Electronic Design Laboratory |
8 | * |
9 | * Written by Andrea Merello <andrea.merello@gmail.com> |
10 | * |
11 | * Based on LM95241 driver and LM90 driver |
12 | */ |
13 | |
14 | #include <linux/bitops.h> |
15 | #include <linux/err.h> |
16 | #include <linux/hwmon.h> |
17 | #include <linux/hwmon-sysfs.h> |
18 | #include <linux/i2c.h> |
19 | #include <linux/init.h> |
20 | #include <linux/interrupt.h> |
21 | #include <linux/jiffies.h> |
22 | #include <linux/module.h> |
23 | #include <linux/mutex.h> |
24 | #include <linux/property.h> |
25 | #include <linux/slab.h> |
26 | #include <linux/sysfs.h> |
27 | #include <linux/util_macros.h> |
28 | |
29 | #define DEVNAME "stts751" |
30 | |
31 | static const unsigned short normal_i2c[] = { |
32 | 0x48, 0x49, 0x38, 0x39, /* STTS751-0 */ |
33 | 0x4A, 0x4B, 0x3A, 0x3B, /* STTS751-1 */ |
34 | I2C_CLIENT_END }; |
35 | |
36 | #define STTS751_REG_TEMP_H 0x00 |
37 | #define STTS751_REG_STATUS 0x01 |
38 | #define STTS751_STATUS_TRIPT BIT(0) |
39 | #define STTS751_STATUS_TRIPL BIT(5) |
40 | #define STTS751_STATUS_TRIPH BIT(6) |
41 | #define STTS751_REG_TEMP_L 0x02 |
42 | #define STTS751_REG_CONF 0x03 |
43 | #define STTS751_CONF_RES_MASK 0x0C |
44 | #define STTS751_CONF_RES_SHIFT 2 |
45 | #define STTS751_CONF_EVENT_DIS BIT(7) |
46 | #define STTS751_CONF_STOP BIT(6) |
47 | #define STTS751_REG_RATE 0x04 |
48 | #define STTS751_REG_HLIM_H 0x05 |
49 | #define STTS751_REG_HLIM_L 0x06 |
50 | #define STTS751_REG_LLIM_H 0x07 |
51 | #define STTS751_REG_LLIM_L 0x08 |
52 | #define STTS751_REG_TLIM 0x20 |
53 | #define STTS751_REG_HYST 0x21 |
54 | #define STTS751_REG_SMBUS_TO 0x22 |
55 | |
56 | #define STTS751_REG_PROD_ID 0xFD |
57 | #define STTS751_REG_MAN_ID 0xFE |
58 | #define STTS751_REG_REV_ID 0xFF |
59 | |
60 | #define STTS751_0_PROD_ID 0x00 |
61 | #define STTS751_1_PROD_ID 0x01 |
62 | #define ST_MAN_ID 0x53 |
63 | |
64 | /* |
65 | * Possible update intervals are (in mS): |
66 | * 16000, 8000, 4000, 2000, 1000, 500, 250, 125, 62.5, 31.25 |
67 | * However we are not going to complicate things too much and we stick to the |
68 | * approx value in mS. |
69 | */ |
70 | static const int stts751_intervals[] = { |
71 | 16000, 8000, 4000, 2000, 1000, 500, 250, 125, 63, 31 |
72 | }; |
73 | |
74 | static const struct i2c_device_id stts751_id[] = { |
75 | { "stts751" , 0 }, |
76 | { } |
77 | }; |
78 | |
79 | static const struct of_device_id __maybe_unused stts751_of_match[] = { |
80 | { .compatible = "stts751" }, |
81 | { }, |
82 | }; |
83 | MODULE_DEVICE_TABLE(of, stts751_of_match); |
84 | |
85 | struct stts751_priv { |
86 | struct device *dev; |
87 | struct i2c_client *client; |
88 | struct mutex access_lock; |
89 | u8 interval; |
90 | int res; |
91 | int event_max, event_min; |
92 | int therm; |
93 | int hyst; |
94 | bool smbus_timeout; |
95 | int temp; |
96 | unsigned long last_update, last_alert_update; |
97 | u8 config; |
98 | bool min_alert, max_alert, therm_trip; |
99 | bool data_valid, alert_valid; |
100 | bool notify_max, notify_min; |
101 | }; |
102 | |
103 | /* |
104 | * These functions converts temperature from HW format to integer format and |
105 | * vice-vers. They are (mostly) taken from lm90 driver. Unit is in mC. |
106 | */ |
107 | static int stts751_to_deg(s16 hw_val) |
108 | { |
109 | return hw_val * 125 / 32; |
110 | } |
111 | |
112 | static s32 stts751_to_hw(int val) |
113 | { |
114 | return DIV_ROUND_CLOSEST(val, 125) * 32; |
115 | } |
116 | |
117 | static int stts751_adjust_resolution(struct stts751_priv *priv) |
118 | { |
119 | u8 res; |
120 | |
121 | switch (priv->interval) { |
122 | case 9: |
123 | /* 10 bits */ |
124 | res = 0; |
125 | break; |
126 | case 8: |
127 | /* 11 bits */ |
128 | res = 1; |
129 | break; |
130 | default: |
131 | /* 12 bits */ |
132 | res = 3; |
133 | break; |
134 | } |
135 | |
136 | if (priv->res == res) |
137 | return 0; |
138 | |
139 | priv->config &= ~STTS751_CONF_RES_MASK; |
140 | priv->config |= res << STTS751_CONF_RES_SHIFT; |
141 | dev_dbg(&priv->client->dev, "setting res %d. config %x" , |
142 | res, priv->config); |
143 | priv->res = res; |
144 | |
145 | return i2c_smbus_write_byte_data(client: priv->client, |
146 | STTS751_REG_CONF, value: priv->config); |
147 | } |
148 | |
149 | static int stts751_update_temp(struct stts751_priv *priv) |
150 | { |
151 | s32 integer1, integer2, frac; |
152 | |
153 | /* |
154 | * There is a trick here, like in the lm90 driver. We have to read two |
155 | * registers to get the sensor temperature, but we have to beware a |
156 | * conversion could occur between the readings. We could use the |
157 | * one-shot conversion register, but we don't want to do this (disables |
158 | * hardware monitoring). So the solution used here is to read the high |
159 | * byte once, then the low byte, then the high byte again. If the new |
160 | * high byte matches the old one, then we have a valid reading. Else we |
161 | * have to read the low byte again, and now we believe we have a correct |
162 | * reading. |
163 | */ |
164 | integer1 = i2c_smbus_read_byte_data(client: priv->client, STTS751_REG_TEMP_H); |
165 | if (integer1 < 0) { |
166 | dev_dbg(&priv->client->dev, |
167 | "I2C read failed (temp H). ret: %x\n" , integer1); |
168 | return integer1; |
169 | } |
170 | |
171 | frac = i2c_smbus_read_byte_data(client: priv->client, STTS751_REG_TEMP_L); |
172 | if (frac < 0) { |
173 | dev_dbg(&priv->client->dev, |
174 | "I2C read failed (temp L). ret: %x\n" , frac); |
175 | return frac; |
176 | } |
177 | |
178 | integer2 = i2c_smbus_read_byte_data(client: priv->client, STTS751_REG_TEMP_H); |
179 | if (integer2 < 0) { |
180 | dev_dbg(&priv->client->dev, |
181 | "I2C 2nd read failed (temp H). ret: %x\n" , integer2); |
182 | return integer2; |
183 | } |
184 | |
185 | if (integer1 != integer2) { |
186 | frac = i2c_smbus_read_byte_data(client: priv->client, |
187 | STTS751_REG_TEMP_L); |
188 | if (frac < 0) { |
189 | dev_dbg(&priv->client->dev, |
190 | "I2C 2nd read failed (temp L). ret: %x\n" , |
191 | frac); |
192 | return frac; |
193 | } |
194 | } |
195 | |
196 | priv->temp = stts751_to_deg(hw_val: (integer1 << 8) | frac); |
197 | return 0; |
198 | } |
199 | |
200 | static int stts751_set_temp_reg16(struct stts751_priv *priv, int temp, |
201 | u8 hreg, u8 lreg) |
202 | { |
203 | s32 hwval; |
204 | int ret; |
205 | |
206 | hwval = stts751_to_hw(val: temp); |
207 | |
208 | ret = i2c_smbus_write_byte_data(client: priv->client, command: hreg, value: hwval >> 8); |
209 | if (ret) |
210 | return ret; |
211 | |
212 | return i2c_smbus_write_byte_data(client: priv->client, command: lreg, value: hwval & 0xff); |
213 | } |
214 | |
215 | static int stts751_set_temp_reg8(struct stts751_priv *priv, int temp, u8 reg) |
216 | { |
217 | s32 hwval; |
218 | |
219 | hwval = stts751_to_hw(val: temp); |
220 | return i2c_smbus_write_byte_data(client: priv->client, command: reg, value: hwval >> 8); |
221 | } |
222 | |
223 | static int stts751_read_reg16(struct stts751_priv *priv, int *temp, |
224 | u8 hreg, u8 lreg) |
225 | { |
226 | int integer, frac; |
227 | |
228 | integer = i2c_smbus_read_byte_data(client: priv->client, command: hreg); |
229 | if (integer < 0) |
230 | return integer; |
231 | |
232 | frac = i2c_smbus_read_byte_data(client: priv->client, command: lreg); |
233 | if (frac < 0) |
234 | return frac; |
235 | |
236 | *temp = stts751_to_deg(hw_val: (integer << 8) | frac); |
237 | |
238 | return 0; |
239 | } |
240 | |
241 | static int stts751_read_reg8(struct stts751_priv *priv, int *temp, u8 reg) |
242 | { |
243 | int integer; |
244 | |
245 | integer = i2c_smbus_read_byte_data(client: priv->client, command: reg); |
246 | if (integer < 0) |
247 | return integer; |
248 | |
249 | *temp = stts751_to_deg(hw_val: integer << 8); |
250 | |
251 | return 0; |
252 | } |
253 | |
254 | /* |
255 | * Update alert flags without waiting for cache to expire. We detects alerts |
256 | * immediately for the sake of the alert handler; we still need to deal with |
257 | * caching to workaround the fact that alarm flags int the status register, |
258 | * despite what the datasheet claims, gets always cleared on read. |
259 | */ |
260 | static int stts751_update_alert(struct stts751_priv *priv) |
261 | { |
262 | int ret; |
263 | bool conv_done; |
264 | int cache_time = msecs_to_jiffies(m: stts751_intervals[priv->interval]); |
265 | |
266 | /* |
267 | * Add another 10% because if we run faster than the HW conversion |
268 | * rate we will end up in reporting incorrectly alarms. |
269 | */ |
270 | cache_time += cache_time / 10; |
271 | |
272 | ret = i2c_smbus_read_byte_data(client: priv->client, STTS751_REG_STATUS); |
273 | if (ret < 0) |
274 | return ret; |
275 | |
276 | dev_dbg(&priv->client->dev, "status reg %x\n" , ret); |
277 | conv_done = ret & (STTS751_STATUS_TRIPH | STTS751_STATUS_TRIPL); |
278 | /* |
279 | * Reset the cache if the cache time expired, or if we are sure |
280 | * we have valid data from a device conversion, or if we know |
281 | * our cache has been never written. |
282 | * |
283 | * Note that when the cache has been never written the point is |
284 | * to correctly initialize the timestamp, rather than clearing |
285 | * the cache values. |
286 | * |
287 | * Note that updating the cache timestamp when we get an alarm flag |
288 | * is required, otherwise we could incorrectly report alarms to be zero. |
289 | */ |
290 | if (time_after(jiffies, priv->last_alert_update + cache_time) || |
291 | conv_done || !priv->alert_valid) { |
292 | priv->max_alert = false; |
293 | priv->min_alert = false; |
294 | priv->alert_valid = true; |
295 | priv->last_alert_update = jiffies; |
296 | dev_dbg(&priv->client->dev, "invalidating alert cache\n" ); |
297 | } |
298 | |
299 | priv->max_alert |= !!(ret & STTS751_STATUS_TRIPH); |
300 | priv->min_alert |= !!(ret & STTS751_STATUS_TRIPL); |
301 | priv->therm_trip = !!(ret & STTS751_STATUS_TRIPT); |
302 | |
303 | dev_dbg(&priv->client->dev, "max_alert: %d, min_alert: %d, therm_trip: %d\n" , |
304 | priv->max_alert, priv->min_alert, priv->therm_trip); |
305 | |
306 | return 0; |
307 | } |
308 | |
309 | static void stts751_alert(struct i2c_client *client, |
310 | enum i2c_alert_protocol type, unsigned int data) |
311 | { |
312 | int ret; |
313 | struct stts751_priv *priv = i2c_get_clientdata(client); |
314 | |
315 | if (type != I2C_PROTOCOL_SMBUS_ALERT) |
316 | return; |
317 | |
318 | dev_dbg(&client->dev, "alert!" ); |
319 | |
320 | mutex_lock(&priv->access_lock); |
321 | ret = stts751_update_alert(priv); |
322 | if (ret < 0) { |
323 | /* default to worst case */ |
324 | priv->max_alert = true; |
325 | priv->min_alert = true; |
326 | |
327 | dev_warn(priv->dev, |
328 | "Alert received, but can't communicate to the device. Triggering all alarms!" ); |
329 | } |
330 | |
331 | if (priv->max_alert) { |
332 | if (priv->notify_max) |
333 | dev_notice(priv->dev, "got alert for HIGH temperature" ); |
334 | priv->notify_max = false; |
335 | |
336 | /* unblock alert poll */ |
337 | sysfs_notify(kobj: &priv->dev->kobj, NULL, attr: "temp1_max_alarm" ); |
338 | } |
339 | |
340 | if (priv->min_alert) { |
341 | if (priv->notify_min) |
342 | dev_notice(priv->dev, "got alert for LOW temperature" ); |
343 | priv->notify_min = false; |
344 | |
345 | /* unblock alert poll */ |
346 | sysfs_notify(kobj: &priv->dev->kobj, NULL, attr: "temp1_min_alarm" ); |
347 | } |
348 | |
349 | if (priv->min_alert || priv->max_alert) |
350 | kobject_uevent(kobj: &priv->dev->kobj, action: KOBJ_CHANGE); |
351 | |
352 | mutex_unlock(lock: &priv->access_lock); |
353 | } |
354 | |
355 | static int stts751_update(struct stts751_priv *priv) |
356 | { |
357 | int ret; |
358 | int cache_time = msecs_to_jiffies(m: stts751_intervals[priv->interval]); |
359 | |
360 | if (time_after(jiffies, priv->last_update + cache_time) || |
361 | !priv->data_valid) { |
362 | ret = stts751_update_temp(priv); |
363 | if (ret) |
364 | return ret; |
365 | |
366 | ret = stts751_update_alert(priv); |
367 | if (ret) |
368 | return ret; |
369 | priv->data_valid = true; |
370 | priv->last_update = jiffies; |
371 | } |
372 | |
373 | return 0; |
374 | } |
375 | |
376 | static ssize_t max_alarm_show(struct device *dev, |
377 | struct device_attribute *attr, char *buf) |
378 | { |
379 | int ret; |
380 | struct stts751_priv *priv = dev_get_drvdata(dev); |
381 | |
382 | mutex_lock(&priv->access_lock); |
383 | ret = stts751_update(priv); |
384 | if (!ret) |
385 | priv->notify_max = true; |
386 | mutex_unlock(lock: &priv->access_lock); |
387 | if (ret < 0) |
388 | return ret; |
389 | |
390 | return sysfs_emit(buf, fmt: "%d\n" , priv->max_alert); |
391 | } |
392 | |
393 | static ssize_t min_alarm_show(struct device *dev, |
394 | struct device_attribute *attr, char *buf) |
395 | { |
396 | int ret; |
397 | struct stts751_priv *priv = dev_get_drvdata(dev); |
398 | |
399 | mutex_lock(&priv->access_lock); |
400 | ret = stts751_update(priv); |
401 | if (!ret) |
402 | priv->notify_min = true; |
403 | mutex_unlock(lock: &priv->access_lock); |
404 | if (ret < 0) |
405 | return ret; |
406 | |
407 | return sysfs_emit(buf, fmt: "%d\n" , priv->min_alert); |
408 | } |
409 | |
410 | static ssize_t input_show(struct device *dev, struct device_attribute *attr, |
411 | char *buf) |
412 | { |
413 | int ret; |
414 | struct stts751_priv *priv = dev_get_drvdata(dev); |
415 | |
416 | mutex_lock(&priv->access_lock); |
417 | ret = stts751_update(priv); |
418 | mutex_unlock(lock: &priv->access_lock); |
419 | if (ret < 0) |
420 | return ret; |
421 | |
422 | return sysfs_emit(buf, fmt: "%d\n" , priv->temp); |
423 | } |
424 | |
425 | static ssize_t therm_show(struct device *dev, struct device_attribute *attr, |
426 | char *buf) |
427 | { |
428 | struct stts751_priv *priv = dev_get_drvdata(dev); |
429 | |
430 | return sysfs_emit(buf, fmt: "%d\n" , priv->therm); |
431 | } |
432 | |
433 | static ssize_t therm_store(struct device *dev, struct device_attribute *attr, |
434 | const char *buf, size_t count) |
435 | { |
436 | int ret; |
437 | long temp; |
438 | struct stts751_priv *priv = dev_get_drvdata(dev); |
439 | |
440 | if (kstrtol(s: buf, base: 10, res: &temp) < 0) |
441 | return -EINVAL; |
442 | |
443 | /* HW works in range -64C to +127.937C */ |
444 | temp = clamp_val(temp, -64000, 127937); |
445 | mutex_lock(&priv->access_lock); |
446 | ret = stts751_set_temp_reg8(priv, temp, STTS751_REG_TLIM); |
447 | if (ret) |
448 | goto exit; |
449 | |
450 | dev_dbg(&priv->client->dev, "setting therm %ld" , temp); |
451 | |
452 | /* |
453 | * hysteresis reg is relative to therm, so the HW does not need to be |
454 | * adjusted, we need to update our local copy only. |
455 | */ |
456 | priv->hyst = temp - (priv->therm - priv->hyst); |
457 | priv->therm = temp; |
458 | |
459 | exit: |
460 | mutex_unlock(lock: &priv->access_lock); |
461 | if (ret) |
462 | return ret; |
463 | |
464 | return count; |
465 | } |
466 | |
467 | static ssize_t hyst_show(struct device *dev, struct device_attribute *attr, |
468 | char *buf) |
469 | { |
470 | struct stts751_priv *priv = dev_get_drvdata(dev); |
471 | |
472 | return sysfs_emit(buf, fmt: "%d\n" , priv->hyst); |
473 | } |
474 | |
475 | static ssize_t hyst_store(struct device *dev, struct device_attribute *attr, |
476 | const char *buf, size_t count) |
477 | { |
478 | int ret; |
479 | long temp; |
480 | |
481 | struct stts751_priv *priv = dev_get_drvdata(dev); |
482 | |
483 | if (kstrtol(s: buf, base: 10, res: &temp) < 0) |
484 | return -EINVAL; |
485 | |
486 | mutex_lock(&priv->access_lock); |
487 | /* HW works in range -64C to +127.937C */ |
488 | temp = clamp_val(temp, -64000, priv->therm); |
489 | priv->hyst = temp; |
490 | dev_dbg(&priv->client->dev, "setting hyst %ld" , temp); |
491 | temp = priv->therm - temp; |
492 | ret = stts751_set_temp_reg8(priv, temp, STTS751_REG_HYST); |
493 | mutex_unlock(lock: &priv->access_lock); |
494 | if (ret) |
495 | return ret; |
496 | |
497 | return count; |
498 | } |
499 | |
500 | static ssize_t therm_trip_show(struct device *dev, |
501 | struct device_attribute *attr, char *buf) |
502 | { |
503 | int ret; |
504 | struct stts751_priv *priv = dev_get_drvdata(dev); |
505 | |
506 | mutex_lock(&priv->access_lock); |
507 | ret = stts751_update(priv); |
508 | mutex_unlock(lock: &priv->access_lock); |
509 | if (ret < 0) |
510 | return ret; |
511 | |
512 | return sysfs_emit(buf, fmt: "%d\n" , priv->therm_trip); |
513 | } |
514 | |
515 | static ssize_t max_show(struct device *dev, struct device_attribute *attr, |
516 | char *buf) |
517 | { |
518 | struct stts751_priv *priv = dev_get_drvdata(dev); |
519 | |
520 | return sysfs_emit(buf, fmt: "%d\n" , priv->event_max); |
521 | } |
522 | |
523 | static ssize_t max_store(struct device *dev, struct device_attribute *attr, |
524 | const char *buf, size_t count) |
525 | { |
526 | int ret; |
527 | long temp; |
528 | struct stts751_priv *priv = dev_get_drvdata(dev); |
529 | |
530 | if (kstrtol(s: buf, base: 10, res: &temp) < 0) |
531 | return -EINVAL; |
532 | |
533 | mutex_lock(&priv->access_lock); |
534 | /* HW works in range -64C to +127.937C */ |
535 | temp = clamp_val(temp, priv->event_min, 127937); |
536 | ret = stts751_set_temp_reg16(priv, temp, |
537 | STTS751_REG_HLIM_H, STTS751_REG_HLIM_L); |
538 | if (ret) |
539 | goto exit; |
540 | |
541 | dev_dbg(&priv->client->dev, "setting event max %ld" , temp); |
542 | priv->event_max = temp; |
543 | ret = count; |
544 | exit: |
545 | mutex_unlock(lock: &priv->access_lock); |
546 | return ret; |
547 | } |
548 | |
549 | static ssize_t min_show(struct device *dev, struct device_attribute *attr, |
550 | char *buf) |
551 | { |
552 | struct stts751_priv *priv = dev_get_drvdata(dev); |
553 | |
554 | return sysfs_emit(buf, fmt: "%d\n" , priv->event_min); |
555 | } |
556 | |
557 | static ssize_t min_store(struct device *dev, struct device_attribute *attr, |
558 | const char *buf, size_t count) |
559 | { |
560 | int ret; |
561 | long temp; |
562 | struct stts751_priv *priv = dev_get_drvdata(dev); |
563 | |
564 | if (kstrtol(s: buf, base: 10, res: &temp) < 0) |
565 | return -EINVAL; |
566 | |
567 | mutex_lock(&priv->access_lock); |
568 | /* HW works in range -64C to +127.937C */ |
569 | temp = clamp_val(temp, -64000, priv->event_max); |
570 | ret = stts751_set_temp_reg16(priv, temp, |
571 | STTS751_REG_LLIM_H, STTS751_REG_LLIM_L); |
572 | if (ret) |
573 | goto exit; |
574 | |
575 | dev_dbg(&priv->client->dev, "setting event min %ld" , temp); |
576 | priv->event_min = temp; |
577 | ret = count; |
578 | exit: |
579 | mutex_unlock(lock: &priv->access_lock); |
580 | return ret; |
581 | } |
582 | |
583 | static ssize_t interval_show(struct device *dev, |
584 | struct device_attribute *attr, char *buf) |
585 | { |
586 | struct stts751_priv *priv = dev_get_drvdata(dev); |
587 | |
588 | return sysfs_emit(buf, fmt: "%d\n" , |
589 | stts751_intervals[priv->interval]); |
590 | } |
591 | |
592 | static ssize_t interval_store(struct device *dev, |
593 | struct device_attribute *attr, const char *buf, |
594 | size_t count) |
595 | { |
596 | unsigned long val; |
597 | int idx; |
598 | int ret = count; |
599 | struct stts751_priv *priv = dev_get_drvdata(dev); |
600 | |
601 | if (kstrtoul(s: buf, base: 10, res: &val) < 0) |
602 | return -EINVAL; |
603 | |
604 | idx = find_closest_descending(val, stts751_intervals, |
605 | ARRAY_SIZE(stts751_intervals)); |
606 | |
607 | dev_dbg(&priv->client->dev, "setting interval. req:%lu, idx: %d, val: %d" , |
608 | val, idx, stts751_intervals[idx]); |
609 | |
610 | mutex_lock(&priv->access_lock); |
611 | if (priv->interval == idx) |
612 | goto exit; |
613 | |
614 | /* |
615 | * In early development stages I've become suspicious about the chip |
616 | * starting to misbehave if I ever set, even briefly, an invalid |
617 | * configuration. While I'm not sure this is really needed, be |
618 | * conservative and set rate/resolution in such an order that avoids |
619 | * passing through an invalid configuration. |
620 | */ |
621 | |
622 | /* speed up: lower the resolution, then modify convrate */ |
623 | if (priv->interval < idx) { |
624 | dev_dbg(&priv->client->dev, "lower resolution, then modify convrate" ); |
625 | priv->interval = idx; |
626 | ret = stts751_adjust_resolution(priv); |
627 | if (ret) |
628 | goto exit; |
629 | } |
630 | |
631 | ret = i2c_smbus_write_byte_data(client: priv->client, STTS751_REG_RATE, value: idx); |
632 | if (ret) |
633 | goto exit; |
634 | /* slow down: modify convrate, then raise resolution */ |
635 | if (priv->interval != idx) { |
636 | dev_dbg(&priv->client->dev, "modify convrate, then raise resolution" ); |
637 | priv->interval = idx; |
638 | ret = stts751_adjust_resolution(priv); |
639 | if (ret) |
640 | goto exit; |
641 | } |
642 | ret = count; |
643 | exit: |
644 | mutex_unlock(lock: &priv->access_lock); |
645 | |
646 | return ret; |
647 | } |
648 | |
649 | static int stts751_detect(struct i2c_client *new_client, |
650 | struct i2c_board_info *info) |
651 | { |
652 | struct i2c_adapter *adapter = new_client->adapter; |
653 | const char *name; |
654 | int tmp; |
655 | |
656 | if (!i2c_check_functionality(adap: adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
657 | return -ENODEV; |
658 | |
659 | tmp = i2c_smbus_read_byte_data(client: new_client, STTS751_REG_MAN_ID); |
660 | if (tmp != ST_MAN_ID) |
661 | return -ENODEV; |
662 | |
663 | /* lower temperaure registers always have bits 0-3 set to zero */ |
664 | tmp = i2c_smbus_read_byte_data(client: new_client, STTS751_REG_TEMP_L); |
665 | if (tmp & 0xf) |
666 | return -ENODEV; |
667 | |
668 | tmp = i2c_smbus_read_byte_data(client: new_client, STTS751_REG_HLIM_L); |
669 | if (tmp & 0xf) |
670 | return -ENODEV; |
671 | |
672 | tmp = i2c_smbus_read_byte_data(client: new_client, STTS751_REG_LLIM_L); |
673 | if (tmp & 0xf) |
674 | return -ENODEV; |
675 | |
676 | /* smbus timeout register always have bits 0-7 set to zero */ |
677 | tmp = i2c_smbus_read_byte_data(client: new_client, STTS751_REG_SMBUS_TO); |
678 | if (tmp & 0x7f) |
679 | return -ENODEV; |
680 | |
681 | tmp = i2c_smbus_read_byte_data(client: new_client, STTS751_REG_PROD_ID); |
682 | |
683 | switch (tmp) { |
684 | case STTS751_0_PROD_ID: |
685 | name = "STTS751-0" ; |
686 | break; |
687 | case STTS751_1_PROD_ID: |
688 | name = "STTS751-1" ; |
689 | break; |
690 | default: |
691 | return -ENODEV; |
692 | } |
693 | dev_dbg(&new_client->dev, "Chip %s detected" , name); |
694 | |
695 | strscpy(info->type, stts751_id[0].name, I2C_NAME_SIZE); |
696 | return 0; |
697 | } |
698 | |
699 | static int stts751_read_chip_config(struct stts751_priv *priv) |
700 | { |
701 | int ret; |
702 | int tmp; |
703 | |
704 | ret = i2c_smbus_read_byte_data(client: priv->client, STTS751_REG_CONF); |
705 | if (ret < 0) |
706 | return ret; |
707 | priv->config = ret; |
708 | priv->res = (ret & STTS751_CONF_RES_MASK) >> STTS751_CONF_RES_SHIFT; |
709 | |
710 | ret = i2c_smbus_read_byte_data(client: priv->client, STTS751_REG_RATE); |
711 | if (ret < 0) |
712 | return ret; |
713 | if (ret >= ARRAY_SIZE(stts751_intervals)) { |
714 | dev_err(priv->dev, "Unrecognized conversion rate 0x%x\n" , ret); |
715 | return -ENODEV; |
716 | } |
717 | priv->interval = ret; |
718 | |
719 | ret = stts751_read_reg16(priv, temp: &priv->event_max, |
720 | STTS751_REG_HLIM_H, STTS751_REG_HLIM_L); |
721 | if (ret) |
722 | return ret; |
723 | |
724 | ret = stts751_read_reg16(priv, temp: &priv->event_min, |
725 | STTS751_REG_LLIM_H, STTS751_REG_LLIM_L); |
726 | if (ret) |
727 | return ret; |
728 | |
729 | ret = stts751_read_reg8(priv, temp: &priv->therm, STTS751_REG_TLIM); |
730 | if (ret) |
731 | return ret; |
732 | |
733 | ret = stts751_read_reg8(priv, temp: &tmp, STTS751_REG_HYST); |
734 | if (ret) |
735 | return ret; |
736 | priv->hyst = priv->therm - tmp; |
737 | |
738 | return 0; |
739 | } |
740 | |
741 | static SENSOR_DEVICE_ATTR_RO(temp1_input, input, 0); |
742 | static SENSOR_DEVICE_ATTR_RW(temp1_min, min, 0); |
743 | static SENSOR_DEVICE_ATTR_RW(temp1_max, max, 0); |
744 | static SENSOR_DEVICE_ATTR_RO(temp1_min_alarm, min_alarm, 0); |
745 | static SENSOR_DEVICE_ATTR_RO(temp1_max_alarm, max_alarm, 0); |
746 | static SENSOR_DEVICE_ATTR_RW(temp1_crit, therm, 0); |
747 | static SENSOR_DEVICE_ATTR_RW(temp1_crit_hyst, hyst, 0); |
748 | static SENSOR_DEVICE_ATTR_RO(temp1_crit_alarm, therm_trip, 0); |
749 | static SENSOR_DEVICE_ATTR_RW(update_interval, interval, 0); |
750 | |
751 | static struct attribute *stts751_attrs[] = { |
752 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
753 | &sensor_dev_attr_temp1_min.dev_attr.attr, |
754 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
755 | &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, |
756 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, |
757 | &sensor_dev_attr_temp1_crit.dev_attr.attr, |
758 | &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, |
759 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, |
760 | &sensor_dev_attr_update_interval.dev_attr.attr, |
761 | NULL |
762 | }; |
763 | ATTRIBUTE_GROUPS(stts751); |
764 | |
765 | static int stts751_probe(struct i2c_client *client) |
766 | { |
767 | struct stts751_priv *priv; |
768 | int ret; |
769 | bool smbus_nto; |
770 | int rev_id; |
771 | |
772 | priv = devm_kzalloc(dev: &client->dev, size: sizeof(*priv), GFP_KERNEL); |
773 | if (!priv) |
774 | return -ENOMEM; |
775 | |
776 | priv->client = client; |
777 | priv->notify_max = true; |
778 | priv->notify_min = true; |
779 | i2c_set_clientdata(client, data: priv); |
780 | mutex_init(&priv->access_lock); |
781 | |
782 | if (device_property_present(dev: &client->dev, |
783 | propname: "smbus-timeout-disable" )) { |
784 | smbus_nto = device_property_read_bool(dev: &client->dev, |
785 | propname: "smbus-timeout-disable" ); |
786 | |
787 | ret = i2c_smbus_write_byte_data(client, STTS751_REG_SMBUS_TO, |
788 | value: smbus_nto ? 0 : 0x80); |
789 | if (ret) |
790 | return ret; |
791 | } |
792 | |
793 | rev_id = i2c_smbus_read_byte_data(client, STTS751_REG_REV_ID); |
794 | if (rev_id < 0) |
795 | return -ENODEV; |
796 | if (rev_id != 0x1) { |
797 | dev_dbg(&client->dev, "Chip revision 0x%x is untested\n" , |
798 | rev_id); |
799 | } |
800 | |
801 | ret = stts751_read_chip_config(priv); |
802 | if (ret) |
803 | return ret; |
804 | |
805 | priv->config &= ~(STTS751_CONF_STOP | STTS751_CONF_EVENT_DIS); |
806 | ret = i2c_smbus_write_byte_data(client, STTS751_REG_CONF, value: priv->config); |
807 | if (ret) |
808 | return ret; |
809 | |
810 | priv->dev = devm_hwmon_device_register_with_groups(dev: &client->dev, |
811 | name: client->name, drvdata: priv, |
812 | groups: stts751_groups); |
813 | return PTR_ERR_OR_ZERO(ptr: priv->dev); |
814 | } |
815 | |
816 | MODULE_DEVICE_TABLE(i2c, stts751_id); |
817 | |
818 | static struct i2c_driver stts751_driver = { |
819 | .class = I2C_CLASS_HWMON, |
820 | .driver = { |
821 | .name = DEVNAME, |
822 | .of_match_table = of_match_ptr(stts751_of_match), |
823 | }, |
824 | .probe = stts751_probe, |
825 | .id_table = stts751_id, |
826 | .detect = stts751_detect, |
827 | .alert = stts751_alert, |
828 | .address_list = normal_i2c, |
829 | }; |
830 | |
831 | module_i2c_driver(stts751_driver); |
832 | |
833 | MODULE_AUTHOR("Andrea Merello <andrea.merello@gmail.com>" ); |
834 | MODULE_DESCRIPTION("STTS751 sensor driver" ); |
835 | MODULE_LICENSE("GPL" ); |
836 | |