Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hwmon: Add support for ltc2947

The ltc2947 is a high precision power and energy monitor with an
internal sense resistor supporting up to +/- 30A. Three internal no
Latency ADCs ensure accurate measurement of voltage and current, while
high-bandwidth analog multiplication of voltage and current provides
accurate power measurement in a wide range of applications. Internal or
external clocking options enable precise charge and energy measurements.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
Link: https://lore.kernel.org/r/20191021154115.319073-1-nuno.sa@analog.com
[groeck: Removed unnecessary checks when reading temperature and energy;
PAGE{0,1} -> LTC2947_PAGE_{0,1}]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>

authored by

Nuno Sá and committed by
Guenter Roeck
9f90fd65 2057bdfb

+1435
+1
Documentation/hwmon/index.rst
··· 90 90 lm95245 91 91 lochnagar 92 92 ltc2945 93 + ltc2947 93 94 ltc2978 94 95 ltc2990 95 96 ltc3815
+100
Documentation/hwmon/ltc2947.rst
··· 1 + Kernel drivers ltc2947-i2c and ltc2947-spi 2 + ========================================== 3 + 4 + Supported chips: 5 + 6 + * Analog Devices LTC2947 7 + 8 + Prefix: 'ltc2947' 9 + 10 + Addresses scanned: - 11 + 12 + Datasheet: 13 + 14 + https://www.analog.com/media/en/technical-documentation/data-sheets/LTC2947.pdf 15 + 16 + Author: Nuno Sá <nuno.sa@analog.com> 17 + 18 + Description 19 + ___________ 20 + 21 + The LTC2947 is a high precision power and energy monitor that measures current, 22 + voltage, power, temperature, charge and energy. The device supports both SPI 23 + and I2C depending on the chip configuration. 24 + The device also measures accumulated quantities as energy. It has two banks of 25 + register's to read/set energy related values. These banks can be configured 26 + independently to have setups like: energy1 accumulates always and enrgy2 only 27 + accumulates if current is positive (to check battery charging efficiency for 28 + example). The device also supports a GPIO pin that can be configured as output 29 + to control a fan as a function of measured temperature. Then, the GPIO becomes 30 + active as soon as a temperature reading is higher than a defined threshold. The 31 + temp2 channel is used to control this thresholds and to read the respective 32 + alarms. 33 + 34 + Sysfs entries 35 + _____________ 36 + 37 + The following attributes are supported. Limits are read-write, reset_history 38 + is write-only and all the other attributes are read-only. 39 + 40 + ======================= ========================================== 41 + in0_input VP-VM voltage (mV). 42 + in0_min Undervoltage threshold 43 + in0_max Overvoltage threshold 44 + in0_lowest Lowest measured voltage 45 + in0_highest Highest measured voltage 46 + in0_reset_history Write 1 to reset in1 history 47 + in0_min_alarm Undervoltage alarm 48 + in0_max_alarm Overvoltage alarm 49 + in0_label Channel label (VP-VM) 50 + 51 + in1_input DVCC voltage (mV) 52 + in1_min Undervoltage threshold 53 + in1_max Overvoltage threshold 54 + in1_lowest Lowest measured voltage 55 + in1_highest Highest measured voltage 56 + in1_reset_history Write 1 to reset in2 history 57 + in1_min_alarm Undervoltage alarm 58 + in1_max_alarm Overvoltage alarm 59 + in1_label Channel label (DVCC) 60 + 61 + curr1_input IP-IM Sense current (mA) 62 + curr1_min Undercurrent threshold 63 + curr1_max Overcurrent threshold 64 + curr1_lowest Lowest measured current 65 + curr1_highest Highest measured current 66 + curr1_reset_history Write 1 to reset curr1 history 67 + curr1_min_alarm Undercurrent alarm 68 + curr1_max_alarm Overcurrent alarm 69 + curr1_label Channel label (IP-IM) 70 + 71 + power1_input Power (in uW) 72 + power1_min Low power threshold 73 + power1_max High power threshold 74 + power1_input_lowest Historical minimum power use 75 + power1_input_highest Historical maximum power use 76 + power1_reset_history Write 1 to reset power1 history 77 + power1_min_alarm Low power alarm 78 + power1_max_alarm High power alarm 79 + power1_label Channel label (Power) 80 + 81 + temp1_input Chip Temperature (in milliC) 82 + temp1_min Low temperature threshold 83 + temp1_max High temperature threshold 84 + temp1_input_lowest Historical minimum temperature use 85 + temp1_input_highest Historical maximum temperature use 86 + temp1_reset_history Write 1 to reset temp1 history 87 + temp1_min_alarm Low temperature alarm 88 + temp1_max_alarm High temperature alarm 89 + temp1_label Channel label (Ambient) 90 + 91 + temp2_min Low temperature threshold for fan control 92 + temp2_max High temperature threshold for fan control 93 + temp2_min_alarm Low temperature fan control alarm 94 + temp2_max_alarm High temperature fan control alarm 95 + temp2_label Channel label (TEMPFAN) 96 + 97 + energy1_input Measured energy over time (in microJoule) 98 + 99 + energy2_input Measured energy over time (in microJoule) 100 + ======================= ==========================================
+10
MAINTAINERS
··· 9630 9630 F: Documentation/hwmon/ltc4261.rst 9631 9631 F: drivers/hwmon/ltc4261.c 9632 9632 9633 + LTC2947 HARDWARE MONITOR DRIVER 9634 + M: Nuno Sá <nuno.sa@analog.com> 9635 + W: http://ez.analog.com/community/linux-device-drivers 9636 + L: linux-hwmon@vger.kernel.org 9637 + S: Supported 9638 + F: drivers/hwmon/ltc2947-core.c 9639 + F: drivers/hwmon/ltc2947-spi.c 9640 + F: drivers/hwmon/ltc2947-i2c.c 9641 + F: drivers/hwmon/ltc2947.h 9642 + 9633 9643 LTC4306 I2C MULTIPLEXER DRIVER 9634 9644 M: Michael Hennerich <michael.hennerich@analog.com> 9635 9645 W: http://ez.analog.com/community/linux-device-drivers
+27
drivers/hwmon/Kconfig
··· 726 726 This driver can also be built as a module. If so, the module will 727 727 be called ltc2945. 728 728 729 + config SENSORS_LTC2947 730 + tristate 731 + 732 + config SENSORS_LTC2947_I2C 733 + tristate "Analog Devices LTC2947 High Precision Power and Energy Monitor over I2C" 734 + depends on I2C 735 + select REGMAP_I2C 736 + select SENSORS_LTC2947 737 + help 738 + If you say yes here you get support for Linear Technology LTC2947 739 + I2C High Precision Power and Energy Monitor 740 + 741 + This driver can also be built as a module. If so, the module will 742 + be called ltc2947-i2c. 743 + 744 + config SENSORS_LTC2947_SPI 745 + tristate "Analog Devices LTC2947 High Precision Power and Energy Monitor over SPI" 746 + depends on SPI_MASTER 747 + select REGMAP_SPI 748 + select SENSORS_LTC2947 749 + help 750 + If you say yes here you get support for Linear Technology LTC2947 751 + SPI High Precision Power and Energy Monitor 752 + 753 + This driver can also be built as a module. If so, the module will 754 + be called ltc2947-spi. 755 + 729 756 config SENSORS_LTC2990 730 757 tristate "Linear Technology LTC2990" 731 758 depends on I2C
+3
drivers/hwmon/Makefile
··· 106 106 obj-$(CONFIG_SENSORS_LM95241) += lm95241.o 107 107 obj-$(CONFIG_SENSORS_LM95245) += lm95245.o 108 108 obj-$(CONFIG_SENSORS_LTC2945) += ltc2945.o 109 + obj-$(CONFIG_SENSORS_LTC2947) += ltc2947-core.o 110 + obj-$(CONFIG_SENSORS_LTC2947_I2C) += ltc2947-i2c.o 111 + obj-$(CONFIG_SENSORS_LTC2947_SPI) += ltc2947-spi.o 109 112 obj-$(CONFIG_SENSORS_LTC2990) += ltc2990.o 110 113 obj-$(CONFIG_SENSORS_LTC4151) += ltc4151.o 111 114 obj-$(CONFIG_SENSORS_LTC4215) += ltc4215.o
+1183
drivers/hwmon/ltc2947-core.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Analog Devices LTC2947 high precision power and energy monitor 4 + * 5 + * Copyright 2019 Analog Devices Inc. 6 + */ 7 + #include <linux/bitfield.h> 8 + #include <linux/bits.h> 9 + #include <linux/clk.h> 10 + #include <linux/device.h> 11 + #include <linux/hwmon.h> 12 + #include <linux/hwmon-sysfs.h> 13 + #include <linux/module.h> 14 + #include <linux/of.h> 15 + #include <linux/regmap.h> 16 + 17 + #include "ltc2947.h" 18 + 19 + /* register's */ 20 + #define LTC2947_REG_PAGE_CTRL 0xFF 21 + #define LTC2947_REG_CTRL 0xF0 22 + #define LTC2947_REG_TBCTL 0xE9 23 + #define LTC2947_CONT_MODE_MASK BIT(3) 24 + #define LTC2947_CONT_MODE(x) FIELD_PREP(LTC2947_CONT_MODE_MASK, x) 25 + #define LTC2947_PRE_MASK GENMASK(2, 0) 26 + #define LTC2947_PRE(x) FIELD_PREP(LTC2947_PRE_MASK, x) 27 + #define LTC2947_DIV_MASK GENMASK(7, 3) 28 + #define LTC2947_DIV(x) FIELD_PREP(LTC2947_DIV_MASK, x) 29 + #define LTC2947_SHUTDOWN_MASK BIT(0) 30 + #define LTC2947_REG_ACCUM_POL 0xE1 31 + #define LTC2947_ACCUM_POL_1_MASK GENMASK(1, 0) 32 + #define LTC2947_ACCUM_POL_1(x) FIELD_PREP(LTC2947_ACCUM_POL_1_MASK, x) 33 + #define LTC2947_ACCUM_POL_2_MASK GENMASK(3, 2) 34 + #define LTC2947_ACCUM_POL_2(x) FIELD_PREP(LTC2947_ACCUM_POL_2_MASK, x) 35 + #define LTC2947_REG_ACCUM_DEADBAND 0xE4 36 + #define LTC2947_REG_GPIOSTATCTL 0x67 37 + #define LTC2947_GPIO_EN_MASK BIT(0) 38 + #define LTC2947_GPIO_EN(x) FIELD_PREP(LTC2947_GPIO_EN_MASK, x) 39 + #define LTC2947_GPIO_FAN_EN_MASK BIT(6) 40 + #define LTC2947_GPIO_FAN_EN(x) FIELD_PREP(LTC2947_GPIO_FAN_EN_MASK, x) 41 + #define LTC2947_GPIO_FAN_POL_MASK BIT(7) 42 + #define LTC2947_GPIO_FAN_POL(x) FIELD_PREP(LTC2947_GPIO_FAN_POL_MASK, x) 43 + #define LTC2947_REG_GPIO_ACCUM 0xE3 44 + /* 200Khz */ 45 + #define LTC2947_CLK_MIN 200000 46 + /* 25Mhz */ 47 + #define LTC2947_CLK_MAX 25000000 48 + #define LTC2947_PAGE0 0 49 + #define LTC2947_PAGE1 1 50 + /* Voltage registers */ 51 + #define LTC2947_REG_VOLTAGE 0xA0 52 + #define LTC2947_REG_VOLTAGE_MAX 0x50 53 + #define LTC2947_REG_VOLTAGE_MIN 0x52 54 + #define LTC2947_REG_VOLTAGE_THRE_H 0x90 55 + #define LTC2947_REG_VOLTAGE_THRE_L 0x92 56 + #define LTC2947_REG_DVCC 0xA4 57 + #define LTC2947_REG_DVCC_MAX 0x58 58 + #define LTC2947_REG_DVCC_MIN 0x5A 59 + #define LTC2947_REG_DVCC_THRE_H 0x98 60 + #define LTC2947_REG_DVCC_THRE_L 0x9A 61 + #define LTC2947_VOLTAGE_GEN_CHAN 0 62 + #define LTC2947_VOLTAGE_DVCC_CHAN 1 63 + /* in mV */ 64 + #define VOLTAGE_MAX 15500 65 + #define VOLTAGE_MIN -300 66 + #define VDVCC_MAX 15000 67 + #define VDVCC_MIN 4750 68 + /* Current registers */ 69 + #define LTC2947_REG_CURRENT 0x90 70 + #define LTC2947_REG_CURRENT_MAX 0x40 71 + #define LTC2947_REG_CURRENT_MIN 0x42 72 + #define LTC2947_REG_CURRENT_THRE_H 0x80 73 + #define LTC2947_REG_CURRENT_THRE_L 0x82 74 + /* in mA */ 75 + #define CURRENT_MAX 30000 76 + #define CURRENT_MIN -30000 77 + /* Power registers */ 78 + #define LTC2947_REG_POWER 0x93 79 + #define LTC2947_REG_POWER_MAX 0x44 80 + #define LTC2947_REG_POWER_MIN 0x46 81 + #define LTC2947_REG_POWER_THRE_H 0x84 82 + #define LTC2947_REG_POWER_THRE_L 0x86 83 + /* in uW */ 84 + #define POWER_MAX 450000000 85 + #define POWER_MIN -450000000 86 + /* Temperature registers */ 87 + #define LTC2947_REG_TEMP 0xA2 88 + #define LTC2947_REG_TEMP_MAX 0x54 89 + #define LTC2947_REG_TEMP_MIN 0x56 90 + #define LTC2947_REG_TEMP_THRE_H 0x94 91 + #define LTC2947_REG_TEMP_THRE_L 0x96 92 + #define LTC2947_REG_TEMP_FAN_THRE_H 0x9C 93 + #define LTC2947_REG_TEMP_FAN_THRE_L 0x9E 94 + #define LTC2947_TEMP_FAN_CHAN 1 95 + /* in millidegress Celsius */ 96 + #define TEMP_MAX 85000 97 + #define TEMP_MIN -40000 98 + /* Energy registers */ 99 + #define LTC2947_REG_ENERGY1 0x06 100 + #define LTC2947_REG_ENERGY2 0x16 101 + /* Status/Alarm/Overflow registers */ 102 + #define LTC2947_REG_STATUS 0x80 103 + #define LTC2947_REG_STATVT 0x81 104 + #define LTC2947_REG_STATIP 0x82 105 + #define LTC2947_REG_STATVDVCC 0x87 106 + 107 + #define LTC2947_ALERTS_SIZE (LTC2947_REG_STATVDVCC - LTC2947_REG_STATUS) 108 + #define LTC2947_MAX_VOLTAGE_MASK BIT(0) 109 + #define LTC2947_MIN_VOLTAGE_MASK BIT(1) 110 + #define LTC2947_MAX_CURRENT_MASK BIT(0) 111 + #define LTC2947_MIN_CURRENT_MASK BIT(1) 112 + #define LTC2947_MAX_POWER_MASK BIT(2) 113 + #define LTC2947_MIN_POWER_MASK BIT(3) 114 + #define LTC2947_MAX_TEMP_MASK BIT(2) 115 + #define LTC2947_MIN_TEMP_MASK BIT(3) 116 + #define LTC2947_MAX_TEMP_FAN_MASK BIT(4) 117 + #define LTC2947_MIN_TEMP_FAN_MASK BIT(5) 118 + 119 + struct ltc2947_data { 120 + struct regmap *map; 121 + struct device *dev; 122 + /* 123 + * The mutex is needed because the device has 2 memory pages. When 124 + * reading/writing the correct page needs to be set so that, the 125 + * complete sequence select_page->read/write needs to be protected. 126 + */ 127 + struct mutex lock; 128 + u32 lsb_energy; 129 + bool gpio_out; 130 + }; 131 + 132 + static int __ltc2947_val_read16(const struct ltc2947_data *st, const u8 reg, 133 + u64 *val) 134 + { 135 + __be16 __val = 0; 136 + int ret; 137 + 138 + ret = regmap_bulk_read(st->map, reg, &__val, 2); 139 + if (ret) 140 + return ret; 141 + 142 + *val = be16_to_cpu(__val); 143 + 144 + return 0; 145 + } 146 + 147 + static int __ltc2947_val_read24(const struct ltc2947_data *st, const u8 reg, 148 + u64 *val) 149 + { 150 + __be32 __val = 0; 151 + int ret; 152 + 153 + ret = regmap_bulk_read(st->map, reg, &__val, 3); 154 + if (ret) 155 + return ret; 156 + 157 + *val = be32_to_cpu(__val) >> 8; 158 + 159 + return 0; 160 + } 161 + 162 + static int __ltc2947_val_read64(const struct ltc2947_data *st, const u8 reg, 163 + u64 *val) 164 + { 165 + __be64 __val = 0; 166 + int ret; 167 + 168 + ret = regmap_bulk_read(st->map, reg, &__val, 6); 169 + if (ret) 170 + return ret; 171 + 172 + *val = be64_to_cpu(__val) >> 16; 173 + 174 + return 0; 175 + } 176 + 177 + static int ltc2947_val_read(struct ltc2947_data *st, const u8 reg, 178 + const u8 page, const size_t size, s64 *val) 179 + { 180 + int ret; 181 + u64 __val = 0; 182 + 183 + mutex_lock(&st->lock); 184 + 185 + ret = regmap_write(st->map, LTC2947_REG_PAGE_CTRL, page); 186 + if (ret) { 187 + mutex_unlock(&st->lock); 188 + return ret; 189 + } 190 + 191 + dev_dbg(st->dev, "Read val, reg:%02X, p:%d sz:%zu\n", reg, page, 192 + size); 193 + 194 + switch (size) { 195 + case 2: 196 + ret = __ltc2947_val_read16(st, reg, &__val); 197 + break; 198 + case 3: 199 + ret = __ltc2947_val_read24(st, reg, &__val); 200 + break; 201 + case 6: 202 + ret = __ltc2947_val_read64(st, reg, &__val); 203 + break; 204 + default: 205 + ret = -EINVAL; 206 + break; 207 + } 208 + 209 + mutex_unlock(&st->lock); 210 + 211 + if (ret) 212 + return ret; 213 + 214 + *val = sign_extend64(__val, (8 * size) - 1); 215 + 216 + dev_dbg(st->dev, "Got s:%lld, u:%016llX\n", *val, __val); 217 + 218 + return 0; 219 + } 220 + 221 + static int __ltc2947_val_write64(const struct ltc2947_data *st, const u8 reg, 222 + const u64 val) 223 + { 224 + __be64 __val; 225 + 226 + __val = cpu_to_be64(val << 16); 227 + return regmap_bulk_write(st->map, reg, &__val, 6); 228 + } 229 + 230 + static int __ltc2947_val_write16(const struct ltc2947_data *st, const u8 reg, 231 + const u16 val) 232 + { 233 + __be16 __val; 234 + 235 + __val = cpu_to_be16(val); 236 + return regmap_bulk_write(st->map, reg, &__val, 2); 237 + } 238 + 239 + static int ltc2947_val_write(struct ltc2947_data *st, const u8 reg, 240 + const u8 page, const size_t size, const u64 val) 241 + { 242 + int ret; 243 + 244 + mutex_lock(&st->lock); 245 + /* set device on correct page */ 246 + ret = regmap_write(st->map, LTC2947_REG_PAGE_CTRL, page); 247 + if (ret) { 248 + mutex_unlock(&st->lock); 249 + return ret; 250 + } 251 + 252 + dev_dbg(st->dev, "Write val, r:%02X, p:%d, sz:%zu, val:%016llX\n", 253 + reg, page, size, val); 254 + 255 + switch (size) { 256 + case 2: 257 + ret = __ltc2947_val_write16(st, reg, val); 258 + break; 259 + case 6: 260 + ret = __ltc2947_val_write64(st, reg, val); 261 + break; 262 + default: 263 + ret = -EINVAL; 264 + break; 265 + } 266 + 267 + mutex_unlock(&st->lock); 268 + 269 + return ret; 270 + } 271 + 272 + static int ltc2947_reset_history(struct ltc2947_data *st, const u8 reg_h, 273 + const u8 reg_l) 274 + { 275 + int ret; 276 + /* 277 + * let's reset the tracking register's. Tracking register's have all 278 + * 2 bytes size 279 + */ 280 + ret = ltc2947_val_write(st, reg_h, LTC2947_PAGE0, 2, 0x8000U); 281 + if (ret) 282 + return ret; 283 + 284 + return ltc2947_val_write(st, reg_l, LTC2947_PAGE0, 2, 0x7FFFU); 285 + } 286 + 287 + static int ltc2947_alarm_read(struct ltc2947_data *st, const u8 reg, 288 + const u32 mask, long *val) 289 + { 290 + u8 offset = reg - LTC2947_REG_STATUS; 291 + /* +1 to include status reg */ 292 + char alarms[LTC2947_ALERTS_SIZE + 1]; 293 + int ret = 0; 294 + 295 + memset(alarms, 0, sizeof(alarms)); 296 + 297 + mutex_lock(&st->lock); 298 + 299 + ret = regmap_write(st->map, LTC2947_REG_PAGE_CTRL, LTC2947_PAGE0); 300 + if (ret) 301 + goto unlock; 302 + 303 + dev_dbg(st->dev, "Read alarm, reg:%02X, mask:%02X\n", reg, mask); 304 + /* 305 + * As stated in the datasheet, when Threshold and Overflow registers 306 + * are used, the status and all alert registers must be read in one 307 + * multi-byte transaction. 308 + */ 309 + ret = regmap_bulk_read(st->map, LTC2947_REG_STATUS, alarms, 310 + sizeof(alarms)); 311 + if (ret) 312 + goto unlock; 313 + 314 + /* get the alarm */ 315 + *val = !!(alarms[offset] & mask); 316 + unlock: 317 + mutex_unlock(&st->lock); 318 + return ret; 319 + } 320 + 321 + static ssize_t ltc2947_show_value(struct device *dev, 322 + struct device_attribute *da, char *buf) 323 + { 324 + struct ltc2947_data *st = dev_get_drvdata(dev); 325 + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 326 + int ret; 327 + s64 val = 0; 328 + 329 + ret = ltc2947_val_read(st, attr->index, LTC2947_PAGE0, 6, &val); 330 + if (ret) 331 + return ret; 332 + 333 + /* value in microJoule. st->lsb_energy was multiplied by 10E9 */ 334 + val = div_s64(val * st->lsb_energy, 1000); 335 + 336 + return sprintf(buf, "%lld\n", val); 337 + } 338 + 339 + static int ltc2947_read_temp(struct device *dev, const u32 attr, long *val, 340 + const int channel) 341 + { 342 + int ret; 343 + struct ltc2947_data *st = dev_get_drvdata(dev); 344 + s64 __val = 0; 345 + 346 + switch (attr) { 347 + case hwmon_temp_input: 348 + ret = ltc2947_val_read(st, LTC2947_REG_TEMP, LTC2947_PAGE0, 349 + 2, &__val); 350 + break; 351 + case hwmon_temp_highest: 352 + ret = ltc2947_val_read(st, LTC2947_REG_TEMP_MAX, LTC2947_PAGE0, 353 + 2, &__val); 354 + break; 355 + case hwmon_temp_lowest: 356 + ret = ltc2947_val_read(st, LTC2947_REG_TEMP_MIN, LTC2947_PAGE0, 357 + 2, &__val); 358 + break; 359 + case hwmon_temp_max_alarm: 360 + if (channel == LTC2947_TEMP_FAN_CHAN) 361 + return ltc2947_alarm_read(st, LTC2947_REG_STATVT, 362 + LTC2947_MAX_TEMP_FAN_MASK, 363 + val); 364 + 365 + return ltc2947_alarm_read(st, LTC2947_REG_STATVT, 366 + LTC2947_MAX_TEMP_MASK, val); 367 + case hwmon_temp_min_alarm: 368 + if (channel == LTC2947_TEMP_FAN_CHAN) 369 + return ltc2947_alarm_read(st, LTC2947_REG_STATVT, 370 + LTC2947_MIN_TEMP_FAN_MASK, 371 + val); 372 + 373 + return ltc2947_alarm_read(st, LTC2947_REG_STATVT, 374 + LTC2947_MIN_TEMP_MASK, val); 375 + case hwmon_temp_max: 376 + if (channel == LTC2947_TEMP_FAN_CHAN) 377 + ret = ltc2947_val_read(st, LTC2947_REG_TEMP_FAN_THRE_H, 378 + LTC2947_PAGE1, 2, &__val); 379 + else 380 + ret = ltc2947_val_read(st, LTC2947_REG_TEMP_THRE_H, 381 + LTC2947_PAGE1, 2, &__val); 382 + break; 383 + case hwmon_temp_min: 384 + if (channel == LTC2947_TEMP_FAN_CHAN) 385 + ret = ltc2947_val_read(st, LTC2947_REG_TEMP_FAN_THRE_L, 386 + LTC2947_PAGE1, 2, &__val); 387 + else 388 + ret = ltc2947_val_read(st, LTC2947_REG_TEMP_THRE_L, 389 + LTC2947_PAGE1, 2, &__val); 390 + break; 391 + default: 392 + return -ENOTSUPP; 393 + } 394 + 395 + if (ret) 396 + return ret; 397 + 398 + /* in milidegrees celcius, temp is given by: */ 399 + *val = (__val * 204) + 550; 400 + 401 + return 0; 402 + } 403 + 404 + static int ltc2947_read_power(struct device *dev, const u32 attr, long *val) 405 + { 406 + struct ltc2947_data *st = dev_get_drvdata(dev); 407 + int ret; 408 + u32 lsb = 200000; /* in uW */ 409 + s64 __val = 0; 410 + 411 + switch (attr) { 412 + case hwmon_power_input: 413 + ret = ltc2947_val_read(st, LTC2947_REG_POWER, LTC2947_PAGE0, 414 + 3, &__val); 415 + lsb = 50000; 416 + break; 417 + case hwmon_power_input_highest: 418 + ret = ltc2947_val_read(st, LTC2947_REG_POWER_MAX, LTC2947_PAGE0, 419 + 2, &__val); 420 + break; 421 + case hwmon_power_input_lowest: 422 + ret = ltc2947_val_read(st, LTC2947_REG_POWER_MIN, LTC2947_PAGE0, 423 + 2, &__val); 424 + break; 425 + case hwmon_power_max_alarm: 426 + return ltc2947_alarm_read(st, LTC2947_REG_STATIP, 427 + LTC2947_MAX_POWER_MASK, val); 428 + case hwmon_power_min_alarm: 429 + return ltc2947_alarm_read(st, LTC2947_REG_STATIP, 430 + LTC2947_MIN_POWER_MASK, val); 431 + case hwmon_power_max: 432 + ret = ltc2947_val_read(st, LTC2947_REG_POWER_THRE_H, 433 + LTC2947_PAGE1, 2, &__val); 434 + break; 435 + case hwmon_power_min: 436 + ret = ltc2947_val_read(st, LTC2947_REG_POWER_THRE_L, 437 + LTC2947_PAGE1, 2, &__val); 438 + break; 439 + default: 440 + return -ENOTSUPP; 441 + } 442 + 443 + if (ret) 444 + return ret; 445 + 446 + *val = __val * lsb; 447 + 448 + return 0; 449 + } 450 + 451 + static int ltc2947_read_curr(struct device *dev, const u32 attr, long *val) 452 + { 453 + struct ltc2947_data *st = dev_get_drvdata(dev); 454 + int ret; 455 + u8 lsb = 12; /* in mA */ 456 + s64 __val = 0; 457 + 458 + switch (attr) { 459 + case hwmon_curr_input: 460 + ret = ltc2947_val_read(st, LTC2947_REG_CURRENT, 461 + LTC2947_PAGE0, 3, &__val); 462 + lsb = 3; 463 + break; 464 + case hwmon_curr_highest: 465 + ret = ltc2947_val_read(st, LTC2947_REG_CURRENT_MAX, 466 + LTC2947_PAGE0, 2, &__val); 467 + break; 468 + case hwmon_curr_lowest: 469 + ret = ltc2947_val_read(st, LTC2947_REG_CURRENT_MIN, 470 + LTC2947_PAGE0, 2, &__val); 471 + break; 472 + case hwmon_curr_max_alarm: 473 + return ltc2947_alarm_read(st, LTC2947_REG_STATIP, 474 + LTC2947_MAX_CURRENT_MASK, val); 475 + case hwmon_curr_min_alarm: 476 + return ltc2947_alarm_read(st, LTC2947_REG_STATIP, 477 + LTC2947_MIN_CURRENT_MASK, val); 478 + case hwmon_curr_max: 479 + ret = ltc2947_val_read(st, LTC2947_REG_CURRENT_THRE_H, 480 + LTC2947_PAGE1, 2, &__val); 481 + break; 482 + case hwmon_curr_min: 483 + ret = ltc2947_val_read(st, LTC2947_REG_CURRENT_THRE_L, 484 + LTC2947_PAGE1, 2, &__val); 485 + break; 486 + default: 487 + return -ENOTSUPP; 488 + } 489 + 490 + if (ret) 491 + return ret; 492 + 493 + *val = __val * lsb; 494 + 495 + return 0; 496 + } 497 + 498 + static int ltc2947_read_in(struct device *dev, const u32 attr, long *val, 499 + const int channel) 500 + { 501 + struct ltc2947_data *st = dev_get_drvdata(dev); 502 + int ret; 503 + u8 lsb = 2; /* in mV */ 504 + s64 __val = 0; 505 + 506 + if (channel < 0 || channel > LTC2947_VOLTAGE_DVCC_CHAN) { 507 + dev_err(st->dev, "Invalid chan%d for voltage", channel); 508 + return -EINVAL; 509 + } 510 + 511 + switch (attr) { 512 + case hwmon_in_input: 513 + if (channel == LTC2947_VOLTAGE_DVCC_CHAN) { 514 + ret = ltc2947_val_read(st, LTC2947_REG_DVCC, 515 + LTC2947_PAGE0, 2, &__val); 516 + lsb = 145; 517 + } else { 518 + ret = ltc2947_val_read(st, LTC2947_REG_VOLTAGE, 519 + LTC2947_PAGE0, 2, &__val); 520 + } 521 + break; 522 + case hwmon_in_highest: 523 + if (channel == LTC2947_VOLTAGE_DVCC_CHAN) { 524 + ret = ltc2947_val_read(st, LTC2947_REG_DVCC_MAX, 525 + LTC2947_PAGE0, 2, &__val); 526 + lsb = 145; 527 + } else { 528 + ret = ltc2947_val_read(st, LTC2947_REG_VOLTAGE_MAX, 529 + LTC2947_PAGE0, 2, &__val); 530 + } 531 + break; 532 + case hwmon_in_lowest: 533 + if (channel == LTC2947_VOLTAGE_DVCC_CHAN) { 534 + ret = ltc2947_val_read(st, LTC2947_REG_DVCC_MIN, 535 + LTC2947_PAGE0, 2, &__val); 536 + lsb = 145; 537 + } else { 538 + ret = ltc2947_val_read(st, LTC2947_REG_VOLTAGE_MIN, 539 + LTC2947_PAGE0, 2, &__val); 540 + } 541 + break; 542 + case hwmon_in_max_alarm: 543 + if (channel == LTC2947_VOLTAGE_DVCC_CHAN) 544 + return ltc2947_alarm_read(st, LTC2947_REG_STATVDVCC, 545 + LTC2947_MAX_VOLTAGE_MASK, 546 + val); 547 + 548 + return ltc2947_alarm_read(st, LTC2947_REG_STATVT, 549 + LTC2947_MAX_VOLTAGE_MASK, val); 550 + case hwmon_in_min_alarm: 551 + if (channel == LTC2947_VOLTAGE_DVCC_CHAN) 552 + return ltc2947_alarm_read(st, LTC2947_REG_STATVDVCC, 553 + LTC2947_MIN_VOLTAGE_MASK, 554 + val); 555 + 556 + return ltc2947_alarm_read(st, LTC2947_REG_STATVT, 557 + LTC2947_MIN_VOLTAGE_MASK, val); 558 + case hwmon_in_max: 559 + if (channel == LTC2947_VOLTAGE_DVCC_CHAN) { 560 + ret = ltc2947_val_read(st, LTC2947_REG_DVCC_THRE_H, 561 + LTC2947_PAGE1, 2, &__val); 562 + lsb = 145; 563 + } else { 564 + ret = ltc2947_val_read(st, LTC2947_REG_VOLTAGE_THRE_H, 565 + LTC2947_PAGE1, 2, &__val); 566 + } 567 + break; 568 + case hwmon_in_min: 569 + if (channel == LTC2947_VOLTAGE_DVCC_CHAN) { 570 + ret = ltc2947_val_read(st, LTC2947_REG_DVCC_THRE_L, 571 + LTC2947_PAGE1, 2, &__val); 572 + lsb = 145; 573 + } else { 574 + ret = ltc2947_val_read(st, LTC2947_REG_VOLTAGE_THRE_L, 575 + LTC2947_PAGE1, 2, &__val); 576 + } 577 + break; 578 + default: 579 + return -ENOTSUPP; 580 + } 581 + 582 + if (ret) 583 + return ret; 584 + 585 + *val = __val * lsb; 586 + 587 + return 0; 588 + } 589 + 590 + static int ltc2947_read(struct device *dev, enum hwmon_sensor_types type, 591 + u32 attr, int channel, long *val) 592 + { 593 + switch (type) { 594 + case hwmon_in: 595 + return ltc2947_read_in(dev, attr, val, channel); 596 + case hwmon_curr: 597 + return ltc2947_read_curr(dev, attr, val); 598 + case hwmon_power: 599 + return ltc2947_read_power(dev, attr, val); 600 + case hwmon_temp: 601 + return ltc2947_read_temp(dev, attr, val, channel); 602 + default: 603 + return -ENOTSUPP; 604 + } 605 + } 606 + 607 + static int ltc2947_write_temp(struct device *dev, const u32 attr, 608 + long val, const int channel) 609 + { 610 + struct ltc2947_data *st = dev_get_drvdata(dev); 611 + 612 + if (channel < 0 || channel > LTC2947_TEMP_FAN_CHAN) { 613 + dev_err(st->dev, "Invalid chan%d for temperature", channel); 614 + return -EINVAL; 615 + } 616 + 617 + switch (attr) { 618 + case hwmon_temp_reset_history: 619 + if (val != 1) 620 + return -EINVAL; 621 + return ltc2947_reset_history(st, LTC2947_REG_TEMP_MAX, 622 + LTC2947_REG_TEMP_MIN); 623 + case hwmon_temp_max: 624 + val = clamp_val(val, TEMP_MIN, TEMP_MAX); 625 + if (channel == LTC2947_TEMP_FAN_CHAN) { 626 + if (!st->gpio_out) 627 + return -ENOTSUPP; 628 + 629 + return ltc2947_val_write(st, 630 + LTC2947_REG_TEMP_FAN_THRE_H, 631 + LTC2947_PAGE1, 2, 632 + DIV_ROUND_CLOSEST(val - 550, 204)); 633 + } 634 + 635 + return ltc2947_val_write(st, LTC2947_REG_TEMP_THRE_H, 636 + LTC2947_PAGE1, 2, 637 + DIV_ROUND_CLOSEST(val - 550, 204)); 638 + case hwmon_temp_min: 639 + val = clamp_val(val, TEMP_MIN, TEMP_MAX); 640 + if (channel == LTC2947_TEMP_FAN_CHAN) { 641 + if (!st->gpio_out) 642 + return -ENOTSUPP; 643 + 644 + return ltc2947_val_write(st, 645 + LTC2947_REG_TEMP_FAN_THRE_L, 646 + LTC2947_PAGE1, 2, 647 + DIV_ROUND_CLOSEST(val - 550, 204)); 648 + } 649 + 650 + return ltc2947_val_write(st, LTC2947_REG_TEMP_THRE_L, 651 + LTC2947_PAGE1, 2, 652 + DIV_ROUND_CLOSEST(val - 550, 204)); 653 + default: 654 + return -ENOTSUPP; 655 + } 656 + } 657 + 658 + static int ltc2947_write_power(struct device *dev, const u32 attr, 659 + long val) 660 + { 661 + struct ltc2947_data *st = dev_get_drvdata(dev); 662 + 663 + switch (attr) { 664 + case hwmon_power_reset_history: 665 + if (val != 1) 666 + return -EINVAL; 667 + return ltc2947_reset_history(st, LTC2947_REG_POWER_MAX, 668 + LTC2947_REG_POWER_MIN); 669 + case hwmon_power_max: 670 + val = clamp_val(val, POWER_MIN, POWER_MAX); 671 + return ltc2947_val_write(st, LTC2947_REG_POWER_THRE_H, 672 + LTC2947_PAGE1, 2, 673 + DIV_ROUND_CLOSEST(val, 200000)); 674 + case hwmon_power_min: 675 + val = clamp_val(val, POWER_MIN, POWER_MAX); 676 + return ltc2947_val_write(st, LTC2947_REG_POWER_THRE_L, 677 + LTC2947_PAGE1, 2, 678 + DIV_ROUND_CLOSEST(val, 200000)); 679 + default: 680 + return -ENOTSUPP; 681 + } 682 + } 683 + 684 + static int ltc2947_write_curr(struct device *dev, const u32 attr, 685 + long val) 686 + { 687 + struct ltc2947_data *st = dev_get_drvdata(dev); 688 + 689 + switch (attr) { 690 + case hwmon_curr_reset_history: 691 + if (val != 1) 692 + return -EINVAL; 693 + return ltc2947_reset_history(st, LTC2947_REG_CURRENT_MAX, 694 + LTC2947_REG_CURRENT_MIN); 695 + case hwmon_curr_max: 696 + val = clamp_val(val, CURRENT_MIN, CURRENT_MAX); 697 + return ltc2947_val_write(st, LTC2947_REG_CURRENT_THRE_H, 698 + LTC2947_PAGE1, 2, 699 + DIV_ROUND_CLOSEST(val, 12)); 700 + case hwmon_curr_min: 701 + val = clamp_val(val, CURRENT_MIN, CURRENT_MAX); 702 + return ltc2947_val_write(st, LTC2947_REG_CURRENT_THRE_L, 703 + LTC2947_PAGE1, 2, 704 + DIV_ROUND_CLOSEST(val, 12)); 705 + default: 706 + return -ENOTSUPP; 707 + } 708 + } 709 + 710 + static int ltc2947_write_in(struct device *dev, const u32 attr, long val, 711 + const int channel) 712 + { 713 + struct ltc2947_data *st = dev_get_drvdata(dev); 714 + 715 + if (channel > LTC2947_VOLTAGE_DVCC_CHAN) { 716 + dev_err(st->dev, "Invalid chan%d for voltage", channel); 717 + return -EINVAL; 718 + } 719 + 720 + switch (attr) { 721 + case hwmon_in_reset_history: 722 + if (val != 1) 723 + return -EINVAL; 724 + 725 + if (channel == LTC2947_VOLTAGE_DVCC_CHAN) 726 + return ltc2947_reset_history(st, LTC2947_REG_DVCC_MAX, 727 + LTC2947_REG_DVCC_MIN); 728 + 729 + return ltc2947_reset_history(st, LTC2947_REG_VOLTAGE_MAX, 730 + LTC2947_REG_VOLTAGE_MIN); 731 + case hwmon_in_max: 732 + if (channel == LTC2947_VOLTAGE_DVCC_CHAN) { 733 + val = clamp_val(val, VDVCC_MIN, VDVCC_MAX); 734 + return ltc2947_val_write(st, LTC2947_REG_DVCC_THRE_H, 735 + LTC2947_PAGE1, 2, 736 + DIV_ROUND_CLOSEST(val, 145)); 737 + } 738 + 739 + val = clamp_val(val, VOLTAGE_MIN, VOLTAGE_MAX); 740 + return ltc2947_val_write(st, LTC2947_REG_VOLTAGE_THRE_H, 741 + LTC2947_PAGE1, 2, 742 + DIV_ROUND_CLOSEST(val, 2)); 743 + case hwmon_in_min: 744 + if (channel == LTC2947_VOLTAGE_DVCC_CHAN) { 745 + val = clamp_val(val, VDVCC_MIN, VDVCC_MAX); 746 + return ltc2947_val_write(st, LTC2947_REG_DVCC_THRE_L, 747 + LTC2947_PAGE1, 2, 748 + DIV_ROUND_CLOSEST(val, 145)); 749 + } 750 + 751 + val = clamp_val(val, VOLTAGE_MIN, VOLTAGE_MAX); 752 + return ltc2947_val_write(st, LTC2947_REG_VOLTAGE_THRE_L, 753 + LTC2947_PAGE1, 2, 754 + DIV_ROUND_CLOSEST(val, 2)); 755 + default: 756 + return -ENOTSUPP; 757 + } 758 + } 759 + 760 + static int ltc2947_write(struct device *dev, 761 + enum hwmon_sensor_types type, 762 + u32 attr, int channel, long val) 763 + { 764 + switch (type) { 765 + case hwmon_in: 766 + return ltc2947_write_in(dev, attr, val, channel); 767 + case hwmon_curr: 768 + return ltc2947_write_curr(dev, attr, val); 769 + case hwmon_power: 770 + return ltc2947_write_power(dev, attr, val); 771 + case hwmon_temp: 772 + return ltc2947_write_temp(dev, attr, val, channel); 773 + default: 774 + return -ENOTSUPP; 775 + } 776 + } 777 + 778 + static int ltc2947_read_labels(struct device *dev, 779 + enum hwmon_sensor_types type, 780 + u32 attr, int channel, const char **str) 781 + { 782 + switch (type) { 783 + case hwmon_in: 784 + if (channel == LTC2947_VOLTAGE_DVCC_CHAN) 785 + *str = "DVCC"; 786 + else 787 + *str = "VP-VM"; 788 + return 0; 789 + case hwmon_curr: 790 + *str = "IP-IM"; 791 + return 0; 792 + case hwmon_temp: 793 + if (channel == LTC2947_TEMP_FAN_CHAN) 794 + *str = "TEMPFAN"; 795 + else 796 + *str = "Ambient"; 797 + return 0; 798 + case hwmon_power: 799 + *str = "Power"; 800 + return 0; 801 + default: 802 + return -ENOTSUPP; 803 + } 804 + } 805 + 806 + static int ltc2947_in_is_visible(const u32 attr) 807 + { 808 + switch (attr) { 809 + case hwmon_in_input: 810 + case hwmon_in_highest: 811 + case hwmon_in_lowest: 812 + case hwmon_in_max_alarm: 813 + case hwmon_in_min_alarm: 814 + case hwmon_in_label: 815 + return 0444; 816 + case hwmon_in_reset_history: 817 + return 0200; 818 + case hwmon_in_max: 819 + case hwmon_in_min: 820 + return 0644; 821 + default: 822 + return 0; 823 + } 824 + } 825 + 826 + static int ltc2947_curr_is_visible(const u32 attr) 827 + { 828 + switch (attr) { 829 + case hwmon_curr_input: 830 + case hwmon_curr_highest: 831 + case hwmon_curr_lowest: 832 + case hwmon_curr_max_alarm: 833 + case hwmon_curr_min_alarm: 834 + case hwmon_curr_label: 835 + return 0444; 836 + case hwmon_curr_reset_history: 837 + return 0200; 838 + case hwmon_curr_max: 839 + case hwmon_curr_min: 840 + return 0644; 841 + default: 842 + return 0; 843 + } 844 + } 845 + 846 + static int ltc2947_power_is_visible(const u32 attr) 847 + { 848 + switch (attr) { 849 + case hwmon_power_input: 850 + case hwmon_power_input_highest: 851 + case hwmon_power_input_lowest: 852 + case hwmon_power_label: 853 + case hwmon_power_max_alarm: 854 + case hwmon_power_min_alarm: 855 + return 0444; 856 + case hwmon_power_reset_history: 857 + return 0200; 858 + case hwmon_power_max: 859 + case hwmon_power_min: 860 + return 0644; 861 + default: 862 + return 0; 863 + } 864 + } 865 + 866 + static int ltc2947_temp_is_visible(const u32 attr) 867 + { 868 + switch (attr) { 869 + case hwmon_temp_input: 870 + case hwmon_temp_highest: 871 + case hwmon_temp_lowest: 872 + case hwmon_temp_max_alarm: 873 + case hwmon_temp_min_alarm: 874 + case hwmon_temp_label: 875 + return 0444; 876 + case hwmon_temp_reset_history: 877 + return 0200; 878 + case hwmon_temp_max: 879 + case hwmon_temp_min: 880 + return 0644; 881 + default: 882 + return 0; 883 + } 884 + } 885 + 886 + static umode_t ltc2947_is_visible(const void *data, 887 + enum hwmon_sensor_types type, 888 + u32 attr, int channel) 889 + { 890 + switch (type) { 891 + case hwmon_in: 892 + return ltc2947_in_is_visible(attr); 893 + case hwmon_curr: 894 + return ltc2947_curr_is_visible(attr); 895 + case hwmon_power: 896 + return ltc2947_power_is_visible(attr); 897 + case hwmon_temp: 898 + return ltc2947_temp_is_visible(attr); 899 + default: 900 + return 0; 901 + } 902 + } 903 + 904 + static const struct hwmon_channel_info *ltc2947_info[] = { 905 + HWMON_CHANNEL_INFO(in, 906 + HWMON_I_INPUT | HWMON_I_LOWEST | HWMON_I_HIGHEST | 907 + HWMON_I_MAX | HWMON_I_MIN | HWMON_I_RESET_HISTORY | 908 + HWMON_I_MIN_ALARM | HWMON_I_MAX_ALARM | 909 + HWMON_I_LABEL, 910 + HWMON_I_INPUT | HWMON_I_LOWEST | HWMON_I_HIGHEST | 911 + HWMON_I_MAX | HWMON_I_MIN | HWMON_I_RESET_HISTORY | 912 + HWMON_I_MIN_ALARM | HWMON_I_MAX_ALARM | 913 + HWMON_I_LABEL), 914 + HWMON_CHANNEL_INFO(curr, 915 + HWMON_C_INPUT | HWMON_C_LOWEST | HWMON_C_HIGHEST | 916 + HWMON_C_MAX | HWMON_C_MIN | HWMON_C_RESET_HISTORY | 917 + HWMON_C_MIN_ALARM | HWMON_C_MAX_ALARM | 918 + HWMON_C_LABEL), 919 + HWMON_CHANNEL_INFO(power, 920 + HWMON_P_INPUT | HWMON_P_INPUT_LOWEST | 921 + HWMON_P_INPUT_HIGHEST | HWMON_P_MAX | HWMON_P_MIN | 922 + HWMON_P_RESET_HISTORY | HWMON_P_MAX_ALARM | 923 + HWMON_P_MIN_ALARM | HWMON_P_LABEL), 924 + HWMON_CHANNEL_INFO(temp, 925 + HWMON_T_INPUT | HWMON_T_LOWEST | HWMON_T_HIGHEST | 926 + HWMON_T_MAX | HWMON_T_MIN | HWMON_T_RESET_HISTORY | 927 + HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM | 928 + HWMON_T_LABEL, 929 + HWMON_T_MAX_ALARM | HWMON_T_MIN_ALARM | HWMON_T_MAX | 930 + HWMON_T_MIN | HWMON_T_LABEL), 931 + NULL 932 + }; 933 + 934 + static const struct hwmon_ops ltc2947_hwmon_ops = { 935 + .is_visible = ltc2947_is_visible, 936 + .read = ltc2947_read, 937 + .write = ltc2947_write, 938 + .read_string = ltc2947_read_labels, 939 + }; 940 + 941 + static const struct hwmon_chip_info ltc2947_chip_info = { 942 + .ops = &ltc2947_hwmon_ops, 943 + .info = ltc2947_info, 944 + }; 945 + 946 + /* energy attributes are 6bytes wide so we need u64 */ 947 + static SENSOR_DEVICE_ATTR(energy1_input, 0444, ltc2947_show_value, NULL, 948 + LTC2947_REG_ENERGY1); 949 + static SENSOR_DEVICE_ATTR(energy2_input, 0444, ltc2947_show_value, NULL, 950 + LTC2947_REG_ENERGY2); 951 + 952 + static struct attribute *ltc2947_attrs[] = { 953 + &sensor_dev_attr_energy1_input.dev_attr.attr, 954 + &sensor_dev_attr_energy2_input.dev_attr.attr, 955 + NULL, 956 + }; 957 + ATTRIBUTE_GROUPS(ltc2947); 958 + 959 + static void ltc2947_clk_disable(void *data) 960 + { 961 + struct clk *extclk = data; 962 + 963 + clk_disable_unprepare(extclk); 964 + } 965 + 966 + static int ltc2947_setup(struct ltc2947_data *st) 967 + { 968 + int ret; 969 + struct clk *extclk; 970 + u32 dummy, deadband, pol; 971 + u32 accum[2]; 972 + 973 + /* clear status register by reading it */ 974 + ret = regmap_read(st->map, LTC2947_REG_STATUS, &dummy); 975 + if (ret) 976 + return ret; 977 + /* 978 + * Set max/min for power here since the default values x scale 979 + * would overflow on 32bit arch 980 + */ 981 + ret = ltc2947_val_write(st, LTC2947_REG_POWER_THRE_H, LTC2947_PAGE1, 2, 982 + POWER_MAX / 200000); 983 + if (ret) 984 + return ret; 985 + 986 + ret = ltc2947_val_write(st, LTC2947_REG_POWER_THRE_L, LTC2947_PAGE1, 2, 987 + POWER_MIN / 200000); 988 + if (ret) 989 + return ret; 990 + 991 + /* check external clock presence */ 992 + extclk = devm_clk_get(st->dev, NULL); 993 + if (!IS_ERR(extclk)) { 994 + unsigned long rate_hz; 995 + u8 pre = 0, div, tbctl; 996 + u64 aux; 997 + 998 + /* let's calculate and set the right valus in TBCTL */ 999 + rate_hz = clk_get_rate(extclk); 1000 + if (rate_hz < LTC2947_CLK_MIN || rate_hz > LTC2947_CLK_MAX) { 1001 + dev_err(st->dev, "Invalid rate:%lu for external clock", 1002 + rate_hz); 1003 + return -EINVAL; 1004 + } 1005 + 1006 + ret = clk_prepare_enable(extclk); 1007 + if (ret) 1008 + return ret; 1009 + 1010 + ret = devm_add_action_or_reset(st->dev, ltc2947_clk_disable, 1011 + extclk); 1012 + if (ret) 1013 + return ret; 1014 + /* as in table 1 of the datasheet */ 1015 + if (rate_hz >= LTC2947_CLK_MIN && rate_hz <= 1000000) 1016 + pre = 0; 1017 + else if (rate_hz > 1000000 && rate_hz <= 2000000) 1018 + pre = 1; 1019 + else if (rate_hz > 2000000 && rate_hz <= 4000000) 1020 + pre = 2; 1021 + else if (rate_hz > 4000000 && rate_hz <= 8000000) 1022 + pre = 3; 1023 + else if (rate_hz > 8000000 && rate_hz <= 16000000) 1024 + pre = 4; 1025 + else if (rate_hz > 16000000 && rate_hz <= LTC2947_CLK_MAX) 1026 + pre = 5; 1027 + /* 1028 + * Div is given by: 1029 + * floor(fref / (2^PRE * 32768)) 1030 + */ 1031 + div = rate_hz / ((1 << pre) * 32768); 1032 + tbctl = LTC2947_PRE(pre) | LTC2947_DIV(div); 1033 + 1034 + ret = regmap_write(st->map, LTC2947_REG_TBCTL, tbctl); 1035 + if (ret) 1036 + return ret; 1037 + /* 1038 + * The energy lsb is given by (in W*s): 1039 + * 06416 * (1/fref) * 2^PRE * (DIV + 1) 1040 + * The value is multiplied by 10E9 1041 + */ 1042 + aux = (div + 1) * ((1 << pre) * 641600000ULL); 1043 + st->lsb_energy = DIV_ROUND_CLOSEST_ULL(aux, rate_hz); 1044 + } else { 1045 + /* 19.89E-6 * 10E9 */ 1046 + st->lsb_energy = 19890; 1047 + } 1048 + ret = of_property_read_u32_array(st->dev->of_node, 1049 + "adi,accumulator-ctl-pol", accum, 1050 + ARRAY_SIZE(accum)); 1051 + if (!ret) { 1052 + u32 accum_reg = LTC2947_ACCUM_POL_1(accum[0]) | 1053 + LTC2947_ACCUM_POL_2(accum[1]); 1054 + 1055 + ret = regmap_write(st->map, LTC2947_REG_ACCUM_POL, accum_reg); 1056 + if (ret) 1057 + return ret; 1058 + } 1059 + ret = of_property_read_u32(st->dev->of_node, 1060 + "adi,accumulation-deadband-microamp", 1061 + &deadband); 1062 + if (!ret) { 1063 + /* the LSB is the same as the current, so 3mA */ 1064 + ret = regmap_write(st->map, LTC2947_REG_ACCUM_DEADBAND, 1065 + deadband / (1000 * 3)); 1066 + if (ret) 1067 + return ret; 1068 + } 1069 + /* check gpio cfg */ 1070 + ret = of_property_read_u32(st->dev->of_node, "adi,gpio-out-pol", &pol); 1071 + if (!ret) { 1072 + /* setup GPIO as output */ 1073 + u32 gpio_ctl = LTC2947_GPIO_EN(1) | LTC2947_GPIO_FAN_EN(1) | 1074 + LTC2947_GPIO_FAN_POL(pol); 1075 + 1076 + st->gpio_out = true; 1077 + ret = regmap_write(st->map, LTC2947_REG_GPIOSTATCTL, gpio_ctl); 1078 + if (ret) 1079 + return ret; 1080 + } 1081 + ret = of_property_read_u32_array(st->dev->of_node, "adi,gpio-in-accum", 1082 + accum, ARRAY_SIZE(accum)); 1083 + if (!ret) { 1084 + /* 1085 + * Setup the accum options. The gpioctl is already defined as 1086 + * input by default. 1087 + */ 1088 + u32 accum_val = LTC2947_ACCUM_POL_1(accum[0]) | 1089 + LTC2947_ACCUM_POL_2(accum[1]); 1090 + 1091 + if (st->gpio_out) { 1092 + dev_err(st->dev, 1093 + "Cannot have input gpio config if already configured as output"); 1094 + return -EINVAL; 1095 + } 1096 + 1097 + ret = regmap_write(st->map, LTC2947_REG_GPIO_ACCUM, accum_val); 1098 + if (ret) 1099 + return ret; 1100 + } 1101 + 1102 + /* set continuos mode */ 1103 + return regmap_update_bits(st->map, LTC2947_REG_CTRL, 1104 + LTC2947_CONT_MODE_MASK, LTC2947_CONT_MODE(1)); 1105 + } 1106 + 1107 + int ltc2947_core_probe(struct regmap *map, const char *name) 1108 + { 1109 + struct ltc2947_data *st; 1110 + struct device *dev = regmap_get_device(map); 1111 + struct device *hwmon; 1112 + int ret; 1113 + 1114 + st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL); 1115 + if (!st) 1116 + return -ENOMEM; 1117 + 1118 + st->map = map; 1119 + st->dev = dev; 1120 + dev_set_drvdata(dev, st); 1121 + mutex_init(&st->lock); 1122 + 1123 + ret = ltc2947_setup(st); 1124 + if (ret) 1125 + return ret; 1126 + 1127 + hwmon = devm_hwmon_device_register_with_info(dev, name, st, 1128 + &ltc2947_chip_info, 1129 + ltc2947_groups); 1130 + return PTR_ERR_OR_ZERO(hwmon); 1131 + } 1132 + EXPORT_SYMBOL_GPL(ltc2947_core_probe); 1133 + 1134 + static int __maybe_unused ltc2947_resume(struct device *dev) 1135 + { 1136 + struct ltc2947_data *st = dev_get_drvdata(dev); 1137 + u32 ctrl = 0; 1138 + int ret; 1139 + 1140 + /* dummy read to wake the device */ 1141 + ret = regmap_read(st->map, LTC2947_REG_CTRL, &ctrl); 1142 + if (ret) 1143 + return ret; 1144 + /* 1145 + * Wait for the device. It takes 100ms to wake up so, 10ms extra 1146 + * should be enough. 1147 + */ 1148 + msleep(110); 1149 + ret = regmap_read(st->map, LTC2947_REG_CTRL, &ctrl); 1150 + if (ret) 1151 + return ret; 1152 + /* ctrl should be 0 */ 1153 + if (ctrl != 0) { 1154 + dev_err(st->dev, "Device failed to wake up, ctl:%02X\n", ctrl); 1155 + return -ETIMEDOUT; 1156 + } 1157 + 1158 + /* set continuous mode */ 1159 + return regmap_update_bits(st->map, LTC2947_REG_CTRL, 1160 + LTC2947_CONT_MODE_MASK, LTC2947_CONT_MODE(1)); 1161 + } 1162 + 1163 + static int __maybe_unused ltc2947_suspend(struct device *dev) 1164 + { 1165 + struct ltc2947_data *st = dev_get_drvdata(dev); 1166 + 1167 + return regmap_update_bits(st->map, LTC2947_REG_CTRL, 1168 + LTC2947_SHUTDOWN_MASK, 1); 1169 + } 1170 + 1171 + SIMPLE_DEV_PM_OPS(ltc2947_pm_ops, ltc2947_suspend, ltc2947_resume); 1172 + EXPORT_SYMBOL_GPL(ltc2947_pm_ops); 1173 + 1174 + const struct of_device_id ltc2947_of_match[] = { 1175 + { .compatible = "adi,ltc2947" }, 1176 + {} 1177 + }; 1178 + EXPORT_SYMBOL_GPL(ltc2947_of_match); 1179 + MODULE_DEVICE_TABLE(of, ltc2947_of_match); 1180 + 1181 + MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>"); 1182 + MODULE_DESCRIPTION("LTC2947 power and energy monitor core driver"); 1183 + MODULE_LICENSE("GPL");
+49
drivers/hwmon/ltc2947-i2c.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Analog Devices LTC2947 high precision power and energy monitor over I2C 4 + * 5 + * Copyright 2019 Analog Devices Inc. 6 + */ 7 + #include <linux/i2c.h> 8 + #include <linux/module.h> 9 + #include <linux/regmap.h> 10 + 11 + #include "ltc2947.h" 12 + 13 + static const struct regmap_config ltc2947_regmap_config = { 14 + .reg_bits = 8, 15 + .val_bits = 8, 16 + }; 17 + 18 + static int ltc2947_probe(struct i2c_client *i2c, 19 + const struct i2c_device_id *id) 20 + { 21 + struct regmap *map; 22 + 23 + map = devm_regmap_init_i2c(i2c, &ltc2947_regmap_config); 24 + if (IS_ERR(map)) 25 + return PTR_ERR(map); 26 + 27 + return ltc2947_core_probe(map, i2c->name); 28 + } 29 + 30 + static const struct i2c_device_id ltc2947_id[] = { 31 + {"ltc2947", 0}, 32 + {} 33 + }; 34 + MODULE_DEVICE_TABLE(i2c, ltc2947_id); 35 + 36 + static struct i2c_driver ltc2947_driver = { 37 + .driver = { 38 + .name = "ltc2947", 39 + .of_match_table = ltc2947_of_match, 40 + .pm = &ltc2947_pm_ops, 41 + }, 42 + .probe = ltc2947_probe, 43 + .id_table = ltc2947_id, 44 + }; 45 + module_i2c_driver(ltc2947_driver); 46 + 47 + MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>"); 48 + MODULE_DESCRIPTION("LTC2947 I2C power and energy monitor driver"); 49 + MODULE_LICENSE("GPL");
+50
drivers/hwmon/ltc2947-spi.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Analog Devices LTC2947 high precision power and energy monitor over SPI 4 + * 5 + * Copyright 2019 Analog Devices Inc. 6 + */ 7 + #include <linux/module.h> 8 + #include <linux/of.h> 9 + #include <linux/regmap.h> 10 + #include <linux/spi/spi.h> 11 + 12 + #include "ltc2947.h" 13 + 14 + static const struct regmap_config ltc2947_regmap_config = { 15 + .reg_bits = 16, 16 + .val_bits = 8, 17 + .read_flag_mask = BIT(0), 18 + }; 19 + 20 + static int ltc2947_probe(struct spi_device *spi) 21 + { 22 + struct regmap *map; 23 + 24 + map = devm_regmap_init_spi(spi, &ltc2947_regmap_config); 25 + if (IS_ERR(map)) 26 + return PTR_ERR(map); 27 + 28 + return ltc2947_core_probe(map, spi_get_device_id(spi)->name); 29 + } 30 + 31 + static const struct spi_device_id ltc2947_id[] = { 32 + {"ltc2947", 0}, 33 + {} 34 + }; 35 + MODULE_DEVICE_TABLE(spi, ltc2947_id); 36 + 37 + static struct spi_driver ltc2947_driver = { 38 + .driver = { 39 + .name = "ltc2947", 40 + .of_match_table = ltc2947_of_match, 41 + .pm = &ltc2947_pm_ops, 42 + }, 43 + .probe = ltc2947_probe, 44 + .id_table = ltc2947_id, 45 + }; 46 + module_spi_driver(ltc2947_driver); 47 + 48 + MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>"); 49 + MODULE_DESCRIPTION("LTC2947 SPI power and energy monitor driver"); 50 + MODULE_LICENSE("GPL");
+12
drivers/hwmon/ltc2947.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _LINUX_LTC2947_H 3 + #define _LINUX_LTC2947_H 4 + 5 + struct regmap; 6 + 7 + extern const struct of_device_id ltc2947_of_match[]; 8 + extern const struct dev_pm_ops ltc2947_pm_ops; 9 + 10 + int ltc2947_core_probe(struct regmap *map, const char *name); 11 + 12 + #endif