Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Driver for Linear Technology LTC2945 I2C Power Monitor
0004  *
0005  * Copyright (c) 2014 Guenter Roeck
0006  */
0007 
0008 #include <linux/kernel.h>
0009 #include <linux/module.h>
0010 #include <linux/err.h>
0011 #include <linux/slab.h>
0012 #include <linux/i2c.h>
0013 #include <linux/hwmon.h>
0014 #include <linux/hwmon-sysfs.h>
0015 #include <linux/jiffies.h>
0016 #include <linux/regmap.h>
0017 
0018 /* chip registers */
0019 #define LTC2945_CONTROL         0x00
0020 #define LTC2945_ALERT           0x01
0021 #define LTC2945_STATUS          0x02
0022 #define LTC2945_FAULT           0x03
0023 #define LTC2945_POWER_H         0x05
0024 #define LTC2945_MAX_POWER_H     0x08
0025 #define LTC2945_MIN_POWER_H     0x0b
0026 #define LTC2945_MAX_POWER_THRES_H   0x0e
0027 #define LTC2945_MIN_POWER_THRES_H   0x11
0028 #define LTC2945_SENSE_H         0x14
0029 #define LTC2945_MAX_SENSE_H     0x16
0030 #define LTC2945_MIN_SENSE_H     0x18
0031 #define LTC2945_MAX_SENSE_THRES_H   0x1a
0032 #define LTC2945_MIN_SENSE_THRES_H   0x1c
0033 #define LTC2945_VIN_H           0x1e
0034 #define LTC2945_MAX_VIN_H       0x20
0035 #define LTC2945_MIN_VIN_H       0x22
0036 #define LTC2945_MAX_VIN_THRES_H     0x24
0037 #define LTC2945_MIN_VIN_THRES_H     0x26
0038 #define LTC2945_ADIN_H          0x28
0039 #define LTC2945_MAX_ADIN_H      0x2a
0040 #define LTC2945_MIN_ADIN_H      0x2c
0041 #define LTC2945_MAX_ADIN_THRES_H    0x2e
0042 #define LTC2945_MIN_ADIN_THRES_H    0x30
0043 #define LTC2945_MIN_ADIN_THRES_L    0x31
0044 
0045 /* Fault register bits */
0046 
0047 #define FAULT_ADIN_UV       (1 << 0)
0048 #define FAULT_ADIN_OV       (1 << 1)
0049 #define FAULT_VIN_UV        (1 << 2)
0050 #define FAULT_VIN_OV        (1 << 3)
0051 #define FAULT_SENSE_UV      (1 << 4)
0052 #define FAULT_SENSE_OV      (1 << 5)
0053 #define FAULT_POWER_UV      (1 << 6)
0054 #define FAULT_POWER_OV      (1 << 7)
0055 
0056 /* Control register bits */
0057 
0058 #define CONTROL_MULT_SELECT (1 << 0)
0059 #define CONTROL_TEST_MODE   (1 << 4)
0060 
0061 static inline bool is_power_reg(u8 reg)
0062 {
0063     return reg < LTC2945_SENSE_H;
0064 }
0065 
0066 /* Return the value from the given register in uW, mV, or mA */
0067 static long long ltc2945_reg_to_val(struct device *dev, u8 reg)
0068 {
0069     struct regmap *regmap = dev_get_drvdata(dev);
0070     unsigned int control;
0071     u8 buf[3];
0072     long long val;
0073     int ret;
0074 
0075     ret = regmap_bulk_read(regmap, reg, buf,
0076                    is_power_reg(reg) ? 3 : 2);
0077     if (ret < 0)
0078         return ret;
0079 
0080     if (is_power_reg(reg)) {
0081         /* power */
0082         val = (buf[0] << 16) + (buf[1] << 8) + buf[2];
0083     } else {
0084         /* current, voltage */
0085         val = (buf[0] << 4) + (buf[1] >> 4);
0086     }
0087 
0088     switch (reg) {
0089     case LTC2945_POWER_H:
0090     case LTC2945_MAX_POWER_H:
0091     case LTC2945_MIN_POWER_H:
0092     case LTC2945_MAX_POWER_THRES_H:
0093     case LTC2945_MIN_POWER_THRES_H:
0094         /*
0095          * Convert to uW by assuming current is measured with
0096          * an 1mOhm sense resistor, similar to current
0097          * measurements.
0098          * Control register bit 0 selects if voltage at SENSE+/VDD
0099          * or voltage at ADIN is used to measure power.
0100          */
0101         ret = regmap_read(regmap, LTC2945_CONTROL, &control);
0102         if (ret < 0)
0103             return ret;
0104         if (control & CONTROL_MULT_SELECT) {
0105             /* 25 mV * 25 uV = 0.625 uV resolution. */
0106             val *= 625LL;
0107         } else {
0108             /* 0.5 mV * 25 uV = 0.0125 uV resolution. */
0109             val = (val * 25LL) >> 1;
0110         }
0111         break;
0112     case LTC2945_VIN_H:
0113     case LTC2945_MAX_VIN_H:
0114     case LTC2945_MIN_VIN_H:
0115     case LTC2945_MAX_VIN_THRES_H:
0116     case LTC2945_MIN_VIN_THRES_H:
0117         /* 25 mV resolution. Convert to mV. */
0118         val *= 25;
0119         break;
0120     case LTC2945_ADIN_H:
0121     case LTC2945_MAX_ADIN_H:
0122     case LTC2945_MIN_ADIN_THRES_H:
0123     case LTC2945_MAX_ADIN_THRES_H:
0124     case LTC2945_MIN_ADIN_H:
0125         /* 0.5mV resolution. Convert to mV. */
0126         val = val >> 1;
0127         break;
0128     case LTC2945_SENSE_H:
0129     case LTC2945_MAX_SENSE_H:
0130     case LTC2945_MIN_SENSE_H:
0131     case LTC2945_MAX_SENSE_THRES_H:
0132     case LTC2945_MIN_SENSE_THRES_H:
0133         /*
0134          * 25 uV resolution. Convert to current as measured with
0135          * an 1 mOhm sense resistor, in mA. If a different sense
0136          * resistor is installed, calculate the actual current by
0137          * dividing the reported current by the sense resistor value
0138          * in mOhm.
0139          */
0140         val *= 25;
0141         break;
0142     default:
0143         return -EINVAL;
0144     }
0145     return val;
0146 }
0147 
0148 static int ltc2945_val_to_reg(struct device *dev, u8 reg,
0149                   unsigned long val)
0150 {
0151     struct regmap *regmap = dev_get_drvdata(dev);
0152     unsigned int control;
0153     int ret;
0154 
0155     switch (reg) {
0156     case LTC2945_POWER_H:
0157     case LTC2945_MAX_POWER_H:
0158     case LTC2945_MIN_POWER_H:
0159     case LTC2945_MAX_POWER_THRES_H:
0160     case LTC2945_MIN_POWER_THRES_H:
0161         /*
0162          * Convert to register value by assuming current is measured
0163          * with an 1mOhm sense resistor, similar to current
0164          * measurements.
0165          * Control register bit 0 selects if voltage at SENSE+/VDD
0166          * or voltage at ADIN is used to measure power, which in turn
0167          * determines register calculations.
0168          */
0169         ret = regmap_read(regmap, LTC2945_CONTROL, &control);
0170         if (ret < 0)
0171             return ret;
0172         if (control & CONTROL_MULT_SELECT) {
0173             /* 25 mV * 25 uV = 0.625 uV resolution. */
0174             val = DIV_ROUND_CLOSEST(val, 625);
0175         } else {
0176             /*
0177              * 0.5 mV * 25 uV = 0.0125 uV resolution.
0178              * Divide first to avoid overflow;
0179              * accept loss of accuracy.
0180              */
0181             val = DIV_ROUND_CLOSEST(val, 25) * 2;
0182         }
0183         break;
0184     case LTC2945_VIN_H:
0185     case LTC2945_MAX_VIN_H:
0186     case LTC2945_MIN_VIN_H:
0187     case LTC2945_MAX_VIN_THRES_H:
0188     case LTC2945_MIN_VIN_THRES_H:
0189         /* 25 mV resolution. */
0190         val /= 25;
0191         break;
0192     case LTC2945_ADIN_H:
0193     case LTC2945_MAX_ADIN_H:
0194     case LTC2945_MIN_ADIN_THRES_H:
0195     case LTC2945_MAX_ADIN_THRES_H:
0196     case LTC2945_MIN_ADIN_H:
0197         /* 0.5mV resolution. */
0198         val *= 2;
0199         break;
0200     case LTC2945_SENSE_H:
0201     case LTC2945_MAX_SENSE_H:
0202     case LTC2945_MIN_SENSE_H:
0203     case LTC2945_MAX_SENSE_THRES_H:
0204     case LTC2945_MIN_SENSE_THRES_H:
0205         /*
0206          * 25 uV resolution. Convert to current as measured with
0207          * an 1 mOhm sense resistor, in mA. If a different sense
0208          * resistor is installed, calculate the actual current by
0209          * dividing the reported current by the sense resistor value
0210          * in mOhm.
0211          */
0212         val = DIV_ROUND_CLOSEST(val, 25);
0213         break;
0214     default:
0215         return -EINVAL;
0216     }
0217     return val;
0218 }
0219 
0220 static ssize_t ltc2945_value_show(struct device *dev,
0221                   struct device_attribute *da, char *buf)
0222 {
0223     struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
0224     long long value;
0225 
0226     value = ltc2945_reg_to_val(dev, attr->index);
0227     if (value < 0)
0228         return value;
0229     return sysfs_emit(buf, "%lld\n", value);
0230 }
0231 
0232 static ssize_t ltc2945_value_store(struct device *dev,
0233                    struct device_attribute *da,
0234                    const char *buf, size_t count)
0235 {
0236     struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
0237     struct regmap *regmap = dev_get_drvdata(dev);
0238     u8 reg = attr->index;
0239     unsigned long val;
0240     u8 regbuf[3];
0241     int num_regs;
0242     int regval;
0243     int ret;
0244 
0245     ret = kstrtoul(buf, 10, &val);
0246     if (ret)
0247         return ret;
0248 
0249     /* convert to register value, then clamp and write result */
0250     regval = ltc2945_val_to_reg(dev, reg, val);
0251     if (is_power_reg(reg)) {
0252         regval = clamp_val(regval, 0, 0xffffff);
0253         regbuf[0] = regval >> 16;
0254         regbuf[1] = (regval >> 8) & 0xff;
0255         regbuf[2] = regval;
0256         num_regs = 3;
0257     } else {
0258         regval = clamp_val(regval, 0, 0xfff) << 4;
0259         regbuf[0] = regval >> 8;
0260         regbuf[1] = regval & 0xff;
0261         num_regs = 2;
0262     }
0263     ret = regmap_bulk_write(regmap, reg, regbuf, num_regs);
0264     return ret < 0 ? ret : count;
0265 }
0266 
0267 static ssize_t ltc2945_history_store(struct device *dev,
0268                      struct device_attribute *da,
0269                      const char *buf, size_t count)
0270 {
0271     struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
0272     struct regmap *regmap = dev_get_drvdata(dev);
0273     u8 reg = attr->index;
0274     int num_regs = is_power_reg(reg) ? 3 : 2;
0275     u8 buf_min[3] = { 0xff, 0xff, 0xff };
0276     u8 buf_max[3] = { 0, 0, 0 };
0277     unsigned long val;
0278     int ret;
0279 
0280     ret = kstrtoul(buf, 10, &val);
0281     if (ret)
0282         return ret;
0283     if (val != 1)
0284         return -EINVAL;
0285 
0286     ret = regmap_update_bits(regmap, LTC2945_CONTROL, CONTROL_TEST_MODE,
0287                  CONTROL_TEST_MODE);
0288 
0289     /* Reset minimum */
0290     ret = regmap_bulk_write(regmap, reg, buf_min, num_regs);
0291     if (ret)
0292         return ret;
0293 
0294     switch (reg) {
0295     case LTC2945_MIN_POWER_H:
0296         reg = LTC2945_MAX_POWER_H;
0297         break;
0298     case LTC2945_MIN_SENSE_H:
0299         reg = LTC2945_MAX_SENSE_H;
0300         break;
0301     case LTC2945_MIN_VIN_H:
0302         reg = LTC2945_MAX_VIN_H;
0303         break;
0304     case LTC2945_MIN_ADIN_H:
0305         reg = LTC2945_MAX_ADIN_H;
0306         break;
0307     default:
0308         WARN_ONCE(1, "Bad register: 0x%x\n", reg);
0309         return -EINVAL;
0310     }
0311     /* Reset maximum */
0312     ret = regmap_bulk_write(regmap, reg, buf_max, num_regs);
0313 
0314     /* Try resetting test mode even if there was an error */
0315     regmap_update_bits(regmap, LTC2945_CONTROL, CONTROL_TEST_MODE, 0);
0316 
0317     return ret ? : count;
0318 }
0319 
0320 static ssize_t ltc2945_bool_show(struct device *dev,
0321                  struct device_attribute *da, char *buf)
0322 {
0323     struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
0324     struct regmap *regmap = dev_get_drvdata(dev);
0325     unsigned int fault;
0326     int ret;
0327 
0328     ret = regmap_read(regmap, LTC2945_FAULT, &fault);
0329     if (ret < 0)
0330         return ret;
0331 
0332     fault &= attr->index;
0333     if (fault)      /* Clear reported faults in chip register */
0334         regmap_update_bits(regmap, LTC2945_FAULT, attr->index, 0);
0335 
0336     return sysfs_emit(buf, "%d\n", !!fault);
0337 }
0338 
0339 /* Input voltages */
0340 
0341 static SENSOR_DEVICE_ATTR_RO(in1_input, ltc2945_value, LTC2945_VIN_H);
0342 static SENSOR_DEVICE_ATTR_RW(in1_min, ltc2945_value, LTC2945_MIN_VIN_THRES_H);
0343 static SENSOR_DEVICE_ATTR_RW(in1_max, ltc2945_value, LTC2945_MAX_VIN_THRES_H);
0344 static SENSOR_DEVICE_ATTR_RO(in1_lowest, ltc2945_value, LTC2945_MIN_VIN_H);
0345 static SENSOR_DEVICE_ATTR_RO(in1_highest, ltc2945_value, LTC2945_MAX_VIN_H);
0346 static SENSOR_DEVICE_ATTR_WO(in1_reset_history, ltc2945_history,
0347                  LTC2945_MIN_VIN_H);
0348 
0349 static SENSOR_DEVICE_ATTR_RO(in2_input, ltc2945_value, LTC2945_ADIN_H);
0350 static SENSOR_DEVICE_ATTR_RW(in2_min, ltc2945_value, LTC2945_MIN_ADIN_THRES_H);
0351 static SENSOR_DEVICE_ATTR_RW(in2_max, ltc2945_value, LTC2945_MAX_ADIN_THRES_H);
0352 static SENSOR_DEVICE_ATTR_RO(in2_lowest, ltc2945_value, LTC2945_MIN_ADIN_H);
0353 static SENSOR_DEVICE_ATTR_RO(in2_highest, ltc2945_value, LTC2945_MAX_ADIN_H);
0354 static SENSOR_DEVICE_ATTR_WO(in2_reset_history, ltc2945_history,
0355                  LTC2945_MIN_ADIN_H);
0356 
0357 /* Voltage alarms */
0358 
0359 static SENSOR_DEVICE_ATTR_RO(in1_min_alarm, ltc2945_bool, FAULT_VIN_UV);
0360 static SENSOR_DEVICE_ATTR_RO(in1_max_alarm, ltc2945_bool, FAULT_VIN_OV);
0361 static SENSOR_DEVICE_ATTR_RO(in2_min_alarm, ltc2945_bool, FAULT_ADIN_UV);
0362 static SENSOR_DEVICE_ATTR_RO(in2_max_alarm, ltc2945_bool, FAULT_ADIN_OV);
0363 
0364 /* Currents (via sense resistor) */
0365 
0366 static SENSOR_DEVICE_ATTR_RO(curr1_input, ltc2945_value, LTC2945_SENSE_H);
0367 static SENSOR_DEVICE_ATTR_RW(curr1_min, ltc2945_value,
0368                  LTC2945_MIN_SENSE_THRES_H);
0369 static SENSOR_DEVICE_ATTR_RW(curr1_max, ltc2945_value,
0370                  LTC2945_MAX_SENSE_THRES_H);
0371 static SENSOR_DEVICE_ATTR_RO(curr1_lowest, ltc2945_value, LTC2945_MIN_SENSE_H);
0372 static SENSOR_DEVICE_ATTR_RO(curr1_highest, ltc2945_value,
0373                  LTC2945_MAX_SENSE_H);
0374 static SENSOR_DEVICE_ATTR_WO(curr1_reset_history, ltc2945_history,
0375                  LTC2945_MIN_SENSE_H);
0376 
0377 /* Current alarms */
0378 
0379 static SENSOR_DEVICE_ATTR_RO(curr1_min_alarm, ltc2945_bool, FAULT_SENSE_UV);
0380 static SENSOR_DEVICE_ATTR_RO(curr1_max_alarm, ltc2945_bool, FAULT_SENSE_OV);
0381 
0382 /* Power */
0383 
0384 static SENSOR_DEVICE_ATTR_RO(power1_input, ltc2945_value, LTC2945_POWER_H);
0385 static SENSOR_DEVICE_ATTR_RW(power1_min, ltc2945_value,
0386                  LTC2945_MIN_POWER_THRES_H);
0387 static SENSOR_DEVICE_ATTR_RW(power1_max, ltc2945_value,
0388                  LTC2945_MAX_POWER_THRES_H);
0389 static SENSOR_DEVICE_ATTR_RO(power1_input_lowest, ltc2945_value,
0390                  LTC2945_MIN_POWER_H);
0391 static SENSOR_DEVICE_ATTR_RO(power1_input_highest, ltc2945_value,
0392                  LTC2945_MAX_POWER_H);
0393 static SENSOR_DEVICE_ATTR_WO(power1_reset_history, ltc2945_history,
0394                  LTC2945_MIN_POWER_H);
0395 
0396 /* Power alarms */
0397 
0398 static SENSOR_DEVICE_ATTR_RO(power1_min_alarm, ltc2945_bool, FAULT_POWER_UV);
0399 static SENSOR_DEVICE_ATTR_RO(power1_max_alarm, ltc2945_bool, FAULT_POWER_OV);
0400 
0401 static struct attribute *ltc2945_attrs[] = {
0402     &sensor_dev_attr_in1_input.dev_attr.attr,
0403     &sensor_dev_attr_in1_min.dev_attr.attr,
0404     &sensor_dev_attr_in1_max.dev_attr.attr,
0405     &sensor_dev_attr_in1_lowest.dev_attr.attr,
0406     &sensor_dev_attr_in1_highest.dev_attr.attr,
0407     &sensor_dev_attr_in1_reset_history.dev_attr.attr,
0408     &sensor_dev_attr_in1_min_alarm.dev_attr.attr,
0409     &sensor_dev_attr_in1_max_alarm.dev_attr.attr,
0410 
0411     &sensor_dev_attr_in2_input.dev_attr.attr,
0412     &sensor_dev_attr_in2_min.dev_attr.attr,
0413     &sensor_dev_attr_in2_max.dev_attr.attr,
0414     &sensor_dev_attr_in2_lowest.dev_attr.attr,
0415     &sensor_dev_attr_in2_highest.dev_attr.attr,
0416     &sensor_dev_attr_in2_reset_history.dev_attr.attr,
0417     &sensor_dev_attr_in2_min_alarm.dev_attr.attr,
0418     &sensor_dev_attr_in2_max_alarm.dev_attr.attr,
0419 
0420     &sensor_dev_attr_curr1_input.dev_attr.attr,
0421     &sensor_dev_attr_curr1_min.dev_attr.attr,
0422     &sensor_dev_attr_curr1_max.dev_attr.attr,
0423     &sensor_dev_attr_curr1_lowest.dev_attr.attr,
0424     &sensor_dev_attr_curr1_highest.dev_attr.attr,
0425     &sensor_dev_attr_curr1_reset_history.dev_attr.attr,
0426     &sensor_dev_attr_curr1_min_alarm.dev_attr.attr,
0427     &sensor_dev_attr_curr1_max_alarm.dev_attr.attr,
0428 
0429     &sensor_dev_attr_power1_input.dev_attr.attr,
0430     &sensor_dev_attr_power1_min.dev_attr.attr,
0431     &sensor_dev_attr_power1_max.dev_attr.attr,
0432     &sensor_dev_attr_power1_input_lowest.dev_attr.attr,
0433     &sensor_dev_attr_power1_input_highest.dev_attr.attr,
0434     &sensor_dev_attr_power1_reset_history.dev_attr.attr,
0435     &sensor_dev_attr_power1_min_alarm.dev_attr.attr,
0436     &sensor_dev_attr_power1_max_alarm.dev_attr.attr,
0437 
0438     NULL,
0439 };
0440 ATTRIBUTE_GROUPS(ltc2945);
0441 
0442 static const struct regmap_config ltc2945_regmap_config = {
0443     .reg_bits = 8,
0444     .val_bits = 8,
0445     .max_register = LTC2945_MIN_ADIN_THRES_L,
0446 };
0447 
0448 static int ltc2945_probe(struct i2c_client *client)
0449 {
0450     struct device *dev = &client->dev;
0451     struct device *hwmon_dev;
0452     struct regmap *regmap;
0453 
0454     regmap = devm_regmap_init_i2c(client, &ltc2945_regmap_config);
0455     if (IS_ERR(regmap)) {
0456         dev_err(dev, "failed to allocate register map\n");
0457         return PTR_ERR(regmap);
0458     }
0459 
0460     /* Clear faults */
0461     regmap_write(regmap, LTC2945_FAULT, 0x00);
0462 
0463     hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
0464                                regmap,
0465                                ltc2945_groups);
0466     return PTR_ERR_OR_ZERO(hwmon_dev);
0467 }
0468 
0469 static const struct i2c_device_id ltc2945_id[] = {
0470     {"ltc2945", 0},
0471     { }
0472 };
0473 
0474 MODULE_DEVICE_TABLE(i2c, ltc2945_id);
0475 
0476 static struct i2c_driver ltc2945_driver = {
0477     .driver = {
0478            .name = "ltc2945",
0479            },
0480     .probe_new = ltc2945_probe,
0481     .id_table = ltc2945_id,
0482 };
0483 
0484 module_i2c_driver(ltc2945_driver);
0485 
0486 MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
0487 MODULE_DESCRIPTION("LTC2945 driver");
0488 MODULE_LICENSE("GPL");