Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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, &reg_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");