^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) // max14577_charger.c - Battery charger driver for the Maxim 14577/77836
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) // Copyright (C) 2013,2014 Samsung Electronics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) // Krzysztof Kozlowski <krzk@kernel.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/power_supply.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/mfd/max14577-private.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/mfd/max14577.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) struct max14577_charger {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) struct max14577 *max14577;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) struct power_supply *charger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct max14577_charger_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Helper function for mapping values of STATUS2/CHGTYP register on max14577
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * and max77836 chipsets to enum maxim_muic_charger_type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static enum max14577_muic_charger_type maxim_get_charger_type(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) enum maxim_device_type dev_type, u8 val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) case MAX14577_CHARGER_TYPE_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) case MAX14577_CHARGER_TYPE_USB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) case MAX14577_CHARGER_TYPE_DOWNSTREAM_PORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) case MAX14577_CHARGER_TYPE_DEDICATED_CHG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) case MAX14577_CHARGER_TYPE_SPECIAL_500MA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) case MAX14577_CHARGER_TYPE_SPECIAL_1A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) case MAX14577_CHARGER_TYPE_DEAD_BATTERY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) case MAX14577_CHARGER_TYPE_RESERVED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (dev_type == MAXIM_DEVICE_TYPE_MAX77836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) val |= 0x8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) WARN_ONCE(1, "max14577: Unsupported chgtyp register value 0x%02x", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static int max14577_get_charger_state(struct max14577_charger *chg, int *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct regmap *rmap = chg->max14577->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) u8 reg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * Charging occurs only if:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * - CHGCTRL2/MBCHOSTEN == 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * - STATUS2/CGMBC == 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * TODO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * - handle FULL after Top-off timer (EOC register may be off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * and the charger won't be charging although MBCHOSTEN is on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * - handle properly dead-battery charging (respect timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * - handle timers (fast-charge and prequal) /MBCCHGERR/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) ret = max14577_read_reg(rmap, MAX14577_CHG_REG_CHG_CTRL2, ®_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if ((reg_data & CHGCTRL2_MBCHOSTEN_MASK) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) *val = POWER_SUPPLY_STATUS_DISCHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) ret = max14577_read_reg(rmap, MAX14577_CHG_REG_STATUS3, ®_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (reg_data & STATUS3_CGMBC_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* Charger or USB-cable is connected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (reg_data & STATUS3_EOC_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) *val = POWER_SUPPLY_STATUS_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) *val = POWER_SUPPLY_STATUS_CHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) *val = POWER_SUPPLY_STATUS_DISCHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * Supported charge types:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * - POWER_SUPPLY_CHARGE_TYPE_NONE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * - POWER_SUPPLY_CHARGE_TYPE_FAST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static int max14577_get_charge_type(struct max14577_charger *chg, int *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) int ret, charging;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * TODO: CHARGE_TYPE_TRICKLE (VCHGR_RC or EOC)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * As spec says:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * [after reaching EOC interrupt]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * "When the battery is fully charged, the 30-minute (typ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * top-off timer starts. The device continues to trickle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * charge the battery until the top-off timer runs out."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) ret = max14577_get_charger_state(chg, &charging);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (charging == POWER_SUPPLY_STATUS_CHARGING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) *val = POWER_SUPPLY_CHARGE_TYPE_FAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) *val = POWER_SUPPLY_CHARGE_TYPE_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static int max14577_get_online(struct max14577_charger *chg, int *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct regmap *rmap = chg->max14577->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) u8 reg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) enum max14577_muic_charger_type chg_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) ret = max14577_read_reg(rmap, MAX14577_MUIC_REG_STATUS2, ®_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) reg_data = ((reg_data & STATUS2_CHGTYP_MASK) >> STATUS2_CHGTYP_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) chg_type = maxim_get_charger_type(chg->max14577->dev_type, reg_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) switch (chg_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) case MAX14577_CHARGER_TYPE_USB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) case MAX14577_CHARGER_TYPE_DEDICATED_CHG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) case MAX14577_CHARGER_TYPE_SPECIAL_500MA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) case MAX14577_CHARGER_TYPE_SPECIAL_1A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) case MAX14577_CHARGER_TYPE_DEAD_BATTERY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) case MAX77836_CHARGER_TYPE_SPECIAL_BIAS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) *val = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) case MAX14577_CHARGER_TYPE_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) case MAX14577_CHARGER_TYPE_DOWNSTREAM_PORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) case MAX14577_CHARGER_TYPE_RESERVED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) case MAX77836_CHARGER_TYPE_RESERVED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) *val = 0;
^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) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * Supported health statuses:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * - POWER_SUPPLY_HEALTH_DEAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * - POWER_SUPPLY_HEALTH_OVERVOLTAGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * - POWER_SUPPLY_HEALTH_GOOD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static int max14577_get_battery_health(struct max14577_charger *chg, int *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct regmap *rmap = chg->max14577->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) u8 reg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) enum max14577_muic_charger_type chg_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) ret = max14577_read_reg(rmap, MAX14577_MUIC_REG_STATUS2, ®_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) reg_data = ((reg_data & STATUS2_CHGTYP_MASK) >> STATUS2_CHGTYP_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) chg_type = maxim_get_charger_type(chg->max14577->dev_type, reg_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (chg_type == MAX14577_CHARGER_TYPE_DEAD_BATTERY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) *val = POWER_SUPPLY_HEALTH_DEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) ret = max14577_read_reg(rmap, MAX14577_CHG_REG_STATUS3, ®_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (reg_data & STATUS3_OVP_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) *val = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* Not dead, not overvoltage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) *val = POWER_SUPPLY_HEALTH_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * Always returns 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * The max14577 chip doesn't report any status of battery presence.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * Lets assume that it will always be used with some battery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static int max14577_get_present(struct max14577_charger *chg, int *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) *val = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static int max14577_set_fast_charge_timer(struct max14577_charger *chg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) unsigned long hours)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) u8 reg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) switch (hours) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) case 5 ... 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) reg_data = hours - 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /* Disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) reg_data = 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) dev_err(chg->dev, "Wrong value for Fast-Charge Timer: %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) hours);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) reg_data <<= CHGCTRL1_TCHW_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return max14577_update_reg(chg->max14577->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) MAX14577_REG_CHGCTRL1, CHGCTRL1_TCHW_MASK, reg_data);
^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 max14577_init_constant_voltage(struct max14577_charger *chg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) unsigned int uvolt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) u8 reg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (uvolt < MAXIM_CHARGER_CONSTANT_VOLTAGE_MIN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) uvolt > MAXIM_CHARGER_CONSTANT_VOLTAGE_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (uvolt == 4200000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) reg_data = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) else if (uvolt == MAXIM_CHARGER_CONSTANT_VOLTAGE_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) reg_data = 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) else if (uvolt <= 4280000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) unsigned int val = uvolt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) val -= MAXIM_CHARGER_CONSTANT_VOLTAGE_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) val /= MAXIM_CHARGER_CONSTANT_VOLTAGE_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (uvolt <= 4180000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) reg_data = 0x1 + val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) reg_data = val; /* Fix for gap between 4.18V and 4.22V */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) reg_data <<= CHGCTRL3_MBCCVWRC_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return max14577_write_reg(chg->max14577->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) MAX14577_CHG_REG_CHG_CTRL3, reg_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static int max14577_init_eoc(struct max14577_charger *chg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) unsigned int uamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) unsigned int current_bits = 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) u8 reg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) switch (chg->max14577->dev_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) case MAXIM_DEVICE_TYPE_MAX77836:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (uamp < 5000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return -EINVAL; /* Requested current is too low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (uamp >= 7500 && uamp < 10000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) current_bits = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) else if (uamp <= 50000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /* <5000, 7499> and <10000, 50000> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) current_bits = uamp / 5000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) uamp = min(uamp, 100000U) - 50000U;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) current_bits = 0xa + uamp / 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) case MAXIM_DEVICE_TYPE_MAX14577:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (uamp < MAX14577_CHARGER_EOC_CURRENT_LIMIT_MIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return -EINVAL; /* Requested current is too low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) uamp = min(uamp, MAX14577_CHARGER_EOC_CURRENT_LIMIT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) uamp -= MAX14577_CHARGER_EOC_CURRENT_LIMIT_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) current_bits = uamp / MAX14577_CHARGER_EOC_CURRENT_LIMIT_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) reg_data = current_bits << CHGCTRL5_EOCS_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return max14577_update_reg(chg->max14577->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) MAX14577_CHG_REG_CHG_CTRL5, CHGCTRL5_EOCS_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) reg_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static int max14577_init_fast_charge(struct max14577_charger *chg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) unsigned int uamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) u8 reg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) const struct maxim_charger_current *limits =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) &maxim_charger_currents[chg->max14577->dev_type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) ret = maxim_charger_calc_reg_current(limits, uamp, uamp, ®_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) dev_err(chg->dev, "Wrong value for fast charge: %u\n", uamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return max14577_update_reg(chg->max14577->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) MAX14577_CHG_REG_CHG_CTRL4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) CHGCTRL4_MBCICHWRCL_MASK | CHGCTRL4_MBCICHWRCH_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) reg_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * Sets charger registers to proper and safe default values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * Some of these values are equal to defaults in MAX14577E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * data sheet but there are minor differences.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static int max14577_charger_reg_init(struct max14577_charger *chg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) struct regmap *rmap = chg->max14577->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) u8 reg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * Charger-Type Manual Detection, default off (set CHGTYPMAN to 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) * Charger-Detection Enable, default on (set CHGDETEN to 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * Combined mask of CHGDETEN and CHGTYPMAN will zero the CHGTYPMAN bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) reg_data = 0x1 << CDETCTRL1_CHGDETEN_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) max14577_update_reg(rmap, MAX14577_REG_CDETCTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) CDETCTRL1_CHGDETEN_MASK | CDETCTRL1_CHGTYPMAN_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) reg_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * Wall-Adapter Rapid Charge, default on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * Battery-Charger, default on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) reg_data = 0x1 << CHGCTRL2_VCHGR_RC_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) reg_data |= 0x1 << CHGCTRL2_MBCHOSTEN_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) max14577_write_reg(rmap, MAX14577_REG_CHGCTRL2, reg_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) /* Auto Charging Stop, default off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) reg_data = 0x0 << CHGCTRL6_AUTOSTOP_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) max14577_write_reg(rmap, MAX14577_REG_CHGCTRL6, reg_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) ret = max14577_init_constant_voltage(chg, chg->pdata->constant_uvolt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) ret = max14577_init_eoc(chg, chg->pdata->eoc_uamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) ret = max14577_init_fast_charge(chg, chg->pdata->fast_charge_uamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) ret = max14577_set_fast_charge_timer(chg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) MAXIM_CHARGER_FAST_CHARGE_TIMER_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) /* Initialize Overvoltage-Protection Threshold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) switch (chg->pdata->ovp_uvolt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) case 7500000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) reg_data = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) case 6000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) case 6500000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) case 7000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) reg_data = 0x1 + (chg->pdata->ovp_uvolt - 6000000) / 500000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) dev_err(chg->dev, "Wrong value for OVP: %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) chg->pdata->ovp_uvolt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) reg_data <<= CHGCTRL7_OTPCGHCVS_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) max14577_write_reg(rmap, MAX14577_REG_CHGCTRL7, reg_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /* Support property from charger */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) static enum power_supply_property max14577_charger_props[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) POWER_SUPPLY_PROP_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) POWER_SUPPLY_PROP_CHARGE_TYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) POWER_SUPPLY_PROP_HEALTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) POWER_SUPPLY_PROP_PRESENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) POWER_SUPPLY_PROP_ONLINE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) POWER_SUPPLY_PROP_MODEL_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) POWER_SUPPLY_PROP_MANUFACTURER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static const char * const model_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) [MAXIM_DEVICE_TYPE_UNKNOWN] = "MAX14577-like",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) [MAXIM_DEVICE_TYPE_MAX14577] = "MAX14577",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) [MAXIM_DEVICE_TYPE_MAX77836] = "MAX77836",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) static const char *manufacturer = "Maxim Integrated";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) static int max14577_charger_get_property(struct power_supply *psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) enum power_supply_property psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) struct max14577_charger *chg = power_supply_get_drvdata(psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) case POWER_SUPPLY_PROP_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) ret = max14577_get_charger_state(chg, &val->intval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) case POWER_SUPPLY_PROP_CHARGE_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) ret = max14577_get_charge_type(chg, &val->intval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) case POWER_SUPPLY_PROP_HEALTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) ret = max14577_get_battery_health(chg, &val->intval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) case POWER_SUPPLY_PROP_PRESENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) ret = max14577_get_present(chg, &val->intval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) case POWER_SUPPLY_PROP_ONLINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) ret = max14577_get_online(chg, &val->intval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) case POWER_SUPPLY_PROP_MODEL_NAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) BUILD_BUG_ON(ARRAY_SIZE(model_names) != MAXIM_DEVICE_TYPE_NUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) val->strval = model_names[chg->max14577->dev_type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) case POWER_SUPPLY_PROP_MANUFACTURER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) val->strval = manufacturer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) static const struct power_supply_desc max14577_charger_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) .name = "max14577-charger",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) .type = POWER_SUPPLY_TYPE_BATTERY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) .properties = max14577_charger_props,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) .num_properties = ARRAY_SIZE(max14577_charger_props),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) .get_property = max14577_charger_get_property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) static struct max14577_charger_platform_data *max14577_charger_dt_init(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) struct max14577_charger_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) struct device_node *np = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (!np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) dev_err(&pdev->dev, "No charger OF node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (!pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) ret = of_property_read_u32(np, "maxim,constant-uvolt",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) &pdata->constant_uvolt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) dev_err(&pdev->dev, "Cannot parse maxim,constant-uvolt field from DT\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) ret = of_property_read_u32(np, "maxim,fast-charge-uamp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) &pdata->fast_charge_uamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) dev_err(&pdev->dev, "Cannot parse maxim,fast-charge-uamp field from DT\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) ret = of_property_read_u32(np, "maxim,eoc-uamp", &pdata->eoc_uamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) dev_err(&pdev->dev, "Cannot parse maxim,eoc-uamp field from DT\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return ERR_PTR(ret);
^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) ret = of_property_read_u32(np, "maxim,ovp-uvolt", &pdata->ovp_uvolt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) dev_err(&pdev->dev, "Cannot parse maxim,ovp-uvolt field from DT\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) return ERR_PTR(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) return pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) #else /* CONFIG_OF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) static struct max14577_charger_platform_data *max14577_charger_dt_init(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) #endif /* CONFIG_OF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) static ssize_t show_fast_charge_timer(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) struct max14577_charger *chg = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) u8 reg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) ret = max14577_read_reg(chg->max14577->regmap, MAX14577_REG_CHGCTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) ®_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) reg_data &= CHGCTRL1_TCHW_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) reg_data >>= CHGCTRL1_TCHW_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) switch (reg_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) case 0x2 ... 0x4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) val = reg_data + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) case 0x7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) val = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return scnprintf(buf, PAGE_SIZE, "%u\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) static ssize_t store_fast_charge_timer(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) struct device_attribute *attr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct max14577_charger *chg = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) ret = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) ret = max14577_set_fast_charge_timer(chg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) static DEVICE_ATTR(fast_charge_timer, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) show_fast_charge_timer, store_fast_charge_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) static int max14577_charger_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) struct max14577_charger *chg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) struct power_supply_config psy_cfg = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) struct max14577 *max14577 = dev_get_drvdata(pdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) chg = devm_kzalloc(&pdev->dev, sizeof(*chg), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (!chg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) platform_set_drvdata(pdev, chg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) chg->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) chg->max14577 = max14577;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) chg->pdata = max14577_charger_dt_init(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (IS_ERR_OR_NULL(chg->pdata))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return PTR_ERR(chg->pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) ret = max14577_charger_reg_init(chg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) ret = device_create_file(&pdev->dev, &dev_attr_fast_charge_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) dev_err(&pdev->dev, "failed: create sysfs entry\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) psy_cfg.drv_data = chg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) chg->charger = power_supply_register(&pdev->dev, &max14577_charger_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) &psy_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if (IS_ERR(chg->charger)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) dev_err(&pdev->dev, "failed: power supply register\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) ret = PTR_ERR(chg->charger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /* Check for valid values for charger */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) BUILD_BUG_ON(MAX14577_CHARGER_EOC_CURRENT_LIMIT_MIN +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) MAX14577_CHARGER_EOC_CURRENT_LIMIT_STEP * 0xf !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) MAX14577_CHARGER_EOC_CURRENT_LIMIT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) device_remove_file(&pdev->dev, &dev_attr_fast_charge_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) static int max14577_charger_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) struct max14577_charger *chg = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) device_remove_file(&pdev->dev, &dev_attr_fast_charge_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) power_supply_unregister(chg->charger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) static const struct platform_device_id max14577_charger_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) { "max14577-charger", MAXIM_DEVICE_TYPE_MAX14577, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) { "max77836-charger", MAXIM_DEVICE_TYPE_MAX77836, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) MODULE_DEVICE_TABLE(platform, max14577_charger_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) static const struct of_device_id of_max14577_charger_dt_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) { .compatible = "maxim,max14577-charger",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) .data = (void *)MAXIM_DEVICE_TYPE_MAX14577, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) { .compatible = "maxim,max77836-charger",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) .data = (void *)MAXIM_DEVICE_TYPE_MAX77836, },
^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) MODULE_DEVICE_TABLE(of, of_max14577_charger_dt_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) static struct platform_driver max14577_charger_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) .name = "max14577-charger",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) .of_match_table = of_max14577_charger_dt_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) .probe = max14577_charger_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) .remove = max14577_charger_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) .id_table = max14577_charger_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) module_platform_driver(max14577_charger_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) MODULE_DESCRIPTION("Maxim 14577/77836 charger driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) MODULE_LICENSE("GPL");