^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // Fuel gauge driver for Maxim 17042 / 8966 / 8997
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) // Note that Maxim 8966 and 8997 are mfd and this is its subdevice.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) // Copyright (C) 2011 Samsung Electronics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) // MyungJoo Ham <myungjoo.ham@samsung.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) // This driver is based on max17040_battery.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/pm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/mod_devicetable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/power_supply.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/power/max17042_battery.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* Status register bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define STATUS_POR_BIT (1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define STATUS_BST_BIT (1 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define STATUS_VMN_BIT (1 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define STATUS_TMN_BIT (1 << 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define STATUS_SMN_BIT (1 << 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define STATUS_BI_BIT (1 << 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define STATUS_VMX_BIT (1 << 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define STATUS_TMX_BIT (1 << 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define STATUS_SMX_BIT (1 << 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define STATUS_BR_BIT (1 << 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /* Interrupt mask bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define CONFIG_ALRT_BIT_ENBL (1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define STATUS_INTR_SOCMIN_BIT (1 << 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define STATUS_INTR_SOCMAX_BIT (1 << 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define VFSOC0_LOCK 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define VFSOC0_UNLOCK 0x0080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define MODEL_UNLOCK1 0X0059
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define MODEL_UNLOCK2 0X00C4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define MODEL_LOCK1 0X0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define MODEL_LOCK2 0X0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define dQ_ACC_DIV 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define dP_ACC_100 0x1900
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define dP_ACC_200 0x3200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define MAX17042_VMAX_TOLERANCE 50 /* 50 mV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct max17042_chip {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct power_supply *battery;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) enum max170xx_chip_type chip_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct max17042_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct work_struct work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) int init_complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static enum power_supply_property max17042_battery_props[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) POWER_SUPPLY_PROP_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) POWER_SUPPLY_PROP_PRESENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) POWER_SUPPLY_PROP_TECHNOLOGY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) POWER_SUPPLY_PROP_CYCLE_COUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) POWER_SUPPLY_PROP_VOLTAGE_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) POWER_SUPPLY_PROP_VOLTAGE_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) POWER_SUPPLY_PROP_VOLTAGE_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) POWER_SUPPLY_PROP_VOLTAGE_AVG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) POWER_SUPPLY_PROP_VOLTAGE_OCV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) POWER_SUPPLY_PROP_CAPACITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) POWER_SUPPLY_PROP_CHARGE_FULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) POWER_SUPPLY_PROP_CHARGE_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) POWER_SUPPLY_PROP_CHARGE_COUNTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) POWER_SUPPLY_PROP_TEMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) POWER_SUPPLY_PROP_TEMP_ALERT_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) POWER_SUPPLY_PROP_TEMP_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) POWER_SUPPLY_PROP_TEMP_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) POWER_SUPPLY_PROP_HEALTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) POWER_SUPPLY_PROP_SCOPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) // these two have to be at the end on the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) POWER_SUPPLY_PROP_CURRENT_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) POWER_SUPPLY_PROP_CURRENT_AVG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static int max17042_get_temperature(struct max17042_chip *chip, int *temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct regmap *map = chip->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) ret = regmap_read(map, MAX17042_TEMP, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) *temp = sign_extend32(data, 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* The value is converted into deci-centigrade scale */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* Units of LSB = 1 / 256 degree Celsius */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) *temp = *temp * 10 / 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static int max17042_get_status(struct max17042_chip *chip, int *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) int ret, charge_full, charge_now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int avg_current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) ret = power_supply_am_i_supplied(chip->battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) *status = POWER_SUPPLY_STATUS_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) *status = POWER_SUPPLY_STATUS_DISCHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * The MAX170xx has builtin end-of-charge detection and will update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * FullCAP to match RepCap when it detects end of charging.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * When this cycle the battery gets charged to a higher (calculated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * capacity then the previous cycle then FullCAP will get updated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * contineously once end-of-charge detection kicks in, so allow the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * 2 to differ a bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ret = regmap_read(chip->regmap, MAX17042_FullCAP, &charge_full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) ret = regmap_read(chip->regmap, MAX17042_RepCap, &charge_now);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if ((charge_full - charge_now) <= MAX17042_FULL_THRESHOLD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) *status = POWER_SUPPLY_STATUS_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * Even though we are supplied, we may still be discharging if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * supply is e.g. only delivering 5V 0.5A. Check current if available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (!chip->pdata->enable_current_sense) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) *status = POWER_SUPPLY_STATUS_CHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ret = regmap_read(chip->regmap, MAX17042_AvgCurrent, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) avg_current = sign_extend32(data, 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) avg_current *= 1562500 / chip->pdata->r_sns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (avg_current > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) *status = POWER_SUPPLY_STATUS_CHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) *status = POWER_SUPPLY_STATUS_DISCHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static int max17042_get_battery_health(struct max17042_chip *chip, int *health)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) int temp, vavg, vbatt, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ret = regmap_read(chip->regmap, MAX17042_AvgVCELL, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) goto health_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* bits [0-3] unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) vavg = val * 625 / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /* Convert to millivolts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) vavg /= 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ret = regmap_read(chip->regmap, MAX17042_VCELL, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) goto health_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /* bits [0-3] unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) vbatt = val * 625 / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* Convert to millivolts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) vbatt /= 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (vavg < chip->pdata->vmin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) *health = POWER_SUPPLY_HEALTH_DEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (vbatt > chip->pdata->vmax + MAX17042_VMAX_TOLERANCE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) *health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ret = max17042_get_temperature(chip, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) goto health_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (temp < chip->pdata->temp_min) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) *health = POWER_SUPPLY_HEALTH_COLD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (temp > chip->pdata->temp_max) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) *health = POWER_SUPPLY_HEALTH_OVERHEAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) *health = POWER_SUPPLY_HEALTH_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) health_error:
^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) static int max17042_get_property(struct power_supply *psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) enum power_supply_property psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct max17042_chip *chip = power_supply_get_drvdata(psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct regmap *map = chip->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) u64 data64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (!chip->init_complete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) case POWER_SUPPLY_PROP_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) ret = max17042_get_status(chip, &val->intval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) case POWER_SUPPLY_PROP_PRESENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) ret = regmap_read(map, MAX17042_STATUS, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (data & MAX17042_STATUS_BattAbsent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) val->intval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) val->intval = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) case POWER_SUPPLY_PROP_TECHNOLOGY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) case POWER_SUPPLY_PROP_CYCLE_COUNT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) ret = regmap_read(map, MAX17042_Cycles, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) val->intval = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) case POWER_SUPPLY_PROP_VOLTAGE_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) ret = regmap_read(map, MAX17042_MinMaxVolt, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) val->intval = data >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) val->intval *= 20000; /* Units of LSB = 20mV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) case POWER_SUPPLY_PROP_VOLTAGE_MIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) ret = regmap_read(map, MAX17042_MinMaxVolt, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) val->intval = (data & 0xff) * 20000; /* Units of 20mV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) ret = regmap_read(map, MAX17042_V_empty, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) else if (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) ret = regmap_read(map, MAX17055_V_empty, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) ret = regmap_read(map, MAX17047_V_empty, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) val->intval = data >> 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) val->intval *= 10000; /* Units of LSB = 10mV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) case POWER_SUPPLY_PROP_VOLTAGE_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) ret = regmap_read(map, MAX17042_VCELL, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) val->intval = data * 625 / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) case POWER_SUPPLY_PROP_VOLTAGE_AVG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) ret = regmap_read(map, MAX17042_AvgVCELL, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) val->intval = data * 625 / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) case POWER_SUPPLY_PROP_VOLTAGE_OCV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) ret = regmap_read(map, MAX17042_OCVInternal, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) val->intval = data * 625 / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) case POWER_SUPPLY_PROP_CAPACITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (chip->pdata->enable_current_sense)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) ret = regmap_read(map, MAX17042_RepSOC, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) ret = regmap_read(map, MAX17042_VFSOC, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) val->intval = data >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) ret = regmap_read(map, MAX17042_DesignCap, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) data64 = data * 5000000ll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) do_div(data64, chip->pdata->r_sns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) val->intval = data64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) case POWER_SUPPLY_PROP_CHARGE_FULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) ret = regmap_read(map, MAX17042_FullCAP, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) data64 = data * 5000000ll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) do_div(data64, chip->pdata->r_sns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) val->intval = data64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) case POWER_SUPPLY_PROP_CHARGE_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ret = regmap_read(map, MAX17042_RepCap, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) data64 = data * 5000000ll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) do_div(data64, chip->pdata->r_sns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) val->intval = data64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) case POWER_SUPPLY_PROP_CHARGE_COUNTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) ret = regmap_read(map, MAX17042_QH, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) val->intval = data * 1000 / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) case POWER_SUPPLY_PROP_TEMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) ret = max17042_get_temperature(chip, &val->intval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) case POWER_SUPPLY_PROP_TEMP_ALERT_MIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) ret = regmap_read(map, MAX17042_TALRT_Th, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) /* LSB is Alert Minimum. In deci-centigrade */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) val->intval = sign_extend32(data & 0xff, 7) * 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) ret = regmap_read(map, MAX17042_TALRT_Th, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /* MSB is Alert Maximum. In deci-centigrade */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) val->intval = sign_extend32(data >> 8, 7) * 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) case POWER_SUPPLY_PROP_TEMP_MIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) val->intval = chip->pdata->temp_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) case POWER_SUPPLY_PROP_TEMP_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) val->intval = chip->pdata->temp_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) case POWER_SUPPLY_PROP_HEALTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) ret = max17042_get_battery_health(chip, &val->intval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) case POWER_SUPPLY_PROP_SCOPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) case POWER_SUPPLY_PROP_CURRENT_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (chip->pdata->enable_current_sense) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) ret = regmap_read(map, MAX17042_Current, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) val->intval = sign_extend32(data, 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) val->intval *= 1562500 / chip->pdata->r_sns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) case POWER_SUPPLY_PROP_CURRENT_AVG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (chip->pdata->enable_current_sense) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) ret = regmap_read(map, MAX17042_AvgCurrent, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) val->intval = sign_extend32(data, 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) val->intval *= 1562500 / chip->pdata->r_sns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) ret = regmap_read(map, MAX17042_TTE, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) val->intval = data * 5625 / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static int max17042_set_property(struct power_supply *psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) enum power_supply_property psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) const union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct max17042_chip *chip = power_supply_get_drvdata(psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) struct regmap *map = chip->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) int8_t temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) case POWER_SUPPLY_PROP_TEMP_ALERT_MIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) ret = regmap_read(map, MAX17042_TALRT_Th, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /* Input in deci-centigrade, convert to centigrade */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) temp = val->intval / 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) /* force min < max */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (temp >= (int8_t)(data >> 8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) temp = (int8_t)(data >> 8) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) /* Write both MAX and MIN ALERT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) data = (data & 0xff00) + temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) ret = regmap_write(map, MAX17042_TALRT_Th, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) ret = regmap_read(map, MAX17042_TALRT_Th, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) /* Input in Deci-Centigrade, convert to centigrade */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) temp = val->intval / 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) /* force max > min */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (temp <= (int8_t)(data & 0xff))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) temp = (int8_t)(data & 0xff) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) /* Write both MAX and MIN ALERT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) data = (data & 0xff) + (temp << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) ret = regmap_write(map, MAX17042_TALRT_Th, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) static int max17042_property_is_writeable(struct power_supply *psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) enum power_supply_property psp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) case POWER_SUPPLY_PROP_TEMP_ALERT_MIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) static void max17042_external_power_changed(struct power_supply *psy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) power_supply_changed(psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) static int max17042_write_verify_reg(struct regmap *map, u8 reg, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) int retries = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) u32 read_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) ret = regmap_write(map, reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) regmap_read(map, reg, &read_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (read_value != value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) retries--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) } while (retries && read_value != value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) pr_err("%s: err %d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return ret;
^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) static inline void max17042_override_por(struct regmap *map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) u8 reg, u16 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) regmap_write(map, reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) static inline void max17042_unlock_model(struct max17042_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) struct regmap *map = chip->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) regmap_write(map, MAX17042_MLOCKReg1, MODEL_UNLOCK1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) regmap_write(map, MAX17042_MLOCKReg2, MODEL_UNLOCK2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static inline void max17042_lock_model(struct max17042_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) struct regmap *map = chip->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) regmap_write(map, MAX17042_MLOCKReg1, MODEL_LOCK1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) regmap_write(map, MAX17042_MLOCKReg2, MODEL_LOCK2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) static inline void max17042_write_model_data(struct max17042_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) u8 addr, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) struct regmap *map = chip->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) for (i = 0; i < size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) regmap_write(map, addr + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) chip->pdata->config_data->cell_char_tbl[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) static inline void max17042_read_model_data(struct max17042_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) u8 addr, u16 *data, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) struct regmap *map = chip->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) for (i = 0; i < size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) regmap_read(map, addr + i, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) data[i] = (u16)tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) static inline int max17042_model_data_compare(struct max17042_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) u16 *data1, u16 *data2, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (memcmp(data1, data2, size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) dev_err(&chip->client->dev, "%s compare failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) for (i = 0; i < size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) dev_info(&chip->client->dev, "0x%x, 0x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) data1[i], data2[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) dev_info(&chip->client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) static int max17042_init_model(struct max17042_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) int table_size = ARRAY_SIZE(chip->pdata->config_data->cell_char_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) u16 *temp_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) temp_data = kcalloc(table_size, sizeof(*temp_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if (!temp_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) max17042_unlock_model(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) max17042_write_model_data(chip, MAX17042_MODELChrTbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) table_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) max17042_read_model_data(chip, MAX17042_MODELChrTbl, temp_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) table_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) ret = max17042_model_data_compare(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) chip->pdata->config_data->cell_char_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) temp_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) table_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) max17042_lock_model(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) kfree(temp_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) static int max17042_verify_model_lock(struct max17042_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) int table_size = ARRAY_SIZE(chip->pdata->config_data->cell_char_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) u16 *temp_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) temp_data = kcalloc(table_size, sizeof(*temp_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (!temp_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) max17042_read_model_data(chip, MAX17042_MODELChrTbl, temp_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) table_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) for (i = 0; i < table_size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (temp_data[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) kfree(temp_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) static void max17042_write_config_regs(struct max17042_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) struct max17042_config_data *config = chip->pdata->config_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) struct regmap *map = chip->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) regmap_write(map, MAX17042_CONFIG, config->config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) regmap_write(map, MAX17042_LearnCFG, config->learn_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) regmap_write(map, MAX17042_FilterCFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) config->filter_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) regmap_write(map, MAX17042_RelaxCFG, config->relax_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17047 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) chip->chip_type == MAXIM_DEVICE_TYPE_MAX17050 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) chip->chip_type == MAXIM_DEVICE_TYPE_MAX17055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) regmap_write(map, MAX17047_FullSOCThr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) config->full_soc_thresh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) static void max17042_write_custom_regs(struct max17042_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) struct max17042_config_data *config = chip->pdata->config_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) struct regmap *map = chip->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) max17042_write_verify_reg(map, MAX17042_RCOMP0, config->rcomp0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) max17042_write_verify_reg(map, MAX17042_TempCo, config->tcompc0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) max17042_write_verify_reg(map, MAX17042_ICHGTerm, config->ichgt_term);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17042) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) regmap_write(map, MAX17042_EmptyTempCo, config->empty_tempco);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) max17042_write_verify_reg(map, MAX17042_K_empty0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) config->kempty0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) max17042_write_verify_reg(map, MAX17047_QRTbl00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) config->qrtbl00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) max17042_write_verify_reg(map, MAX17047_QRTbl10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) config->qrtbl10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) max17042_write_verify_reg(map, MAX17047_QRTbl20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) config->qrtbl20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) max17042_write_verify_reg(map, MAX17047_QRTbl30,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) config->qrtbl30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) static void max17042_update_capacity_regs(struct max17042_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) struct max17042_config_data *config = chip->pdata->config_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) struct regmap *map = chip->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) max17042_write_verify_reg(map, MAX17042_FullCAP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) config->fullcap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) regmap_write(map, MAX17042_DesignCap, config->design_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) max17042_write_verify_reg(map, MAX17042_FullCAPNom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) config->fullcapnom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) static void max17042_reset_vfsoc0_reg(struct max17042_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) unsigned int vfSoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) struct regmap *map = chip->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) regmap_read(map, MAX17042_VFSOC, &vfSoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) regmap_write(map, MAX17042_VFSOC0Enable, VFSOC0_UNLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) max17042_write_verify_reg(map, MAX17042_VFSOC0, vfSoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) regmap_write(map, MAX17042_VFSOC0Enable, VFSOC0_LOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) static void max17042_load_new_capacity_params(struct max17042_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) u32 full_cap0, rep_cap, dq_acc, vfSoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) u32 rem_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) struct max17042_config_data *config = chip->pdata->config_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct regmap *map = chip->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) regmap_read(map, MAX17042_FullCAP0, &full_cap0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) regmap_read(map, MAX17042_VFSOC, &vfSoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) /* fg_vfSoc needs to shifted by 8 bits to get the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) * perc in 1% accuracy, to get the right rem_cap multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) * full_cap0, fg_vfSoc and devide by 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) rem_cap = ((vfSoc >> 8) * full_cap0) / 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) max17042_write_verify_reg(map, MAX17042_RemCap, rem_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) rep_cap = rem_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) max17042_write_verify_reg(map, MAX17042_RepCap, rep_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) /* Write dQ_acc to 200% of Capacity and dP_acc to 200% */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) dq_acc = config->fullcap / dQ_ACC_DIV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) max17042_write_verify_reg(map, MAX17042_dQacc, dq_acc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) max17042_write_verify_reg(map, MAX17042_dPacc, dP_ACC_200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) max17042_write_verify_reg(map, MAX17042_FullCAP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) config->fullcap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) regmap_write(map, MAX17042_DesignCap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) config->design_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) max17042_write_verify_reg(map, MAX17042_FullCAPNom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) config->fullcapnom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) /* Update SOC register with new SOC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) regmap_write(map, MAX17042_RepSOC, vfSoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) * Block write all the override values coming from platform data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) * This function MUST be called before the POR initialization proceedure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) * specified by maxim.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) static inline void max17042_override_por_values(struct max17042_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) struct regmap *map = chip->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) struct max17042_config_data *config = chip->pdata->config_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) max17042_override_por(map, MAX17042_TGAIN, config->tgain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) max17042_override_por(map, MAX17042_TOFF, config->toff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) max17042_override_por(map, MAX17042_CGAIN, config->cgain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) max17042_override_por(map, MAX17042_COFF, config->coff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) max17042_override_por(map, MAX17042_VALRT_Th, config->valrt_thresh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) max17042_override_por(map, MAX17042_TALRT_Th, config->talrt_thresh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) max17042_override_por(map, MAX17042_SALRT_Th,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) config->soc_alrt_thresh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) max17042_override_por(map, MAX17042_CONFIG, config->config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) max17042_override_por(map, MAX17042_SHDNTIMER, config->shdntimer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) max17042_override_por(map, MAX17042_DesignCap, config->design_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) max17042_override_por(map, MAX17042_ICHGTerm, config->ichgt_term);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) max17042_override_por(map, MAX17042_AtRate, config->at_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) max17042_override_por(map, MAX17042_LearnCFG, config->learn_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) max17042_override_por(map, MAX17042_FilterCFG, config->filter_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) max17042_override_por(map, MAX17042_RelaxCFG, config->relax_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) max17042_override_por(map, MAX17042_MiscCFG, config->misc_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) max17042_override_por(map, MAX17042_MaskSOC, config->masksoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) max17042_override_por(map, MAX17042_FullCAP, config->fullcap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) max17042_override_por(map, MAX17042_FullCAPNom, config->fullcapnom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) max17042_override_por(map, MAX17042_SOC_empty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) config->socempty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) max17042_override_por(map, MAX17042_LAvg_empty, config->lavg_empty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) max17042_override_por(map, MAX17042_dQacc, config->dqacc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) max17042_override_por(map, MAX17042_dPacc, config->dpacc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) max17042_override_por(map, MAX17042_V_empty, config->vempty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) max17042_override_por(map, MAX17055_V_empty, config->vempty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) max17042_override_por(map, MAX17047_V_empty, config->vempty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) max17042_override_por(map, MAX17042_TempNom, config->temp_nom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) max17042_override_por(map, MAX17042_TempLim, config->temp_lim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) max17042_override_por(map, MAX17042_FCTC, config->fctc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) max17042_override_por(map, MAX17042_RCOMP0, config->rcomp0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) max17042_override_por(map, MAX17042_TempCo, config->tcompc0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (chip->chip_type &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) ((chip->chip_type == MAXIM_DEVICE_TYPE_MAX17042) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17047) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17050))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) max17042_override_por(map, MAX17042_EmptyTempCo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) config->empty_tempco);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) max17042_override_por(map, MAX17042_K_empty0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) config->kempty0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) static int max17042_init_chip(struct max17042_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) struct regmap *map = chip->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) max17042_override_por_values(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) /* After Power up, the MAX17042 requires 500mS in order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) * to perform signal debouncing and initial SOC reporting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) msleep(500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) /* Initialize configaration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) max17042_write_config_regs(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) /* write cell characterization data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) ret = max17042_init_model(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) dev_err(&chip->client->dev, "%s init failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) ret = max17042_verify_model_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) dev_err(&chip->client->dev, "%s lock verify failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) /* write custom parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) max17042_write_custom_regs(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) /* update capacity params */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) max17042_update_capacity_regs(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) /* delay must be atleast 350mS to allow VFSOC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) * to be calculated from the new configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) msleep(350);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) /* reset vfsoc0 reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) max17042_reset_vfsoc0_reg(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) /* load new capacity params */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) max17042_load_new_capacity_params(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) /* Init complete, Clear the POR bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) regmap_update_bits(map, MAX17042_STATUS, STATUS_POR_BIT, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) static void max17042_set_soc_threshold(struct max17042_chip *chip, u16 off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) struct regmap *map = chip->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) u32 soc, soc_tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) /* program interrupt thesholds such that we should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) * get interrupt for every 'off' perc change in the soc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) regmap_read(map, MAX17042_RepSOC, &soc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) soc >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) soc_tr = (soc + off) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (off < soc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) soc_tr |= soc - off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) regmap_write(map, MAX17042_SALRT_Th, soc_tr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) static irqreturn_t max17042_thread_handler(int id, void *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) struct max17042_chip *chip = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) ret = regmap_read(chip->regmap, MAX17042_STATUS, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if ((val & STATUS_INTR_SOCMIN_BIT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) (val & STATUS_INTR_SOCMAX_BIT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) dev_info(&chip->client->dev, "SOC threshold INTR\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) max17042_set_soc_threshold(chip, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) /* we implicitly handle all alerts via power_supply_changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) regmap_clear_bits(chip->regmap, MAX17042_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 0xFFFF & ~(STATUS_POR_BIT | STATUS_BST_BIT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) power_supply_changed(chip->battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) static void max17042_init_worker(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) struct max17042_chip *chip = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) struct max17042_chip, work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) /* Initialize registers according to values from the platform data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) if (chip->pdata->enable_por_init && chip->pdata->config_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) ret = max17042_init_chip(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) chip->init_complete = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) static struct max17042_platform_data *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) max17042_get_of_pdata(struct max17042_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) struct device *dev = &chip->client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) struct device_node *np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) u32 prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) struct max17042_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) if (!pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) return NULL;
^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) * Require current sense resistor value to be specified for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) * current-sense functionality to be enabled at all.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) if (of_property_read_u32(np, "maxim,rsns-microohm", &prop) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) pdata->r_sns = prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) pdata->enable_current_sense = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if (of_property_read_s32(np, "maxim,cold-temp", &pdata->temp_min))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) pdata->temp_min = INT_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (of_property_read_s32(np, "maxim,over-heat-temp", &pdata->temp_max))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) pdata->temp_max = INT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (of_property_read_s32(np, "maxim,dead-volt", &pdata->vmin))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) pdata->vmin = INT_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (of_property_read_s32(np, "maxim,over-volt", &pdata->vmax))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) pdata->vmax = INT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) return pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) static struct max17042_reg_data max17047_default_pdata_init_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) * Some firmwares do not set FullSOCThr, Enable End-of-Charge Detection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) * when the voltage FG reports 95%, as recommended in the datasheet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) { MAX17047_FullSOCThr, MAX17042_BATTERY_FULL << 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) static struct max17042_platform_data *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) max17042_get_default_pdata(struct max17042_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) struct device *dev = &chip->client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) struct max17042_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) int ret, misc_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) * The MAX17047 gets used on x86 where we might not have pdata, assume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) * the firmware will already have initialized the fuel-gauge and provide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) * default values for the non init bits to make things work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) if (!pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) return pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) if ((chip->chip_type == MAXIM_DEVICE_TYPE_MAX17047) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17050)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) pdata->init_data = max17047_default_pdata_init_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) pdata->num_init_data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) ARRAY_SIZE(max17047_default_pdata_init_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) ret = regmap_read(chip->regmap, MAX17042_MiscCFG, &misc_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) /* If bits 0-1 are set to 3 then only Voltage readings are used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if ((misc_cfg & 0x3) == 0x3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) pdata->enable_current_sense = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) pdata->enable_current_sense = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) pdata->vmin = MAX17042_DEFAULT_VMIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) pdata->vmax = MAX17042_DEFAULT_VMAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) pdata->temp_min = MAX17042_DEFAULT_TEMP_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) pdata->temp_max = MAX17042_DEFAULT_TEMP_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) return pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) static struct max17042_platform_data *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) max17042_get_pdata(struct max17042_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) struct device *dev = &chip->client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if (dev->of_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) return max17042_get_of_pdata(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) if (dev->platform_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) return dev->platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) return max17042_get_default_pdata(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) static const struct regmap_config max17042_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) .reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) .val_bits = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) .val_format_endian = REGMAP_ENDIAN_NATIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) static const struct power_supply_desc max17042_psy_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) .name = "max170xx_battery",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) .type = POWER_SUPPLY_TYPE_BATTERY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) .get_property = max17042_get_property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) .set_property = max17042_set_property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) .property_is_writeable = max17042_property_is_writeable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) .external_power_changed = max17042_external_power_changed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) .properties = max17042_battery_props,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) .num_properties = ARRAY_SIZE(max17042_battery_props),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) static const struct power_supply_desc max17042_no_current_sense_psy_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) .name = "max170xx_battery",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) .type = POWER_SUPPLY_TYPE_BATTERY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) .get_property = max17042_get_property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) .set_property = max17042_set_property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) .property_is_writeable = max17042_property_is_writeable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) .properties = max17042_battery_props,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) .num_properties = ARRAY_SIZE(max17042_battery_props) - 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) static void max17042_stop_work(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) struct max17042_chip *chip = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) cancel_work_sync(&chip->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) static int max17042_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) struct i2c_adapter *adapter = client->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) const struct power_supply_desc *max17042_desc = &max17042_psy_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) struct power_supply_config psy_cfg = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) const struct acpi_device_id *acpi_id = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) struct max17042_chip *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) if (!chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) chip->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) chip->chip_type = id->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) if (!acpi_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) chip->chip_type = acpi_id->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) chip->regmap = devm_regmap_init_i2c(client, &max17042_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) if (IS_ERR(chip->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) dev_err(&client->dev, "Failed to initialize regmap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) chip->pdata = max17042_get_pdata(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (!chip->pdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) dev_err(&client->dev, "no platform data provided\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) i2c_set_clientdata(client, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) psy_cfg.drv_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) psy_cfg.of_node = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) /* When current is not measured,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) * CURRENT_NOW and CURRENT_AVG properties should be invisible. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) if (!chip->pdata->enable_current_sense)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) max17042_desc = &max17042_no_current_sense_psy_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) if (chip->pdata->r_sns == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) chip->pdata->r_sns = MAX17042_DEFAULT_SNS_RESISTOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) if (chip->pdata->init_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) for (i = 0; i < chip->pdata->num_init_data; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) regmap_write(chip->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) chip->pdata->init_data[i].addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) chip->pdata->init_data[i].data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (!chip->pdata->enable_current_sense) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) regmap_write(chip->regmap, MAX17042_CGAIN, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) regmap_write(chip->regmap, MAX17042_MiscCFG, 0x0003);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) regmap_write(chip->regmap, MAX17042_LearnCFG, 0x0007);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) chip->battery = devm_power_supply_register(&client->dev, max17042_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) &psy_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) if (IS_ERR(chip->battery)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) dev_err(&client->dev, "failed: power supply register\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) return PTR_ERR(chip->battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) if (client->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) unsigned int flags = IRQF_ONESHOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) * On ACPI systems the IRQ may be handled by ACPI-event code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) * so we need to share (if the ACPI code is willing to share).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) if (acpi_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) flags |= IRQF_SHARED | IRQF_PROBE_SHARED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) ret = devm_request_threaded_irq(&client->dev, client->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) max17042_thread_handler, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) chip->battery->desc->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) regmap_update_bits(chip->regmap, MAX17042_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) CONFIG_ALRT_BIT_ENBL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) CONFIG_ALRT_BIT_ENBL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) max17042_set_soc_threshold(chip, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) client->irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) if (ret != -EBUSY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) dev_err(&client->dev, "Failed to get IRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) /* Not able to update the charge threshold when exceeded? -> disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) if (!client->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) regmap_write(chip->regmap, MAX17042_SALRT_Th, 0xff00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) regmap_read(chip->regmap, MAX17042_STATUS, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (val & STATUS_POR_BIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) INIT_WORK(&chip->work, max17042_init_worker);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) ret = devm_add_action(&client->dev, max17042_stop_work, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) schedule_work(&chip->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) chip->init_complete = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) static int max17042_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) struct max17042_chip *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) * disable the irq and enable irq_wake
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) * capability to the interrupt line.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) if (chip->client->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) disable_irq(chip->client->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) enable_irq_wake(chip->client->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) static int max17042_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) struct max17042_chip *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) if (chip->client->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) disable_irq_wake(chip->client->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) enable_irq(chip->client->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) /* re-program the SOC thresholds to 1% change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) max17042_set_soc_threshold(chip, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) static SIMPLE_DEV_PM_OPS(max17042_pm_ops, max17042_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) max17042_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) #ifdef CONFIG_ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) static const struct acpi_device_id max17042_acpi_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) { "MAX17047", MAXIM_DEVICE_TYPE_MAX17047 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) MODULE_DEVICE_TABLE(acpi, max17042_acpi_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) static const struct of_device_id max17042_dt_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) { .compatible = "maxim,max17042" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) { .compatible = "maxim,max17047" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) { .compatible = "maxim,max17050" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) { .compatible = "maxim,max17055" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) MODULE_DEVICE_TABLE(of, max17042_dt_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) static const struct i2c_device_id max17042_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) { "max17042", MAXIM_DEVICE_TYPE_MAX17042 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) { "max17047", MAXIM_DEVICE_TYPE_MAX17047 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) { "max17050", MAXIM_DEVICE_TYPE_MAX17050 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) { "max17055", MAXIM_DEVICE_TYPE_MAX17055 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) MODULE_DEVICE_TABLE(i2c, max17042_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) static struct i2c_driver max17042_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) .name = "max17042",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) .acpi_match_table = ACPI_PTR(max17042_acpi_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) .of_match_table = of_match_ptr(max17042_dt_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) .pm = &max17042_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) .probe = max17042_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) .id_table = max17042_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) module_i2c_driver(max17042_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) MODULE_DESCRIPTION("MAX17042 Fuel Gauge");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) MODULE_LICENSE("GPL");