1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 27f07ec0fSandrea.merello /* 37f07ec0fSandrea.merello * STTS751 sensor driver 47f07ec0fSandrea.merello * 57f07ec0fSandrea.merello * Copyright (C) 2016-2017 Istituto Italiano di Tecnologia - RBCS - EDL 67f07ec0fSandrea.merello * Robotics, Brain and Cognitive Sciences department 77f07ec0fSandrea.merello * Electronic Design Laboratory 87f07ec0fSandrea.merello * 97f07ec0fSandrea.merello * Written by Andrea Merello <andrea.merello@gmail.com> 107f07ec0fSandrea.merello * 117f07ec0fSandrea.merello * Based on LM95241 driver and LM90 driver 127f07ec0fSandrea.merello */ 137f07ec0fSandrea.merello 147f07ec0fSandrea.merello #include <linux/bitops.h> 157f07ec0fSandrea.merello #include <linux/err.h> 167f07ec0fSandrea.merello #include <linux/hwmon.h> 177f07ec0fSandrea.merello #include <linux/hwmon-sysfs.h> 187f07ec0fSandrea.merello #include <linux/i2c.h> 197f07ec0fSandrea.merello #include <linux/init.h> 207f07ec0fSandrea.merello #include <linux/interrupt.h> 217f07ec0fSandrea.merello #include <linux/jiffies.h> 227f07ec0fSandrea.merello #include <linux/module.h> 237f07ec0fSandrea.merello #include <linux/mutex.h> 247f07ec0fSandrea.merello #include <linux/property.h> 257f07ec0fSandrea.merello #include <linux/slab.h> 267f07ec0fSandrea.merello #include <linux/sysfs.h> 277f07ec0fSandrea.merello #include <linux/util_macros.h> 287f07ec0fSandrea.merello 297f07ec0fSandrea.merello #define DEVNAME "stts751" 307f07ec0fSandrea.merello 317f07ec0fSandrea.merello static const unsigned short normal_i2c[] = { 327f07ec0fSandrea.merello 0x48, 0x49, 0x38, 0x39, /* STTS751-0 */ 337f07ec0fSandrea.merello 0x4A, 0x4B, 0x3A, 0x3B, /* STTS751-1 */ 347f07ec0fSandrea.merello I2C_CLIENT_END }; 357f07ec0fSandrea.merello 367f07ec0fSandrea.merello #define STTS751_REG_TEMP_H 0x00 377f07ec0fSandrea.merello #define STTS751_REG_STATUS 0x01 387f07ec0fSandrea.merello #define STTS751_STATUS_TRIPT BIT(0) 397f07ec0fSandrea.merello #define STTS751_STATUS_TRIPL BIT(5) 407f07ec0fSandrea.merello #define STTS751_STATUS_TRIPH BIT(6) 417f07ec0fSandrea.merello #define STTS751_REG_TEMP_L 0x02 427f07ec0fSandrea.merello #define STTS751_REG_CONF 0x03 437f07ec0fSandrea.merello #define STTS751_CONF_RES_MASK 0x0C 447f07ec0fSandrea.merello #define STTS751_CONF_RES_SHIFT 2 457f07ec0fSandrea.merello #define STTS751_CONF_EVENT_DIS BIT(7) 467f07ec0fSandrea.merello #define STTS751_CONF_STOP BIT(6) 477f07ec0fSandrea.merello #define STTS751_REG_RATE 0x04 487f07ec0fSandrea.merello #define STTS751_REG_HLIM_H 0x05 497f07ec0fSandrea.merello #define STTS751_REG_HLIM_L 0x06 507f07ec0fSandrea.merello #define STTS751_REG_LLIM_H 0x07 517f07ec0fSandrea.merello #define STTS751_REG_LLIM_L 0x08 527f07ec0fSandrea.merello #define STTS751_REG_TLIM 0x20 537f07ec0fSandrea.merello #define STTS751_REG_HYST 0x21 547f07ec0fSandrea.merello #define STTS751_REG_SMBUS_TO 0x22 557f07ec0fSandrea.merello 567f07ec0fSandrea.merello #define STTS751_REG_PROD_ID 0xFD 577f07ec0fSandrea.merello #define STTS751_REG_MAN_ID 0xFE 587f07ec0fSandrea.merello #define STTS751_REG_REV_ID 0xFF 597f07ec0fSandrea.merello 607f07ec0fSandrea.merello #define STTS751_0_PROD_ID 0x00 617f07ec0fSandrea.merello #define STTS751_1_PROD_ID 0x01 627f07ec0fSandrea.merello #define ST_MAN_ID 0x53 637f07ec0fSandrea.merello 647f07ec0fSandrea.merello /* 657f07ec0fSandrea.merello * Possible update intervals are (in mS): 667f07ec0fSandrea.merello * 16000, 8000, 4000, 2000, 1000, 500, 250, 125, 62.5, 31.25 677f07ec0fSandrea.merello * However we are not going to complicate things too much and we stick to the 687f07ec0fSandrea.merello * approx value in mS. 697f07ec0fSandrea.merello */ 707f07ec0fSandrea.merello static const int stts751_intervals[] = { 717f07ec0fSandrea.merello 16000, 8000, 4000, 2000, 1000, 500, 250, 125, 63, 31 727f07ec0fSandrea.merello }; 737f07ec0fSandrea.merello 747f07ec0fSandrea.merello static const struct i2c_device_id stts751_id[] = { 757f07ec0fSandrea.merello { "stts751", 0 }, 767f07ec0fSandrea.merello { } 777f07ec0fSandrea.merello }; 787f07ec0fSandrea.merello 791cbee124SGuenter Roeck static const struct of_device_id __maybe_unused stts751_of_match[] = { 801c1a7b75SJavier Martinez Canillas { .compatible = "stts751" }, 811c1a7b75SJavier Martinez Canillas { }, 821c1a7b75SJavier Martinez Canillas }; 831c1a7b75SJavier Martinez Canillas MODULE_DEVICE_TABLE(of, stts751_of_match); 841c1a7b75SJavier Martinez Canillas 857f07ec0fSandrea.merello struct stts751_priv { 867f07ec0fSandrea.merello struct device *dev; 877f07ec0fSandrea.merello struct i2c_client *client; 887f07ec0fSandrea.merello struct mutex access_lock; 897f07ec0fSandrea.merello u8 interval; 907f07ec0fSandrea.merello int res; 917f07ec0fSandrea.merello int event_max, event_min; 927f07ec0fSandrea.merello int therm; 937f07ec0fSandrea.merello int hyst; 947f07ec0fSandrea.merello bool smbus_timeout; 957f07ec0fSandrea.merello int temp; 967f07ec0fSandrea.merello unsigned long last_update, last_alert_update; 977f07ec0fSandrea.merello u8 config; 987f07ec0fSandrea.merello bool min_alert, max_alert, therm_trip; 997f07ec0fSandrea.merello bool data_valid, alert_valid; 1007f07ec0fSandrea.merello bool notify_max, notify_min; 1017f07ec0fSandrea.merello }; 1027f07ec0fSandrea.merello 1037f07ec0fSandrea.merello /* 1047f07ec0fSandrea.merello * These functions converts temperature from HW format to integer format and 1057f07ec0fSandrea.merello * vice-vers. They are (mostly) taken from lm90 driver. Unit is in mC. 1067f07ec0fSandrea.merello */ 1077f07ec0fSandrea.merello static int stts751_to_deg(s16 hw_val) 1087f07ec0fSandrea.merello { 1097f07ec0fSandrea.merello return hw_val * 125 / 32; 1107f07ec0fSandrea.merello } 1117f07ec0fSandrea.merello 1127f07ec0fSandrea.merello static s32 stts751_to_hw(int val) 1137f07ec0fSandrea.merello { 1147f07ec0fSandrea.merello return DIV_ROUND_CLOSEST(val, 125) * 32; 1157f07ec0fSandrea.merello } 1167f07ec0fSandrea.merello 1177f07ec0fSandrea.merello static int stts751_adjust_resolution(struct stts751_priv *priv) 1187f07ec0fSandrea.merello { 1197f07ec0fSandrea.merello u8 res; 1207f07ec0fSandrea.merello 1217f07ec0fSandrea.merello switch (priv->interval) { 1227f07ec0fSandrea.merello case 9: 1237f07ec0fSandrea.merello /* 10 bits */ 1247f07ec0fSandrea.merello res = 0; 1257f07ec0fSandrea.merello break; 1267f07ec0fSandrea.merello case 8: 1277f07ec0fSandrea.merello /* 11 bits */ 1287f07ec0fSandrea.merello res = 1; 1297f07ec0fSandrea.merello break; 1307f07ec0fSandrea.merello default: 1317f07ec0fSandrea.merello /* 12 bits */ 1327f07ec0fSandrea.merello res = 3; 1337f07ec0fSandrea.merello break; 1347f07ec0fSandrea.merello } 1357f07ec0fSandrea.merello 1367f07ec0fSandrea.merello if (priv->res == res) 1377f07ec0fSandrea.merello return 0; 1387f07ec0fSandrea.merello 1397f07ec0fSandrea.merello priv->config &= ~STTS751_CONF_RES_MASK; 1407f07ec0fSandrea.merello priv->config |= res << STTS751_CONF_RES_SHIFT; 1417f07ec0fSandrea.merello dev_dbg(&priv->client->dev, "setting res %d. config %x", 1427f07ec0fSandrea.merello res, priv->config); 1437f07ec0fSandrea.merello priv->res = res; 1447f07ec0fSandrea.merello 1457f07ec0fSandrea.merello return i2c_smbus_write_byte_data(priv->client, 1467f07ec0fSandrea.merello STTS751_REG_CONF, priv->config); 1477f07ec0fSandrea.merello } 1487f07ec0fSandrea.merello 1497f07ec0fSandrea.merello static int stts751_update_temp(struct stts751_priv *priv) 1507f07ec0fSandrea.merello { 1517f07ec0fSandrea.merello s32 integer1, integer2, frac; 1527f07ec0fSandrea.merello 1537f07ec0fSandrea.merello /* 1547f07ec0fSandrea.merello * There is a trick here, like in the lm90 driver. We have to read two 1557f07ec0fSandrea.merello * registers to get the sensor temperature, but we have to beware a 1567f07ec0fSandrea.merello * conversion could occur between the readings. We could use the 1577f07ec0fSandrea.merello * one-shot conversion register, but we don't want to do this (disables 1587f07ec0fSandrea.merello * hardware monitoring). So the solution used here is to read the high 1597f07ec0fSandrea.merello * byte once, then the low byte, then the high byte again. If the new 1607f07ec0fSandrea.merello * high byte matches the old one, then we have a valid reading. Else we 1617f07ec0fSandrea.merello * have to read the low byte again, and now we believe we have a correct 1627f07ec0fSandrea.merello * reading. 1637f07ec0fSandrea.merello */ 1647f07ec0fSandrea.merello integer1 = i2c_smbus_read_byte_data(priv->client, STTS751_REG_TEMP_H); 1657f07ec0fSandrea.merello if (integer1 < 0) { 1667f07ec0fSandrea.merello dev_dbg(&priv->client->dev, 1677f07ec0fSandrea.merello "I2C read failed (temp H). ret: %x\n", integer1); 1687f07ec0fSandrea.merello return integer1; 1697f07ec0fSandrea.merello } 1707f07ec0fSandrea.merello 1717f07ec0fSandrea.merello frac = i2c_smbus_read_byte_data(priv->client, STTS751_REG_TEMP_L); 1727f07ec0fSandrea.merello if (frac < 0) { 1737f07ec0fSandrea.merello dev_dbg(&priv->client->dev, 1747f07ec0fSandrea.merello "I2C read failed (temp L). ret: %x\n", frac); 1757f07ec0fSandrea.merello return frac; 1767f07ec0fSandrea.merello } 1777f07ec0fSandrea.merello 1787f07ec0fSandrea.merello integer2 = i2c_smbus_read_byte_data(priv->client, STTS751_REG_TEMP_H); 1797f07ec0fSandrea.merello if (integer2 < 0) { 1807f07ec0fSandrea.merello dev_dbg(&priv->client->dev, 1817f07ec0fSandrea.merello "I2C 2nd read failed (temp H). ret: %x\n", integer2); 1827f07ec0fSandrea.merello return integer2; 1837f07ec0fSandrea.merello } 1847f07ec0fSandrea.merello 1857f07ec0fSandrea.merello if (integer1 != integer2) { 1867f07ec0fSandrea.merello frac = i2c_smbus_read_byte_data(priv->client, 1877f07ec0fSandrea.merello STTS751_REG_TEMP_L); 1887f07ec0fSandrea.merello if (frac < 0) { 1897f07ec0fSandrea.merello dev_dbg(&priv->client->dev, 1907f07ec0fSandrea.merello "I2C 2nd read failed (temp L). ret: %x\n", 1917f07ec0fSandrea.merello frac); 1927f07ec0fSandrea.merello return frac; 1937f07ec0fSandrea.merello } 1947f07ec0fSandrea.merello } 1957f07ec0fSandrea.merello 1967f07ec0fSandrea.merello priv->temp = stts751_to_deg((integer1 << 8) | frac); 1977f07ec0fSandrea.merello return 0; 1987f07ec0fSandrea.merello } 1997f07ec0fSandrea.merello 2007f07ec0fSandrea.merello static int stts751_set_temp_reg16(struct stts751_priv *priv, int temp, 2017f07ec0fSandrea.merello u8 hreg, u8 lreg) 2027f07ec0fSandrea.merello { 2037f07ec0fSandrea.merello s32 hwval; 2047f07ec0fSandrea.merello int ret; 2057f07ec0fSandrea.merello 2067f07ec0fSandrea.merello hwval = stts751_to_hw(temp); 2077f07ec0fSandrea.merello 2087f07ec0fSandrea.merello ret = i2c_smbus_write_byte_data(priv->client, hreg, hwval >> 8); 2097f07ec0fSandrea.merello if (ret) 2107f07ec0fSandrea.merello return ret; 2117f07ec0fSandrea.merello 2127f07ec0fSandrea.merello return i2c_smbus_write_byte_data(priv->client, lreg, hwval & 0xff); 2137f07ec0fSandrea.merello } 2147f07ec0fSandrea.merello 2157f07ec0fSandrea.merello static int stts751_set_temp_reg8(struct stts751_priv *priv, int temp, u8 reg) 2167f07ec0fSandrea.merello { 2177f07ec0fSandrea.merello s32 hwval; 2187f07ec0fSandrea.merello 2197f07ec0fSandrea.merello hwval = stts751_to_hw(temp); 2207f07ec0fSandrea.merello return i2c_smbus_write_byte_data(priv->client, reg, hwval >> 8); 2217f07ec0fSandrea.merello } 2227f07ec0fSandrea.merello 2237f07ec0fSandrea.merello static int stts751_read_reg16(struct stts751_priv *priv, int *temp, 2247f07ec0fSandrea.merello u8 hreg, u8 lreg) 2257f07ec0fSandrea.merello { 2267f07ec0fSandrea.merello int integer, frac; 2277f07ec0fSandrea.merello 2287f07ec0fSandrea.merello integer = i2c_smbus_read_byte_data(priv->client, hreg); 2297f07ec0fSandrea.merello if (integer < 0) 2307f07ec0fSandrea.merello return integer; 2317f07ec0fSandrea.merello 2327f07ec0fSandrea.merello frac = i2c_smbus_read_byte_data(priv->client, lreg); 2337f07ec0fSandrea.merello if (frac < 0) 2347f07ec0fSandrea.merello return frac; 2357f07ec0fSandrea.merello 2367f07ec0fSandrea.merello *temp = stts751_to_deg((integer << 8) | frac); 2377f07ec0fSandrea.merello 2387f07ec0fSandrea.merello return 0; 2397f07ec0fSandrea.merello } 2407f07ec0fSandrea.merello 2417f07ec0fSandrea.merello static int stts751_read_reg8(struct stts751_priv *priv, int *temp, u8 reg) 2427f07ec0fSandrea.merello { 2437f07ec0fSandrea.merello int integer; 2447f07ec0fSandrea.merello 2457f07ec0fSandrea.merello integer = i2c_smbus_read_byte_data(priv->client, reg); 2467f07ec0fSandrea.merello if (integer < 0) 2477f07ec0fSandrea.merello return integer; 2487f07ec0fSandrea.merello 2497f07ec0fSandrea.merello *temp = stts751_to_deg(integer << 8); 2507f07ec0fSandrea.merello 2517f07ec0fSandrea.merello return 0; 2527f07ec0fSandrea.merello } 2537f07ec0fSandrea.merello 2547f07ec0fSandrea.merello /* 2557f07ec0fSandrea.merello * Update alert flags without waiting for cache to expire. We detects alerts 2567f07ec0fSandrea.merello * immediately for the sake of the alert handler; we still need to deal with 2577f07ec0fSandrea.merello * caching to workaround the fact that alarm flags int the status register, 2587f07ec0fSandrea.merello * despite what the datasheet claims, gets always cleared on read. 2597f07ec0fSandrea.merello */ 2607f07ec0fSandrea.merello static int stts751_update_alert(struct stts751_priv *priv) 2617f07ec0fSandrea.merello { 2627f07ec0fSandrea.merello int ret; 2637f07ec0fSandrea.merello bool conv_done; 2647f07ec0fSandrea.merello int cache_time = msecs_to_jiffies(stts751_intervals[priv->interval]); 2657f07ec0fSandrea.merello 2667f07ec0fSandrea.merello /* 2677f07ec0fSandrea.merello * Add another 10% because if we run faster than the HW conversion 2687f07ec0fSandrea.merello * rate we will end up in reporting incorrectly alarms. 2697f07ec0fSandrea.merello */ 2707f07ec0fSandrea.merello cache_time += cache_time / 10; 2717f07ec0fSandrea.merello 2727f07ec0fSandrea.merello ret = i2c_smbus_read_byte_data(priv->client, STTS751_REG_STATUS); 2737f07ec0fSandrea.merello if (ret < 0) 2747f07ec0fSandrea.merello return ret; 2757f07ec0fSandrea.merello 2767f07ec0fSandrea.merello dev_dbg(&priv->client->dev, "status reg %x\n", ret); 2777f07ec0fSandrea.merello conv_done = ret & (STTS751_STATUS_TRIPH | STTS751_STATUS_TRIPL); 2787f07ec0fSandrea.merello /* 2797f07ec0fSandrea.merello * Reset the cache if the cache time expired, or if we are sure 2807f07ec0fSandrea.merello * we have valid data from a device conversion, or if we know 2817f07ec0fSandrea.merello * our cache has been never written. 2827f07ec0fSandrea.merello * 2837f07ec0fSandrea.merello * Note that when the cache has been never written the point is 2847f07ec0fSandrea.merello * to correctly initialize the timestamp, rather than clearing 2857f07ec0fSandrea.merello * the cache values. 2867f07ec0fSandrea.merello * 2877f07ec0fSandrea.merello * Note that updating the cache timestamp when we get an alarm flag 2887f07ec0fSandrea.merello * is required, otherwise we could incorrectly report alarms to be zero. 2897f07ec0fSandrea.merello */ 2907f07ec0fSandrea.merello if (time_after(jiffies, priv->last_alert_update + cache_time) || 2917f07ec0fSandrea.merello conv_done || !priv->alert_valid) { 2927f07ec0fSandrea.merello priv->max_alert = false; 2937f07ec0fSandrea.merello priv->min_alert = false; 2947f07ec0fSandrea.merello priv->alert_valid = true; 2957f07ec0fSandrea.merello priv->last_alert_update = jiffies; 2967f07ec0fSandrea.merello dev_dbg(&priv->client->dev, "invalidating alert cache\n"); 2977f07ec0fSandrea.merello } 2987f07ec0fSandrea.merello 2997f07ec0fSandrea.merello priv->max_alert |= !!(ret & STTS751_STATUS_TRIPH); 3007f07ec0fSandrea.merello priv->min_alert |= !!(ret & STTS751_STATUS_TRIPL); 3017f07ec0fSandrea.merello priv->therm_trip = !!(ret & STTS751_STATUS_TRIPT); 3027f07ec0fSandrea.merello 3037f07ec0fSandrea.merello dev_dbg(&priv->client->dev, "max_alert: %d, min_alert: %d, therm_trip: %d\n", 3047f07ec0fSandrea.merello priv->max_alert, priv->min_alert, priv->therm_trip); 3057f07ec0fSandrea.merello 3067f07ec0fSandrea.merello return 0; 3077f07ec0fSandrea.merello } 3087f07ec0fSandrea.merello 3097f07ec0fSandrea.merello static void stts751_alert(struct i2c_client *client, 3107f07ec0fSandrea.merello enum i2c_alert_protocol type, unsigned int data) 3117f07ec0fSandrea.merello { 3127f07ec0fSandrea.merello int ret; 3137f07ec0fSandrea.merello struct stts751_priv *priv = i2c_get_clientdata(client); 3147f07ec0fSandrea.merello 3157f07ec0fSandrea.merello if (type != I2C_PROTOCOL_SMBUS_ALERT) 3167f07ec0fSandrea.merello return; 3177f07ec0fSandrea.merello 3187f07ec0fSandrea.merello dev_dbg(&client->dev, "alert!"); 3197f07ec0fSandrea.merello 3207f07ec0fSandrea.merello mutex_lock(&priv->access_lock); 3217f07ec0fSandrea.merello ret = stts751_update_alert(priv); 3227f07ec0fSandrea.merello if (ret < 0) { 3237f07ec0fSandrea.merello /* default to worst case */ 3247f07ec0fSandrea.merello priv->max_alert = true; 3257f07ec0fSandrea.merello priv->min_alert = true; 3267f07ec0fSandrea.merello 3277f07ec0fSandrea.merello dev_warn(priv->dev, 3287f07ec0fSandrea.merello "Alert received, but can't communicate to the device. Triggering all alarms!"); 3297f07ec0fSandrea.merello } 3307f07ec0fSandrea.merello 3317f07ec0fSandrea.merello if (priv->max_alert) { 3327f07ec0fSandrea.merello if (priv->notify_max) 3337f07ec0fSandrea.merello dev_notice(priv->dev, "got alert for HIGH temperature"); 3347f07ec0fSandrea.merello priv->notify_max = false; 3357f07ec0fSandrea.merello 3367f07ec0fSandrea.merello /* unblock alert poll */ 3377f07ec0fSandrea.merello sysfs_notify(&priv->dev->kobj, NULL, "temp1_max_alarm"); 3387f07ec0fSandrea.merello } 3397f07ec0fSandrea.merello 3407f07ec0fSandrea.merello if (priv->min_alert) { 3417f07ec0fSandrea.merello if (priv->notify_min) 3427f07ec0fSandrea.merello dev_notice(priv->dev, "got alert for LOW temperature"); 3437f07ec0fSandrea.merello priv->notify_min = false; 3447f07ec0fSandrea.merello 3457f07ec0fSandrea.merello /* unblock alert poll */ 3467f07ec0fSandrea.merello sysfs_notify(&priv->dev->kobj, NULL, "temp1_min_alarm"); 3477f07ec0fSandrea.merello } 3487f07ec0fSandrea.merello 3497f07ec0fSandrea.merello if (priv->min_alert || priv->max_alert) 3507f07ec0fSandrea.merello kobject_uevent(&priv->dev->kobj, KOBJ_CHANGE); 3517f07ec0fSandrea.merello 3527f07ec0fSandrea.merello mutex_unlock(&priv->access_lock); 3537f07ec0fSandrea.merello } 3547f07ec0fSandrea.merello 3557f07ec0fSandrea.merello static int stts751_update(struct stts751_priv *priv) 3567f07ec0fSandrea.merello { 3577f07ec0fSandrea.merello int ret; 3587f07ec0fSandrea.merello int cache_time = msecs_to_jiffies(stts751_intervals[priv->interval]); 3597f07ec0fSandrea.merello 3607f07ec0fSandrea.merello if (time_after(jiffies, priv->last_update + cache_time) || 3617f07ec0fSandrea.merello !priv->data_valid) { 3627f07ec0fSandrea.merello ret = stts751_update_temp(priv); 3637f07ec0fSandrea.merello if (ret) 3647f07ec0fSandrea.merello return ret; 3657f07ec0fSandrea.merello 3667f07ec0fSandrea.merello ret = stts751_update_alert(priv); 3677f07ec0fSandrea.merello if (ret) 3687f07ec0fSandrea.merello return ret; 3697f07ec0fSandrea.merello priv->data_valid = true; 3707f07ec0fSandrea.merello priv->last_update = jiffies; 3717f07ec0fSandrea.merello } 3727f07ec0fSandrea.merello 3737f07ec0fSandrea.merello return 0; 3747f07ec0fSandrea.merello } 3757f07ec0fSandrea.merello 376ecd52d7bSGuenter Roeck static ssize_t max_alarm_show(struct device *dev, 377ecd52d7bSGuenter Roeck struct device_attribute *attr, char *buf) 3787f07ec0fSandrea.merello { 3797f07ec0fSandrea.merello int ret; 3807f07ec0fSandrea.merello struct stts751_priv *priv = dev_get_drvdata(dev); 3817f07ec0fSandrea.merello 3827f07ec0fSandrea.merello mutex_lock(&priv->access_lock); 3837f07ec0fSandrea.merello ret = stts751_update(priv); 3847f07ec0fSandrea.merello if (!ret) 3857f07ec0fSandrea.merello priv->notify_max = true; 3867f07ec0fSandrea.merello mutex_unlock(&priv->access_lock); 3877f07ec0fSandrea.merello if (ret < 0) 3887f07ec0fSandrea.merello return ret; 3897f07ec0fSandrea.merello 390*1f4d4af4SGuenter Roeck return sysfs_emit(buf, "%d\n", priv->max_alert); 3917f07ec0fSandrea.merello } 3927f07ec0fSandrea.merello 393ecd52d7bSGuenter Roeck static ssize_t min_alarm_show(struct device *dev, 394ecd52d7bSGuenter Roeck struct device_attribute *attr, char *buf) 3957f07ec0fSandrea.merello { 3967f07ec0fSandrea.merello int ret; 3977f07ec0fSandrea.merello struct stts751_priv *priv = dev_get_drvdata(dev); 3987f07ec0fSandrea.merello 3997f07ec0fSandrea.merello mutex_lock(&priv->access_lock); 4007f07ec0fSandrea.merello ret = stts751_update(priv); 4017f07ec0fSandrea.merello if (!ret) 4027f07ec0fSandrea.merello priv->notify_min = true; 4037f07ec0fSandrea.merello mutex_unlock(&priv->access_lock); 4047f07ec0fSandrea.merello if (ret < 0) 4057f07ec0fSandrea.merello return ret; 4067f07ec0fSandrea.merello 407*1f4d4af4SGuenter Roeck return sysfs_emit(buf, "%d\n", priv->min_alert); 4087f07ec0fSandrea.merello } 4097f07ec0fSandrea.merello 410ecd52d7bSGuenter Roeck static ssize_t input_show(struct device *dev, struct device_attribute *attr, 4117f07ec0fSandrea.merello char *buf) 4127f07ec0fSandrea.merello { 4137f07ec0fSandrea.merello int ret; 4147f07ec0fSandrea.merello struct stts751_priv *priv = dev_get_drvdata(dev); 4157f07ec0fSandrea.merello 4167f07ec0fSandrea.merello mutex_lock(&priv->access_lock); 4177f07ec0fSandrea.merello ret = stts751_update(priv); 4187f07ec0fSandrea.merello mutex_unlock(&priv->access_lock); 4197f07ec0fSandrea.merello if (ret < 0) 4207f07ec0fSandrea.merello return ret; 4217f07ec0fSandrea.merello 422*1f4d4af4SGuenter Roeck return sysfs_emit(buf, "%d\n", priv->temp); 4237f07ec0fSandrea.merello } 4247f07ec0fSandrea.merello 425ecd52d7bSGuenter Roeck static ssize_t therm_show(struct device *dev, struct device_attribute *attr, 4267f07ec0fSandrea.merello char *buf) 4277f07ec0fSandrea.merello { 4287f07ec0fSandrea.merello struct stts751_priv *priv = dev_get_drvdata(dev); 4297f07ec0fSandrea.merello 430*1f4d4af4SGuenter Roeck return sysfs_emit(buf, "%d\n", priv->therm); 4317f07ec0fSandrea.merello } 4327f07ec0fSandrea.merello 433ecd52d7bSGuenter Roeck static ssize_t therm_store(struct device *dev, struct device_attribute *attr, 4347f07ec0fSandrea.merello const char *buf, size_t count) 4357f07ec0fSandrea.merello { 4367f07ec0fSandrea.merello int ret; 4377f07ec0fSandrea.merello long temp; 4387f07ec0fSandrea.merello struct stts751_priv *priv = dev_get_drvdata(dev); 4397f07ec0fSandrea.merello 4407f07ec0fSandrea.merello if (kstrtol(buf, 10, &temp) < 0) 4417f07ec0fSandrea.merello return -EINVAL; 4427f07ec0fSandrea.merello 4437f07ec0fSandrea.merello /* HW works in range -64C to +127.937C */ 4447f07ec0fSandrea.merello temp = clamp_val(temp, -64000, 127937); 4457f07ec0fSandrea.merello mutex_lock(&priv->access_lock); 4467f07ec0fSandrea.merello ret = stts751_set_temp_reg8(priv, temp, STTS751_REG_TLIM); 4477f07ec0fSandrea.merello if (ret) 4487f07ec0fSandrea.merello goto exit; 4497f07ec0fSandrea.merello 4507f07ec0fSandrea.merello dev_dbg(&priv->client->dev, "setting therm %ld", temp); 4517f07ec0fSandrea.merello 4527f07ec0fSandrea.merello /* 4537f07ec0fSandrea.merello * hysteresis reg is relative to therm, so the HW does not need to be 4547f07ec0fSandrea.merello * adjusted, we need to update our local copy only. 4557f07ec0fSandrea.merello */ 4567f07ec0fSandrea.merello priv->hyst = temp - (priv->therm - priv->hyst); 4577f07ec0fSandrea.merello priv->therm = temp; 4587f07ec0fSandrea.merello 4597f07ec0fSandrea.merello exit: 4607f07ec0fSandrea.merello mutex_unlock(&priv->access_lock); 4617f07ec0fSandrea.merello if (ret) 4627f07ec0fSandrea.merello return ret; 4637f07ec0fSandrea.merello 4647f07ec0fSandrea.merello return count; 4657f07ec0fSandrea.merello } 4667f07ec0fSandrea.merello 467ecd52d7bSGuenter Roeck static ssize_t hyst_show(struct device *dev, struct device_attribute *attr, 4687f07ec0fSandrea.merello char *buf) 4697f07ec0fSandrea.merello { 4707f07ec0fSandrea.merello struct stts751_priv *priv = dev_get_drvdata(dev); 4717f07ec0fSandrea.merello 472*1f4d4af4SGuenter Roeck return sysfs_emit(buf, "%d\n", priv->hyst); 4737f07ec0fSandrea.merello } 4747f07ec0fSandrea.merello 475ecd52d7bSGuenter Roeck static ssize_t hyst_store(struct device *dev, struct device_attribute *attr, 4767f07ec0fSandrea.merello const char *buf, size_t count) 4777f07ec0fSandrea.merello { 4787f07ec0fSandrea.merello int ret; 4797f07ec0fSandrea.merello long temp; 4807f07ec0fSandrea.merello 4817f07ec0fSandrea.merello struct stts751_priv *priv = dev_get_drvdata(dev); 4827f07ec0fSandrea.merello 4837f07ec0fSandrea.merello if (kstrtol(buf, 10, &temp) < 0) 4847f07ec0fSandrea.merello return -EINVAL; 4857f07ec0fSandrea.merello 4867f07ec0fSandrea.merello mutex_lock(&priv->access_lock); 4877f07ec0fSandrea.merello /* HW works in range -64C to +127.937C */ 4887f07ec0fSandrea.merello temp = clamp_val(temp, -64000, priv->therm); 4897f07ec0fSandrea.merello priv->hyst = temp; 4907f07ec0fSandrea.merello dev_dbg(&priv->client->dev, "setting hyst %ld", temp); 4917f07ec0fSandrea.merello temp = priv->therm - temp; 4927f07ec0fSandrea.merello ret = stts751_set_temp_reg8(priv, temp, STTS751_REG_HYST); 4937f07ec0fSandrea.merello mutex_unlock(&priv->access_lock); 4947f07ec0fSandrea.merello if (ret) 4957f07ec0fSandrea.merello return ret; 4967f07ec0fSandrea.merello 4977f07ec0fSandrea.merello return count; 4987f07ec0fSandrea.merello } 4997f07ec0fSandrea.merello 500ecd52d7bSGuenter Roeck static ssize_t therm_trip_show(struct device *dev, 5017f07ec0fSandrea.merello struct device_attribute *attr, char *buf) 5027f07ec0fSandrea.merello { 5037f07ec0fSandrea.merello int ret; 5047f07ec0fSandrea.merello struct stts751_priv *priv = dev_get_drvdata(dev); 5057f07ec0fSandrea.merello 5067f07ec0fSandrea.merello mutex_lock(&priv->access_lock); 5077f07ec0fSandrea.merello ret = stts751_update(priv); 5087f07ec0fSandrea.merello mutex_unlock(&priv->access_lock); 5097f07ec0fSandrea.merello if (ret < 0) 5107f07ec0fSandrea.merello return ret; 5117f07ec0fSandrea.merello 512*1f4d4af4SGuenter Roeck return sysfs_emit(buf, "%d\n", priv->therm_trip); 5137f07ec0fSandrea.merello } 5147f07ec0fSandrea.merello 515ecd52d7bSGuenter Roeck static ssize_t max_show(struct device *dev, struct device_attribute *attr, 5167f07ec0fSandrea.merello char *buf) 5177f07ec0fSandrea.merello { 5187f07ec0fSandrea.merello struct stts751_priv *priv = dev_get_drvdata(dev); 5197f07ec0fSandrea.merello 520*1f4d4af4SGuenter Roeck return sysfs_emit(buf, "%d\n", priv->event_max); 5217f07ec0fSandrea.merello } 5227f07ec0fSandrea.merello 523ecd52d7bSGuenter Roeck static ssize_t max_store(struct device *dev, struct device_attribute *attr, 5247f07ec0fSandrea.merello const char *buf, size_t count) 5257f07ec0fSandrea.merello { 5267f07ec0fSandrea.merello int ret; 5277f07ec0fSandrea.merello long temp; 5287f07ec0fSandrea.merello struct stts751_priv *priv = dev_get_drvdata(dev); 5297f07ec0fSandrea.merello 5307f07ec0fSandrea.merello if (kstrtol(buf, 10, &temp) < 0) 5317f07ec0fSandrea.merello return -EINVAL; 5327f07ec0fSandrea.merello 5337f07ec0fSandrea.merello mutex_lock(&priv->access_lock); 5347f07ec0fSandrea.merello /* HW works in range -64C to +127.937C */ 5357f07ec0fSandrea.merello temp = clamp_val(temp, priv->event_min, 127937); 5367f07ec0fSandrea.merello ret = stts751_set_temp_reg16(priv, temp, 5377f07ec0fSandrea.merello STTS751_REG_HLIM_H, STTS751_REG_HLIM_L); 5387f07ec0fSandrea.merello if (ret) 5397f07ec0fSandrea.merello goto exit; 5407f07ec0fSandrea.merello 5417f07ec0fSandrea.merello dev_dbg(&priv->client->dev, "setting event max %ld", temp); 5427f07ec0fSandrea.merello priv->event_max = temp; 5437f07ec0fSandrea.merello ret = count; 5447f07ec0fSandrea.merello exit: 5457f07ec0fSandrea.merello mutex_unlock(&priv->access_lock); 5467f07ec0fSandrea.merello return ret; 5477f07ec0fSandrea.merello } 5487f07ec0fSandrea.merello 549ecd52d7bSGuenter Roeck static ssize_t min_show(struct device *dev, struct device_attribute *attr, 5507f07ec0fSandrea.merello char *buf) 5517f07ec0fSandrea.merello { 5527f07ec0fSandrea.merello struct stts751_priv *priv = dev_get_drvdata(dev); 5537f07ec0fSandrea.merello 554*1f4d4af4SGuenter Roeck return sysfs_emit(buf, "%d\n", priv->event_min); 5557f07ec0fSandrea.merello } 5567f07ec0fSandrea.merello 557ecd52d7bSGuenter Roeck static ssize_t min_store(struct device *dev, struct device_attribute *attr, 5587f07ec0fSandrea.merello const char *buf, size_t count) 5597f07ec0fSandrea.merello { 5607f07ec0fSandrea.merello int ret; 5617f07ec0fSandrea.merello long temp; 5627f07ec0fSandrea.merello struct stts751_priv *priv = dev_get_drvdata(dev); 5637f07ec0fSandrea.merello 5647f07ec0fSandrea.merello if (kstrtol(buf, 10, &temp) < 0) 5657f07ec0fSandrea.merello return -EINVAL; 5667f07ec0fSandrea.merello 5677f07ec0fSandrea.merello mutex_lock(&priv->access_lock); 5687f07ec0fSandrea.merello /* HW works in range -64C to +127.937C */ 5697f07ec0fSandrea.merello temp = clamp_val(temp, -64000, priv->event_max); 5707f07ec0fSandrea.merello ret = stts751_set_temp_reg16(priv, temp, 5717f07ec0fSandrea.merello STTS751_REG_LLIM_H, STTS751_REG_LLIM_L); 5727f07ec0fSandrea.merello if (ret) 5737f07ec0fSandrea.merello goto exit; 5747f07ec0fSandrea.merello 5757f07ec0fSandrea.merello dev_dbg(&priv->client->dev, "setting event min %ld", temp); 5767f07ec0fSandrea.merello priv->event_min = temp; 5777f07ec0fSandrea.merello ret = count; 5787f07ec0fSandrea.merello exit: 5797f07ec0fSandrea.merello mutex_unlock(&priv->access_lock); 5807f07ec0fSandrea.merello return ret; 5817f07ec0fSandrea.merello } 5827f07ec0fSandrea.merello 583ecd52d7bSGuenter Roeck static ssize_t interval_show(struct device *dev, 584ecd52d7bSGuenter Roeck struct device_attribute *attr, char *buf) 5857f07ec0fSandrea.merello { 5867f07ec0fSandrea.merello struct stts751_priv *priv = dev_get_drvdata(dev); 5877f07ec0fSandrea.merello 588*1f4d4af4SGuenter Roeck return sysfs_emit(buf, "%d\n", 5897f07ec0fSandrea.merello stts751_intervals[priv->interval]); 5907f07ec0fSandrea.merello } 5917f07ec0fSandrea.merello 592ecd52d7bSGuenter Roeck static ssize_t interval_store(struct device *dev, 593ecd52d7bSGuenter Roeck struct device_attribute *attr, const char *buf, 594ecd52d7bSGuenter Roeck size_t count) 5957f07ec0fSandrea.merello { 5967f07ec0fSandrea.merello unsigned long val; 5977f07ec0fSandrea.merello int idx; 5987f07ec0fSandrea.merello int ret = count; 5997f07ec0fSandrea.merello struct stts751_priv *priv = dev_get_drvdata(dev); 6007f07ec0fSandrea.merello 6017f07ec0fSandrea.merello if (kstrtoul(buf, 10, &val) < 0) 6027f07ec0fSandrea.merello return -EINVAL; 6037f07ec0fSandrea.merello 6047f07ec0fSandrea.merello idx = find_closest_descending(val, stts751_intervals, 6057f07ec0fSandrea.merello ARRAY_SIZE(stts751_intervals)); 6067f07ec0fSandrea.merello 6077f07ec0fSandrea.merello dev_dbg(&priv->client->dev, "setting interval. req:%lu, idx: %d, val: %d", 6087f07ec0fSandrea.merello val, idx, stts751_intervals[idx]); 6097f07ec0fSandrea.merello 6107f07ec0fSandrea.merello mutex_lock(&priv->access_lock); 6117f07ec0fSandrea.merello if (priv->interval == idx) 6127f07ec0fSandrea.merello goto exit; 6137f07ec0fSandrea.merello 6147f07ec0fSandrea.merello /* 6157f07ec0fSandrea.merello * In early development stages I've become suspicious about the chip 6167f07ec0fSandrea.merello * starting to misbehave if I ever set, even briefly, an invalid 6177f07ec0fSandrea.merello * configuration. While I'm not sure this is really needed, be 6187f07ec0fSandrea.merello * conservative and set rate/resolution in such an order that avoids 6197f07ec0fSandrea.merello * passing through an invalid configuration. 6207f07ec0fSandrea.merello */ 6217f07ec0fSandrea.merello 6227f07ec0fSandrea.merello /* speed up: lower the resolution, then modify convrate */ 6237f07ec0fSandrea.merello if (priv->interval < idx) { 6247f07ec0fSandrea.merello dev_dbg(&priv->client->dev, "lower resolution, then modify convrate"); 6257f07ec0fSandrea.merello priv->interval = idx; 6267f07ec0fSandrea.merello ret = stts751_adjust_resolution(priv); 6277f07ec0fSandrea.merello if (ret) 6287f07ec0fSandrea.merello goto exit; 6297f07ec0fSandrea.merello } 6307f07ec0fSandrea.merello 6317f07ec0fSandrea.merello ret = i2c_smbus_write_byte_data(priv->client, STTS751_REG_RATE, idx); 6327f07ec0fSandrea.merello if (ret) 6337f07ec0fSandrea.merello goto exit; 6347f07ec0fSandrea.merello /* slow down: modify convrate, then raise resolution */ 6357f07ec0fSandrea.merello if (priv->interval != idx) { 6367f07ec0fSandrea.merello dev_dbg(&priv->client->dev, "modify convrate, then raise resolution"); 6377f07ec0fSandrea.merello priv->interval = idx; 6387f07ec0fSandrea.merello ret = stts751_adjust_resolution(priv); 6397f07ec0fSandrea.merello if (ret) 6407f07ec0fSandrea.merello goto exit; 6417f07ec0fSandrea.merello } 6427f07ec0fSandrea.merello ret = count; 6437f07ec0fSandrea.merello exit: 6447f07ec0fSandrea.merello mutex_unlock(&priv->access_lock); 6457f07ec0fSandrea.merello 6467f07ec0fSandrea.merello return ret; 6477f07ec0fSandrea.merello } 6487f07ec0fSandrea.merello 6497f07ec0fSandrea.merello static int stts751_detect(struct i2c_client *new_client, 6507f07ec0fSandrea.merello struct i2c_board_info *info) 6517f07ec0fSandrea.merello { 6527f07ec0fSandrea.merello struct i2c_adapter *adapter = new_client->adapter; 6537f07ec0fSandrea.merello const char *name; 6547f07ec0fSandrea.merello int tmp; 6557f07ec0fSandrea.merello 6567f07ec0fSandrea.merello if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 6577f07ec0fSandrea.merello return -ENODEV; 6587f07ec0fSandrea.merello 6597f07ec0fSandrea.merello tmp = i2c_smbus_read_byte_data(new_client, STTS751_REG_MAN_ID); 6607f07ec0fSandrea.merello if (tmp != ST_MAN_ID) 6617f07ec0fSandrea.merello return -ENODEV; 6627f07ec0fSandrea.merello 6637f07ec0fSandrea.merello /* lower temperaure registers always have bits 0-3 set to zero */ 6647f07ec0fSandrea.merello tmp = i2c_smbus_read_byte_data(new_client, STTS751_REG_TEMP_L); 6657f07ec0fSandrea.merello if (tmp & 0xf) 6667f07ec0fSandrea.merello return -ENODEV; 6677f07ec0fSandrea.merello 6687f07ec0fSandrea.merello tmp = i2c_smbus_read_byte_data(new_client, STTS751_REG_HLIM_L); 6697f07ec0fSandrea.merello if (tmp & 0xf) 6707f07ec0fSandrea.merello return -ENODEV; 6717f07ec0fSandrea.merello 6727f07ec0fSandrea.merello tmp = i2c_smbus_read_byte_data(new_client, STTS751_REG_LLIM_L); 6737f07ec0fSandrea.merello if (tmp & 0xf) 6747f07ec0fSandrea.merello return -ENODEV; 6757f07ec0fSandrea.merello 6767f07ec0fSandrea.merello /* smbus timeout register always have bits 0-7 set to zero */ 6777f07ec0fSandrea.merello tmp = i2c_smbus_read_byte_data(new_client, STTS751_REG_SMBUS_TO); 6787f07ec0fSandrea.merello if (tmp & 0x7f) 6797f07ec0fSandrea.merello return -ENODEV; 6807f07ec0fSandrea.merello 6817f07ec0fSandrea.merello tmp = i2c_smbus_read_byte_data(new_client, STTS751_REG_PROD_ID); 6827f07ec0fSandrea.merello 6837f07ec0fSandrea.merello switch (tmp) { 6847f07ec0fSandrea.merello case STTS751_0_PROD_ID: 6857f07ec0fSandrea.merello name = "STTS751-0"; 6867f07ec0fSandrea.merello break; 6877f07ec0fSandrea.merello case STTS751_1_PROD_ID: 6887f07ec0fSandrea.merello name = "STTS751-1"; 6897f07ec0fSandrea.merello break; 6907f07ec0fSandrea.merello default: 6917f07ec0fSandrea.merello return -ENODEV; 6927f07ec0fSandrea.merello } 6937f07ec0fSandrea.merello dev_dbg(&new_client->dev, "Chip %s detected", name); 6947f07ec0fSandrea.merello 6957f07ec0fSandrea.merello strlcpy(info->type, stts751_id[0].name, I2C_NAME_SIZE); 6967f07ec0fSandrea.merello return 0; 6977f07ec0fSandrea.merello } 6987f07ec0fSandrea.merello 6997f07ec0fSandrea.merello static int stts751_read_chip_config(struct stts751_priv *priv) 7007f07ec0fSandrea.merello { 7017f07ec0fSandrea.merello int ret; 7027f07ec0fSandrea.merello int tmp; 7037f07ec0fSandrea.merello 7047f07ec0fSandrea.merello ret = i2c_smbus_read_byte_data(priv->client, STTS751_REG_CONF); 7057f07ec0fSandrea.merello if (ret < 0) 7067f07ec0fSandrea.merello return ret; 7077f07ec0fSandrea.merello priv->config = ret; 7087f07ec0fSandrea.merello priv->res = (ret & STTS751_CONF_RES_MASK) >> STTS751_CONF_RES_SHIFT; 7097f07ec0fSandrea.merello 7107f07ec0fSandrea.merello ret = i2c_smbus_read_byte_data(priv->client, STTS751_REG_RATE); 7117f07ec0fSandrea.merello if (ret < 0) 7127f07ec0fSandrea.merello return ret; 7133be6bd69SAnton Vasilyev if (ret >= ARRAY_SIZE(stts751_intervals)) { 7143be6bd69SAnton Vasilyev dev_err(priv->dev, "Unrecognized conversion rate 0x%x\n", ret); 7153be6bd69SAnton Vasilyev return -ENODEV; 7163be6bd69SAnton Vasilyev } 7177f07ec0fSandrea.merello priv->interval = ret; 7187f07ec0fSandrea.merello 7197f07ec0fSandrea.merello ret = stts751_read_reg16(priv, &priv->event_max, 7207f07ec0fSandrea.merello STTS751_REG_HLIM_H, STTS751_REG_HLIM_L); 7217f07ec0fSandrea.merello if (ret) 7227f07ec0fSandrea.merello return ret; 7237f07ec0fSandrea.merello 7247f07ec0fSandrea.merello ret = stts751_read_reg16(priv, &priv->event_min, 7257f07ec0fSandrea.merello STTS751_REG_LLIM_H, STTS751_REG_LLIM_L); 7267f07ec0fSandrea.merello if (ret) 7277f07ec0fSandrea.merello return ret; 7287f07ec0fSandrea.merello 7297f07ec0fSandrea.merello ret = stts751_read_reg8(priv, &priv->therm, STTS751_REG_TLIM); 7307f07ec0fSandrea.merello if (ret) 7317f07ec0fSandrea.merello return ret; 7327f07ec0fSandrea.merello 7337f07ec0fSandrea.merello ret = stts751_read_reg8(priv, &tmp, STTS751_REG_HYST); 7347f07ec0fSandrea.merello if (ret) 7357f07ec0fSandrea.merello return ret; 7367f07ec0fSandrea.merello priv->hyst = priv->therm - tmp; 7377f07ec0fSandrea.merello 7387f07ec0fSandrea.merello return 0; 7397f07ec0fSandrea.merello } 7407f07ec0fSandrea.merello 741ecd52d7bSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp1_input, input, 0); 742ecd52d7bSGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp1_min, min, 0); 743ecd52d7bSGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp1_max, max, 0); 744ecd52d7bSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp1_min_alarm, min_alarm, 0); 745ecd52d7bSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp1_max_alarm, max_alarm, 0); 746ecd52d7bSGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp1_crit, therm, 0); 747ecd52d7bSGuenter Roeck static SENSOR_DEVICE_ATTR_RW(temp1_crit_hyst, hyst, 0); 748ecd52d7bSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(temp1_crit_alarm, therm_trip, 0); 749ecd52d7bSGuenter Roeck static SENSOR_DEVICE_ATTR_RW(update_interval, interval, 0); 7507f07ec0fSandrea.merello 7517f07ec0fSandrea.merello static struct attribute *stts751_attrs[] = { 7527f07ec0fSandrea.merello &sensor_dev_attr_temp1_input.dev_attr.attr, 7537f07ec0fSandrea.merello &sensor_dev_attr_temp1_min.dev_attr.attr, 7547f07ec0fSandrea.merello &sensor_dev_attr_temp1_max.dev_attr.attr, 7557f07ec0fSandrea.merello &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, 7567f07ec0fSandrea.merello &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, 7577f07ec0fSandrea.merello &sensor_dev_attr_temp1_crit.dev_attr.attr, 7587f07ec0fSandrea.merello &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, 7597f07ec0fSandrea.merello &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, 7607f07ec0fSandrea.merello &sensor_dev_attr_update_interval.dev_attr.attr, 7617f07ec0fSandrea.merello NULL 7627f07ec0fSandrea.merello }; 7637f07ec0fSandrea.merello ATTRIBUTE_GROUPS(stts751); 7647f07ec0fSandrea.merello 76567487038SStephen Kitt static int stts751_probe(struct i2c_client *client) 7667f07ec0fSandrea.merello { 7677f07ec0fSandrea.merello struct stts751_priv *priv; 7687f07ec0fSandrea.merello int ret; 7697f07ec0fSandrea.merello bool smbus_nto; 7707f07ec0fSandrea.merello int rev_id; 7717f07ec0fSandrea.merello 7727f07ec0fSandrea.merello priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); 7737f07ec0fSandrea.merello if (!priv) 7747f07ec0fSandrea.merello return -ENOMEM; 7757f07ec0fSandrea.merello 7767f07ec0fSandrea.merello priv->client = client; 7777f07ec0fSandrea.merello priv->notify_max = true; 7787f07ec0fSandrea.merello priv->notify_min = true; 7797f07ec0fSandrea.merello i2c_set_clientdata(client, priv); 7807f07ec0fSandrea.merello mutex_init(&priv->access_lock); 7817f07ec0fSandrea.merello 7827f07ec0fSandrea.merello if (device_property_present(&client->dev, 7837f07ec0fSandrea.merello "smbus-timeout-disable")) { 7847f07ec0fSandrea.merello smbus_nto = device_property_read_bool(&client->dev, 7857f07ec0fSandrea.merello "smbus-timeout-disable"); 7867f07ec0fSandrea.merello 7877f07ec0fSandrea.merello ret = i2c_smbus_write_byte_data(client, STTS751_REG_SMBUS_TO, 7887f07ec0fSandrea.merello smbus_nto ? 0 : 0x80); 7897f07ec0fSandrea.merello if (ret) 7907f07ec0fSandrea.merello return ret; 7917f07ec0fSandrea.merello } 7927f07ec0fSandrea.merello 7937f07ec0fSandrea.merello rev_id = i2c_smbus_read_byte_data(client, STTS751_REG_REV_ID); 7947f07ec0fSandrea.merello if (rev_id < 0) 7957f07ec0fSandrea.merello return -ENODEV; 7967f07ec0fSandrea.merello if (rev_id != 0x1) { 7977f07ec0fSandrea.merello dev_dbg(&client->dev, "Chip revision 0x%x is untested\n", 7987f07ec0fSandrea.merello rev_id); 7997f07ec0fSandrea.merello } 8007f07ec0fSandrea.merello 8017f07ec0fSandrea.merello ret = stts751_read_chip_config(priv); 8027f07ec0fSandrea.merello if (ret) 8037f07ec0fSandrea.merello return ret; 8047f07ec0fSandrea.merello 8057f07ec0fSandrea.merello priv->config &= ~(STTS751_CONF_STOP | STTS751_CONF_EVENT_DIS); 8067f07ec0fSandrea.merello ret = i2c_smbus_write_byte_data(client, STTS751_REG_CONF, priv->config); 8077f07ec0fSandrea.merello if (ret) 8087f07ec0fSandrea.merello return ret; 8097f07ec0fSandrea.merello 8107f07ec0fSandrea.merello priv->dev = devm_hwmon_device_register_with_groups(&client->dev, 8117f07ec0fSandrea.merello client->name, priv, 8127f07ec0fSandrea.merello stts751_groups); 8137f07ec0fSandrea.merello return PTR_ERR_OR_ZERO(priv->dev); 8147f07ec0fSandrea.merello } 8157f07ec0fSandrea.merello 8167f07ec0fSandrea.merello MODULE_DEVICE_TABLE(i2c, stts751_id); 8177f07ec0fSandrea.merello 8187f07ec0fSandrea.merello static struct i2c_driver stts751_driver = { 8197f07ec0fSandrea.merello .class = I2C_CLASS_HWMON, 8207f07ec0fSandrea.merello .driver = { 8217f07ec0fSandrea.merello .name = DEVNAME, 8221c1a7b75SJavier Martinez Canillas .of_match_table = of_match_ptr(stts751_of_match), 8237f07ec0fSandrea.merello }, 82467487038SStephen Kitt .probe_new = stts751_probe, 8257f07ec0fSandrea.merello .id_table = stts751_id, 8267f07ec0fSandrea.merello .detect = stts751_detect, 8277f07ec0fSandrea.merello .alert = stts751_alert, 8287f07ec0fSandrea.merello .address_list = normal_i2c, 8297f07ec0fSandrea.merello }; 8307f07ec0fSandrea.merello 8317f07ec0fSandrea.merello module_i2c_driver(stts751_driver); 8327f07ec0fSandrea.merello 8337f07ec0fSandrea.merello MODULE_AUTHOR("Andrea Merello <andrea.merello@gmail.com>"); 8347f07ec0fSandrea.merello MODULE_DESCRIPTION("STTS751 sensor driver"); 8357f07ec0fSandrea.merello MODULE_LICENSE("GPL"); 836