16700ce03SGuenter Roeck /* 26700ce03SGuenter Roeck * Driver for Linear Technology LTC2945 I2C Power Monitor 36700ce03SGuenter Roeck * 46700ce03SGuenter Roeck * Copyright (c) 2014 Guenter Roeck 56700ce03SGuenter Roeck * 66700ce03SGuenter Roeck * This program is free software; you can redistribute it and/or modify 76700ce03SGuenter Roeck * it under the terms of the GNU General Public License as published by 86700ce03SGuenter Roeck * the Free Software Foundation; either version 2 of the License, or 96700ce03SGuenter Roeck * (at your option) any later version. 106700ce03SGuenter Roeck * 116700ce03SGuenter Roeck * This program is distributed in the hope that it will be useful, 126700ce03SGuenter Roeck * but WITHOUT ANY WARRANTY; without even the implied warranty of 136700ce03SGuenter Roeck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 146700ce03SGuenter Roeck * GNU General Public License for more details. 156700ce03SGuenter Roeck */ 166700ce03SGuenter Roeck 176700ce03SGuenter Roeck #include <linux/kernel.h> 186700ce03SGuenter Roeck #include <linux/module.h> 196700ce03SGuenter Roeck #include <linux/err.h> 206700ce03SGuenter Roeck #include <linux/slab.h> 216700ce03SGuenter Roeck #include <linux/i2c.h> 226700ce03SGuenter Roeck #include <linux/hwmon.h> 236700ce03SGuenter Roeck #include <linux/hwmon-sysfs.h> 246700ce03SGuenter Roeck #include <linux/jiffies.h> 256700ce03SGuenter Roeck #include <linux/regmap.h> 266700ce03SGuenter Roeck 276700ce03SGuenter Roeck /* chip registers */ 286700ce03SGuenter Roeck #define LTC2945_CONTROL 0x00 296700ce03SGuenter Roeck #define LTC2945_ALERT 0x01 306700ce03SGuenter Roeck #define LTC2945_STATUS 0x02 316700ce03SGuenter Roeck #define LTC2945_FAULT 0x03 326700ce03SGuenter Roeck #define LTC2945_POWER_H 0x05 336700ce03SGuenter Roeck #define LTC2945_MAX_POWER_H 0x08 346700ce03SGuenter Roeck #define LTC2945_MIN_POWER_H 0x0b 356700ce03SGuenter Roeck #define LTC2945_MAX_POWER_THRES_H 0x0e 366700ce03SGuenter Roeck #define LTC2945_MIN_POWER_THRES_H 0x11 376700ce03SGuenter Roeck #define LTC2945_SENSE_H 0x14 386700ce03SGuenter Roeck #define LTC2945_MAX_SENSE_H 0x16 396700ce03SGuenter Roeck #define LTC2945_MIN_SENSE_H 0x18 406700ce03SGuenter Roeck #define LTC2945_MAX_SENSE_THRES_H 0x1a 416700ce03SGuenter Roeck #define LTC2945_MIN_SENSE_THRES_H 0x1c 426700ce03SGuenter Roeck #define LTC2945_VIN_H 0x1e 436700ce03SGuenter Roeck #define LTC2945_MAX_VIN_H 0x20 446700ce03SGuenter Roeck #define LTC2945_MIN_VIN_H 0x22 456700ce03SGuenter Roeck #define LTC2945_MAX_VIN_THRES_H 0x24 466700ce03SGuenter Roeck #define LTC2945_MIN_VIN_THRES_H 0x26 476700ce03SGuenter Roeck #define LTC2945_ADIN_H 0x28 486700ce03SGuenter Roeck #define LTC2945_MAX_ADIN_H 0x2a 496700ce03SGuenter Roeck #define LTC2945_MIN_ADIN_H 0x2c 506700ce03SGuenter Roeck #define LTC2945_MAX_ADIN_THRES_H 0x2e 516700ce03SGuenter Roeck #define LTC2945_MIN_ADIN_THRES_H 0x30 526700ce03SGuenter Roeck #define LTC2945_MIN_ADIN_THRES_L 0x31 536700ce03SGuenter Roeck 546700ce03SGuenter Roeck /* Fault register bits */ 556700ce03SGuenter Roeck 566700ce03SGuenter Roeck #define FAULT_ADIN_UV (1 << 0) 576700ce03SGuenter Roeck #define FAULT_ADIN_OV (1 << 1) 586700ce03SGuenter Roeck #define FAULT_VIN_UV (1 << 2) 596700ce03SGuenter Roeck #define FAULT_VIN_OV (1 << 3) 606700ce03SGuenter Roeck #define FAULT_SENSE_UV (1 << 4) 616700ce03SGuenter Roeck #define FAULT_SENSE_OV (1 << 5) 626700ce03SGuenter Roeck #define FAULT_POWER_UV (1 << 6) 636700ce03SGuenter Roeck #define FAULT_POWER_OV (1 << 7) 646700ce03SGuenter Roeck 656700ce03SGuenter Roeck /* Control register bits */ 666700ce03SGuenter Roeck 676700ce03SGuenter Roeck #define CONTROL_MULT_SELECT (1 << 0) 686700ce03SGuenter Roeck #define CONTROL_TEST_MODE (1 << 4) 696700ce03SGuenter Roeck 706700ce03SGuenter Roeck static inline bool is_power_reg(u8 reg) 716700ce03SGuenter Roeck { 726700ce03SGuenter Roeck return reg < LTC2945_SENSE_H; 736700ce03SGuenter Roeck } 746700ce03SGuenter Roeck 756700ce03SGuenter Roeck /* Return the value from the given register in uW, mV, or mA */ 766700ce03SGuenter Roeck static long long ltc2945_reg_to_val(struct device *dev, u8 reg) 776700ce03SGuenter Roeck { 786700ce03SGuenter Roeck struct regmap *regmap = dev_get_drvdata(dev); 796700ce03SGuenter Roeck unsigned int control; 806700ce03SGuenter Roeck u8 buf[3]; 816700ce03SGuenter Roeck long long val; 826700ce03SGuenter Roeck int ret; 836700ce03SGuenter Roeck 846700ce03SGuenter Roeck ret = regmap_bulk_read(regmap, reg, buf, 856700ce03SGuenter Roeck is_power_reg(reg) ? 3 : 2); 866700ce03SGuenter Roeck if (ret < 0) 876700ce03SGuenter Roeck return ret; 886700ce03SGuenter Roeck 896700ce03SGuenter Roeck if (is_power_reg(reg)) { 906700ce03SGuenter Roeck /* power */ 916700ce03SGuenter Roeck val = (buf[0] << 16) + (buf[1] << 8) + buf[2]; 926700ce03SGuenter Roeck } else { 936700ce03SGuenter Roeck /* current, voltage */ 946700ce03SGuenter Roeck val = (buf[0] << 4) + (buf[1] >> 4); 956700ce03SGuenter Roeck } 966700ce03SGuenter Roeck 976700ce03SGuenter Roeck switch (reg) { 986700ce03SGuenter Roeck case LTC2945_POWER_H: 996700ce03SGuenter Roeck case LTC2945_MAX_POWER_H: 1006700ce03SGuenter Roeck case LTC2945_MIN_POWER_H: 1016700ce03SGuenter Roeck case LTC2945_MAX_POWER_THRES_H: 1026700ce03SGuenter Roeck case LTC2945_MIN_POWER_THRES_H: 1036700ce03SGuenter Roeck /* 1046700ce03SGuenter Roeck * Convert to uW by assuming current is measured with 1056700ce03SGuenter Roeck * an 1mOhm sense resistor, similar to current 1066700ce03SGuenter Roeck * measurements. 1076700ce03SGuenter Roeck * Control register bit 0 selects if voltage at SENSE+/VDD 1086700ce03SGuenter Roeck * or voltage at ADIN is used to measure power. 1096700ce03SGuenter Roeck */ 1106700ce03SGuenter Roeck ret = regmap_read(regmap, LTC2945_CONTROL, &control); 1116700ce03SGuenter Roeck if (ret < 0) 1126700ce03SGuenter Roeck return ret; 1136700ce03SGuenter Roeck if (control & CONTROL_MULT_SELECT) { 1146700ce03SGuenter Roeck /* 25 mV * 25 uV = 0.625 uV resolution. */ 1156700ce03SGuenter Roeck val *= 625LL; 1166700ce03SGuenter Roeck } else { 1176700ce03SGuenter Roeck /* 0.5 mV * 25 uV = 0.0125 uV resolution. */ 1186700ce03SGuenter Roeck val = (val * 25LL) >> 1; 1196700ce03SGuenter Roeck } 1206700ce03SGuenter Roeck break; 1216700ce03SGuenter Roeck case LTC2945_VIN_H: 1226700ce03SGuenter Roeck case LTC2945_MAX_VIN_H: 1236700ce03SGuenter Roeck case LTC2945_MIN_VIN_H: 1246700ce03SGuenter Roeck case LTC2945_MAX_VIN_THRES_H: 1256700ce03SGuenter Roeck case LTC2945_MIN_VIN_THRES_H: 1266700ce03SGuenter Roeck /* 25 mV resolution. Convert to mV. */ 1276700ce03SGuenter Roeck val *= 25; 1286700ce03SGuenter Roeck break; 1296700ce03SGuenter Roeck case LTC2945_ADIN_H: 1306700ce03SGuenter Roeck case LTC2945_MAX_ADIN_H: 1316700ce03SGuenter Roeck case LTC2945_MIN_ADIN_THRES_H: 1326700ce03SGuenter Roeck case LTC2945_MAX_ADIN_THRES_H: 1336700ce03SGuenter Roeck case LTC2945_MIN_ADIN_H: 1346700ce03SGuenter Roeck /* 0.5mV resolution. Convert to mV. */ 1356700ce03SGuenter Roeck val = val >> 1; 1366700ce03SGuenter Roeck break; 1376700ce03SGuenter Roeck case LTC2945_SENSE_H: 1386700ce03SGuenter Roeck case LTC2945_MAX_SENSE_H: 1396700ce03SGuenter Roeck case LTC2945_MIN_SENSE_H: 1406700ce03SGuenter Roeck case LTC2945_MAX_SENSE_THRES_H: 1416700ce03SGuenter Roeck case LTC2945_MIN_SENSE_THRES_H: 1426700ce03SGuenter Roeck /* 1436700ce03SGuenter Roeck * 25 uV resolution. Convert to current as measured with 1446700ce03SGuenter Roeck * an 1 mOhm sense resistor, in mA. If a different sense 1456700ce03SGuenter Roeck * resistor is installed, calculate the actual current by 1466700ce03SGuenter Roeck * dividing the reported current by the sense resistor value 1476700ce03SGuenter Roeck * in mOhm. 1486700ce03SGuenter Roeck */ 1496700ce03SGuenter Roeck val *= 25; 1506700ce03SGuenter Roeck break; 1516700ce03SGuenter Roeck default: 1526700ce03SGuenter Roeck return -EINVAL; 1536700ce03SGuenter Roeck } 1546700ce03SGuenter Roeck return val; 1556700ce03SGuenter Roeck } 1566700ce03SGuenter Roeck 1576700ce03SGuenter Roeck static int ltc2945_val_to_reg(struct device *dev, u8 reg, 1586700ce03SGuenter Roeck unsigned long val) 1596700ce03SGuenter Roeck { 1606700ce03SGuenter Roeck struct regmap *regmap = dev_get_drvdata(dev); 1616700ce03SGuenter Roeck unsigned int control; 1626700ce03SGuenter Roeck int ret; 1636700ce03SGuenter Roeck 1646700ce03SGuenter Roeck switch (reg) { 1656700ce03SGuenter Roeck case LTC2945_POWER_H: 1666700ce03SGuenter Roeck case LTC2945_MAX_POWER_H: 1676700ce03SGuenter Roeck case LTC2945_MIN_POWER_H: 1686700ce03SGuenter Roeck case LTC2945_MAX_POWER_THRES_H: 1696700ce03SGuenter Roeck case LTC2945_MIN_POWER_THRES_H: 1706700ce03SGuenter Roeck /* 1716700ce03SGuenter Roeck * Convert to register value by assuming current is measured 1726700ce03SGuenter Roeck * with an 1mOhm sense resistor, similar to current 1736700ce03SGuenter Roeck * measurements. 1746700ce03SGuenter Roeck * Control register bit 0 selects if voltage at SENSE+/VDD 1756700ce03SGuenter Roeck * or voltage at ADIN is used to measure power, which in turn 1766700ce03SGuenter Roeck * determines register calculations. 1776700ce03SGuenter Roeck */ 1786700ce03SGuenter Roeck ret = regmap_read(regmap, LTC2945_CONTROL, &control); 1796700ce03SGuenter Roeck if (ret < 0) 1806700ce03SGuenter Roeck return ret; 1816700ce03SGuenter Roeck if (control & CONTROL_MULT_SELECT) { 1826700ce03SGuenter Roeck /* 25 mV * 25 uV = 0.625 uV resolution. */ 1836700ce03SGuenter Roeck val = DIV_ROUND_CLOSEST(val, 625); 1846700ce03SGuenter Roeck } else { 1856700ce03SGuenter Roeck /* 1866700ce03SGuenter Roeck * 0.5 mV * 25 uV = 0.0125 uV resolution. 1876700ce03SGuenter Roeck * Divide first to avoid overflow; 1886700ce03SGuenter Roeck * accept loss of accuracy. 1896700ce03SGuenter Roeck */ 1906700ce03SGuenter Roeck val = DIV_ROUND_CLOSEST(val, 25) * 2; 1916700ce03SGuenter Roeck } 1926700ce03SGuenter Roeck break; 1936700ce03SGuenter Roeck case LTC2945_VIN_H: 1946700ce03SGuenter Roeck case LTC2945_MAX_VIN_H: 1956700ce03SGuenter Roeck case LTC2945_MIN_VIN_H: 1966700ce03SGuenter Roeck case LTC2945_MAX_VIN_THRES_H: 1976700ce03SGuenter Roeck case LTC2945_MIN_VIN_THRES_H: 1986700ce03SGuenter Roeck /* 25 mV resolution. */ 1996700ce03SGuenter Roeck val /= 25; 2006700ce03SGuenter Roeck break; 2016700ce03SGuenter Roeck case LTC2945_ADIN_H: 2026700ce03SGuenter Roeck case LTC2945_MAX_ADIN_H: 2036700ce03SGuenter Roeck case LTC2945_MIN_ADIN_THRES_H: 2046700ce03SGuenter Roeck case LTC2945_MAX_ADIN_THRES_H: 2056700ce03SGuenter Roeck case LTC2945_MIN_ADIN_H: 2066700ce03SGuenter Roeck /* 0.5mV resolution. */ 2076700ce03SGuenter Roeck val *= 2; 2086700ce03SGuenter Roeck break; 2096700ce03SGuenter Roeck case LTC2945_SENSE_H: 2106700ce03SGuenter Roeck case LTC2945_MAX_SENSE_H: 2116700ce03SGuenter Roeck case LTC2945_MIN_SENSE_H: 2126700ce03SGuenter Roeck case LTC2945_MAX_SENSE_THRES_H: 2136700ce03SGuenter Roeck case LTC2945_MIN_SENSE_THRES_H: 2146700ce03SGuenter Roeck /* 2156700ce03SGuenter Roeck * 25 uV resolution. Convert to current as measured with 2166700ce03SGuenter Roeck * an 1 mOhm sense resistor, in mA. If a different sense 2176700ce03SGuenter Roeck * resistor is installed, calculate the actual current by 2186700ce03SGuenter Roeck * dividing the reported current by the sense resistor value 2196700ce03SGuenter Roeck * in mOhm. 2206700ce03SGuenter Roeck */ 2216700ce03SGuenter Roeck val = DIV_ROUND_CLOSEST(val, 25); 2226700ce03SGuenter Roeck break; 2236700ce03SGuenter Roeck default: 2246700ce03SGuenter Roeck return -EINVAL; 2256700ce03SGuenter Roeck } 2266700ce03SGuenter Roeck return val; 2276700ce03SGuenter Roeck } 2286700ce03SGuenter Roeck 2296700ce03SGuenter Roeck static ssize_t ltc2945_show_value(struct device *dev, 2306700ce03SGuenter Roeck struct device_attribute *da, char *buf) 2316700ce03SGuenter Roeck { 2326700ce03SGuenter Roeck struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 2336700ce03SGuenter Roeck long long value; 2346700ce03SGuenter Roeck 2356700ce03SGuenter Roeck value = ltc2945_reg_to_val(dev, attr->index); 2366700ce03SGuenter Roeck if (value < 0) 2376700ce03SGuenter Roeck return value; 2386700ce03SGuenter Roeck return snprintf(buf, PAGE_SIZE, "%lld\n", value); 2396700ce03SGuenter Roeck } 2406700ce03SGuenter Roeck 2416700ce03SGuenter Roeck static ssize_t ltc2945_set_value(struct device *dev, 2426700ce03SGuenter Roeck struct device_attribute *da, 2436700ce03SGuenter Roeck const char *buf, size_t count) 2446700ce03SGuenter Roeck { 2456700ce03SGuenter Roeck struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 2466700ce03SGuenter Roeck struct regmap *regmap = dev_get_drvdata(dev); 2476700ce03SGuenter Roeck u8 reg = attr->index; 2486700ce03SGuenter Roeck unsigned long val; 2496700ce03SGuenter Roeck u8 regbuf[3]; 2506700ce03SGuenter Roeck int num_regs; 2516700ce03SGuenter Roeck int regval; 2526700ce03SGuenter Roeck int ret; 2536700ce03SGuenter Roeck 2546700ce03SGuenter Roeck ret = kstrtoul(buf, 10, &val); 2556700ce03SGuenter Roeck if (ret) 2566700ce03SGuenter Roeck return ret; 2576700ce03SGuenter Roeck 2586700ce03SGuenter Roeck /* convert to register value, then clamp and write result */ 2596700ce03SGuenter Roeck regval = ltc2945_val_to_reg(dev, reg, val); 2606700ce03SGuenter Roeck if (is_power_reg(reg)) { 2616700ce03SGuenter Roeck regval = clamp_val(regval, 0, 0xffffff); 2626700ce03SGuenter Roeck regbuf[0] = regval >> 16; 2636700ce03SGuenter Roeck regbuf[1] = (regval >> 8) & 0xff; 2646700ce03SGuenter Roeck regbuf[2] = regval; 2656700ce03SGuenter Roeck num_regs = 3; 2666700ce03SGuenter Roeck } else { 2676700ce03SGuenter Roeck regval = clamp_val(regval, 0, 0xfff) << 4; 2686700ce03SGuenter Roeck regbuf[0] = regval >> 8; 2696700ce03SGuenter Roeck regbuf[1] = regval & 0xff; 2706700ce03SGuenter Roeck num_regs = 2; 2716700ce03SGuenter Roeck } 2726700ce03SGuenter Roeck ret = regmap_bulk_write(regmap, reg, regbuf, num_regs); 2736700ce03SGuenter Roeck return ret < 0 ? ret : count; 2746700ce03SGuenter Roeck } 2756700ce03SGuenter Roeck 2766700ce03SGuenter Roeck static ssize_t ltc2945_reset_history(struct device *dev, 2776700ce03SGuenter Roeck struct device_attribute *da, 2786700ce03SGuenter Roeck const char *buf, size_t count) 2796700ce03SGuenter Roeck { 2806700ce03SGuenter Roeck struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 2816700ce03SGuenter Roeck struct regmap *regmap = dev_get_drvdata(dev); 2826700ce03SGuenter Roeck u8 reg = attr->index; 2836700ce03SGuenter Roeck int num_regs = is_power_reg(reg) ? 3 : 2; 2846700ce03SGuenter Roeck u8 buf_min[3] = { 0xff, 0xff, 0xff }; 2856700ce03SGuenter Roeck u8 buf_max[3] = { 0, 0, 0 }; 2866700ce03SGuenter Roeck unsigned long val; 2876700ce03SGuenter Roeck int ret; 2886700ce03SGuenter Roeck 2896700ce03SGuenter Roeck ret = kstrtoul(buf, 10, &val); 2906700ce03SGuenter Roeck if (ret) 2916700ce03SGuenter Roeck return ret; 2926700ce03SGuenter Roeck if (val != 1) 2936700ce03SGuenter Roeck return -EINVAL; 2946700ce03SGuenter Roeck 2956700ce03SGuenter Roeck ret = regmap_update_bits(regmap, LTC2945_CONTROL, CONTROL_TEST_MODE, 2966700ce03SGuenter Roeck CONTROL_TEST_MODE); 2976700ce03SGuenter Roeck 2986700ce03SGuenter Roeck /* Reset minimum */ 2996700ce03SGuenter Roeck ret = regmap_bulk_write(regmap, reg, buf_min, num_regs); 3006700ce03SGuenter Roeck if (ret) 3016700ce03SGuenter Roeck return ret; 3026700ce03SGuenter Roeck 3036700ce03SGuenter Roeck switch (reg) { 3046700ce03SGuenter Roeck case LTC2945_MIN_POWER_H: 3056700ce03SGuenter Roeck reg = LTC2945_MAX_POWER_H; 3066700ce03SGuenter Roeck break; 3076700ce03SGuenter Roeck case LTC2945_MIN_SENSE_H: 3086700ce03SGuenter Roeck reg = LTC2945_MAX_SENSE_H; 3096700ce03SGuenter Roeck break; 3106700ce03SGuenter Roeck case LTC2945_MIN_VIN_H: 3116700ce03SGuenter Roeck reg = LTC2945_MAX_VIN_H; 3126700ce03SGuenter Roeck break; 3136700ce03SGuenter Roeck case LTC2945_MIN_ADIN_H: 3146700ce03SGuenter Roeck reg = LTC2945_MAX_ADIN_H; 3156700ce03SGuenter Roeck break; 3166700ce03SGuenter Roeck default: 317*f75d7230SGuenter Roeck WARN_ONCE(1, "Bad register: 0x%x\n", reg); 318*f75d7230SGuenter Roeck return -EINVAL; 3196700ce03SGuenter Roeck } 3206700ce03SGuenter Roeck /* Reset maximum */ 3216700ce03SGuenter Roeck ret = regmap_bulk_write(regmap, reg, buf_max, num_regs); 3226700ce03SGuenter Roeck 3236700ce03SGuenter Roeck /* Try resetting test mode even if there was an error */ 3246700ce03SGuenter Roeck regmap_update_bits(regmap, LTC2945_CONTROL, CONTROL_TEST_MODE, 0); 3256700ce03SGuenter Roeck 3266700ce03SGuenter Roeck return ret ? : count; 3276700ce03SGuenter Roeck } 3286700ce03SGuenter Roeck 3296700ce03SGuenter Roeck static ssize_t ltc2945_show_bool(struct device *dev, 3306700ce03SGuenter Roeck struct device_attribute *da, char *buf) 3316700ce03SGuenter Roeck { 3326700ce03SGuenter Roeck struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 3336700ce03SGuenter Roeck struct regmap *regmap = dev_get_drvdata(dev); 3346700ce03SGuenter Roeck unsigned int fault; 3356700ce03SGuenter Roeck int ret; 3366700ce03SGuenter Roeck 3376700ce03SGuenter Roeck ret = regmap_read(regmap, LTC2945_FAULT, &fault); 3386700ce03SGuenter Roeck if (ret < 0) 3396700ce03SGuenter Roeck return ret; 3406700ce03SGuenter Roeck 3416700ce03SGuenter Roeck fault &= attr->index; 3426700ce03SGuenter Roeck if (fault) /* Clear reported faults in chip register */ 3436700ce03SGuenter Roeck regmap_update_bits(regmap, LTC2945_FAULT, attr->index, 0); 3446700ce03SGuenter Roeck 3456700ce03SGuenter Roeck return snprintf(buf, PAGE_SIZE, "%d\n", !!fault); 3466700ce03SGuenter Roeck } 3476700ce03SGuenter Roeck 3486700ce03SGuenter Roeck /* Input voltages */ 3496700ce03SGuenter Roeck 3506700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ltc2945_show_value, NULL, 3516700ce03SGuenter Roeck LTC2945_VIN_H); 3526700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(in1_min, S_IRUGO | S_IWUSR, ltc2945_show_value, 3536700ce03SGuenter Roeck ltc2945_set_value, LTC2945_MIN_VIN_THRES_H); 3546700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO | S_IWUSR, ltc2945_show_value, 3556700ce03SGuenter Roeck ltc2945_set_value, LTC2945_MAX_VIN_THRES_H); 3566700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(in1_lowest, S_IRUGO, ltc2945_show_value, NULL, 3576700ce03SGuenter Roeck LTC2945_MIN_VIN_H); 3586700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(in1_highest, S_IRUGO, ltc2945_show_value, NULL, 3596700ce03SGuenter Roeck LTC2945_MAX_VIN_H); 3606700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(in1_reset_history, S_IWUSR, NULL, 3616700ce03SGuenter Roeck ltc2945_reset_history, LTC2945_MIN_VIN_H); 3626700ce03SGuenter Roeck 3636700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, ltc2945_show_value, NULL, 3646700ce03SGuenter Roeck LTC2945_ADIN_H); 3656700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(in2_min, S_IRUGO | S_IWUSR, ltc2945_show_value, 3666700ce03SGuenter Roeck ltc2945_set_value, LTC2945_MIN_ADIN_THRES_H); 3676700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(in2_max, S_IRUGO | S_IWUSR, ltc2945_show_value, 3686700ce03SGuenter Roeck ltc2945_set_value, LTC2945_MAX_ADIN_THRES_H); 3696700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(in2_lowest, S_IRUGO, ltc2945_show_value, NULL, 3706700ce03SGuenter Roeck LTC2945_MIN_ADIN_H); 3716700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(in2_highest, S_IRUGO, ltc2945_show_value, NULL, 3726700ce03SGuenter Roeck LTC2945_MAX_ADIN_H); 3736700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(in2_reset_history, S_IWUSR, NULL, 3746700ce03SGuenter Roeck ltc2945_reset_history, LTC2945_MIN_ADIN_H); 3756700ce03SGuenter Roeck 3766700ce03SGuenter Roeck /* Voltage alarms */ 3776700ce03SGuenter Roeck 3786700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(in1_min_alarm, S_IRUGO, ltc2945_show_bool, NULL, 3796700ce03SGuenter Roeck FAULT_VIN_UV); 3806700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(in1_max_alarm, S_IRUGO, ltc2945_show_bool, NULL, 3816700ce03SGuenter Roeck FAULT_VIN_OV); 3826700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(in2_min_alarm, S_IRUGO, ltc2945_show_bool, NULL, 3836700ce03SGuenter Roeck FAULT_ADIN_UV); 3846700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(in2_max_alarm, S_IRUGO, ltc2945_show_bool, NULL, 3856700ce03SGuenter Roeck FAULT_ADIN_OV); 3866700ce03SGuenter Roeck 3876700ce03SGuenter Roeck /* Currents (via sense resistor) */ 3886700ce03SGuenter Roeck 3896700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc2945_show_value, NULL, 3906700ce03SGuenter Roeck LTC2945_SENSE_H); 3916700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(curr1_min, S_IRUGO | S_IWUSR, ltc2945_show_value, 3926700ce03SGuenter Roeck ltc2945_set_value, LTC2945_MIN_SENSE_THRES_H); 3936700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(curr1_max, S_IRUGO | S_IWUSR, ltc2945_show_value, 3946700ce03SGuenter Roeck ltc2945_set_value, LTC2945_MAX_SENSE_THRES_H); 3956700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(curr1_lowest, S_IRUGO, ltc2945_show_value, NULL, 3966700ce03SGuenter Roeck LTC2945_MIN_SENSE_H); 3976700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(curr1_highest, S_IRUGO, ltc2945_show_value, NULL, 3986700ce03SGuenter Roeck LTC2945_MAX_SENSE_H); 3996700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(curr1_reset_history, S_IWUSR, NULL, 4006700ce03SGuenter Roeck ltc2945_reset_history, LTC2945_MIN_SENSE_H); 4016700ce03SGuenter Roeck 4026700ce03SGuenter Roeck /* Current alarms */ 4036700ce03SGuenter Roeck 4046700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(curr1_min_alarm, S_IRUGO, ltc2945_show_bool, NULL, 4056700ce03SGuenter Roeck FAULT_SENSE_UV); 4066700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(curr1_max_alarm, S_IRUGO, ltc2945_show_bool, NULL, 4076700ce03SGuenter Roeck FAULT_SENSE_OV); 4086700ce03SGuenter Roeck 4096700ce03SGuenter Roeck /* Power */ 4106700ce03SGuenter Roeck 4116700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ltc2945_show_value, NULL, 4126700ce03SGuenter Roeck LTC2945_POWER_H); 4136700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(power1_min, S_IRUGO | S_IWUSR, ltc2945_show_value, 4146700ce03SGuenter Roeck ltc2945_set_value, LTC2945_MIN_POWER_THRES_H); 4156700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(power1_max, S_IRUGO | S_IWUSR, ltc2945_show_value, 4166700ce03SGuenter Roeck ltc2945_set_value, LTC2945_MAX_POWER_THRES_H); 4176700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(power1_input_lowest, S_IRUGO, ltc2945_show_value, 4186700ce03SGuenter Roeck NULL, LTC2945_MIN_POWER_H); 4196700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(power1_input_highest, S_IRUGO, ltc2945_show_value, 4206700ce03SGuenter Roeck NULL, LTC2945_MAX_POWER_H); 4216700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(power1_reset_history, S_IWUSR, NULL, 4226700ce03SGuenter Roeck ltc2945_reset_history, LTC2945_MIN_POWER_H); 4236700ce03SGuenter Roeck 4246700ce03SGuenter Roeck /* Power alarms */ 4256700ce03SGuenter Roeck 4266700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(power1_min_alarm, S_IRUGO, ltc2945_show_bool, NULL, 4276700ce03SGuenter Roeck FAULT_POWER_UV); 4286700ce03SGuenter Roeck static SENSOR_DEVICE_ATTR(power1_max_alarm, S_IRUGO, ltc2945_show_bool, NULL, 4296700ce03SGuenter Roeck FAULT_POWER_OV); 4306700ce03SGuenter Roeck 4316700ce03SGuenter Roeck static struct attribute *ltc2945_attrs[] = { 4326700ce03SGuenter Roeck &sensor_dev_attr_in1_input.dev_attr.attr, 4336700ce03SGuenter Roeck &sensor_dev_attr_in1_min.dev_attr.attr, 4346700ce03SGuenter Roeck &sensor_dev_attr_in1_max.dev_attr.attr, 4356700ce03SGuenter Roeck &sensor_dev_attr_in1_lowest.dev_attr.attr, 4366700ce03SGuenter Roeck &sensor_dev_attr_in1_highest.dev_attr.attr, 4376700ce03SGuenter Roeck &sensor_dev_attr_in1_reset_history.dev_attr.attr, 4386700ce03SGuenter Roeck &sensor_dev_attr_in1_min_alarm.dev_attr.attr, 4396700ce03SGuenter Roeck &sensor_dev_attr_in1_max_alarm.dev_attr.attr, 4406700ce03SGuenter Roeck 4416700ce03SGuenter Roeck &sensor_dev_attr_in2_input.dev_attr.attr, 4426700ce03SGuenter Roeck &sensor_dev_attr_in2_min.dev_attr.attr, 4436700ce03SGuenter Roeck &sensor_dev_attr_in2_max.dev_attr.attr, 4446700ce03SGuenter Roeck &sensor_dev_attr_in2_lowest.dev_attr.attr, 4456700ce03SGuenter Roeck &sensor_dev_attr_in2_highest.dev_attr.attr, 4466700ce03SGuenter Roeck &sensor_dev_attr_in2_reset_history.dev_attr.attr, 4476700ce03SGuenter Roeck &sensor_dev_attr_in2_min_alarm.dev_attr.attr, 4486700ce03SGuenter Roeck &sensor_dev_attr_in2_max_alarm.dev_attr.attr, 4496700ce03SGuenter Roeck 4506700ce03SGuenter Roeck &sensor_dev_attr_curr1_input.dev_attr.attr, 4516700ce03SGuenter Roeck &sensor_dev_attr_curr1_min.dev_attr.attr, 4526700ce03SGuenter Roeck &sensor_dev_attr_curr1_max.dev_attr.attr, 4536700ce03SGuenter Roeck &sensor_dev_attr_curr1_lowest.dev_attr.attr, 4546700ce03SGuenter Roeck &sensor_dev_attr_curr1_highest.dev_attr.attr, 4556700ce03SGuenter Roeck &sensor_dev_attr_curr1_reset_history.dev_attr.attr, 4566700ce03SGuenter Roeck &sensor_dev_attr_curr1_min_alarm.dev_attr.attr, 4576700ce03SGuenter Roeck &sensor_dev_attr_curr1_max_alarm.dev_attr.attr, 4586700ce03SGuenter Roeck 4596700ce03SGuenter Roeck &sensor_dev_attr_power1_input.dev_attr.attr, 4606700ce03SGuenter Roeck &sensor_dev_attr_power1_min.dev_attr.attr, 4616700ce03SGuenter Roeck &sensor_dev_attr_power1_max.dev_attr.attr, 4626700ce03SGuenter Roeck &sensor_dev_attr_power1_input_lowest.dev_attr.attr, 4636700ce03SGuenter Roeck &sensor_dev_attr_power1_input_highest.dev_attr.attr, 4646700ce03SGuenter Roeck &sensor_dev_attr_power1_reset_history.dev_attr.attr, 4656700ce03SGuenter Roeck &sensor_dev_attr_power1_min_alarm.dev_attr.attr, 4666700ce03SGuenter Roeck &sensor_dev_attr_power1_max_alarm.dev_attr.attr, 4676700ce03SGuenter Roeck 4686700ce03SGuenter Roeck NULL, 4696700ce03SGuenter Roeck }; 4706700ce03SGuenter Roeck ATTRIBUTE_GROUPS(ltc2945); 4716700ce03SGuenter Roeck 4726700ce03SGuenter Roeck static struct regmap_config ltc2945_regmap_config = { 4736700ce03SGuenter Roeck .reg_bits = 8, 4746700ce03SGuenter Roeck .val_bits = 8, 4756700ce03SGuenter Roeck .max_register = LTC2945_MIN_ADIN_THRES_L, 4766700ce03SGuenter Roeck }; 4776700ce03SGuenter Roeck 4786700ce03SGuenter Roeck static int ltc2945_probe(struct i2c_client *client, 4796700ce03SGuenter Roeck const struct i2c_device_id *id) 4806700ce03SGuenter Roeck { 4816700ce03SGuenter Roeck struct device *dev = &client->dev; 4826700ce03SGuenter Roeck struct device *hwmon_dev; 4836700ce03SGuenter Roeck struct regmap *regmap; 4846700ce03SGuenter Roeck 4856700ce03SGuenter Roeck regmap = devm_regmap_init_i2c(client, <c2945_regmap_config); 4866700ce03SGuenter Roeck if (IS_ERR(regmap)) { 4876700ce03SGuenter Roeck dev_err(dev, "failed to allocate register map\n"); 4886700ce03SGuenter Roeck return PTR_ERR(regmap); 4896700ce03SGuenter Roeck } 4906700ce03SGuenter Roeck 4916700ce03SGuenter Roeck /* Clear faults */ 4926700ce03SGuenter Roeck regmap_write(regmap, LTC2945_FAULT, 0x00); 4936700ce03SGuenter Roeck 4946700ce03SGuenter Roeck hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, 4956700ce03SGuenter Roeck regmap, 4966700ce03SGuenter Roeck ltc2945_groups); 4976700ce03SGuenter Roeck return PTR_ERR_OR_ZERO(hwmon_dev); 4986700ce03SGuenter Roeck } 4996700ce03SGuenter Roeck 5006700ce03SGuenter Roeck static const struct i2c_device_id ltc2945_id[] = { 5016700ce03SGuenter Roeck {"ltc2945", 0}, 5026700ce03SGuenter Roeck { } 5036700ce03SGuenter Roeck }; 5046700ce03SGuenter Roeck 5056700ce03SGuenter Roeck MODULE_DEVICE_TABLE(i2c, ltc2945_id); 5066700ce03SGuenter Roeck 5076700ce03SGuenter Roeck static struct i2c_driver ltc2945_driver = { 5086700ce03SGuenter Roeck .driver = { 5096700ce03SGuenter Roeck .name = "ltc2945", 5106700ce03SGuenter Roeck }, 5116700ce03SGuenter Roeck .probe = ltc2945_probe, 5126700ce03SGuenter Roeck .id_table = ltc2945_id, 5136700ce03SGuenter Roeck }; 5146700ce03SGuenter Roeck 5156700ce03SGuenter Roeck module_i2c_driver(ltc2945_driver); 5166700ce03SGuenter Roeck 5176700ce03SGuenter Roeck MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); 5186700ce03SGuenter Roeck MODULE_DESCRIPTION("LTC2945 driver"); 5196700ce03SGuenter Roeck MODULE_LICENSE("GPL"); 520