^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * INA3221 Triple Current/Voltage Monitor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2016 Texas Instruments Incorporated - https://www.ti.com/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Andrew F. Davis <afd@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/hwmon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/hwmon-sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/util_macros.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define INA3221_DRIVER_NAME "ina3221"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define INA3221_CONFIG 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define INA3221_SHUNT1 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define INA3221_BUS1 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define INA3221_SHUNT2 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define INA3221_BUS2 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define INA3221_SHUNT3 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define INA3221_BUS3 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define INA3221_CRIT1 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define INA3221_WARN1 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define INA3221_CRIT2 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define INA3221_WARN2 0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define INA3221_CRIT3 0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define INA3221_WARN3 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define INA3221_SHUNT_SUM 0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define INA3221_CRIT_SUM 0x0e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define INA3221_MASK_ENABLE 0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define INA3221_CONFIG_MODE_MASK GENMASK(2, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define INA3221_CONFIG_MODE_POWERDOWN 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define INA3221_CONFIG_MODE_SHUNT BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define INA3221_CONFIG_MODE_BUS BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define INA3221_CONFIG_MODE_CONTINUOUS BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define INA3221_CONFIG_VSH_CT_SHIFT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define INA3221_CONFIG_VSH_CT_MASK GENMASK(5, 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define INA3221_CONFIG_VSH_CT(x) (((x) & GENMASK(5, 3)) >> 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define INA3221_CONFIG_VBUS_CT_SHIFT 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define INA3221_CONFIG_VBUS_CT_MASK GENMASK(8, 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define INA3221_CONFIG_VBUS_CT(x) (((x) & GENMASK(8, 6)) >> 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define INA3221_CONFIG_AVG_SHIFT 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define INA3221_CONFIG_AVG_MASK GENMASK(11, 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define INA3221_CONFIG_AVG(x) (((x) & GENMASK(11, 9)) >> 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define INA3221_CONFIG_CHs_EN_MASK GENMASK(14, 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define INA3221_CONFIG_CHx_EN(x) BIT(14 - (x))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define INA3221_MASK_ENABLE_SCC_MASK GENMASK(14, 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define INA3221_CONFIG_DEFAULT 0x7127
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define INA3221_RSHUNT_DEFAULT 10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) enum ina3221_fields {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* Configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) F_RST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* Status Flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) F_CVRF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* Warning Flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) F_WF3, F_WF2, F_WF1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* Alert Flags: SF is the summation-alert flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) F_SF, F_CF3, F_CF2, F_CF1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /* sentinel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) F_MAX_FIELDS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static const struct reg_field ina3221_reg_fields[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) [F_RST] = REG_FIELD(INA3221_CONFIG, 15, 15),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) [F_CVRF] = REG_FIELD(INA3221_MASK_ENABLE, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) [F_WF3] = REG_FIELD(INA3221_MASK_ENABLE, 3, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) [F_WF2] = REG_FIELD(INA3221_MASK_ENABLE, 4, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) [F_WF1] = REG_FIELD(INA3221_MASK_ENABLE, 5, 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) [F_SF] = REG_FIELD(INA3221_MASK_ENABLE, 6, 6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) [F_CF3] = REG_FIELD(INA3221_MASK_ENABLE, 7, 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) [F_CF2] = REG_FIELD(INA3221_MASK_ENABLE, 8, 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) [F_CF1] = REG_FIELD(INA3221_MASK_ENABLE, 9, 9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) enum ina3221_channels {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) INA3221_CHANNEL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) INA3221_CHANNEL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) INA3221_CHANNEL3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) INA3221_NUM_CHANNELS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * struct ina3221_input - channel input source specific information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * @label: label of channel input source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * @shunt_resistor: shunt resistor value of channel input source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * @disconnected: connection status of channel input source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct ina3221_input {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) const char *label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int shunt_resistor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) bool disconnected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * struct ina3221_data - device specific information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * @pm_dev: Device pointer for pm runtime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * @regmap: Register map of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * @fields: Register fields of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * @inputs: Array of channel input source specific structures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * @lock: mutex lock to serialize sysfs attribute accesses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * @reg_config: Register value of INA3221_CONFIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * @summation_shunt_resistor: equivalent shunt resistor value for summation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * @single_shot: running in single-shot operating mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct ina3221_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct device *pm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct regmap_field *fields[F_MAX_FIELDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct ina3221_input inputs[INA3221_NUM_CHANNELS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) u32 reg_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int summation_shunt_resistor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) bool single_shot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static inline bool ina3221_is_enabled(struct ina3221_data *ina, int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /* Summation channel checks shunt resistor values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (channel > INA3221_CHANNEL3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return ina->summation_shunt_resistor != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return pm_runtime_active(ina->pm_dev) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) (ina->reg_config & INA3221_CONFIG_CHx_EN(channel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * Helper function to return the resistor value for current summation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * There is a condition to calculate current summation -- all the shunt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * resistor values should be the same, so as to simply fit the formula:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * current summation = shunt voltage summation / shunt resistor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * Returns the equivalent shunt resistor value on success or 0 on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static inline int ina3221_summation_shunt_resistor(struct ina3221_data *ina)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct ina3221_input *input = ina->inputs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) int i, shunt_resistor = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) for (i = 0; i < INA3221_NUM_CHANNELS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (input[i].disconnected || !input[i].shunt_resistor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (!shunt_resistor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* Found the reference shunt resistor value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) shunt_resistor = input[i].shunt_resistor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* No summation if resistor values are different */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (shunt_resistor != input[i].shunt_resistor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return shunt_resistor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /* Lookup table for Bus and Shunt conversion times in usec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static const u16 ina3221_conv_time[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 140, 204, 332, 588, 1100, 2116, 4156, 8244,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /* Lookup table for number of samples using in averaging mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static const int ina3221_avg_samples[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 1, 4, 16, 64, 128, 256, 512, 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /* Converting update_interval in msec to conversion time in usec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static inline u32 ina3221_interval_ms_to_conv_time(u16 config, int interval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) u32 channels = hweight16(config & INA3221_CONFIG_CHs_EN_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) u32 samples_idx = INA3221_CONFIG_AVG(config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) u32 samples = ina3221_avg_samples[samples_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /* Bisect the result to Bus and Shunt conversion times */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return DIV_ROUND_CLOSEST(interval * 1000 / 2, channels * samples);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /* Converting CONFIG register value to update_interval in usec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) static inline u32 ina3221_reg_to_interval_us(u16 config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) u32 channels = hweight16(config & INA3221_CONFIG_CHs_EN_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) u32 vbus_ct_idx = INA3221_CONFIG_VBUS_CT(config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) u32 vsh_ct_idx = INA3221_CONFIG_VSH_CT(config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) u32 samples_idx = INA3221_CONFIG_AVG(config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) u32 samples = ina3221_avg_samples[samples_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) u32 vbus_ct = ina3221_conv_time[vbus_ct_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) u32 vsh_ct = ina3221_conv_time[vsh_ct_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* Calculate total conversion time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return channels * (vbus_ct + vsh_ct) * samples;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static inline int ina3221_wait_for_data(struct ina3221_data *ina)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) u32 wait, cvrf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) wait = ina3221_reg_to_interval_us(ina->reg_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /* Polling the CVRF bit to make sure read data is ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return regmap_field_read_poll_timeout(ina->fields[F_CVRF],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) cvrf, cvrf, wait, wait * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static int ina3221_read_value(struct ina3221_data *ina, unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) int *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) unsigned int regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ret = regmap_read(ina->regmap, reg, ®val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * Shunt Voltage Sum register has 14-bit value with 1-bit shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * Other Shunt Voltage registers have 12 bits with 3-bit shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (reg == INA3221_SHUNT_SUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) *val = sign_extend32(regval >> 1, 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) *val = sign_extend32(regval >> 3, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static const u8 ina3221_in_reg[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) INA3221_BUS1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) INA3221_BUS2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) INA3221_BUS3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) INA3221_SHUNT1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) INA3221_SHUNT2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) INA3221_SHUNT3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) INA3221_SHUNT_SUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static int ina3221_read_chip(struct device *dev, u32 attr, long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct ina3221_data *ina = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) int regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) case hwmon_chip_samples:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) regval = INA3221_CONFIG_AVG(ina->reg_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) *val = ina3221_avg_samples[regval];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) case hwmon_chip_update_interval:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* Return in msec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) *val = ina3221_reg_to_interval_us(ina->reg_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) *val = DIV_ROUND_CLOSEST(*val, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static int ina3221_read_in(struct device *dev, u32 attr, int channel, long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) const bool is_shunt = channel > INA3221_CHANNEL3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) struct ina3221_data *ina = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) u8 reg = ina3221_in_reg[channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) int regval, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * Translate shunt channel index to sensor channel index except
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * the 7th channel (6 since being 0-aligned) is for summation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (channel != 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) channel %= INA3221_NUM_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) case hwmon_in_input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (!ina3221_is_enabled(ina, channel))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /* Write CONFIG register to trigger a single-shot measurement */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (ina->single_shot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) regmap_write(ina->regmap, INA3221_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) ina->reg_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) ret = ina3221_wait_for_data(ina);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) ret = ina3221_read_value(ina, reg, ®val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * Scale of shunt voltage (uV): LSB is 40uV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * Scale of bus voltage (mV): LSB is 8mV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) *val = regval * (is_shunt ? 40 : 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) case hwmon_in_enable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) *val = ina3221_is_enabled(ina, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static const u8 ina3221_curr_reg[][INA3221_NUM_CHANNELS + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) [hwmon_curr_input] = { INA3221_SHUNT1, INA3221_SHUNT2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) INA3221_SHUNT3, INA3221_SHUNT_SUM },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) [hwmon_curr_max] = { INA3221_WARN1, INA3221_WARN2, INA3221_WARN3, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) [hwmon_curr_crit] = { INA3221_CRIT1, INA3221_CRIT2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) INA3221_CRIT3, INA3221_CRIT_SUM },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) [hwmon_curr_max_alarm] = { F_WF1, F_WF2, F_WF3, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) [hwmon_curr_crit_alarm] = { F_CF1, F_CF2, F_CF3, F_SF },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static int ina3221_read_curr(struct device *dev, u32 attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) int channel, long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct ina3221_data *ina = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct ina3221_input *input = ina->inputs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) u8 reg = ina3221_curr_reg[attr][channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) int resistance_uo, voltage_nv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) int regval, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (channel > INA3221_CHANNEL3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) resistance_uo = ina->summation_shunt_resistor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) resistance_uo = input[channel].shunt_resistor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) case hwmon_curr_input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (!ina3221_is_enabled(ina, channel))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /* Write CONFIG register to trigger a single-shot measurement */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (ina->single_shot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) regmap_write(ina->regmap, INA3221_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) ina->reg_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ret = ina3221_wait_for_data(ina);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) case hwmon_curr_crit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) case hwmon_curr_max:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (!resistance_uo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) ret = ina3221_read_value(ina, reg, ®val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) /* Scale of shunt voltage: LSB is 40uV (40000nV) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) voltage_nv = regval * 40000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /* Return current in mA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) *val = DIV_ROUND_CLOSEST(voltage_nv, resistance_uo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) case hwmon_curr_crit_alarm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) case hwmon_curr_max_alarm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /* No actual register read if channel is disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (!ina3221_is_enabled(ina, channel)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) /* Return 0 for alert flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) *val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) ret = regmap_field_read(ina->fields[reg], ®val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) *val = regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) static int ina3221_write_chip(struct device *dev, u32 attr, long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) struct ina3221_data *ina = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) int ret, idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) case hwmon_chip_samples:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) idx = find_closest(val, ina3221_avg_samples,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) ARRAY_SIZE(ina3221_avg_samples));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) tmp = (ina->reg_config & ~INA3221_CONFIG_AVG_MASK) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) (idx << INA3221_CONFIG_AVG_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) ret = regmap_write(ina->regmap, INA3221_CONFIG, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /* Update reg_config accordingly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) ina->reg_config = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) case hwmon_chip_update_interval:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) tmp = ina3221_interval_ms_to_conv_time(ina->reg_config, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) idx = find_closest(tmp, ina3221_conv_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) ARRAY_SIZE(ina3221_conv_time));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /* Update Bus and Shunt voltage conversion times */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) tmp = INA3221_CONFIG_VBUS_CT_MASK | INA3221_CONFIG_VSH_CT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) tmp = (ina->reg_config & ~tmp) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) (idx << INA3221_CONFIG_VBUS_CT_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) (idx << INA3221_CONFIG_VSH_CT_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) ret = regmap_write(ina->regmap, INA3221_CONFIG, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /* Update reg_config accordingly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) ina->reg_config = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static int ina3221_write_curr(struct device *dev, u32 attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) int channel, long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct ina3221_data *ina = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct ina3221_input *input = ina->inputs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) u8 reg = ina3221_curr_reg[attr][channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) int resistance_uo, current_ma, voltage_uv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) int regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (channel > INA3221_CHANNEL3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) resistance_uo = ina->summation_shunt_resistor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) resistance_uo = input[channel].shunt_resistor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (!resistance_uo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /* clamp current */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) current_ma = clamp_val(val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) INT_MIN / resistance_uo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) INT_MAX / resistance_uo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) voltage_uv = DIV_ROUND_CLOSEST(current_ma * resistance_uo, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) /* clamp voltage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) voltage_uv = clamp_val(voltage_uv, -163800, 163800);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * Formula to convert voltage_uv to register value:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * regval = (voltage_uv / scale) << shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * Note:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) * The scale is 40uV for all shunt voltage registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * Shunt Voltage Sum register left-shifts 1 bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * All other Shunt Voltage registers shift 3 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * Results:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * SHUNT_SUM: (1 / 40uV) << 1 = 1 / 20uV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) * SHUNT[1-3]: (1 / 40uV) << 3 = 1 / 5uV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (reg == INA3221_SHUNT_SUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) regval = DIV_ROUND_CLOSEST(voltage_uv, 20) & 0xfffe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) regval = DIV_ROUND_CLOSEST(voltage_uv, 5) & 0xfff8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return regmap_write(ina->regmap, reg, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) static int ina3221_write_enable(struct device *dev, int channel, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) struct ina3221_data *ina = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) u16 config, mask = INA3221_CONFIG_CHx_EN(channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) u16 config_old = ina->reg_config & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) config = enable ? mask : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* Bypass if enable status is not being changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (config_old == config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) /* For enabling routine, increase refcount and resume() at first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ret = pm_runtime_resume_and_get(ina->pm_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) dev_err(dev, "Failed to get PM runtime\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) /* Enable or disable the channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) tmp = (ina->reg_config & ~mask) | (config & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) ret = regmap_write(ina->regmap, INA3221_CONFIG, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) /* Cache the latest config register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) ina->reg_config = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) /* For disabling routine, decrease refcount or suspend() at last */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (!enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) pm_runtime_put_sync(ina->pm_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) dev_err(dev, "Failed to enable channel %d: error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) channel, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) pm_runtime_put_sync(ina->pm_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) static int ina3221_read(struct device *dev, enum hwmon_sensor_types type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) u32 attr, int channel, long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) struct ina3221_data *ina = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) mutex_lock(&ina->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) case hwmon_chip:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) ret = ina3221_read_chip(dev, attr, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) case hwmon_in:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /* 0-align channel ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) ret = ina3221_read_in(dev, attr, channel - 1, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) case hwmon_curr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) ret = ina3221_read_curr(dev, attr, channel, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) ret = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) mutex_unlock(&ina->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) static int ina3221_write(struct device *dev, enum hwmon_sensor_types type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) u32 attr, int channel, long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) struct ina3221_data *ina = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) mutex_lock(&ina->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) case hwmon_chip:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) ret = ina3221_write_chip(dev, attr, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) case hwmon_in:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) /* 0-align channel ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) ret = ina3221_write_enable(dev, channel - 1, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) case hwmon_curr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) ret = ina3221_write_curr(dev, attr, channel, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) ret = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) mutex_unlock(&ina->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static int ina3221_read_string(struct device *dev, enum hwmon_sensor_types type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) u32 attr, int channel, const char **str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct ina3221_data *ina = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) int index = channel - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (channel == 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) *str = "sum of shunt voltages";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) *str = ina->inputs[index].label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) static umode_t ina3221_is_visible(const void *drvdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) enum hwmon_sensor_types type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) u32 attr, int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) const struct ina3221_data *ina = drvdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) const struct ina3221_input *input = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) case hwmon_chip:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) case hwmon_chip_samples:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) case hwmon_chip_update_interval:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) return 0644;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) case hwmon_in:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) /* Ignore in0_ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (channel == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) case hwmon_in_label:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if (channel - 1 <= INA3221_CHANNEL3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) input = &ina->inputs[channel - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) else if (channel == 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) return 0444;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) /* Hide label node if label is not provided */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) return (input && input->label) ? 0444 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) case hwmon_in_input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) return 0444;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) case hwmon_in_enable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return 0644;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) case hwmon_curr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) case hwmon_curr_input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) case hwmon_curr_crit_alarm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) case hwmon_curr_max_alarm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) return 0444;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) case hwmon_curr_crit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) case hwmon_curr_max:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) return 0644;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) #define INA3221_HWMON_CURR_CONFIG (HWMON_C_INPUT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) HWMON_C_CRIT | HWMON_C_CRIT_ALARM | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) HWMON_C_MAX | HWMON_C_MAX_ALARM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) static const struct hwmon_channel_info *ina3221_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) HWMON_CHANNEL_INFO(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) HWMON_C_SAMPLES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) HWMON_C_UPDATE_INTERVAL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) HWMON_CHANNEL_INFO(in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) /* 0: dummy, skipped in is_visible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) HWMON_I_INPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) /* 1-3: input voltage Channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) HWMON_I_INPUT | HWMON_I_ENABLE | HWMON_I_LABEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) HWMON_I_INPUT | HWMON_I_ENABLE | HWMON_I_LABEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) HWMON_I_INPUT | HWMON_I_ENABLE | HWMON_I_LABEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) /* 4-6: shunt voltage Channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) HWMON_I_INPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) HWMON_I_INPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) HWMON_I_INPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) /* 7: summation of shunt voltage channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) HWMON_I_INPUT | HWMON_I_LABEL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) HWMON_CHANNEL_INFO(curr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) /* 1-3: current channels*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) INA3221_HWMON_CURR_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) INA3221_HWMON_CURR_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) INA3221_HWMON_CURR_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) /* 4: summation of current channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) HWMON_C_INPUT | HWMON_C_CRIT | HWMON_C_CRIT_ALARM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) static const struct hwmon_ops ina3221_hwmon_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) .is_visible = ina3221_is_visible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) .read_string = ina3221_read_string,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) .read = ina3221_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) .write = ina3221_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) static const struct hwmon_chip_info ina3221_chip_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) .ops = &ina3221_hwmon_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) .info = ina3221_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) /* Extra attribute groups */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) static ssize_t ina3221_shunt_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) struct ina3221_data *ina = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) unsigned int channel = sd_attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) struct ina3221_input *input = &ina->inputs[channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) return snprintf(buf, PAGE_SIZE, "%d\n", input->shunt_resistor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) static ssize_t ina3221_shunt_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) struct ina3221_data *ina = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) unsigned int channel = sd_attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) struct ina3221_input *input = &ina->inputs[channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) ret = kstrtoint(buf, 0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) val = clamp_val(val, 1, INT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) input->shunt_resistor = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) /* Update summation_shunt_resistor for summation channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) ina->summation_shunt_resistor = ina3221_summation_shunt_resistor(ina);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) /* shunt resistance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) static SENSOR_DEVICE_ATTR_RW(shunt1_resistor, ina3221_shunt, INA3221_CHANNEL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) static SENSOR_DEVICE_ATTR_RW(shunt2_resistor, ina3221_shunt, INA3221_CHANNEL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) static SENSOR_DEVICE_ATTR_RW(shunt3_resistor, ina3221_shunt, INA3221_CHANNEL3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) static struct attribute *ina3221_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) &sensor_dev_attr_shunt1_resistor.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) &sensor_dev_attr_shunt2_resistor.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) &sensor_dev_attr_shunt3_resistor.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) ATTRIBUTE_GROUPS(ina3221);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) static const struct regmap_range ina3221_yes_ranges[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) regmap_reg_range(INA3221_CONFIG, INA3221_BUS3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) regmap_reg_range(INA3221_SHUNT_SUM, INA3221_SHUNT_SUM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) regmap_reg_range(INA3221_MASK_ENABLE, INA3221_MASK_ENABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) static const struct regmap_access_table ina3221_volatile_table = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) .yes_ranges = ina3221_yes_ranges,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) .n_yes_ranges = ARRAY_SIZE(ina3221_yes_ranges),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) static const struct regmap_config ina3221_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) .reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) .val_bits = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) .cache_type = REGCACHE_RBTREE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) .volatile_table = &ina3221_volatile_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) static int ina3221_probe_child_from_dt(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) struct device_node *child,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) struct ina3221_data *ina)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) struct ina3221_input *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) ret = of_property_read_u32(child, "reg", &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) dev_err(dev, "missing reg property of %pOFn\n", child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) } else if (val > INA3221_CHANNEL3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) dev_err(dev, "invalid reg %d of %pOFn\n", val, child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) input = &ina->inputs[val];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) /* Log the disconnected channel input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if (!of_device_is_available(child)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) input->disconnected = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) /* Save the connected input label if available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) of_property_read_string(child, "label", &input->label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) /* Overwrite default shunt resistor value optionally */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (!of_property_read_u32(child, "shunt-resistor-micro-ohms", &val)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) if (val < 1 || val > INT_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) dev_err(dev, "invalid shunt resistor value %u of %pOFn\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) val, child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) input->shunt_resistor = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) static int ina3221_probe_from_dt(struct device *dev, struct ina3221_data *ina)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) const struct device_node *np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) struct device_node *child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) /* Compatible with non-DT platforms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) ina->single_shot = of_property_read_bool(np, "ti,single-shot");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) for_each_child_of_node(np, child) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) ret = ina3221_probe_child_from_dt(dev, child, ina);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) of_node_put(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) static int ina3221_probe(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) struct ina3221_data *ina;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) struct device *hwmon_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) ina = devm_kzalloc(dev, sizeof(*ina), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (!ina)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) ina->regmap = devm_regmap_init_i2c(client, &ina3221_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (IS_ERR(ina->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) dev_err(dev, "Unable to allocate register map\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) return PTR_ERR(ina->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) for (i = 0; i < F_MAX_FIELDS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) ina->fields[i] = devm_regmap_field_alloc(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) ina->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) ina3221_reg_fields[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) if (IS_ERR(ina->fields[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) dev_err(dev, "Unable to allocate regmap fields\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) return PTR_ERR(ina->fields[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) for (i = 0; i < INA3221_NUM_CHANNELS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) ina->inputs[i].shunt_resistor = INA3221_RSHUNT_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) ret = ina3221_probe_from_dt(dev, ina);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) dev_err(dev, "Unable to probe from device tree\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) /* The driver will be reset, so use reset value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) ina->reg_config = INA3221_CONFIG_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) /* Clear continuous bit to use single-shot mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) if (ina->single_shot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) ina->reg_config &= ~INA3221_CONFIG_MODE_CONTINUOUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) /* Disable channels if their inputs are disconnected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) for (i = 0; i < INA3221_NUM_CHANNELS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (ina->inputs[i].disconnected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) ina->reg_config &= ~INA3221_CONFIG_CHx_EN(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) /* Initialize summation_shunt_resistor for summation channel control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) ina->summation_shunt_resistor = ina3221_summation_shunt_resistor(ina);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) ina->pm_dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) mutex_init(&ina->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) dev_set_drvdata(dev, ina);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) /* Enable PM runtime -- status is suspended by default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) pm_runtime_enable(ina->pm_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) /* Initialize (resume) the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) for (i = 0; i < INA3221_NUM_CHANNELS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (ina->inputs[i].disconnected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) /* Match the refcount with number of enabled channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) ret = pm_runtime_get_sync(ina->pm_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, ina,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) &ina3221_chip_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) ina3221_groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) if (IS_ERR(hwmon_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) dev_err(dev, "Unable to register hwmon device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) ret = PTR_ERR(hwmon_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) pm_runtime_disable(ina->pm_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) pm_runtime_set_suspended(ina->pm_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) /* pm_runtime_put_noidle() will decrease the PM refcount until 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) for (i = 0; i < INA3221_NUM_CHANNELS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) pm_runtime_put_noidle(ina->pm_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) mutex_destroy(&ina->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) static int ina3221_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) struct ina3221_data *ina = dev_get_drvdata(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) pm_runtime_disable(ina->pm_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) pm_runtime_set_suspended(ina->pm_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) /* pm_runtime_put_noidle() will decrease the PM refcount until 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) for (i = 0; i < INA3221_NUM_CHANNELS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) pm_runtime_put_noidle(ina->pm_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) mutex_destroy(&ina->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) static int __maybe_unused ina3221_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) struct ina3221_data *ina = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) /* Save config register value and enable cache-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) ret = regmap_read(ina->regmap, INA3221_CONFIG, &ina->reg_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) /* Set to power-down mode for power saving */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) ret = regmap_update_bits(ina->regmap, INA3221_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) INA3221_CONFIG_MODE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) INA3221_CONFIG_MODE_POWERDOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) regcache_cache_only(ina->regmap, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) regcache_mark_dirty(ina->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) static int __maybe_unused ina3221_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) struct ina3221_data *ina = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) regcache_cache_only(ina->regmap, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) /* Software reset the chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) ret = regmap_field_write(ina->fields[F_RST], true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) dev_err(dev, "Unable to reset device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) /* Restore cached register values to hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) ret = regcache_sync(ina->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) /* Restore config register value to hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) ret = regmap_write(ina->regmap, INA3221_CONFIG, ina->reg_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) /* Initialize summation channel control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) if (ina->summation_shunt_resistor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) * Take all three channels into summation by default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) * Shunt measurements of disconnected channels should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) * be 0, so it does not matter for summation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) ret = regmap_update_bits(ina->regmap, INA3221_MASK_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) INA3221_MASK_ENABLE_SCC_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) INA3221_MASK_ENABLE_SCC_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) dev_err(dev, "Unable to control summation channel\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) static const struct dev_pm_ops ina3221_pm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) pm_runtime_force_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) SET_RUNTIME_PM_OPS(ina3221_suspend, ina3221_resume, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) static const struct of_device_id ina3221_of_match_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) { .compatible = "ti,ina3221", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) MODULE_DEVICE_TABLE(of, ina3221_of_match_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) static const struct i2c_device_id ina3221_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) { "ina3221", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) MODULE_DEVICE_TABLE(i2c, ina3221_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) static struct i2c_driver ina3221_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) .probe_new = ina3221_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) .remove = ina3221_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) .name = INA3221_DRIVER_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) .of_match_table = ina3221_of_match_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) .pm = &ina3221_pm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) .id_table = ina3221_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) module_i2c_driver(ina3221_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) MODULE_DESCRIPTION("Texas Instruments INA3221 HWMon Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) MODULE_LICENSE("GPL v2");