^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright 2012 ST Ericsson.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Power supply driver for ST Ericsson pm2xxx_charger charger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/power_supply.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/mfd/abx500/ab8500.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/mfd/abx500/ab8500-bm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/mfd/abx500/ux500_chargalg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/pm2301_charger.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/pm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "pm2301_charger.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define to_pm2xxx_charger_ac_device_info(x) container_of((x), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct pm2xxx_charger, ac_chg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define SLEEP_MIN 50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define SLEEP_MAX 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define PM2XXX_AUTOSUSPEND_DELAY 500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static int pm2xxx_interrupt_registers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) PM2XXX_REG_INT1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) PM2XXX_REG_INT2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) PM2XXX_REG_INT3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) PM2XXX_REG_INT4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) PM2XXX_REG_INT5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) PM2XXX_REG_INT6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static enum power_supply_property pm2xxx_charger_ac_props[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) POWER_SUPPLY_PROP_HEALTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) POWER_SUPPLY_PROP_PRESENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) POWER_SUPPLY_PROP_ONLINE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) POWER_SUPPLY_PROP_VOLTAGE_AVG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static int pm2xxx_charger_voltage_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) 3500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) 3525,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) 3550,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) 3575,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) 3600,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) 3625,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) 3650,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) 3675,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) 3700,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 3725,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) 3750,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 3775,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) 3800,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 3825,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) 3850,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 3875,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) 3900,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) 3925,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) 3950,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) 3975,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) 4000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) 4025,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) 4050,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) 4075,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) 4100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) 4125,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) 4150,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) 4175,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) 4200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) 4225,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) 4250,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) 4275,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) 4300,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static int pm2xxx_charger_current_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) 200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) 200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) 400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) 600,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) 800,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) 1200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) 1400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) 1600,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) 1800,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) 2000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 2200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 2400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 2600,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 2800,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 3000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static void set_lpn_pin(struct pm2xxx_charger *pm2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (!pm2->ac.charger_connected && gpio_is_valid(pm2->lpn_pin)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) gpio_set_value(pm2->lpn_pin, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) usleep_range(SLEEP_MIN, SLEEP_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static void clear_lpn_pin(struct pm2xxx_charger *pm2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (!pm2->ac.charger_connected && gpio_is_valid(pm2->lpn_pin))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) gpio_set_value(pm2->lpn_pin, 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 pm2xxx_reg_read(struct pm2xxx_charger *pm2, int reg, u8 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* wake up the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) pm_runtime_get_sync(pm2->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) ret = i2c_smbus_read_i2c_block_data(pm2->config.pm2xxx_i2c, reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 1, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) dev_err(pm2->dev, "Error reading register at 0x%x\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) pm_runtime_put_sync(pm2->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static int pm2xxx_reg_write(struct pm2xxx_charger *pm2, int reg, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* wake up the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) pm_runtime_get_sync(pm2->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ret = i2c_smbus_write_i2c_block_data(pm2->config.pm2xxx_i2c, reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 1, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) dev_err(pm2->dev, "Error writing register at 0x%x\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) pm_runtime_put_sync(pm2->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return ret;
^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) static int pm2xxx_charging_enable_mngt(struct pm2xxx_charger *pm2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* Enable charging */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) (PM2XXX_CH_AUTO_RESUME_EN | PM2XXX_CHARGER_ENA));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static int pm2xxx_charging_disable_mngt(struct pm2xxx_charger *pm2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* Disable SW EOC ctrl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) ret = pm2xxx_reg_write(pm2, PM2XXX_SW_CTRL_REG, PM2XXX_SWCTRL_HW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /* Disable charging */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) (PM2XXX_CH_AUTO_RESUME_DIS | PM2XXX_CHARGER_DIS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static int pm2xxx_charger_batt_therm_mngt(struct pm2xxx_charger *pm2, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) queue_work(pm2->charger_wq, &pm2->check_main_thermal_prot_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static int pm2xxx_charger_die_therm_mngt(struct pm2xxx_charger *pm2, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) queue_work(pm2->charger_wq, &pm2->check_main_thermal_prot_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return 0;
^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) static int pm2xxx_charger_ovv_mngt(struct pm2xxx_charger *pm2, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) dev_err(pm2->dev, "Overvoltage detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) pm2->flags.ovv = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) power_supply_changed(pm2->ac_chg.psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /* Schedule a new HW failure check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) queue_delayed_work(pm2->charger_wq, &pm2->check_hw_failure_work, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static int pm2xxx_charger_wd_exp_mngt(struct pm2xxx_charger *pm2, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) dev_dbg(pm2->dev , "20 minutes watchdog expired\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) pm2->ac.wd_expired = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) power_supply_changed(pm2->ac_chg.psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static int pm2xxx_charger_vbat_lsig_mngt(struct pm2xxx_charger *pm2, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) case PM2XXX_INT1_ITVBATLOWR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) dev_dbg(pm2->dev, "VBAT grows above VBAT_LOW level\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /* Enable SW EOC ctrl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) ret = pm2xxx_reg_write(pm2, PM2XXX_SW_CTRL_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) PM2XXX_SWCTRL_SW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) case PM2XXX_INT1_ITVBATLOWF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) dev_dbg(pm2->dev, "VBAT drops below VBAT_LOW level\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /* Disable SW EOC ctrl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) ret = pm2xxx_reg_write(pm2, PM2XXX_SW_CTRL_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) PM2XXX_SWCTRL_HW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__);
^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) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) dev_err(pm2->dev, "Unknown VBAT level\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static int pm2xxx_charger_bat_disc_mngt(struct pm2xxx_charger *pm2, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) dev_dbg(pm2->dev, "battery disconnected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static int pm2xxx_charger_detection(struct pm2xxx_charger *pm2, u8 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ret = pm2xxx_reg_read(pm2, PM2XXX_SRCE_REG_INT2, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) dev_err(pm2->dev, "Charger detection failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) *val &= (PM2XXX_INT2_S_ITVPWR1PLUG | PM2XXX_INT2_S_ITVPWR2PLUG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) static int pm2xxx_charger_itv_pwr_plug_mngt(struct pm2xxx_charger *pm2, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) u8 read_val;
^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) * Since we can't be sure that the events are received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * synchronously, we have the check if the main charger is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * connected by reading the interrupt source register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) ret = pm2xxx_charger_detection(pm2, &read_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if ((ret == 0) && read_val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) pm2->ac.charger_connected = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) pm2->ac_conn = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) queue_work(pm2->charger_wq, &pm2->ac_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static int pm2xxx_charger_itv_pwr_unplug_mngt(struct pm2xxx_charger *pm2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) pm2->ac.charger_connected = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) queue_work(pm2->charger_wq, &pm2->ac_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) static int pm2_int_reg0(void *pm2_data, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) struct pm2xxx_charger *pm2 = pm2_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (val & PM2XXX_INT1_ITVBATLOWR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) ret = pm2xxx_charger_vbat_lsig_mngt(pm2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) PM2XXX_INT1_ITVBATLOWR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (val & PM2XXX_INT1_ITVBATLOWF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) ret = pm2xxx_charger_vbat_lsig_mngt(pm2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) PM2XXX_INT1_ITVBATLOWF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (val & PM2XXX_INT1_ITVBATDISCONNECT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) ret = pm2xxx_charger_bat_disc_mngt(pm2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) PM2XXX_INT1_ITVBATDISCONNECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) static int pm2_int_reg1(void *pm2_data, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) struct pm2xxx_charger *pm2 = pm2_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (val & (PM2XXX_INT2_ITVPWR1PLUG | PM2XXX_INT2_ITVPWR2PLUG)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) dev_dbg(pm2->dev , "Main charger plugged\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) ret = pm2xxx_charger_itv_pwr_plug_mngt(pm2, val &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) (PM2XXX_INT2_ITVPWR1PLUG | PM2XXX_INT2_ITVPWR2PLUG));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (val &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) (PM2XXX_INT2_ITVPWR1UNPLUG | PM2XXX_INT2_ITVPWR2UNPLUG)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) dev_dbg(pm2->dev , "Main charger unplugged\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) ret = pm2xxx_charger_itv_pwr_unplug_mngt(pm2, val &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) (PM2XXX_INT2_ITVPWR1UNPLUG |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) PM2XXX_INT2_ITVPWR2UNPLUG));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static int pm2_int_reg2(void *pm2_data, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) struct pm2xxx_charger *pm2 = pm2_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (val & PM2XXX_INT3_ITAUTOTIMEOUTWD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) ret = pm2xxx_charger_wd_exp_mngt(pm2, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (val & (PM2XXX_INT3_ITCHPRECHARGEWD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) PM2XXX_INT3_ITCHCCWD | PM2XXX_INT3_ITCHCVWD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) dev_dbg(pm2->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) "Watchdog occurred for precharge, CC and CV charge\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) static int pm2_int_reg3(void *pm2_data, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) struct pm2xxx_charger *pm2 = pm2_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (val & (PM2XXX_INT4_ITCHARGINGON)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) dev_dbg(pm2->dev ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) "charging operation has started\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (val & (PM2XXX_INT4_ITVRESUME)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) dev_dbg(pm2->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) "battery discharged down to VResume threshold\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (val & (PM2XXX_INT4_ITBATTFULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) dev_dbg(pm2->dev , "battery fully detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (val & (PM2XXX_INT4_ITCVPHASE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) dev_dbg(pm2->dev, "CV phase enter with 0.5C charging\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (val & (PM2XXX_INT4_ITVPWR2OVV | PM2XXX_INT4_ITVPWR1OVV)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) pm2->failure_case = VPWR_OVV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) ret = pm2xxx_charger_ovv_mngt(pm2, val &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) (PM2XXX_INT4_ITVPWR2OVV | PM2XXX_INT4_ITVPWR1OVV));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) dev_dbg(pm2->dev, "VPWR/VSYSTEM overvoltage detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (val & (PM2XXX_INT4_S_ITBATTEMPCOLD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) PM2XXX_INT4_S_ITBATTEMPHOT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) ret = pm2xxx_charger_batt_therm_mngt(pm2, val &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) (PM2XXX_INT4_S_ITBATTEMPCOLD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) PM2XXX_INT4_S_ITBATTEMPHOT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) dev_dbg(pm2->dev, "BTEMP is too Low/High\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) static int pm2_int_reg4(void *pm2_data, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct pm2xxx_charger *pm2 = pm2_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (val & PM2XXX_INT5_ITVSYSTEMOVV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) pm2->failure_case = VSYSTEM_OVV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) ret = pm2xxx_charger_ovv_mngt(pm2, val &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) PM2XXX_INT5_ITVSYSTEMOVV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) dev_dbg(pm2->dev, "VSYSTEM overvoltage detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (val & (PM2XXX_INT5_ITTHERMALWARNINGFALL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) PM2XXX_INT5_ITTHERMALWARNINGRISE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) PM2XXX_INT5_ITTHERMALSHUTDOWNFALL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) PM2XXX_INT5_ITTHERMALSHUTDOWNRISE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) dev_dbg(pm2->dev, "BTEMP die temperature is too Low/High\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) ret = pm2xxx_charger_die_therm_mngt(pm2, val &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) (PM2XXX_INT5_ITTHERMALWARNINGFALL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) PM2XXX_INT5_ITTHERMALWARNINGRISE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) PM2XXX_INT5_ITTHERMALSHUTDOWNFALL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) PM2XXX_INT5_ITTHERMALSHUTDOWNRISE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) return ret;
^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) static int pm2_int_reg5(void *pm2_data, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) struct pm2xxx_charger *pm2 = pm2_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (val & (PM2XXX_INT6_ITVPWR2DROP | PM2XXX_INT6_ITVPWR1DROP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) dev_dbg(pm2->dev, "VMPWR drop to VBAT level\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (val & (PM2XXX_INT6_ITVPWR2VALIDRISE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) PM2XXX_INT6_ITVPWR1VALIDRISE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) PM2XXX_INT6_ITVPWR2VALIDFALL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) PM2XXX_INT6_ITVPWR1VALIDFALL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) dev_dbg(pm2->dev, "Falling/Rising edge on WPWR1/2\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) static irqreturn_t pm2xxx_irq_int(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) struct pm2xxx_charger *pm2 = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) struct pm2xxx_interrupts *interrupt = pm2->pm2_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) /* wake up the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) pm_runtime_get_sync(pm2->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) for (i = 0; i < PM2XXX_NUM_INT_REG; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) pm2xxx_reg_read(pm2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) pm2xxx_interrupt_registers[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) &(interrupt->reg[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (interrupt->reg[i] > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) interrupt->handler[i](pm2, interrupt->reg[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) } while (gpio_get_value(pm2->pdata->gpio_irq_number) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) pm_runtime_mark_last_busy(pm2->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) pm_runtime_put_autosuspend(pm2->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) return IRQ_HANDLED;
^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 pm2xxx_charger_get_ac_cv(struct pm2xxx_charger *pm2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (pm2->ac.charger_connected && pm2->ac.charger_online) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) ret = pm2xxx_reg_read(pm2, PM2XXX_SRCE_REG_INT4, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) dev_err(pm2->dev, "%s pm2xxx read failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (val & PM2XXX_INT4_S_ITCVPHASE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) ret = PM2XXX_CONST_VOLT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) ret = PM2XXX_CONST_CURR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) out:
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) static int pm2xxx_current_to_regval(int curr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (curr < pm2xxx_charger_current_map[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) for (i = 1; i < ARRAY_SIZE(pm2xxx_charger_current_map); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (curr < pm2xxx_charger_current_map[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) return (i - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) i = ARRAY_SIZE(pm2xxx_charger_current_map) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (curr == pm2xxx_charger_current_map[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) static int pm2xxx_voltage_to_regval(int curr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (curr < pm2xxx_charger_voltage_map[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) for (i = 1; i < ARRAY_SIZE(pm2xxx_charger_voltage_map); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (curr < pm2xxx_charger_voltage_map[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return i - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) i = ARRAY_SIZE(pm2xxx_charger_voltage_map) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (curr == pm2xxx_charger_voltage_map[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static int pm2xxx_charger_update_charger_current(struct ux500_charger *charger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) int ich_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) int curr_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct pm2xxx_charger *pm2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (charger->psy->desc->type == POWER_SUPPLY_TYPE_MAINS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) pm2 = to_pm2xxx_charger_ac_device_info(charger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) curr_index = pm2xxx_current_to_regval(ich_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (curr_index < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) dev_err(pm2->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) "Charger current too high, charging not started\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) ret = pm2xxx_reg_read(pm2, PM2XXX_BATT_CTRL_REG6, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (ret >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) val &= ~PM2XXX_DIR_CH_CC_CURRENT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) val |= curr_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG6, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) dev_err(pm2->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) "%s write failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) dev_err(pm2->dev, "%s read failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) static int pm2xxx_charger_ac_get_property(struct power_supply *psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) enum power_supply_property psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) struct pm2xxx_charger *pm2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) pm2 = to_pm2xxx_charger_ac_device_info(psy_to_ux500_charger(psy));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) case POWER_SUPPLY_PROP_HEALTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (pm2->flags.mainextchnotok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) else if (pm2->ac.wd_expired)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) val->intval = POWER_SUPPLY_HEALTH_DEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) else if (pm2->flags.main_thermal_prot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) else if (pm2->flags.ovv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) val->intval = POWER_SUPPLY_HEALTH_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) case POWER_SUPPLY_PROP_ONLINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) val->intval = pm2->ac.charger_online;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) case POWER_SUPPLY_PROP_PRESENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) val->intval = pm2->ac.charger_connected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) case POWER_SUPPLY_PROP_VOLTAGE_AVG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) pm2->ac.cv_active = pm2xxx_charger_get_ac_cv(pm2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) val->intval = pm2->ac.cv_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) static int pm2xxx_charging_init(struct pm2xxx_charger *pm2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) /* enable CC and CV watchdog */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) (PM2XXX_CH_WD_CV_PHASE_60MIN | PM2XXX_CH_WD_CC_PHASE_60MIN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if( ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) /* enable precharge watchdog */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) PM2XXX_CH_WD_PRECH_PHASE_60MIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) /* Disable auto timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) PM2XXX_CH_WD_AUTO_TIMEOUT_20MIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) * EOC current level = 100mA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * Precharge current level = 100mA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * CC current level = 1000mA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) (PM2XXX_DIR_CH_CC_CURRENT_1000MA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) PM2XXX_CH_PRECH_CURRENT_100MA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) PM2XXX_CH_EOC_CURRENT_100MA));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * recharge threshold = 3.8V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) * Precharge to CC threshold = 2.9V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) (PM2XXX_CH_PRECH_VOL_2_9 | PM2XXX_CH_VRESUME_VOL_3_8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) /* float voltage charger level = 4.2V */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) PM2XXX_CH_VOLT_4_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) /* Voltage drop between VBAT and VSYS in HW charging = 300mV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) (PM2XXX_CH_150MV_DROP_300MV | PM2XXX_CHARCHING_INFO_DIS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) PM2XXX_CH_CC_REDUCED_CURRENT_IDENT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) PM2XXX_CH_CC_MODEDROP_DIS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) /* Input charger level of over voltage = 10V */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) ret = pm2xxx_reg_write(pm2, PM2XXX_INP_VOLT_VPWR2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) PM2XXX_VPWR2_OVV_10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) ret = pm2xxx_reg_write(pm2, PM2XXX_INP_VOLT_VPWR1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) PM2XXX_VPWR1_OVV_10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) /* Input charger drop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) ret = pm2xxx_reg_write(pm2, PM2XXX_INP_DROP_VPWR2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) (PM2XXX_VPWR2_HW_OPT_DIS | PM2XXX_VPWR2_VALID_DIS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) PM2XXX_VPWR2_DROP_DIS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) ret = pm2xxx_reg_write(pm2, PM2XXX_INP_DROP_VPWR1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) (PM2XXX_VPWR1_HW_OPT_DIS | PM2XXX_VPWR1_VALID_DIS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) PM2XXX_VPWR1_DROP_DIS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) /* Disable battery low monitoring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_LOW_LEV_COMP_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) PM2XXX_VBAT_LOW_MONITORING_ENA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) static int pm2xxx_charger_ac_en(struct ux500_charger *charger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) int enable, int vset, int iset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) int volt_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) int curr_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) struct pm2xxx_charger *pm2 = to_pm2xxx_charger_ac_device_info(charger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (!pm2->ac.charger_connected) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) dev_dbg(pm2->dev, "AC charger not connected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) dev_dbg(pm2->dev, "Enable AC: %dmV %dmA\n", vset, iset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (!pm2->vddadc_en_ac) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) ret = regulator_enable(pm2->regu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) dev_warn(pm2->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) "Failed to enable vddadc regulator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) pm2->vddadc_en_ac = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) ret = pm2xxx_charging_init(pm2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) dev_err(pm2->dev, "%s charging init failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) goto error_occured;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) volt_index = pm2xxx_voltage_to_regval(vset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) curr_index = pm2xxx_current_to_regval(iset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (volt_index < 0 || curr_index < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) dev_err(pm2->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) "Charger voltage or current too high, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) "charging not started\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) ret = pm2xxx_reg_read(pm2, PM2XXX_BATT_CTRL_REG8, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) dev_err(pm2->dev, "%s pm2xxx read failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) goto error_occured;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) val &= ~PM2XXX_CH_VOLT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) val |= volt_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG8, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) goto error_occured;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) ret = pm2xxx_reg_read(pm2, PM2XXX_BATT_CTRL_REG6, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) dev_err(pm2->dev, "%s pm2xxx read failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) goto error_occured;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) val &= ~PM2XXX_DIR_CH_CC_CURRENT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) val |= curr_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG6, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) goto error_occured;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (!pm2->bat->enable_overshoot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) ret = pm2xxx_reg_read(pm2, PM2XXX_LED_CTRL_REG, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) dev_err(pm2->dev, "%s pm2xxx read failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) goto error_occured;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) val |= PM2XXX_ANTI_OVERSHOOT_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) ret = pm2xxx_reg_write(pm2, PM2XXX_LED_CTRL_REG, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) dev_err(pm2->dev, "%s pm2xxx write failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) goto error_occured;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) ret = pm2xxx_charging_enable_mngt(pm2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) dev_err(pm2->dev, "Failed to enable"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) "pm2xxx ac charger\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) goto error_occured;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) pm2->ac.charger_online = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) pm2->ac.charger_online = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) pm2->ac.wd_expired = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) /* Disable regulator if enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) if (pm2->vddadc_en_ac) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) regulator_disable(pm2->regu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) pm2->vddadc_en_ac = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) ret = pm2xxx_charging_disable_mngt(pm2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) dev_err(pm2->dev, "failed to disable"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) "pm2xxx ac charger\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) goto error_occured;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) dev_dbg(pm2->dev, "PM2301: " "Disabled AC charging\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) power_supply_changed(pm2->ac_chg.psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) error_occured:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) static int pm2xxx_charger_watchdog_kick(struct ux500_charger *charger)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) struct pm2xxx_charger *pm2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (charger->psy->desc->type == POWER_SUPPLY_TYPE_MAINS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) pm2 = to_pm2xxx_charger_ac_device_info(charger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_WD_KICK, WD_TIMER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) dev_err(pm2->dev, "Failed to kick WD!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) static void pm2xxx_charger_ac_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) struct pm2xxx_charger *pm2 = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) struct pm2xxx_charger, ac_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) power_supply_changed(pm2->ac_chg.psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) sysfs_notify(&pm2->ac_chg.psy->dev.kobj, NULL, "present");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) static void pm2xxx_charger_check_hw_failure_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) u8 reg_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) struct pm2xxx_charger *pm2 = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) struct pm2xxx_charger, check_hw_failure_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) if (pm2->flags.ovv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) pm2xxx_reg_read(pm2, PM2XXX_SRCE_REG_INT4, ®_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (!(reg_value & (PM2XXX_INT4_S_ITVPWR1OVV |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) PM2XXX_INT4_S_ITVPWR2OVV))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) pm2->flags.ovv = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) power_supply_changed(pm2->ac_chg.psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) /* If we still have a failure, schedule a new check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) if (pm2->flags.ovv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) queue_delayed_work(pm2->charger_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) &pm2->check_hw_failure_work, round_jiffies(HZ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) static void pm2xxx_charger_check_main_thermal_prot_work(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) struct pm2xxx_charger *pm2 = container_of(work, struct pm2xxx_charger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) check_main_thermal_prot_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) /* Check if die temp warning is still active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) ret = pm2xxx_reg_read(pm2, PM2XXX_SRCE_REG_INT5, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) dev_err(pm2->dev, "%s pm2xxx read failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (val & (PM2XXX_INT5_S_ITTHERMALWARNINGRISE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) | PM2XXX_INT5_S_ITTHERMALSHUTDOWNRISE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) pm2->flags.main_thermal_prot = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) else if (val & (PM2XXX_INT5_S_ITTHERMALWARNINGFALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) | PM2XXX_INT5_S_ITTHERMALSHUTDOWNFALL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) pm2->flags.main_thermal_prot = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) power_supply_changed(pm2->ac_chg.psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) static struct pm2xxx_interrupts pm2xxx_int = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) .handler[0] = pm2_int_reg0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) .handler[1] = pm2_int_reg1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) .handler[2] = pm2_int_reg2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) .handler[3] = pm2_int_reg3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) .handler[4] = pm2_int_reg4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) .handler[5] = pm2_int_reg5,
^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) static struct pm2xxx_irq pm2xxx_charger_irq[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) {"PM2XXX_IRQ_INT", pm2xxx_irq_int},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) static int __maybe_unused pm2xxx_wall_charger_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) struct i2c_client *i2c_client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) struct pm2xxx_charger *pm2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(i2c_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) set_lpn_pin(pm2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) /* If we still have a HW failure, schedule a new check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if (pm2->flags.ovv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) queue_delayed_work(pm2->charger_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) &pm2->check_hw_failure_work, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) static int __maybe_unused pm2xxx_wall_charger_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) struct i2c_client *i2c_client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) struct pm2xxx_charger *pm2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(i2c_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) clear_lpn_pin(pm2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) /* Cancel any pending HW failure check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (delayed_work_pending(&pm2->check_hw_failure_work))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) cancel_delayed_work(&pm2->check_hw_failure_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) flush_work(&pm2->ac_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) flush_work(&pm2->check_main_thermal_prot_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) static int __maybe_unused pm2xxx_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) struct pm2xxx_charger *pm2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(pm2xxx_i2c_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) clear_lpn_pin(pm2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) static int __maybe_unused pm2xxx_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) struct pm2xxx_charger *pm2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(pm2xxx_i2c_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) if (gpio_is_valid(pm2->lpn_pin) && gpio_get_value(pm2->lpn_pin) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) set_lpn_pin(pm2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) static const struct dev_pm_ops pm2xxx_pm_ops __maybe_unused = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) SET_SYSTEM_SLEEP_PM_OPS(pm2xxx_wall_charger_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) pm2xxx_wall_charger_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) SET_RUNTIME_PM_OPS(pm2xxx_runtime_suspend, pm2xxx_runtime_resume, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) struct pm2xxx_platform_data *pl_data = i2c_client->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) struct power_supply_config psy_cfg = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) struct pm2xxx_charger *pm2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) if (!pl_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) dev_err(&i2c_client->dev, "No platform data supplied\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) pm2 = kzalloc(sizeof(struct pm2xxx_charger), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) if (!pm2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) dev_err(&i2c_client->dev, "pm2xxx_charger allocation failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) /* get parent data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) pm2->dev = &i2c_client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) pm2->pm2_int = &pm2xxx_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) /* get charger spcific platform data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) if (!pl_data->wall_charger) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) dev_err(pm2->dev, "no charger platform data supplied\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) goto free_device_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) pm2->pdata = pl_data->wall_charger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) /* get battery specific platform data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (!pl_data->battery) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) dev_err(pm2->dev, "no battery platform data supplied\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) goto free_device_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) pm2->bat = pl_data->battery;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (!i2c_check_functionality(i2c_client->adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) I2C_FUNC_SMBUS_BYTE_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) I2C_FUNC_SMBUS_READ_WORD_DATA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) dev_info(pm2->dev, "pm2301 i2c_check_functionality failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) goto free_device_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) pm2->config.pm2xxx_i2c = i2c_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) pm2->config.pm2xxx_id = (struct i2c_device_id *) id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) i2c_set_clientdata(i2c_client, pm2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) /* AC supply */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) /* power_supply base class */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) pm2->ac_chg_desc.name = pm2->pdata->label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) pm2->ac_chg_desc.type = POWER_SUPPLY_TYPE_MAINS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) pm2->ac_chg_desc.properties = pm2xxx_charger_ac_props;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) pm2->ac_chg_desc.num_properties = ARRAY_SIZE(pm2xxx_charger_ac_props);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) pm2->ac_chg_desc.get_property = pm2xxx_charger_ac_get_property;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) psy_cfg.supplied_to = pm2->pdata->supplied_to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) psy_cfg.num_supplicants = pm2->pdata->num_supplicants;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) /* pm2xxx_charger sub-class */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) pm2->ac_chg.ops.enable = &pm2xxx_charger_ac_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) pm2->ac_chg.ops.kick_wd = &pm2xxx_charger_watchdog_kick;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) pm2->ac_chg.ops.update_curr = &pm2xxx_charger_update_charger_current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) pm2->ac_chg.max_out_volt = pm2xxx_charger_voltage_map[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) ARRAY_SIZE(pm2xxx_charger_voltage_map) - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) pm2->ac_chg.max_out_curr = pm2xxx_charger_current_map[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) ARRAY_SIZE(pm2xxx_charger_current_map) - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) pm2->ac_chg.wdt_refresh = WD_KICK_INTERVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) pm2->ac_chg.enabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) pm2->ac_chg.external = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) /* Create a work queue for the charger */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) pm2->charger_wq = alloc_ordered_workqueue("pm2xxx_charger_wq",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) WQ_MEM_RECLAIM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) if (pm2->charger_wq == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) dev_err(pm2->dev, "failed to create work queue\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) goto free_device_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) /* Init work for charger detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) INIT_WORK(&pm2->ac_work, pm2xxx_charger_ac_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) /* Init work for checking HW status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) INIT_WORK(&pm2->check_main_thermal_prot_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) pm2xxx_charger_check_main_thermal_prot_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) /* Init work for HW failure check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) INIT_DEFERRABLE_WORK(&pm2->check_hw_failure_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) pm2xxx_charger_check_hw_failure_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) * VDD ADC supply needs to be enabled from this driver when there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) * is a charger connected to avoid erroneous BTEMP_HIGH/LOW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) * interrupts during charging
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) pm2->regu = regulator_get(pm2->dev, "vddadc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) if (IS_ERR(pm2->regu)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) ret = PTR_ERR(pm2->regu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) dev_err(pm2->dev, "failed to get vddadc regulator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) goto free_charger_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) /* Register AC charger class */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) pm2->ac_chg.psy = power_supply_register(pm2->dev, &pm2->ac_chg_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) &psy_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) if (IS_ERR(pm2->ac_chg.psy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) dev_err(pm2->dev, "failed to register AC charger\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) ret = PTR_ERR(pm2->ac_chg.psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) goto free_regulator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) /* Register interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) ret = request_threaded_irq(gpio_to_irq(pm2->pdata->gpio_irq_number),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) pm2xxx_charger_irq[0].isr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) pm2->pdata->irq_type | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) pm2xxx_charger_irq[0].name, pm2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) dev_err(pm2->dev, "failed to request %s IRQ %d: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) pm2xxx_charger_irq[0].name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) gpio_to_irq(pm2->pdata->gpio_irq_number), ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) goto unregister_pm2xxx_charger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) ret = pm_runtime_set_active(pm2->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) dev_err(pm2->dev, "set active Error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) pm_runtime_enable(pm2->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) pm_runtime_set_autosuspend_delay(pm2->dev, PM2XXX_AUTOSUSPEND_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) pm_runtime_use_autosuspend(pm2->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) pm_runtime_resume(pm2->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) /* pm interrupt can wake up system */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) ret = enable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) dev_err(pm2->dev, "failed to set irq wake\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) goto unregister_pm2xxx_interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) mutex_init(&pm2->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (gpio_is_valid(pm2->pdata->lpn_gpio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) /* get lpn GPIO from platform data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) pm2->lpn_pin = pm2->pdata->lpn_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) * Charger detection mechanism requires pulling up the LPN pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) * while i2c communication if Charger is not connected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) * LPN pin of PM2301 is GPIO60 of AB9540
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) ret = gpio_request(pm2->lpn_pin, "pm2301_lpm_gpio");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) dev_err(pm2->dev, "pm2301_lpm_gpio request failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) goto disable_pm2_irq_wake;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) ret = gpio_direction_output(pm2->lpn_pin, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) dev_err(pm2->dev, "pm2301_lpm_gpio direction failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) goto free_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) set_lpn_pin(pm2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) /* read interrupt registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) for (i = 0; i < PM2XXX_NUM_INT_REG; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) pm2xxx_reg_read(pm2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) pm2xxx_interrupt_registers[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) ret = pm2xxx_charger_detection(pm2, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) if ((ret == 0) && val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) pm2->ac.charger_connected = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) ab8500_override_turn_on_stat(~AB8500_POW_KEY_1_ON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) AB8500_MAIN_CH_DET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) pm2->ac_conn = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) power_supply_changed(pm2->ac_chg.psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) sysfs_notify(&pm2->ac_chg.psy->dev.kobj, NULL, "present");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) free_gpio:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (gpio_is_valid(pm2->lpn_pin))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) gpio_free(pm2->lpn_pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) disable_pm2_irq_wake:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) disable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) unregister_pm2xxx_interrupt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) /* disable interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) free_irq(gpio_to_irq(pm2->pdata->gpio_irq_number), pm2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) unregister_pm2xxx_charger:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) /* unregister power supply */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) power_supply_unregister(pm2->ac_chg.psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) free_regulator:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) /* disable the regulator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) regulator_put(pm2->regu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) free_charger_wq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) destroy_workqueue(pm2->charger_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) free_device_info:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) kfree(pm2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) static int pm2xxx_wall_charger_remove(struct i2c_client *i2c_client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) struct pm2xxx_charger *pm2 = i2c_get_clientdata(i2c_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) /* Disable pm_runtime */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) pm_runtime_disable(pm2->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) /* Disable AC charging */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) pm2xxx_charger_ac_en(&pm2->ac_chg, false, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) /* Disable wake by pm interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) disable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) /* Disable interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) free_irq(gpio_to_irq(pm2->pdata->gpio_irq_number), pm2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) /* Delete the work queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) destroy_workqueue(pm2->charger_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) flush_scheduled_work();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) /* disable the regulator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) regulator_put(pm2->regu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) power_supply_unregister(pm2->ac_chg.psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) if (gpio_is_valid(pm2->lpn_pin))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) gpio_free(pm2->lpn_pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) kfree(pm2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) static const struct i2c_device_id pm2xxx_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) { "pm2301", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) MODULE_DEVICE_TABLE(i2c, pm2xxx_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) static struct i2c_driver pm2xxx_charger_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) .probe = pm2xxx_wall_charger_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) .remove = pm2xxx_wall_charger_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) .name = "pm2xxx-wall_charger",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) .pm = IS_ENABLED(CONFIG_PM) ? &pm2xxx_pm_ops : NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) .id_table = pm2xxx_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) static int __init pm2xxx_charger_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) return i2c_add_driver(&pm2xxx_charger_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) static void __exit pm2xxx_charger_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) i2c_del_driver(&pm2xxx_charger_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) device_initcall_sync(pm2xxx_charger_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) module_exit(pm2xxx_charger_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) MODULE_AUTHOR("Rajkumar kasirajan, Olivier Launay");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) MODULE_DESCRIPTION("PM2xxx charger management driver");