1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 26700ce03SGuenter Roeck /* 36700ce03SGuenter Roeck * Driver for Linear Technology LTC2945 I2C Power Monitor 46700ce03SGuenter Roeck * 56700ce03SGuenter Roeck * Copyright (c) 2014 Guenter Roeck 66700ce03SGuenter Roeck */ 76700ce03SGuenter Roeck 86700ce03SGuenter Roeck #include <linux/kernel.h> 96700ce03SGuenter Roeck #include <linux/module.h> 106700ce03SGuenter Roeck #include <linux/err.h> 116700ce03SGuenter Roeck #include <linux/slab.h> 126700ce03SGuenter Roeck #include <linux/i2c.h> 136700ce03SGuenter Roeck #include <linux/hwmon.h> 146700ce03SGuenter Roeck #include <linux/hwmon-sysfs.h> 156700ce03SGuenter Roeck #include <linux/jiffies.h> 166700ce03SGuenter Roeck #include <linux/regmap.h> 176700ce03SGuenter Roeck 186700ce03SGuenter Roeck /* chip registers */ 196700ce03SGuenter Roeck #define LTC2945_CONTROL 0x00 206700ce03SGuenter Roeck #define LTC2945_ALERT 0x01 216700ce03SGuenter Roeck #define LTC2945_STATUS 0x02 226700ce03SGuenter Roeck #define LTC2945_FAULT 0x03 236700ce03SGuenter Roeck #define LTC2945_POWER_H 0x05 246700ce03SGuenter Roeck #define LTC2945_MAX_POWER_H 0x08 256700ce03SGuenter Roeck #define LTC2945_MIN_POWER_H 0x0b 266700ce03SGuenter Roeck #define LTC2945_MAX_POWER_THRES_H 0x0e 276700ce03SGuenter Roeck #define LTC2945_MIN_POWER_THRES_H 0x11 286700ce03SGuenter Roeck #define LTC2945_SENSE_H 0x14 296700ce03SGuenter Roeck #define LTC2945_MAX_SENSE_H 0x16 306700ce03SGuenter Roeck #define LTC2945_MIN_SENSE_H 0x18 316700ce03SGuenter Roeck #define LTC2945_MAX_SENSE_THRES_H 0x1a 326700ce03SGuenter Roeck #define LTC2945_MIN_SENSE_THRES_H 0x1c 336700ce03SGuenter Roeck #define LTC2945_VIN_H 0x1e 346700ce03SGuenter Roeck #define LTC2945_MAX_VIN_H 0x20 356700ce03SGuenter Roeck #define LTC2945_MIN_VIN_H 0x22 366700ce03SGuenter Roeck #define LTC2945_MAX_VIN_THRES_H 0x24 376700ce03SGuenter Roeck #define LTC2945_MIN_VIN_THRES_H 0x26 386700ce03SGuenter Roeck #define LTC2945_ADIN_H 0x28 396700ce03SGuenter Roeck #define LTC2945_MAX_ADIN_H 0x2a 406700ce03SGuenter Roeck #define LTC2945_MIN_ADIN_H 0x2c 416700ce03SGuenter Roeck #define LTC2945_MAX_ADIN_THRES_H 0x2e 426700ce03SGuenter Roeck #define LTC2945_MIN_ADIN_THRES_H 0x30 436700ce03SGuenter Roeck #define LTC2945_MIN_ADIN_THRES_L 0x31 446700ce03SGuenter Roeck 456700ce03SGuenter Roeck /* Fault register bits */ 466700ce03SGuenter Roeck 476700ce03SGuenter Roeck #define FAULT_ADIN_UV (1 << 0) 486700ce03SGuenter Roeck #define FAULT_ADIN_OV (1 << 1) 496700ce03SGuenter Roeck #define FAULT_VIN_UV (1 << 2) 506700ce03SGuenter Roeck #define FAULT_VIN_OV (1 << 3) 516700ce03SGuenter Roeck #define FAULT_SENSE_UV (1 << 4) 526700ce03SGuenter Roeck #define FAULT_SENSE_OV (1 << 5) 536700ce03SGuenter Roeck #define FAULT_POWER_UV (1 << 6) 546700ce03SGuenter Roeck #define FAULT_POWER_OV (1 << 7) 556700ce03SGuenter Roeck 566700ce03SGuenter Roeck /* Control register bits */ 576700ce03SGuenter Roeck 586700ce03SGuenter Roeck #define CONTROL_MULT_SELECT (1 << 0) 596700ce03SGuenter Roeck #define CONTROL_TEST_MODE (1 << 4) 606700ce03SGuenter Roeck 614b0654e2SJonathan Cormier static const struct of_device_id __maybe_unused ltc2945_of_match[] = { 624b0654e2SJonathan Cormier { .compatible = "adi,ltc2945" }, 634b0654e2SJonathan Cormier { } 644b0654e2SJonathan Cormier }; 654b0654e2SJonathan Cormier MODULE_DEVICE_TABLE(of, ltc2945_of_match); 664b0654e2SJonathan Cormier 67*b11f3d47SJohn Pruitt /** 68*b11f3d47SJohn Pruitt * struct ltc2945_data - LTC2945 device data 69*b11f3d47SJohn Pruitt * @regmap: regmap device 70*b11f3d47SJohn Pruitt * @shunt_resistor: shunt resistor value in micro ohms (1000 by default) 71*b11f3d47SJohn Pruitt */ 72*b11f3d47SJohn Pruitt struct ltc2945_data { 73*b11f3d47SJohn Pruitt struct regmap *regmap; 74*b11f3d47SJohn Pruitt u32 shunt_resistor; 75*b11f3d47SJohn Pruitt }; 76*b11f3d47SJohn Pruitt 776700ce03SGuenter Roeck static inline bool is_power_reg(u8 reg) 786700ce03SGuenter Roeck { 796700ce03SGuenter Roeck return reg < LTC2945_SENSE_H; 806700ce03SGuenter Roeck } 816700ce03SGuenter Roeck 826700ce03SGuenter Roeck /* Return the value from the given register in uW, mV, or mA */ 836700ce03SGuenter Roeck static long long ltc2945_reg_to_val(struct device *dev, u8 reg) 846700ce03SGuenter Roeck { 85*b11f3d47SJohn Pruitt struct ltc2945_data *data = dev_get_drvdata(dev); 86*b11f3d47SJohn Pruitt struct regmap *regmap = data->regmap; 87*b11f3d47SJohn Pruitt u32 shunt_resistor = data->shunt_resistor; 886700ce03SGuenter Roeck unsigned int control; 896700ce03SGuenter Roeck u8 buf[3]; 906700ce03SGuenter Roeck long long val; 916700ce03SGuenter Roeck int ret; 926700ce03SGuenter Roeck 936700ce03SGuenter Roeck ret = regmap_bulk_read(regmap, reg, buf, 946700ce03SGuenter Roeck is_power_reg(reg) ? 3 : 2); 956700ce03SGuenter Roeck if (ret < 0) 966700ce03SGuenter Roeck return ret; 976700ce03SGuenter Roeck 986700ce03SGuenter Roeck if (is_power_reg(reg)) { 99*b11f3d47SJohn Pruitt /* 24-bit power */ 1006700ce03SGuenter Roeck val = (buf[0] << 16) + (buf[1] << 8) + buf[2]; 1016700ce03SGuenter Roeck } else { 102*b11f3d47SJohn Pruitt /* 12-bit current, voltage */ 1036700ce03SGuenter Roeck val = (buf[0] << 4) + (buf[1] >> 4); 1046700ce03SGuenter Roeck } 1056700ce03SGuenter Roeck 1066700ce03SGuenter Roeck switch (reg) { 1076700ce03SGuenter Roeck case LTC2945_POWER_H: 1086700ce03SGuenter Roeck case LTC2945_MAX_POWER_H: 1096700ce03SGuenter Roeck case LTC2945_MIN_POWER_H: 1106700ce03SGuenter Roeck case LTC2945_MAX_POWER_THRES_H: 1116700ce03SGuenter Roeck case LTC2945_MIN_POWER_THRES_H: 1126700ce03SGuenter Roeck /* 113*b11f3d47SJohn Pruitt * Convert to uW 1146700ce03SGuenter Roeck * Control register bit 0 selects if voltage at SENSE+/VDD 1156700ce03SGuenter Roeck * or voltage at ADIN is used to measure power. 1166700ce03SGuenter Roeck */ 1176700ce03SGuenter Roeck ret = regmap_read(regmap, LTC2945_CONTROL, &control); 1186700ce03SGuenter Roeck if (ret < 0) 1196700ce03SGuenter Roeck return ret; 1206700ce03SGuenter Roeck if (control & CONTROL_MULT_SELECT) { 1216700ce03SGuenter Roeck /* 25 mV * 25 uV = 0.625 uV resolution. */ 1226700ce03SGuenter Roeck val *= 625LL; 1236700ce03SGuenter Roeck } else { 1246700ce03SGuenter Roeck /* 0.5 mV * 25 uV = 0.0125 uV resolution. */ 1256700ce03SGuenter Roeck val = (val * 25LL) >> 1; 1266700ce03SGuenter Roeck } 127*b11f3d47SJohn Pruitt val *= 1000; 128*b11f3d47SJohn Pruitt /* Overflow check: Assuming max 24-bit power, val is at most 53 bits right now. */ 129*b11f3d47SJohn Pruitt val = DIV_ROUND_CLOSEST_ULL(val, shunt_resistor); 130*b11f3d47SJohn Pruitt /* 131*b11f3d47SJohn Pruitt * Overflow check: After division, depending on shunt resistor, 132*b11f3d47SJohn Pruitt * val can still be > 32 bits so returning long long makes sense 133*b11f3d47SJohn Pruitt */ 134*b11f3d47SJohn Pruitt 1356700ce03SGuenter Roeck break; 1366700ce03SGuenter Roeck case LTC2945_VIN_H: 1376700ce03SGuenter Roeck case LTC2945_MAX_VIN_H: 1386700ce03SGuenter Roeck case LTC2945_MIN_VIN_H: 1396700ce03SGuenter Roeck case LTC2945_MAX_VIN_THRES_H: 1406700ce03SGuenter Roeck case LTC2945_MIN_VIN_THRES_H: 1416700ce03SGuenter Roeck /* 25 mV resolution. Convert to mV. */ 1426700ce03SGuenter Roeck val *= 25; 1436700ce03SGuenter Roeck break; 1446700ce03SGuenter Roeck case LTC2945_ADIN_H: 1456700ce03SGuenter Roeck case LTC2945_MAX_ADIN_H: 1466700ce03SGuenter Roeck case LTC2945_MIN_ADIN_THRES_H: 1476700ce03SGuenter Roeck case LTC2945_MAX_ADIN_THRES_H: 1486700ce03SGuenter Roeck case LTC2945_MIN_ADIN_H: 1496700ce03SGuenter Roeck /* 0.5mV resolution. Convert to mV. */ 1506700ce03SGuenter Roeck val = val >> 1; 1516700ce03SGuenter Roeck break; 1526700ce03SGuenter Roeck case LTC2945_SENSE_H: 1536700ce03SGuenter Roeck case LTC2945_MAX_SENSE_H: 1546700ce03SGuenter Roeck case LTC2945_MIN_SENSE_H: 1556700ce03SGuenter Roeck case LTC2945_MAX_SENSE_THRES_H: 1566700ce03SGuenter Roeck case LTC2945_MIN_SENSE_THRES_H: 157*b11f3d47SJohn Pruitt /* 25 uV resolution. Convert to mA. */ 158*b11f3d47SJohn Pruitt val *= 25 * 1000; 159*b11f3d47SJohn Pruitt /* Overflow check: Assuming max 12-bit sense, val is at most 27 bits right now */ 160*b11f3d47SJohn Pruitt val = DIV_ROUND_CLOSEST_ULL(val, shunt_resistor); 161*b11f3d47SJohn Pruitt /* Overflow check: After division, <= 27 bits */ 1626700ce03SGuenter Roeck break; 1636700ce03SGuenter Roeck default: 1646700ce03SGuenter Roeck return -EINVAL; 1656700ce03SGuenter Roeck } 1666700ce03SGuenter Roeck return val; 1676700ce03SGuenter Roeck } 1686700ce03SGuenter Roeck 169*b11f3d47SJohn Pruitt static long long ltc2945_val_to_reg(struct device *dev, u8 reg, 170*b11f3d47SJohn Pruitt unsigned long long val) 1716700ce03SGuenter Roeck { 172*b11f3d47SJohn Pruitt struct ltc2945_data *data = dev_get_drvdata(dev); 173*b11f3d47SJohn Pruitt struct regmap *regmap = data->regmap; 174*b11f3d47SJohn Pruitt u32 shunt_resistor = data->shunt_resistor; 1756700ce03SGuenter Roeck unsigned int control; 1766700ce03SGuenter Roeck int ret; 1776700ce03SGuenter Roeck 178*b11f3d47SJohn Pruitt /* Ensure we don't overflow */ 179*b11f3d47SJohn Pruitt val = clamp_val(val, 0, U32_MAX); 180*b11f3d47SJohn Pruitt 1816700ce03SGuenter Roeck switch (reg) { 1826700ce03SGuenter Roeck case LTC2945_POWER_H: 1836700ce03SGuenter Roeck case LTC2945_MAX_POWER_H: 1846700ce03SGuenter Roeck case LTC2945_MIN_POWER_H: 1856700ce03SGuenter Roeck case LTC2945_MAX_POWER_THRES_H: 1866700ce03SGuenter Roeck case LTC2945_MIN_POWER_THRES_H: 1876700ce03SGuenter Roeck /* 1886700ce03SGuenter Roeck * Control register bit 0 selects if voltage at SENSE+/VDD 1896700ce03SGuenter Roeck * or voltage at ADIN is used to measure power, which in turn 1906700ce03SGuenter Roeck * determines register calculations. 1916700ce03SGuenter Roeck */ 1926700ce03SGuenter Roeck ret = regmap_read(regmap, LTC2945_CONTROL, &control); 1936700ce03SGuenter Roeck if (ret < 0) 1946700ce03SGuenter Roeck return ret; 1956700ce03SGuenter Roeck if (control & CONTROL_MULT_SELECT) { 1966700ce03SGuenter Roeck /* 25 mV * 25 uV = 0.625 uV resolution. */ 197*b11f3d47SJohn Pruitt val *= shunt_resistor; 198*b11f3d47SJohn Pruitt /* Overflow check: Assuming 32-bit val and shunt resistor, val <= 64bits */ 199*b11f3d47SJohn Pruitt val = DIV_ROUND_CLOSEST_ULL(val, 625 * 1000); 200*b11f3d47SJohn Pruitt /* Overflow check: val is now <= 44 bits */ 2016700ce03SGuenter Roeck } else { 202*b11f3d47SJohn Pruitt /* 0.5 mV * 25 uV = 0.0125 uV resolution. */ 203*b11f3d47SJohn Pruitt val *= shunt_resistor; 204*b11f3d47SJohn Pruitt /* Overflow check: Assuming 32-bit val and shunt resistor, val <= 64bits */ 205*b11f3d47SJohn Pruitt val = DIV_ROUND_CLOSEST_ULL(val, 25 * 1000) * 2; 206*b11f3d47SJohn Pruitt /* Overflow check: val is now <= 51 bits */ 2076700ce03SGuenter Roeck } 2086700ce03SGuenter Roeck break; 2096700ce03SGuenter Roeck case LTC2945_VIN_H: 2106700ce03SGuenter Roeck case LTC2945_MAX_VIN_H: 2116700ce03SGuenter Roeck case LTC2945_MIN_VIN_H: 2126700ce03SGuenter Roeck case LTC2945_MAX_VIN_THRES_H: 2136700ce03SGuenter Roeck case LTC2945_MIN_VIN_THRES_H: 2146700ce03SGuenter Roeck /* 25 mV resolution. */ 215*b11f3d47SJohn Pruitt val = DIV_ROUND_CLOSEST_ULL(val, 25); 2166700ce03SGuenter Roeck break; 2176700ce03SGuenter Roeck case LTC2945_ADIN_H: 2186700ce03SGuenter Roeck case LTC2945_MAX_ADIN_H: 2196700ce03SGuenter Roeck case LTC2945_MIN_ADIN_THRES_H: 2206700ce03SGuenter Roeck case LTC2945_MAX_ADIN_THRES_H: 2216700ce03SGuenter Roeck case LTC2945_MIN_ADIN_H: 2226700ce03SGuenter Roeck /* 0.5mV resolution. */ 2236700ce03SGuenter Roeck val *= 2; 2246700ce03SGuenter Roeck break; 2256700ce03SGuenter Roeck case LTC2945_SENSE_H: 2266700ce03SGuenter Roeck case LTC2945_MAX_SENSE_H: 2276700ce03SGuenter Roeck case LTC2945_MIN_SENSE_H: 2286700ce03SGuenter Roeck case LTC2945_MAX_SENSE_THRES_H: 2296700ce03SGuenter Roeck case LTC2945_MIN_SENSE_THRES_H: 230*b11f3d47SJohn Pruitt /* 25 uV resolution. Convert to mA. */ 231*b11f3d47SJohn Pruitt val *= shunt_resistor; 232*b11f3d47SJohn Pruitt /* Overflow check: Assuming 32-bit val and 32-bit shunt resistor, val is 64bits */ 233*b11f3d47SJohn Pruitt val = DIV_ROUND_CLOSEST_ULL(val, 25 * 1000); 234*b11f3d47SJohn Pruitt /* Overflow check: val is now <= 50 bits */ 2356700ce03SGuenter Roeck break; 2366700ce03SGuenter Roeck default: 2376700ce03SGuenter Roeck return -EINVAL; 2386700ce03SGuenter Roeck } 2396700ce03SGuenter Roeck return val; 2406700ce03SGuenter Roeck } 2416700ce03SGuenter Roeck 2425614e26dSGuenter Roeck static ssize_t ltc2945_value_show(struct device *dev, 2436700ce03SGuenter Roeck struct device_attribute *da, char *buf) 2446700ce03SGuenter Roeck { 2456700ce03SGuenter Roeck struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 2466700ce03SGuenter Roeck long long value; 2476700ce03SGuenter Roeck 2486700ce03SGuenter Roeck value = ltc2945_reg_to_val(dev, attr->index); 2496700ce03SGuenter Roeck if (value < 0) 2506700ce03SGuenter Roeck return value; 2511f4d4af4SGuenter Roeck return sysfs_emit(buf, "%lld\n", value); 2526700ce03SGuenter Roeck } 2536700ce03SGuenter Roeck 2545614e26dSGuenter Roeck static ssize_t ltc2945_value_store(struct device *dev, 2556700ce03SGuenter Roeck struct device_attribute *da, 2566700ce03SGuenter Roeck const char *buf, size_t count) 2576700ce03SGuenter Roeck { 2586700ce03SGuenter Roeck struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 259*b11f3d47SJohn Pruitt struct ltc2945_data *data = dev_get_drvdata(dev); 260*b11f3d47SJohn Pruitt struct regmap *regmap = data->regmap; 2616700ce03SGuenter Roeck u8 reg = attr->index; 262*b11f3d47SJohn Pruitt unsigned int val; 2636700ce03SGuenter Roeck u8 regbuf[3]; 2646700ce03SGuenter Roeck int num_regs; 265*b11f3d47SJohn Pruitt long long regval; 2666700ce03SGuenter Roeck int ret; 2676700ce03SGuenter Roeck 268*b11f3d47SJohn Pruitt ret = kstrtouint(buf, 10, &val); 2696700ce03SGuenter Roeck if (ret) 2706700ce03SGuenter Roeck return ret; 2716700ce03SGuenter Roeck 2726700ce03SGuenter Roeck /* convert to register value, then clamp and write result */ 2736700ce03SGuenter Roeck regval = ltc2945_val_to_reg(dev, reg, val); 274178b01ecSJonathan Cormier if (regval < 0) 275178b01ecSJonathan Cormier return regval; 2766700ce03SGuenter Roeck if (is_power_reg(reg)) { 2776700ce03SGuenter Roeck regval = clamp_val(regval, 0, 0xffffff); 2786700ce03SGuenter Roeck regbuf[0] = regval >> 16; 2796700ce03SGuenter Roeck regbuf[1] = (regval >> 8) & 0xff; 2806700ce03SGuenter Roeck regbuf[2] = regval; 2816700ce03SGuenter Roeck num_regs = 3; 2826700ce03SGuenter Roeck } else { 2836700ce03SGuenter Roeck regval = clamp_val(regval, 0, 0xfff) << 4; 2846700ce03SGuenter Roeck regbuf[0] = regval >> 8; 2856700ce03SGuenter Roeck regbuf[1] = regval & 0xff; 2866700ce03SGuenter Roeck num_regs = 2; 2876700ce03SGuenter Roeck } 2886700ce03SGuenter Roeck ret = regmap_bulk_write(regmap, reg, regbuf, num_regs); 2896700ce03SGuenter Roeck return ret < 0 ? ret : count; 2906700ce03SGuenter Roeck } 2916700ce03SGuenter Roeck 2925614e26dSGuenter Roeck static ssize_t ltc2945_history_store(struct device *dev, 2936700ce03SGuenter Roeck struct device_attribute *da, 2946700ce03SGuenter Roeck const char *buf, size_t count) 2956700ce03SGuenter Roeck { 2966700ce03SGuenter Roeck struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 297*b11f3d47SJohn Pruitt struct ltc2945_data *data = dev_get_drvdata(dev); 298*b11f3d47SJohn Pruitt struct regmap *regmap = data->regmap; 2996700ce03SGuenter Roeck u8 reg = attr->index; 3006700ce03SGuenter Roeck int num_regs = is_power_reg(reg) ? 3 : 2; 3016700ce03SGuenter Roeck u8 buf_min[3] = { 0xff, 0xff, 0xff }; 3026700ce03SGuenter Roeck u8 buf_max[3] = { 0, 0, 0 }; 3036700ce03SGuenter Roeck unsigned long val; 3046700ce03SGuenter Roeck int ret; 3056700ce03SGuenter Roeck 3066700ce03SGuenter Roeck ret = kstrtoul(buf, 10, &val); 3076700ce03SGuenter Roeck if (ret) 3086700ce03SGuenter Roeck return ret; 3096700ce03SGuenter Roeck if (val != 1) 3106700ce03SGuenter Roeck return -EINVAL; 3116700ce03SGuenter Roeck 3126700ce03SGuenter Roeck ret = regmap_update_bits(regmap, LTC2945_CONTROL, CONTROL_TEST_MODE, 3136700ce03SGuenter Roeck CONTROL_TEST_MODE); 3146700ce03SGuenter Roeck 3156700ce03SGuenter Roeck /* Reset minimum */ 3166700ce03SGuenter Roeck ret = regmap_bulk_write(regmap, reg, buf_min, num_regs); 3176700ce03SGuenter Roeck if (ret) 3186700ce03SGuenter Roeck return ret; 3196700ce03SGuenter Roeck 3206700ce03SGuenter Roeck switch (reg) { 3216700ce03SGuenter Roeck case LTC2945_MIN_POWER_H: 3226700ce03SGuenter Roeck reg = LTC2945_MAX_POWER_H; 3236700ce03SGuenter Roeck break; 3246700ce03SGuenter Roeck case LTC2945_MIN_SENSE_H: 3256700ce03SGuenter Roeck reg = LTC2945_MAX_SENSE_H; 3266700ce03SGuenter Roeck break; 3276700ce03SGuenter Roeck case LTC2945_MIN_VIN_H: 3286700ce03SGuenter Roeck reg = LTC2945_MAX_VIN_H; 3296700ce03SGuenter Roeck break; 3306700ce03SGuenter Roeck case LTC2945_MIN_ADIN_H: 3316700ce03SGuenter Roeck reg = LTC2945_MAX_ADIN_H; 3326700ce03SGuenter Roeck break; 3336700ce03SGuenter Roeck default: 334f75d7230SGuenter Roeck WARN_ONCE(1, "Bad register: 0x%x\n", reg); 335f75d7230SGuenter Roeck return -EINVAL; 3366700ce03SGuenter Roeck } 3376700ce03SGuenter Roeck /* Reset maximum */ 3386700ce03SGuenter Roeck ret = regmap_bulk_write(regmap, reg, buf_max, num_regs); 3396700ce03SGuenter Roeck 3406700ce03SGuenter Roeck /* Try resetting test mode even if there was an error */ 3416700ce03SGuenter Roeck regmap_update_bits(regmap, LTC2945_CONTROL, CONTROL_TEST_MODE, 0); 3426700ce03SGuenter Roeck 3436700ce03SGuenter Roeck return ret ? : count; 3446700ce03SGuenter Roeck } 3456700ce03SGuenter Roeck 3465614e26dSGuenter Roeck static ssize_t ltc2945_bool_show(struct device *dev, 3476700ce03SGuenter Roeck struct device_attribute *da, char *buf) 3486700ce03SGuenter Roeck { 3496700ce03SGuenter Roeck struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 350*b11f3d47SJohn Pruitt struct ltc2945_data *data = dev_get_drvdata(dev); 351*b11f3d47SJohn Pruitt struct regmap *regmap = data->regmap; 3526700ce03SGuenter Roeck unsigned int fault; 3536700ce03SGuenter Roeck int ret; 3546700ce03SGuenter Roeck 3556700ce03SGuenter Roeck ret = regmap_read(regmap, LTC2945_FAULT, &fault); 3566700ce03SGuenter Roeck if (ret < 0) 3576700ce03SGuenter Roeck return ret; 3586700ce03SGuenter Roeck 3596700ce03SGuenter Roeck fault &= attr->index; 3606700ce03SGuenter Roeck if (fault) /* Clear reported faults in chip register */ 3616700ce03SGuenter Roeck regmap_update_bits(regmap, LTC2945_FAULT, attr->index, 0); 3626700ce03SGuenter Roeck 3631f4d4af4SGuenter Roeck return sysfs_emit(buf, "%d\n", !!fault); 3646700ce03SGuenter Roeck } 3656700ce03SGuenter Roeck 3666700ce03SGuenter Roeck /* Input voltages */ 3676700ce03SGuenter Roeck 3685614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in1_input, ltc2945_value, LTC2945_VIN_H); 3695614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RW(in1_min, ltc2945_value, LTC2945_MIN_VIN_THRES_H); 3705614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RW(in1_max, ltc2945_value, LTC2945_MAX_VIN_THRES_H); 3715614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in1_lowest, ltc2945_value, LTC2945_MIN_VIN_H); 3725614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in1_highest, ltc2945_value, LTC2945_MAX_VIN_H); 3735614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_WO(in1_reset_history, ltc2945_history, 3746700ce03SGuenter Roeck LTC2945_MIN_VIN_H); 3756700ce03SGuenter Roeck 3765614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in2_input, ltc2945_value, LTC2945_ADIN_H); 3775614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RW(in2_min, ltc2945_value, LTC2945_MIN_ADIN_THRES_H); 3785614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RW(in2_max, ltc2945_value, LTC2945_MAX_ADIN_THRES_H); 3795614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in2_lowest, ltc2945_value, LTC2945_MIN_ADIN_H); 3805614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in2_highest, ltc2945_value, LTC2945_MAX_ADIN_H); 3815614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_WO(in2_reset_history, ltc2945_history, 3826700ce03SGuenter Roeck LTC2945_MIN_ADIN_H); 3836700ce03SGuenter Roeck 3846700ce03SGuenter Roeck /* Voltage alarms */ 3856700ce03SGuenter Roeck 3865614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in1_min_alarm, ltc2945_bool, FAULT_VIN_UV); 3875614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in1_max_alarm, ltc2945_bool, FAULT_VIN_OV); 3885614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in2_min_alarm, ltc2945_bool, FAULT_ADIN_UV); 3895614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(in2_max_alarm, ltc2945_bool, FAULT_ADIN_OV); 3906700ce03SGuenter Roeck 3916700ce03SGuenter Roeck /* Currents (via sense resistor) */ 3926700ce03SGuenter Roeck 3935614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(curr1_input, ltc2945_value, LTC2945_SENSE_H); 3945614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RW(curr1_min, ltc2945_value, 3955614e26dSGuenter Roeck LTC2945_MIN_SENSE_THRES_H); 3965614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RW(curr1_max, ltc2945_value, 3975614e26dSGuenter Roeck LTC2945_MAX_SENSE_THRES_H); 3985614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(curr1_lowest, ltc2945_value, LTC2945_MIN_SENSE_H); 3995614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(curr1_highest, ltc2945_value, 4006700ce03SGuenter Roeck LTC2945_MAX_SENSE_H); 4015614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_WO(curr1_reset_history, ltc2945_history, 4025614e26dSGuenter Roeck LTC2945_MIN_SENSE_H); 4036700ce03SGuenter Roeck 4046700ce03SGuenter Roeck /* Current alarms */ 4056700ce03SGuenter Roeck 4065614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(curr1_min_alarm, ltc2945_bool, FAULT_SENSE_UV); 4075614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(curr1_max_alarm, ltc2945_bool, FAULT_SENSE_OV); 4086700ce03SGuenter Roeck 4096700ce03SGuenter Roeck /* Power */ 4106700ce03SGuenter Roeck 4115614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(power1_input, ltc2945_value, LTC2945_POWER_H); 4125614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RW(power1_min, ltc2945_value, 4135614e26dSGuenter Roeck LTC2945_MIN_POWER_THRES_H); 4145614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RW(power1_max, ltc2945_value, 4155614e26dSGuenter Roeck LTC2945_MAX_POWER_THRES_H); 4165614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(power1_input_lowest, ltc2945_value, 4175614e26dSGuenter Roeck LTC2945_MIN_POWER_H); 4185614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(power1_input_highest, ltc2945_value, 4195614e26dSGuenter Roeck LTC2945_MAX_POWER_H); 4205614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_WO(power1_reset_history, ltc2945_history, 4215614e26dSGuenter Roeck LTC2945_MIN_POWER_H); 4226700ce03SGuenter Roeck 4236700ce03SGuenter Roeck /* Power alarms */ 4246700ce03SGuenter Roeck 4255614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(power1_min_alarm, ltc2945_bool, FAULT_POWER_UV); 4265614e26dSGuenter Roeck static SENSOR_DEVICE_ATTR_RO(power1_max_alarm, ltc2945_bool, FAULT_POWER_OV); 4276700ce03SGuenter Roeck 4286700ce03SGuenter Roeck static struct attribute *ltc2945_attrs[] = { 4296700ce03SGuenter Roeck &sensor_dev_attr_in1_input.dev_attr.attr, 4306700ce03SGuenter Roeck &sensor_dev_attr_in1_min.dev_attr.attr, 4316700ce03SGuenter Roeck &sensor_dev_attr_in1_max.dev_attr.attr, 4326700ce03SGuenter Roeck &sensor_dev_attr_in1_lowest.dev_attr.attr, 4336700ce03SGuenter Roeck &sensor_dev_attr_in1_highest.dev_attr.attr, 4346700ce03SGuenter Roeck &sensor_dev_attr_in1_reset_history.dev_attr.attr, 4356700ce03SGuenter Roeck &sensor_dev_attr_in1_min_alarm.dev_attr.attr, 4366700ce03SGuenter Roeck &sensor_dev_attr_in1_max_alarm.dev_attr.attr, 4376700ce03SGuenter Roeck 4386700ce03SGuenter Roeck &sensor_dev_attr_in2_input.dev_attr.attr, 4396700ce03SGuenter Roeck &sensor_dev_attr_in2_min.dev_attr.attr, 4406700ce03SGuenter Roeck &sensor_dev_attr_in2_max.dev_attr.attr, 4416700ce03SGuenter Roeck &sensor_dev_attr_in2_lowest.dev_attr.attr, 4426700ce03SGuenter Roeck &sensor_dev_attr_in2_highest.dev_attr.attr, 4436700ce03SGuenter Roeck &sensor_dev_attr_in2_reset_history.dev_attr.attr, 4446700ce03SGuenter Roeck &sensor_dev_attr_in2_min_alarm.dev_attr.attr, 4456700ce03SGuenter Roeck &sensor_dev_attr_in2_max_alarm.dev_attr.attr, 4466700ce03SGuenter Roeck 4476700ce03SGuenter Roeck &sensor_dev_attr_curr1_input.dev_attr.attr, 4486700ce03SGuenter Roeck &sensor_dev_attr_curr1_min.dev_attr.attr, 4496700ce03SGuenter Roeck &sensor_dev_attr_curr1_max.dev_attr.attr, 4506700ce03SGuenter Roeck &sensor_dev_attr_curr1_lowest.dev_attr.attr, 4516700ce03SGuenter Roeck &sensor_dev_attr_curr1_highest.dev_attr.attr, 4526700ce03SGuenter Roeck &sensor_dev_attr_curr1_reset_history.dev_attr.attr, 4536700ce03SGuenter Roeck &sensor_dev_attr_curr1_min_alarm.dev_attr.attr, 4546700ce03SGuenter Roeck &sensor_dev_attr_curr1_max_alarm.dev_attr.attr, 4556700ce03SGuenter Roeck 4566700ce03SGuenter Roeck &sensor_dev_attr_power1_input.dev_attr.attr, 4576700ce03SGuenter Roeck &sensor_dev_attr_power1_min.dev_attr.attr, 4586700ce03SGuenter Roeck &sensor_dev_attr_power1_max.dev_attr.attr, 4596700ce03SGuenter Roeck &sensor_dev_attr_power1_input_lowest.dev_attr.attr, 4606700ce03SGuenter Roeck &sensor_dev_attr_power1_input_highest.dev_attr.attr, 4616700ce03SGuenter Roeck &sensor_dev_attr_power1_reset_history.dev_attr.attr, 4626700ce03SGuenter Roeck &sensor_dev_attr_power1_min_alarm.dev_attr.attr, 4636700ce03SGuenter Roeck &sensor_dev_attr_power1_max_alarm.dev_attr.attr, 4646700ce03SGuenter Roeck 4656700ce03SGuenter Roeck NULL, 4666700ce03SGuenter Roeck }; 4676700ce03SGuenter Roeck ATTRIBUTE_GROUPS(ltc2945); 4686700ce03SGuenter Roeck 469034b44b4SAxel Lin static const struct regmap_config ltc2945_regmap_config = { 4706700ce03SGuenter Roeck .reg_bits = 8, 4716700ce03SGuenter Roeck .val_bits = 8, 4726700ce03SGuenter Roeck .max_register = LTC2945_MIN_ADIN_THRES_L, 4736700ce03SGuenter Roeck }; 4746700ce03SGuenter Roeck 47567487038SStephen Kitt static int ltc2945_probe(struct i2c_client *client) 4766700ce03SGuenter Roeck { 4776700ce03SGuenter Roeck struct device *dev = &client->dev; 4786700ce03SGuenter Roeck struct device *hwmon_dev; 4796700ce03SGuenter Roeck struct regmap *regmap; 480*b11f3d47SJohn Pruitt struct ltc2945_data *data; 481*b11f3d47SJohn Pruitt 482*b11f3d47SJohn Pruitt data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 483*b11f3d47SJohn Pruitt if (!data) 484*b11f3d47SJohn Pruitt return -ENOMEM; 485*b11f3d47SJohn Pruitt dev_set_drvdata(dev, data); 4866700ce03SGuenter Roeck 4876700ce03SGuenter Roeck regmap = devm_regmap_init_i2c(client, <c2945_regmap_config); 4886700ce03SGuenter Roeck if (IS_ERR(regmap)) { 4896700ce03SGuenter Roeck dev_err(dev, "failed to allocate register map\n"); 4906700ce03SGuenter Roeck return PTR_ERR(regmap); 4916700ce03SGuenter Roeck } 4926700ce03SGuenter Roeck 493*b11f3d47SJohn Pruitt data->regmap = regmap; 494*b11f3d47SJohn Pruitt if (device_property_read_u32(dev, "shunt-resistor-micro-ohms", 495*b11f3d47SJohn Pruitt &data->shunt_resistor)) 496*b11f3d47SJohn Pruitt data->shunt_resistor = 1000; 497*b11f3d47SJohn Pruitt 498*b11f3d47SJohn Pruitt if (data->shunt_resistor == 0) 499*b11f3d47SJohn Pruitt return -EINVAL; 500*b11f3d47SJohn Pruitt 5016700ce03SGuenter Roeck /* Clear faults */ 5026700ce03SGuenter Roeck regmap_write(regmap, LTC2945_FAULT, 0x00); 5036700ce03SGuenter Roeck 5046700ce03SGuenter Roeck hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, 505*b11f3d47SJohn Pruitt data, 5066700ce03SGuenter Roeck ltc2945_groups); 5076700ce03SGuenter Roeck return PTR_ERR_OR_ZERO(hwmon_dev); 5086700ce03SGuenter Roeck } 5096700ce03SGuenter Roeck 5106700ce03SGuenter Roeck static const struct i2c_device_id ltc2945_id[] = { 5116700ce03SGuenter Roeck {"ltc2945", 0}, 5126700ce03SGuenter Roeck { } 5136700ce03SGuenter Roeck }; 5146700ce03SGuenter Roeck 5156700ce03SGuenter Roeck MODULE_DEVICE_TABLE(i2c, ltc2945_id); 5166700ce03SGuenter Roeck 5176700ce03SGuenter Roeck static struct i2c_driver ltc2945_driver = { 5186700ce03SGuenter Roeck .driver = { 5196700ce03SGuenter Roeck .name = "ltc2945", 5204b0654e2SJonathan Cormier .of_match_table = of_match_ptr(ltc2945_of_match), 5216700ce03SGuenter Roeck }, 52267487038SStephen Kitt .probe_new = ltc2945_probe, 5236700ce03SGuenter Roeck .id_table = ltc2945_id, 5246700ce03SGuenter Roeck }; 5256700ce03SGuenter Roeck 5266700ce03SGuenter Roeck module_i2c_driver(ltc2945_driver); 5276700ce03SGuenter Roeck 5286700ce03SGuenter Roeck MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); 5296700ce03SGuenter Roeck MODULE_DESCRIPTION("LTC2945 driver"); 5306700ce03SGuenter Roeck MODULE_LICENSE("GPL"); 531