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)  * Battery charger driver for Dialog Semiconductor DA9030
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2008 Compulab, Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * 	Mike Rapoport <mike@compulab.co.il>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/power_supply.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/mfd/da903x.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/notifier.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define DA9030_FAULT_LOG		0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define DA9030_FAULT_LOG_OVER_TEMP	(1 << 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define DA9030_FAULT_LOG_VBAT_OVER	(1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define DA9030_CHARGE_CONTROL		0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define DA9030_CHRG_CHARGER_ENABLE	(1 << 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define DA9030_ADC_MAN_CONTROL		0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define DA9030_ADC_TBATREF_ENABLE	(1 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define DA9030_ADC_LDO_INT_ENABLE	(1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define DA9030_ADC_AUTO_CONTROL		0x31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define DA9030_ADC_TBAT_ENABLE		(1 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define DA9030_ADC_VBAT_IN_TXON		(1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define DA9030_ADC_VCH_ENABLE		(1 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define DA9030_ADC_ICH_ENABLE		(1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define DA9030_ADC_VBAT_ENABLE		(1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define DA9030_ADC_AUTO_SLEEP_ENABLE	(1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define DA9030_VBATMON		0x32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define DA9030_VBATMONTXON	0x33
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define DA9030_TBATHIGHP	0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define DA9030_TBATHIGHN	0x35
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #define DA9030_TBATLOW		0x36
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #define DA9030_VBAT_RES		0x41
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define DA9030_VBATMIN_RES	0x42
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define DA9030_VBATMINTXON_RES	0x43
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define DA9030_ICHMAX_RES	0x44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define DA9030_ICHMIN_RES	0x45
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define DA9030_ICHAVERAGE_RES	0x46
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define DA9030_VCHMAX_RES	0x47
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define DA9030_VCHMIN_RES	0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define DA9030_TBAT_RES		0x49
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) struct da9030_adc_res {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	uint8_t vbat_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	uint8_t vbatmin_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	uint8_t vbatmintxon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	uint8_t ichmax_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	uint8_t ichmin_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	uint8_t ichaverage_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	uint8_t vchmax_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	uint8_t vchmin_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	uint8_t tbat_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	uint8_t adc_in4_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	uint8_t adc_in5_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) struct da9030_battery_thresholds {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	int tbat_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	int tbat_high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	int tbat_restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	int vbat_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	int vbat_crit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	int vbat_charge_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	int vbat_charge_stop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	int vbat_charge_restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	int vcharge_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	int vcharge_max;
^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) struct da9030_charger {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	struct power_supply *psy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	struct power_supply_desc psy_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	struct device *master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	struct da9030_adc_res adc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	struct delayed_work work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	unsigned int interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	struct power_supply_info *battery_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	struct da9030_battery_thresholds thresholds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	unsigned int charge_milliamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	unsigned int charge_millivolt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	/* charger status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	bool chdet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	uint8_t fault;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	int mA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	int mV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	bool is_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	struct notifier_block nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	/* platform callbacks for battery low and critical events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	void (*battery_low)(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	void (*battery_critical)(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	struct dentry *debug_file;
^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 inline int da9030_reg_to_mV(int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	return ((reg * 2650) >> 8) + 2650;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static inline int da9030_millivolt_to_reg(int mV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	return ((mV - 2650) << 8) / 2650;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static inline int da9030_reg_to_mA(int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	return ((reg * 24000) >> 8) / 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static int bat_debug_show(struct seq_file *s, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	struct da9030_charger *charger = s->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	seq_printf(s, "charger is %s\n", charger->is_on ? "on" : "off");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	if (charger->chdet) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		seq_printf(s, "iset = %dmA, vset = %dmV\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 			   charger->mA, charger->mV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	seq_printf(s, "vbat_res = %d (%dmV)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		   charger->adc.vbat_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		   da9030_reg_to_mV(charger->adc.vbat_res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	seq_printf(s, "vbatmin_res = %d (%dmV)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		   charger->adc.vbatmin_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		   da9030_reg_to_mV(charger->adc.vbatmin_res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	seq_printf(s, "vbatmintxon = %d (%dmV)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		   charger->adc.vbatmintxon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		   da9030_reg_to_mV(charger->adc.vbatmintxon));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	seq_printf(s, "ichmax_res = %d (%dmA)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		   charger->adc.ichmax_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		   da9030_reg_to_mV(charger->adc.ichmax_res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	seq_printf(s, "ichmin_res = %d (%dmA)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		   charger->adc.ichmin_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		   da9030_reg_to_mA(charger->adc.ichmin_res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	seq_printf(s, "ichaverage_res = %d (%dmA)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		   charger->adc.ichaverage_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		   da9030_reg_to_mA(charger->adc.ichaverage_res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	seq_printf(s, "vchmax_res = %d (%dmV)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		   charger->adc.vchmax_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		   da9030_reg_to_mA(charger->adc.vchmax_res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	seq_printf(s, "vchmin_res = %d (%dmV)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		   charger->adc.vchmin_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		   da9030_reg_to_mV(charger->adc.vchmin_res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) DEFINE_SHOW_ATTRIBUTE(bat_debug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static struct dentry *da9030_bat_create_debugfs(struct da9030_charger *charger)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	charger->debug_file = debugfs_create_file("charger", 0666, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 						  charger, &bat_debug_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	return charger->debug_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static void da9030_bat_remove_debugfs(struct da9030_charger *charger)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	debugfs_remove(charger->debug_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static inline struct dentry *da9030_bat_create_debugfs(struct da9030_charger *charger)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static inline void da9030_bat_remove_debugfs(struct da9030_charger *charger)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static inline void da9030_read_adc(struct da9030_charger *charger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 				   struct da9030_adc_res *adc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	da903x_reads(charger->master, DA9030_VBAT_RES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		     sizeof(*adc), (uint8_t *)adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static void da9030_charger_update_state(struct da9030_charger *charger)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	uint8_t val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	da903x_read(charger->master, DA9030_CHARGE_CONTROL, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	charger->is_on = (val & DA9030_CHRG_CHARGER_ENABLE) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	charger->mA = ((val >> 3) & 0xf) * 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	charger->mV = (val & 0x7) * 50 + 4000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	da9030_read_adc(charger, &charger->adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	da903x_read(charger->master, DA9030_FAULT_LOG, &charger->fault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	charger->chdet = da903x_query_status(charger->master,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 						     DA9030_STATUS_CHDET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static void da9030_set_charge(struct da9030_charger *charger, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	uint8_t val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		val = DA9030_CHRG_CHARGER_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		val |= (charger->charge_milliamp / 100) << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		val |= (charger->charge_millivolt - 4000) / 50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		charger->is_on = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		charger->is_on = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	da903x_write(charger->master, DA9030_CHARGE_CONTROL, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	power_supply_changed(charger->psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static void da9030_charger_check_state(struct da9030_charger *charger)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	da9030_charger_update_state(charger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	/* we wake or boot with external power on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	if (!charger->is_on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		if ((charger->chdet) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		    (charger->adc.vbat_res <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		     charger->thresholds.vbat_charge_start)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 			da9030_set_charge(charger, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		/* Charger has been pulled out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		if (!charger->chdet) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 			da9030_set_charge(charger, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		if (charger->adc.vbat_res >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		    charger->thresholds.vbat_charge_stop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 			da9030_set_charge(charger, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 			da903x_write(charger->master, DA9030_VBATMON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 				       charger->thresholds.vbat_charge_restart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		} else if (charger->adc.vbat_res >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 			   charger->thresholds.vbat_low) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 			/* we are charging and passed LOW_THRESH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 			   so upate DA9030 VBAT threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 			da903x_write(charger->master, DA9030_VBATMON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 				     charger->thresholds.vbat_low);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		if (charger->adc.vchmax_res > charger->thresholds.vcharge_max ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		    charger->adc.vchmin_res < charger->thresholds.vcharge_min ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		    /* Tempreture readings are negative */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		    charger->adc.tbat_res < charger->thresholds.tbat_high ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		    charger->adc.tbat_res > charger->thresholds.tbat_low) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 			/* disable charger */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 			da9030_set_charge(charger, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static void da9030_charging_monitor(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	struct da9030_charger *charger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	charger = container_of(work, struct da9030_charger, work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	da9030_charger_check_state(charger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	/* reschedule for the next time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	schedule_delayed_work(&charger->work, charger->interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static enum power_supply_property da9030_battery_props[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	POWER_SUPPLY_PROP_MODEL_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	POWER_SUPPLY_PROP_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	POWER_SUPPLY_PROP_HEALTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	POWER_SUPPLY_PROP_TECHNOLOGY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	POWER_SUPPLY_PROP_CURRENT_AVG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static void da9030_battery_check_status(struct da9030_charger *charger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 				    union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	if (charger->chdet) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		if (charger->is_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 			val->intval = POWER_SUPPLY_STATUS_CHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 			val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static void da9030_battery_check_health(struct da9030_charger *charger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 				    union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	if (charger->fault & DA9030_FAULT_LOG_OVER_TEMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	else if (charger->fault & DA9030_FAULT_LOG_VBAT_OVER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		val->intval = POWER_SUPPLY_HEALTH_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static int da9030_battery_get_property(struct power_supply *psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 				   enum power_supply_property psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 				   union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	struct da9030_charger *charger = power_supply_get_drvdata(psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	case POWER_SUPPLY_PROP_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		da9030_battery_check_status(charger, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	case POWER_SUPPLY_PROP_HEALTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		da9030_battery_check_health(charger, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	case POWER_SUPPLY_PROP_TECHNOLOGY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		val->intval = charger->battery_info->technology;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		val->intval = charger->battery_info->voltage_max_design;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		val->intval = charger->battery_info->voltage_min_design;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		val->intval = da9030_reg_to_mV(charger->adc.vbat_res) * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	case POWER_SUPPLY_PROP_CURRENT_AVG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		val->intval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 			da9030_reg_to_mA(charger->adc.ichaverage_res) * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	case POWER_SUPPLY_PROP_MODEL_NAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 		val->strval = charger->battery_info->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	return 0;
^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) static void da9030_battery_vbat_event(struct da9030_charger *charger)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	da9030_read_adc(charger, &charger->adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	if (charger->is_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	if (charger->adc.vbat_res < charger->thresholds.vbat_low) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		/* set VBAT threshold for critical */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		da903x_write(charger->master, DA9030_VBATMON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 			     charger->thresholds.vbat_crit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		if (charger->battery_low)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 			charger->battery_low();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	} else if (charger->adc.vbat_res <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		   charger->thresholds.vbat_crit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		/* notify the system of battery critical */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		if (charger->battery_critical)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 			charger->battery_critical();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) static int da9030_battery_event(struct notifier_block *nb, unsigned long event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 				void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	struct da9030_charger *charger =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		container_of(nb, struct da9030_charger, nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	switch (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	case DA9030_EVENT_CHDET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 		cancel_delayed_work_sync(&charger->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		schedule_work(&charger->work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	case DA9030_EVENT_VBATMON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		da9030_battery_vbat_event(charger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	case DA9030_EVENT_CHIOVER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	case DA9030_EVENT_TBAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		da9030_set_charge(charger, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) static void da9030_battery_convert_thresholds(struct da9030_charger *charger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 					      struct da9030_battery_info *pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	charger->thresholds.tbat_low = pdata->tbat_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	charger->thresholds.tbat_high = pdata->tbat_high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	charger->thresholds.tbat_restart  = pdata->tbat_restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	charger->thresholds.vbat_low =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		da9030_millivolt_to_reg(pdata->vbat_low);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	charger->thresholds.vbat_crit =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		da9030_millivolt_to_reg(pdata->vbat_crit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	charger->thresholds.vbat_charge_start =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		da9030_millivolt_to_reg(pdata->vbat_charge_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	charger->thresholds.vbat_charge_stop =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		da9030_millivolt_to_reg(pdata->vbat_charge_stop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	charger->thresholds.vbat_charge_restart =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		da9030_millivolt_to_reg(pdata->vbat_charge_restart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	charger->thresholds.vcharge_min =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		da9030_millivolt_to_reg(pdata->vcharge_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	charger->thresholds.vcharge_max =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		da9030_millivolt_to_reg(pdata->vcharge_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) static void da9030_battery_setup_psy(struct da9030_charger *charger)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	struct power_supply_desc *psy_desc = &charger->psy_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	struct power_supply_info *info = charger->battery_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	psy_desc->name = info->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	psy_desc->use_for_apm = info->use_for_apm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	psy_desc->type = POWER_SUPPLY_TYPE_BATTERY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	psy_desc->get_property = da9030_battery_get_property;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	psy_desc->properties = da9030_battery_props;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	psy_desc->num_properties = ARRAY_SIZE(da9030_battery_props);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static int da9030_battery_charger_init(struct da9030_charger *charger)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	char v[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	v[0] = v[1] = charger->thresholds.vbat_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	v[2] = charger->thresholds.tbat_high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	v[3] = charger->thresholds.tbat_restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	v[4] = charger->thresholds.tbat_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	ret = da903x_writes(charger->master, DA9030_VBATMON, 5, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		return ret;
^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) 	 * Enable reference voltage supply for ADC from the LDO_INTERNAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	 * regulator. Must be set before ADC measurements can be made.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	ret = da903x_write(charger->master, DA9030_ADC_MAN_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 			   DA9030_ADC_LDO_INT_ENABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 			   DA9030_ADC_TBATREF_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	if (ret)
^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) 	/* enable auto ADC measuremnts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	return da903x_write(charger->master, DA9030_ADC_AUTO_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 			    DA9030_ADC_TBAT_ENABLE | DA9030_ADC_VBAT_IN_TXON |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 			    DA9030_ADC_VCH_ENABLE | DA9030_ADC_ICH_ENABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 			    DA9030_ADC_VBAT_ENABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 			    DA9030_ADC_AUTO_SLEEP_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) static int da9030_battery_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	struct da9030_charger *charger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	struct power_supply_config psy_cfg = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	struct da9030_battery_info *pdata = pdev->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	if (pdata == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	if (pdata->charge_milliamp >= 1500 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	    pdata->charge_millivolt < 4000 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	    pdata->charge_millivolt > 4350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	if (charger == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	charger->master = pdev->dev.parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	/* 10 seconds between monitor runs unless platform defines other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	   interval */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	charger->interval = msecs_to_jiffies(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 		(pdata->batmon_interval ? : 10) * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	charger->charge_milliamp = pdata->charge_milliamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	charger->charge_millivolt = pdata->charge_millivolt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	charger->battery_info = pdata->battery_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	charger->battery_low = pdata->battery_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	charger->battery_critical = pdata->battery_critical;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	da9030_battery_convert_thresholds(charger, pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	ret = da9030_battery_charger_init(charger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		goto err_charger_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	INIT_DELAYED_WORK(&charger->work, da9030_charging_monitor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	schedule_delayed_work(&charger->work, charger->interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	charger->nb.notifier_call = da9030_battery_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	ret = da903x_register_notifier(charger->master, &charger->nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 				       DA9030_EVENT_CHDET |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 				       DA9030_EVENT_VBATMON |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 				       DA9030_EVENT_CHIOVER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 				       DA9030_EVENT_TBAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		goto err_notifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	da9030_battery_setup_psy(charger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	psy_cfg.drv_data = charger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	charger->psy = power_supply_register(&pdev->dev, &charger->psy_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 					     &psy_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	if (IS_ERR(charger->psy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 		ret = PTR_ERR(charger->psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		goto err_ps_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	charger->debug_file = da9030_bat_create_debugfs(charger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	platform_set_drvdata(pdev, charger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) err_ps_register:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	da903x_unregister_notifier(charger->master, &charger->nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 				   DA9030_EVENT_CHDET | DA9030_EVENT_VBATMON |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 				   DA9030_EVENT_CHIOVER | DA9030_EVENT_TBAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) err_notifier:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	cancel_delayed_work(&charger->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) err_charger_init:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) static int da9030_battery_remove(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	struct da9030_charger *charger = platform_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	da9030_bat_remove_debugfs(charger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	da903x_unregister_notifier(charger->master, &charger->nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 				   DA9030_EVENT_CHDET | DA9030_EVENT_VBATMON |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 				   DA9030_EVENT_CHIOVER | DA9030_EVENT_TBAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	cancel_delayed_work_sync(&charger->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	da9030_set_charge(charger, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	power_supply_unregister(charger->psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) static struct platform_driver da903x_battery_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	.driver	= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 		.name	= "da903x-battery",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	.probe = da9030_battery_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	.remove = da9030_battery_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) module_platform_driver(da903x_battery_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) MODULE_DESCRIPTION("DA9030 battery charger driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) MODULE_AUTHOR("Mike Rapoport, CompuLab");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) MODULE_LICENSE("GPL");