brintos

brintos / linux-shallow public Read only

0
0
Text · 38.9 KiB · f0a64c0 Raw
1421 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.4 * Copyright (c) 2022, Linaro Ltd5 */6#include <linux/auxiliary_bus.h>7#include <linux/module.h>8#include <linux/mutex.h>9#include <linux/of_device.h>10#include <linux/power_supply.h>11#include <linux/soc/qcom/pdr.h>12#include <linux/soc/qcom/pmic_glink.h>13#include <linux/math.h>14#include <linux/units.h>15 16#define BATTMGR_CHEMISTRY_LEN	417#define BATTMGR_STRING_LEN	12818 19enum qcom_battmgr_variant {20	QCOM_BATTMGR_SM8350,21	QCOM_BATTMGR_SC8280XP,22};23 24#define BATTMGR_BAT_STATUS		0x125 26#define BATTMGR_REQUEST_NOTIFICATION	0x427 28#define BATTMGR_NOTIFICATION		0x729#define NOTIF_BAT_PROPERTY		0x3030#define NOTIF_USB_PROPERTY		0x3231#define NOTIF_WLS_PROPERTY		0x3432#define NOTIF_BAT_INFO			0x8133#define NOTIF_BAT_STATUS		0x8034 35#define BATTMGR_BAT_INFO		0x936 37#define BATTMGR_BAT_DISCHARGE_TIME	0xc38 39#define BATTMGR_BAT_CHARGE_TIME		0xd40 41#define BATTMGR_BAT_PROPERTY_GET	0x3042#define BATTMGR_BAT_PROPERTY_SET	0x3143#define BATT_STATUS			044#define BATT_HEALTH			145#define BATT_PRESENT			246#define BATT_CHG_TYPE			347#define BATT_CAPACITY			448#define BATT_SOH			549#define BATT_VOLT_OCV			650#define BATT_VOLT_NOW			751#define BATT_VOLT_MAX			852#define BATT_CURR_NOW			953#define BATT_CHG_CTRL_LIM		1054#define BATT_CHG_CTRL_LIM_MAX		1155#define BATT_TEMP			1256#define BATT_TECHNOLOGY			1357#define BATT_CHG_COUNTER		1458#define BATT_CYCLE_COUNT		1559#define BATT_CHG_FULL_DESIGN		1660#define BATT_CHG_FULL			1761#define BATT_MODEL_NAME			1862#define BATT_TTF_AVG			1963#define BATT_TTE_AVG			2064#define BATT_RESISTANCE			2165#define BATT_POWER_NOW			2266#define BATT_POWER_AVG			2367 68#define BATTMGR_USB_PROPERTY_GET	0x3269#define BATTMGR_USB_PROPERTY_SET	0x3370#define USB_ONLINE			071#define USB_VOLT_NOW			172#define USB_VOLT_MAX			273#define USB_CURR_NOW			374#define USB_CURR_MAX			475#define USB_INPUT_CURR_LIMIT		576#define USB_TYPE			677#define USB_ADAP_TYPE			778#define USB_MOISTURE_DET_EN		879#define USB_MOISTURE_DET_STS		980 81#define BATTMGR_WLS_PROPERTY_GET	0x3482#define BATTMGR_WLS_PROPERTY_SET	0x3583#define WLS_ONLINE			084#define WLS_VOLT_NOW			185#define WLS_VOLT_MAX			286#define WLS_CURR_NOW			387#define WLS_CURR_MAX			488#define WLS_TYPE			589#define WLS_BOOST_EN			690 91struct qcom_battmgr_enable_request {92	struct pmic_glink_hdr hdr;93	__le32 battery_id;94	__le32 power_state;95	__le32 low_capacity;96	__le32 high_capacity;97};98 99struct qcom_battmgr_property_request {100	struct pmic_glink_hdr hdr;101	__le32 battery;102	__le32 property;103	__le32 value;104};105 106struct qcom_battmgr_update_request {107	struct pmic_glink_hdr hdr;108	__le32 battery_id;109};110 111struct qcom_battmgr_charge_time_request {112	struct pmic_glink_hdr hdr;113	__le32 battery_id;114	__le32 percent;115	__le32 reserved;116};117 118struct qcom_battmgr_discharge_time_request {119	struct pmic_glink_hdr hdr;120	__le32 battery_id;121	__le32 rate; /* 0 for current rate */122	__le32 reserved;123};124 125struct qcom_battmgr_message {126	struct pmic_glink_hdr hdr;127	union {128		struct {129			__le32 property;130			__le32 value;131			__le32 result;132		} intval;133		struct {134			__le32 property;135			char model[BATTMGR_STRING_LEN];136		} strval;137		struct {138			/*139			 * 0: mWh140			 * 1: mAh141			 */142			__le32 power_unit;143			__le32 design_capacity;144			__le32 last_full_capacity;145			/*146			 * 0 nonrechargable147			 * 1 rechargable148			 */149			__le32 battery_tech;150			__le32 design_voltage; /* mV */151			__le32 capacity_low;152			__le32 capacity_warning;153			__le32 cycle_count;154			/* thousandth of persent */155			__le32 accuracy;156			__le32 max_sample_time_ms;157			__le32 min_sample_time_ms;158			__le32 max_average_interval_ms;159			__le32 min_average_interval_ms;160			/* granularity between low and warning */161			__le32 capacity_granularity1;162			/* granularity between warning and full */163			__le32 capacity_granularity2;164			/*165			 * 0: no166			 * 1: cold167			 * 2: hot168			 */169			__le32 swappable;170			__le32 capabilities;171			char model_number[BATTMGR_STRING_LEN];172			char serial_number[BATTMGR_STRING_LEN];173			char battery_type[BATTMGR_STRING_LEN];174			char oem_info[BATTMGR_STRING_LEN];175			char battery_chemistry[BATTMGR_CHEMISTRY_LEN];176			char uid[BATTMGR_STRING_LEN];177			__le32 critical_bias;178			u8 day;179			u8 month;180			__le16 year;181			__le32 battery_id;182		} info;183		struct {184			/*185			 * BIT(0) discharging186			 * BIT(1) charging187			 * BIT(2) critical low188			 */189			__le32 battery_state;190			/* mWh or mAh, based on info->power_unit */191			__le32 capacity;192			__le32 rate;193			/* mv */194			__le32 battery_voltage;195			/*196			 * BIT(0) power online197			 * BIT(1) discharging198			 * BIT(2) charging199			 * BIT(3) battery critical200			 */201			__le32 power_state;202			/*203			 * 1: AC204			 * 2: USB205			 * 3: Wireless206			 */207			__le32 charging_source;208			__le32 temperature;209		} status;210		__le32 time;211		__le32 notification;212	};213};214 215#define BATTMGR_CHARGING_SOURCE_AC	1216#define BATTMGR_CHARGING_SOURCE_USB	2217#define BATTMGR_CHARGING_SOURCE_WIRELESS 3218 219enum qcom_battmgr_unit {220	QCOM_BATTMGR_UNIT_mWh = 0,221	QCOM_BATTMGR_UNIT_mAh = 1222};223 224struct qcom_battmgr_info {225	bool valid;226 227	bool present;228	unsigned int charge_type;229	unsigned int design_capacity;230	unsigned int last_full_capacity;231	unsigned int voltage_max_design;232	unsigned int voltage_max;233	unsigned int capacity_low;234	unsigned int capacity_warning;235	unsigned int cycle_count;236	unsigned int charge_count;237	char model_number[BATTMGR_STRING_LEN];238	char serial_number[BATTMGR_STRING_LEN];239	char oem_info[BATTMGR_STRING_LEN];240	unsigned char technology;241	unsigned char day;242	unsigned char month;243	unsigned short year;244};245 246struct qcom_battmgr_status {247	unsigned int status;248	unsigned int health;249	unsigned int capacity;250	unsigned int percent;251	int current_now;252	int power_now;253	unsigned int voltage_now;254	unsigned int voltage_ocv;255	unsigned int temperature;256 257	unsigned int discharge_time;258	unsigned int charge_time;259};260 261struct qcom_battmgr_ac {262	bool online;263};264 265struct qcom_battmgr_usb {266	bool online;267	unsigned int voltage_now;268	unsigned int voltage_max;269	unsigned int current_now;270	unsigned int current_max;271	unsigned int current_limit;272	unsigned int usb_type;273};274 275struct qcom_battmgr_wireless {276	bool online;277	unsigned int voltage_now;278	unsigned int voltage_max;279	unsigned int current_now;280	unsigned int current_max;281};282 283struct qcom_battmgr {284	struct device *dev;285	struct pmic_glink_client *client;286 287	enum qcom_battmgr_variant variant;288 289	struct power_supply *ac_psy;290	struct power_supply *bat_psy;291	struct power_supply *usb_psy;292	struct power_supply *wls_psy;293 294	enum qcom_battmgr_unit unit;295 296	int error;297	struct completion ack;298 299	bool service_up;300 301	struct qcom_battmgr_info info;302	struct qcom_battmgr_status status;303	struct qcom_battmgr_ac ac;304	struct qcom_battmgr_usb usb;305	struct qcom_battmgr_wireless wireless;306 307	struct work_struct enable_work;308 309	/*310	 * @lock is used to prevent concurrent power supply requests to the311	 * firmware, as it then stops responding.312	 */313	struct mutex lock;314};315 316static int qcom_battmgr_request(struct qcom_battmgr *battmgr, void *data, size_t len)317{318	unsigned long left;319	int ret;320 321	reinit_completion(&battmgr->ack);322 323	battmgr->error = 0;324 325	ret = pmic_glink_send(battmgr->client, data, len);326	if (ret < 0)327		return ret;328 329	left = wait_for_completion_timeout(&battmgr->ack, HZ);330	if (!left)331		return -ETIMEDOUT;332 333	return battmgr->error;334}335 336static int qcom_battmgr_request_property(struct qcom_battmgr *battmgr, int opcode,337					 int property, u32 value)338{339	struct qcom_battmgr_property_request request = {340		.hdr.owner = cpu_to_le32(PMIC_GLINK_OWNER_BATTMGR),341		.hdr.type = cpu_to_le32(PMIC_GLINK_REQ_RESP),342		.hdr.opcode = cpu_to_le32(opcode),343		.battery = cpu_to_le32(0),344		.property = cpu_to_le32(property),345		.value = cpu_to_le32(value),346	};347 348	return qcom_battmgr_request(battmgr, &request, sizeof(request));349}350 351static int qcom_battmgr_update_status(struct qcom_battmgr *battmgr)352{353	struct qcom_battmgr_update_request request = {354		.hdr.owner = cpu_to_le32(PMIC_GLINK_OWNER_BATTMGR),355		.hdr.type = cpu_to_le32(PMIC_GLINK_REQ_RESP),356		.hdr.opcode = cpu_to_le32(BATTMGR_BAT_STATUS),357		.battery_id = cpu_to_le32(0),358	};359 360	return qcom_battmgr_request(battmgr, &request, sizeof(request));361}362 363static int qcom_battmgr_update_info(struct qcom_battmgr *battmgr)364{365	struct qcom_battmgr_update_request request = {366		.hdr.owner = cpu_to_le32(PMIC_GLINK_OWNER_BATTMGR),367		.hdr.type = cpu_to_le32(PMIC_GLINK_REQ_RESP),368		.hdr.opcode = cpu_to_le32(BATTMGR_BAT_INFO),369		.battery_id = cpu_to_le32(0),370	};371 372	return qcom_battmgr_request(battmgr, &request, sizeof(request));373}374 375static int qcom_battmgr_update_charge_time(struct qcom_battmgr *battmgr)376{377	struct qcom_battmgr_charge_time_request request = {378		.hdr.owner = cpu_to_le32(PMIC_GLINK_OWNER_BATTMGR),379		.hdr.type = cpu_to_le32(PMIC_GLINK_REQ_RESP),380		.hdr.opcode = cpu_to_le32(BATTMGR_BAT_CHARGE_TIME),381		.battery_id = cpu_to_le32(0),382		.percent = cpu_to_le32(100),383	};384 385	return qcom_battmgr_request(battmgr, &request, sizeof(request));386}387 388static int qcom_battmgr_update_discharge_time(struct qcom_battmgr *battmgr)389{390	struct qcom_battmgr_discharge_time_request request = {391		.hdr.owner = cpu_to_le32(PMIC_GLINK_OWNER_BATTMGR),392		.hdr.type = cpu_to_le32(PMIC_GLINK_REQ_RESP),393		.hdr.opcode = cpu_to_le32(BATTMGR_BAT_DISCHARGE_TIME),394		.battery_id = cpu_to_le32(0),395		.rate = cpu_to_le32(0),396	};397 398	return qcom_battmgr_request(battmgr, &request, sizeof(request));399}400 401static const u8 sm8350_bat_prop_map[] = {402	[POWER_SUPPLY_PROP_STATUS] = BATT_STATUS,403	[POWER_SUPPLY_PROP_HEALTH] = BATT_HEALTH,404	[POWER_SUPPLY_PROP_PRESENT] = BATT_PRESENT,405	[POWER_SUPPLY_PROP_CHARGE_TYPE] = BATT_CHG_TYPE,406	[POWER_SUPPLY_PROP_CAPACITY] = BATT_CAPACITY,407	[POWER_SUPPLY_PROP_VOLTAGE_OCV] = BATT_VOLT_OCV,408	[POWER_SUPPLY_PROP_VOLTAGE_NOW] = BATT_VOLT_NOW,409	[POWER_SUPPLY_PROP_VOLTAGE_MAX] = BATT_VOLT_MAX,410	[POWER_SUPPLY_PROP_CURRENT_NOW] = BATT_CURR_NOW,411	[POWER_SUPPLY_PROP_TEMP] = BATT_TEMP,412	[POWER_SUPPLY_PROP_TECHNOLOGY] = BATT_TECHNOLOGY,413	[POWER_SUPPLY_PROP_CHARGE_COUNTER] =  BATT_CHG_COUNTER,414	[POWER_SUPPLY_PROP_CYCLE_COUNT] = BATT_CYCLE_COUNT,415	[POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN] =  BATT_CHG_FULL_DESIGN,416	[POWER_SUPPLY_PROP_CHARGE_FULL] = BATT_CHG_FULL,417	[POWER_SUPPLY_PROP_MODEL_NAME] = BATT_MODEL_NAME,418	[POWER_SUPPLY_PROP_TIME_TO_FULL_AVG] = BATT_TTF_AVG,419	[POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG] = BATT_TTE_AVG,420	[POWER_SUPPLY_PROP_POWER_NOW] = BATT_POWER_NOW,421};422 423static int qcom_battmgr_bat_sm8350_update(struct qcom_battmgr *battmgr,424					  enum power_supply_property psp)425{426	unsigned int prop;427	int ret;428 429	if (psp >= ARRAY_SIZE(sm8350_bat_prop_map))430		return -EINVAL;431 432	prop = sm8350_bat_prop_map[psp];433 434	mutex_lock(&battmgr->lock);435	ret = qcom_battmgr_request_property(battmgr, BATTMGR_BAT_PROPERTY_GET, prop, 0);436	mutex_unlock(&battmgr->lock);437 438	return ret;439}440 441static int qcom_battmgr_bat_sc8280xp_update(struct qcom_battmgr *battmgr,442					    enum power_supply_property psp)443{444	int ret;445 446	mutex_lock(&battmgr->lock);447 448	if (!battmgr->info.valid) {449		ret = qcom_battmgr_update_info(battmgr);450		if (ret < 0)451			goto out_unlock;452		battmgr->info.valid = true;453	}454 455	ret = qcom_battmgr_update_status(battmgr);456	if (ret < 0)457		goto out_unlock;458 459	if (psp == POWER_SUPPLY_PROP_TIME_TO_FULL_AVG) {460		ret = qcom_battmgr_update_charge_time(battmgr);461		if (ret < 0) {462			ret = -ENODATA;463			goto out_unlock;464		}465	}466 467	if (psp == POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG) {468		ret = qcom_battmgr_update_discharge_time(battmgr);469		if (ret < 0) {470			ret = -ENODATA;471			goto out_unlock;472		}473	}474 475out_unlock:476	mutex_unlock(&battmgr->lock);477	return ret;478}479 480static int qcom_battmgr_bat_get_property(struct power_supply *psy,481					 enum power_supply_property psp,482					 union power_supply_propval *val)483{484	struct qcom_battmgr *battmgr = power_supply_get_drvdata(psy);485	enum qcom_battmgr_unit unit = battmgr->unit;486	int ret;487 488	if (!battmgr->service_up)489		return -EAGAIN;490 491	if (battmgr->variant == QCOM_BATTMGR_SC8280XP)492		ret = qcom_battmgr_bat_sc8280xp_update(battmgr, psp);493	else494		ret = qcom_battmgr_bat_sm8350_update(battmgr, psp);495	if (ret < 0)496		return ret;497 498	switch (psp) {499	case POWER_SUPPLY_PROP_STATUS:500		val->intval = battmgr->status.status;501		break;502	case POWER_SUPPLY_PROP_CHARGE_TYPE:503		val->intval = battmgr->info.charge_type;504		break;505	case POWER_SUPPLY_PROP_HEALTH:506		val->intval = battmgr->status.health;507		break;508	case POWER_SUPPLY_PROP_PRESENT:509		val->intval = battmgr->info.present;510		break;511	case POWER_SUPPLY_PROP_TECHNOLOGY:512		val->intval = battmgr->info.technology;513		break;514	case POWER_SUPPLY_PROP_CYCLE_COUNT:515		val->intval = battmgr->info.cycle_count;516		break;517	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:518		val->intval = battmgr->info.voltage_max_design;519		break;520	case POWER_SUPPLY_PROP_VOLTAGE_MAX:521		val->intval = battmgr->info.voltage_max;522		break;523	case POWER_SUPPLY_PROP_VOLTAGE_NOW:524		val->intval = battmgr->status.voltage_now;525		break;526	case POWER_SUPPLY_PROP_VOLTAGE_OCV:527		val->intval = battmgr->status.voltage_ocv;528		break;529	case POWER_SUPPLY_PROP_CURRENT_NOW:530		val->intval = battmgr->status.current_now;531		break;532	case POWER_SUPPLY_PROP_POWER_NOW:533		val->intval = battmgr->status.power_now;534		break;535	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:536		if (unit != QCOM_BATTMGR_UNIT_mAh)537			return -ENODATA;538		val->intval = battmgr->info.design_capacity;539		break;540	case POWER_SUPPLY_PROP_CHARGE_FULL:541		if (unit != QCOM_BATTMGR_UNIT_mAh)542			return -ENODATA;543		val->intval = battmgr->info.last_full_capacity;544		break;545	case POWER_SUPPLY_PROP_CHARGE_EMPTY:546		if (unit != QCOM_BATTMGR_UNIT_mAh)547			return -ENODATA;548		val->intval = battmgr->info.capacity_low;549		break;550	case POWER_SUPPLY_PROP_CHARGE_NOW:551		if (unit != QCOM_BATTMGR_UNIT_mAh)552			return -ENODATA;553		val->intval = battmgr->status.capacity;554		break;555	case POWER_SUPPLY_PROP_CHARGE_COUNTER:556		val->intval = battmgr->info.charge_count;557		break;558	case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:559		if (unit != QCOM_BATTMGR_UNIT_mWh)560			return -ENODATA;561		val->intval = battmgr->info.design_capacity;562		break;563	case POWER_SUPPLY_PROP_ENERGY_FULL:564		if (unit != QCOM_BATTMGR_UNIT_mWh)565			return -ENODATA;566		val->intval = battmgr->info.last_full_capacity;567		break;568	case POWER_SUPPLY_PROP_ENERGY_EMPTY:569		if (unit != QCOM_BATTMGR_UNIT_mWh)570			return -ENODATA;571		val->intval = battmgr->info.capacity_low;572		break;573	case POWER_SUPPLY_PROP_ENERGY_NOW:574		if (unit != QCOM_BATTMGR_UNIT_mWh)575			return -ENODATA;576		val->intval = battmgr->status.capacity;577		break;578	case POWER_SUPPLY_PROP_CAPACITY:579		val->intval = battmgr->status.percent;580		break;581	case POWER_SUPPLY_PROP_TEMP:582		val->intval = battmgr->status.temperature;583		break;584	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:585		val->intval = battmgr->status.discharge_time;586		break;587	case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:588		val->intval = battmgr->status.charge_time;589		break;590	case POWER_SUPPLY_PROP_MANUFACTURE_YEAR:591		val->intval = battmgr->info.year;592		break;593	case POWER_SUPPLY_PROP_MANUFACTURE_MONTH:594		val->intval = battmgr->info.month;595		break;596	case POWER_SUPPLY_PROP_MANUFACTURE_DAY:597		val->intval = battmgr->info.day;598		break;599	case POWER_SUPPLY_PROP_MODEL_NAME:600		val->strval = battmgr->info.model_number;601		break;602	case POWER_SUPPLY_PROP_MANUFACTURER:603		val->strval = battmgr->info.oem_info;604		break;605	case POWER_SUPPLY_PROP_SERIAL_NUMBER:606		val->strval = battmgr->info.serial_number;607		break;608	default:609		return -EINVAL;610	}611 612	return 0;613}614 615static const enum power_supply_property sc8280xp_bat_props[] = {616	POWER_SUPPLY_PROP_STATUS,617	POWER_SUPPLY_PROP_PRESENT,618	POWER_SUPPLY_PROP_TECHNOLOGY,619	POWER_SUPPLY_PROP_CYCLE_COUNT,620	POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,621	POWER_SUPPLY_PROP_VOLTAGE_NOW,622	POWER_SUPPLY_PROP_POWER_NOW,623	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,624	POWER_SUPPLY_PROP_CHARGE_FULL,625	POWER_SUPPLY_PROP_CHARGE_EMPTY,626	POWER_SUPPLY_PROP_CHARGE_NOW,627	POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,628	POWER_SUPPLY_PROP_ENERGY_FULL,629	POWER_SUPPLY_PROP_ENERGY_EMPTY,630	POWER_SUPPLY_PROP_ENERGY_NOW,631	POWER_SUPPLY_PROP_TEMP,632	POWER_SUPPLY_PROP_MANUFACTURE_YEAR,633	POWER_SUPPLY_PROP_MANUFACTURE_MONTH,634	POWER_SUPPLY_PROP_MANUFACTURE_DAY,635	POWER_SUPPLY_PROP_MODEL_NAME,636	POWER_SUPPLY_PROP_MANUFACTURER,637	POWER_SUPPLY_PROP_SERIAL_NUMBER,638};639 640static const struct power_supply_desc sc8280xp_bat_psy_desc = {641	.name = "qcom-battmgr-bat",642	.type = POWER_SUPPLY_TYPE_BATTERY,643	.properties = sc8280xp_bat_props,644	.num_properties = ARRAY_SIZE(sc8280xp_bat_props),645	.get_property = qcom_battmgr_bat_get_property,646};647 648static const enum power_supply_property sm8350_bat_props[] = {649	POWER_SUPPLY_PROP_STATUS,650	POWER_SUPPLY_PROP_HEALTH,651	POWER_SUPPLY_PROP_PRESENT,652	POWER_SUPPLY_PROP_CHARGE_TYPE,653	POWER_SUPPLY_PROP_CAPACITY,654	POWER_SUPPLY_PROP_VOLTAGE_OCV,655	POWER_SUPPLY_PROP_VOLTAGE_NOW,656	POWER_SUPPLY_PROP_VOLTAGE_MAX,657	POWER_SUPPLY_PROP_CURRENT_NOW,658	POWER_SUPPLY_PROP_TEMP,659	POWER_SUPPLY_PROP_TECHNOLOGY,660	POWER_SUPPLY_PROP_CHARGE_COUNTER,661	POWER_SUPPLY_PROP_CYCLE_COUNT,662	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,663	POWER_SUPPLY_PROP_CHARGE_FULL,664	POWER_SUPPLY_PROP_MODEL_NAME,665	POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,666	POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,667	POWER_SUPPLY_PROP_POWER_NOW,668};669 670static const struct power_supply_desc sm8350_bat_psy_desc = {671	.name = "qcom-battmgr-bat",672	.type = POWER_SUPPLY_TYPE_BATTERY,673	.properties = sm8350_bat_props,674	.num_properties = ARRAY_SIZE(sm8350_bat_props),675	.get_property = qcom_battmgr_bat_get_property,676};677 678static int qcom_battmgr_ac_get_property(struct power_supply *psy,679					enum power_supply_property psp,680					union power_supply_propval *val)681{682	struct qcom_battmgr *battmgr = power_supply_get_drvdata(psy);683	int ret;684 685	if (!battmgr->service_up)686		return -EAGAIN;687 688	ret = qcom_battmgr_bat_sc8280xp_update(battmgr, psp);689	if (ret)690		return ret;691 692	switch (psp) {693	case POWER_SUPPLY_PROP_ONLINE:694		val->intval = battmgr->ac.online;695		break;696	default:697		return -EINVAL;698	}699 700	return 0;701}702 703static const enum power_supply_property sc8280xp_ac_props[] = {704	POWER_SUPPLY_PROP_ONLINE,705};706 707static const struct power_supply_desc sc8280xp_ac_psy_desc = {708	.name = "qcom-battmgr-ac",709	.type = POWER_SUPPLY_TYPE_MAINS,710	.properties = sc8280xp_ac_props,711	.num_properties = ARRAY_SIZE(sc8280xp_ac_props),712	.get_property = qcom_battmgr_ac_get_property,713};714 715static const u8 sm8350_usb_prop_map[] = {716	[POWER_SUPPLY_PROP_ONLINE] = USB_ONLINE,717	[POWER_SUPPLY_PROP_VOLTAGE_NOW] = USB_VOLT_NOW,718	[POWER_SUPPLY_PROP_VOLTAGE_MAX] = USB_VOLT_MAX,719	[POWER_SUPPLY_PROP_CURRENT_NOW] = USB_CURR_NOW,720	[POWER_SUPPLY_PROP_CURRENT_MAX] = USB_CURR_MAX,721	[POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT] = USB_INPUT_CURR_LIMIT,722	[POWER_SUPPLY_PROP_USB_TYPE] = USB_TYPE,723};724 725static int qcom_battmgr_usb_sm8350_update(struct qcom_battmgr *battmgr,726					  enum power_supply_property psp)727{728	unsigned int prop;729	int ret;730 731	if (psp >= ARRAY_SIZE(sm8350_usb_prop_map))732		return -EINVAL;733 734	prop = sm8350_usb_prop_map[psp];735 736	mutex_lock(&battmgr->lock);737	ret = qcom_battmgr_request_property(battmgr, BATTMGR_USB_PROPERTY_GET, prop, 0);738	mutex_unlock(&battmgr->lock);739 740	return ret;741}742 743static int qcom_battmgr_usb_get_property(struct power_supply *psy,744					 enum power_supply_property psp,745					 union power_supply_propval *val)746{747	struct qcom_battmgr *battmgr = power_supply_get_drvdata(psy);748	int ret;749 750	if (!battmgr->service_up)751		return -EAGAIN;752 753	if (battmgr->variant == QCOM_BATTMGR_SC8280XP)754		ret = qcom_battmgr_bat_sc8280xp_update(battmgr, psp);755	else756		ret = qcom_battmgr_usb_sm8350_update(battmgr, psp);757	if (ret)758		return ret;759 760	switch (psp) {761	case POWER_SUPPLY_PROP_ONLINE:762		val->intval = battmgr->usb.online;763		break;764	case POWER_SUPPLY_PROP_VOLTAGE_NOW:765		val->intval = battmgr->usb.voltage_now;766		break;767	case POWER_SUPPLY_PROP_VOLTAGE_MAX:768		val->intval = battmgr->usb.voltage_max;769		break;770	case POWER_SUPPLY_PROP_CURRENT_NOW:771		val->intval = battmgr->usb.current_now;772		break;773	case POWER_SUPPLY_PROP_CURRENT_MAX:774		val->intval = battmgr->usb.current_max;775		break;776	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:777		val->intval = battmgr->usb.current_limit;778		break;779	case POWER_SUPPLY_PROP_USB_TYPE:780		val->intval = battmgr->usb.usb_type;781		break;782	default:783		return -EINVAL;784	}785 786	return 0;787}788 789static const enum power_supply_property sc8280xp_usb_props[] = {790	POWER_SUPPLY_PROP_ONLINE,791};792 793static const struct power_supply_desc sc8280xp_usb_psy_desc = {794	.name = "qcom-battmgr-usb",795	.type = POWER_SUPPLY_TYPE_USB,796	.properties = sc8280xp_usb_props,797	.num_properties = ARRAY_SIZE(sc8280xp_usb_props),798	.get_property = qcom_battmgr_usb_get_property,799	.usb_types = BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN) |800		     BIT(POWER_SUPPLY_USB_TYPE_SDP)     |801		     BIT(POWER_SUPPLY_USB_TYPE_DCP)     |802		     BIT(POWER_SUPPLY_USB_TYPE_CDP)     |803		     BIT(POWER_SUPPLY_USB_TYPE_ACA)     |804		     BIT(POWER_SUPPLY_USB_TYPE_C)       |805		     BIT(POWER_SUPPLY_USB_TYPE_PD)      |806		     BIT(POWER_SUPPLY_USB_TYPE_PD_DRP)  |807		     BIT(POWER_SUPPLY_USB_TYPE_PD_PPS)  |808		     BIT(POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID),809};810 811static const enum power_supply_property sm8350_usb_props[] = {812	POWER_SUPPLY_PROP_ONLINE,813	POWER_SUPPLY_PROP_VOLTAGE_NOW,814	POWER_SUPPLY_PROP_VOLTAGE_MAX,815	POWER_SUPPLY_PROP_CURRENT_NOW,816	POWER_SUPPLY_PROP_CURRENT_MAX,817	POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,818	POWER_SUPPLY_PROP_USB_TYPE,819};820 821static const struct power_supply_desc sm8350_usb_psy_desc = {822	.name = "qcom-battmgr-usb",823	.type = POWER_SUPPLY_TYPE_USB,824	.properties = sm8350_usb_props,825	.num_properties = ARRAY_SIZE(sm8350_usb_props),826	.get_property = qcom_battmgr_usb_get_property,827	.usb_types = BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN) |828		     BIT(POWER_SUPPLY_USB_TYPE_SDP)     |829		     BIT(POWER_SUPPLY_USB_TYPE_DCP)     |830		     BIT(POWER_SUPPLY_USB_TYPE_CDP)     |831		     BIT(POWER_SUPPLY_USB_TYPE_ACA)     |832		     BIT(POWER_SUPPLY_USB_TYPE_C)       |833		     BIT(POWER_SUPPLY_USB_TYPE_PD)      |834		     BIT(POWER_SUPPLY_USB_TYPE_PD_DRP)  |835		     BIT(POWER_SUPPLY_USB_TYPE_PD_PPS)  |836		     BIT(POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID),837};838 839static const u8 sm8350_wls_prop_map[] = {840	[POWER_SUPPLY_PROP_ONLINE] = WLS_ONLINE,841	[POWER_SUPPLY_PROP_VOLTAGE_NOW] = WLS_VOLT_NOW,842	[POWER_SUPPLY_PROP_VOLTAGE_MAX] = WLS_VOLT_MAX,843	[POWER_SUPPLY_PROP_CURRENT_NOW] = WLS_CURR_NOW,844	[POWER_SUPPLY_PROP_CURRENT_MAX] = WLS_CURR_MAX,845};846 847static int qcom_battmgr_wls_sm8350_update(struct qcom_battmgr *battmgr,848					  enum power_supply_property psp)849{850	unsigned int prop;851	int ret;852 853	if (psp >= ARRAY_SIZE(sm8350_wls_prop_map))854		return -EINVAL;855 856	prop = sm8350_wls_prop_map[psp];857 858	mutex_lock(&battmgr->lock);859	ret = qcom_battmgr_request_property(battmgr, BATTMGR_WLS_PROPERTY_GET, prop, 0);860	mutex_unlock(&battmgr->lock);861 862	return ret;863}864 865static int qcom_battmgr_wls_get_property(struct power_supply *psy,866					 enum power_supply_property psp,867					 union power_supply_propval *val)868{869	struct qcom_battmgr *battmgr = power_supply_get_drvdata(psy);870	int ret;871 872	if (!battmgr->service_up)873		return -EAGAIN;874 875	if (battmgr->variant == QCOM_BATTMGR_SC8280XP)876		ret = qcom_battmgr_bat_sc8280xp_update(battmgr, psp);877	else878		ret = qcom_battmgr_wls_sm8350_update(battmgr, psp);879	if (ret < 0)880		return ret;881 882	switch (psp) {883	case POWER_SUPPLY_PROP_ONLINE:884		val->intval = battmgr->wireless.online;885		break;886	case POWER_SUPPLY_PROP_VOLTAGE_NOW:887		val->intval = battmgr->wireless.voltage_now;888		break;889	case POWER_SUPPLY_PROP_VOLTAGE_MAX:890		val->intval = battmgr->wireless.voltage_max;891		break;892	case POWER_SUPPLY_PROP_CURRENT_NOW:893		val->intval = battmgr->wireless.current_now;894		break;895	case POWER_SUPPLY_PROP_CURRENT_MAX:896		val->intval = battmgr->wireless.current_max;897		break;898	default:899		return -EINVAL;900	}901 902	return 0;903}904 905static const enum power_supply_property sc8280xp_wls_props[] = {906	POWER_SUPPLY_PROP_ONLINE,907};908 909static const struct power_supply_desc sc8280xp_wls_psy_desc = {910	.name = "qcom-battmgr-wls",911	.type = POWER_SUPPLY_TYPE_WIRELESS,912	.properties = sc8280xp_wls_props,913	.num_properties = ARRAY_SIZE(sc8280xp_wls_props),914	.get_property = qcom_battmgr_wls_get_property,915};916 917static const enum power_supply_property sm8350_wls_props[] = {918	POWER_SUPPLY_PROP_ONLINE,919	POWER_SUPPLY_PROP_VOLTAGE_NOW,920	POWER_SUPPLY_PROP_VOLTAGE_MAX,921	POWER_SUPPLY_PROP_CURRENT_NOW,922	POWER_SUPPLY_PROP_CURRENT_MAX,923};924 925static const struct power_supply_desc sm8350_wls_psy_desc = {926	.name = "qcom-battmgr-wls",927	.type = POWER_SUPPLY_TYPE_WIRELESS,928	.properties = sm8350_wls_props,929	.num_properties = ARRAY_SIZE(sm8350_wls_props),930	.get_property = qcom_battmgr_wls_get_property,931};932 933static void qcom_battmgr_notification(struct qcom_battmgr *battmgr,934				      const struct qcom_battmgr_message *msg,935				      int len)936{937	size_t payload_len = len - sizeof(struct pmic_glink_hdr);938	unsigned int notification;939 940	if (payload_len != sizeof(msg->notification)) {941		dev_warn(battmgr->dev, "ignoring notification with invalid length\n");942		return;943	}944 945	notification = le32_to_cpu(msg->notification);946	switch (notification) {947	case NOTIF_BAT_INFO:948		battmgr->info.valid = false;949		fallthrough;950	case NOTIF_BAT_STATUS:951	case NOTIF_BAT_PROPERTY:952		power_supply_changed(battmgr->bat_psy);953		break;954	case NOTIF_USB_PROPERTY:955		power_supply_changed(battmgr->usb_psy);956		break;957	case NOTIF_WLS_PROPERTY:958		power_supply_changed(battmgr->wls_psy);959		break;960	default:961		dev_err(battmgr->dev, "unknown notification: %#x\n", notification);962		break;963	}964}965 966static void qcom_battmgr_sc8280xp_strcpy(char *dest, const char *src)967{968	size_t len = src[0];969 970	/* Some firmware versions return Pascal-style strings */971	if (len < BATTMGR_STRING_LEN && len == strnlen(src + 1, BATTMGR_STRING_LEN - 1)) {972		memcpy(dest, src + 1, len);973		dest[len] = '\0';974	} else {975		memcpy(dest, src, BATTMGR_STRING_LEN);976	}977}978 979static unsigned int qcom_battmgr_sc8280xp_parse_technology(const char *chemistry)980{981	if (!strncmp(chemistry, "LIO", BATTMGR_CHEMISTRY_LEN))982		return POWER_SUPPLY_TECHNOLOGY_LION;983 984	pr_err("Unknown battery technology '%s'\n", chemistry);985	return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;986}987 988static unsigned int qcom_battmgr_sc8280xp_convert_temp(unsigned int temperature)989{990	return DIV_ROUND_CLOSEST(temperature, 10);991}992 993static void qcom_battmgr_sc8280xp_callback(struct qcom_battmgr *battmgr,994					   const struct qcom_battmgr_message *resp,995					   size_t len)996{997	unsigned int opcode = le32_to_cpu(resp->hdr.opcode);998	unsigned int source;999	unsigned int state;1000	size_t payload_len = len - sizeof(struct pmic_glink_hdr);1001 1002	if (payload_len < sizeof(__le32)) {1003		dev_warn(battmgr->dev, "invalid payload length for %#x: %zd\n",1004			 opcode, len);1005		return;1006	}1007 1008	switch (opcode) {1009	case BATTMGR_REQUEST_NOTIFICATION:1010		battmgr->error = 0;1011		break;1012	case BATTMGR_BAT_INFO:1013		/* some firmware versions report an extra __le32 at the end of the payload */1014		if (payload_len != sizeof(resp->info) &&1015		    payload_len != (sizeof(resp->info) + sizeof(__le32))) {1016			dev_warn(battmgr->dev,1017				 "invalid payload length for battery information request: %zd\n",1018				 payload_len);1019			battmgr->error = -ENODATA;1020			return;1021		}1022 1023		battmgr->unit = le32_to_cpu(resp->info.power_unit);1024 1025		battmgr->info.present = true;1026		battmgr->info.design_capacity = le32_to_cpu(resp->info.design_capacity) * 1000;1027		battmgr->info.last_full_capacity = le32_to_cpu(resp->info.last_full_capacity) * 1000;1028		battmgr->info.voltage_max_design = le32_to_cpu(resp->info.design_voltage) * 1000;1029		battmgr->info.capacity_low = le32_to_cpu(resp->info.capacity_low) * 1000;1030		battmgr->info.cycle_count = le32_to_cpu(resp->info.cycle_count);1031		qcom_battmgr_sc8280xp_strcpy(battmgr->info.model_number, resp->info.model_number);1032		qcom_battmgr_sc8280xp_strcpy(battmgr->info.serial_number, resp->info.serial_number);1033		battmgr->info.technology = qcom_battmgr_sc8280xp_parse_technology(resp->info.battery_chemistry);1034		qcom_battmgr_sc8280xp_strcpy(battmgr->info.oem_info, resp->info.oem_info);1035		battmgr->info.day = resp->info.day;1036		battmgr->info.month = resp->info.month;1037		battmgr->info.year = le16_to_cpu(resp->info.year);1038		break;1039	case BATTMGR_BAT_STATUS:1040		if (payload_len != sizeof(resp->status)) {1041			dev_warn(battmgr->dev,1042				 "invalid payload length for battery status request: %zd\n",1043				 payload_len);1044			battmgr->error = -ENODATA;1045			return;1046		}1047 1048		state = le32_to_cpu(resp->status.battery_state);1049		if (state & BIT(0))1050			battmgr->status.status = POWER_SUPPLY_STATUS_DISCHARGING;1051		else if (state & BIT(1))1052			battmgr->status.status = POWER_SUPPLY_STATUS_CHARGING;1053		else1054			battmgr->status.status = POWER_SUPPLY_STATUS_NOT_CHARGING;1055 1056		battmgr->status.capacity = le32_to_cpu(resp->status.capacity) * 1000;1057		battmgr->status.power_now = le32_to_cpu(resp->status.rate) * 1000;1058		battmgr->status.voltage_now = le32_to_cpu(resp->status.battery_voltage) * 1000;1059		battmgr->status.temperature = qcom_battmgr_sc8280xp_convert_temp(le32_to_cpu(resp->status.temperature));1060 1061		source = le32_to_cpu(resp->status.charging_source);1062		battmgr->ac.online = source == BATTMGR_CHARGING_SOURCE_AC;1063		battmgr->usb.online = source == BATTMGR_CHARGING_SOURCE_USB;1064		battmgr->wireless.online = source == BATTMGR_CHARGING_SOURCE_WIRELESS;1065		break;1066	case BATTMGR_BAT_DISCHARGE_TIME:1067		battmgr->status.discharge_time = le32_to_cpu(resp->time);1068		break;1069	case BATTMGR_BAT_CHARGE_TIME:1070		battmgr->status.charge_time = le32_to_cpu(resp->time);1071		break;1072	default:1073		dev_warn(battmgr->dev, "unknown message %#x\n", opcode);1074		break;1075	}1076 1077	complete(&battmgr->ack);1078}1079 1080static void qcom_battmgr_sm8350_callback(struct qcom_battmgr *battmgr,1081					 const struct qcom_battmgr_message *resp,1082					 size_t len)1083{1084	unsigned int property;1085	unsigned int opcode = le32_to_cpu(resp->hdr.opcode);1086	size_t payload_len = len - sizeof(struct pmic_glink_hdr);1087	unsigned int val;1088 1089	if (payload_len < sizeof(__le32)) {1090		dev_warn(battmgr->dev, "invalid payload length for %#x: %zd\n",1091			 opcode, len);1092		return;1093	}1094 1095	switch (opcode) {1096	case BATTMGR_BAT_PROPERTY_GET:1097		property = le32_to_cpu(resp->intval.property);1098		if (property == BATT_MODEL_NAME) {1099			if (payload_len != sizeof(resp->strval)) {1100				dev_warn(battmgr->dev,1101					 "invalid payload length for BATT_MODEL_NAME request: %zd\n",1102					 payload_len);1103				battmgr->error = -ENODATA;1104				return;1105			}1106		} else {1107			if (payload_len != sizeof(resp->intval)) {1108				dev_warn(battmgr->dev,1109					 "invalid payload length for %#x request: %zd\n",1110					 property, payload_len);1111				battmgr->error = -ENODATA;1112				return;1113			}1114 1115			battmgr->error = le32_to_cpu(resp->intval.result);1116			if (battmgr->error)1117				goto out_complete;1118		}1119 1120		switch (property) {1121		case BATT_STATUS:1122			battmgr->status.status = le32_to_cpu(resp->intval.value);1123			break;1124		case BATT_HEALTH:1125			battmgr->status.health = le32_to_cpu(resp->intval.value);1126			break;1127		case BATT_PRESENT:1128			battmgr->info.present = le32_to_cpu(resp->intval.value);1129			break;1130		case BATT_CHG_TYPE:1131			battmgr->info.charge_type = le32_to_cpu(resp->intval.value);1132			break;1133		case BATT_CAPACITY:1134			battmgr->status.percent = le32_to_cpu(resp->intval.value) / 100;1135			break;1136		case BATT_VOLT_OCV:1137			battmgr->status.voltage_ocv = le32_to_cpu(resp->intval.value);1138			break;1139		case BATT_VOLT_NOW:1140			battmgr->status.voltage_now = le32_to_cpu(resp->intval.value);1141			break;1142		case BATT_VOLT_MAX:1143			battmgr->info.voltage_max = le32_to_cpu(resp->intval.value);1144			break;1145		case BATT_CURR_NOW:1146			battmgr->status.current_now = le32_to_cpu(resp->intval.value);1147			break;1148		case BATT_TEMP:1149			val = le32_to_cpu(resp->intval.value);1150			battmgr->status.temperature = DIV_ROUND_CLOSEST(val, 10);1151			break;1152		case BATT_TECHNOLOGY:1153			battmgr->info.technology = le32_to_cpu(resp->intval.value);1154			break;1155		case BATT_CHG_COUNTER:1156			battmgr->info.charge_count = le32_to_cpu(resp->intval.value);1157			break;1158		case BATT_CYCLE_COUNT:1159			battmgr->info.cycle_count = le32_to_cpu(resp->intval.value);1160			break;1161		case BATT_CHG_FULL_DESIGN:1162			battmgr->info.design_capacity = le32_to_cpu(resp->intval.value);1163			break;1164		case BATT_CHG_FULL:1165			battmgr->info.last_full_capacity = le32_to_cpu(resp->intval.value);1166			break;1167		case BATT_MODEL_NAME:1168			strscpy(battmgr->info.model_number, resp->strval.model, BATTMGR_STRING_LEN);1169			break;1170		case BATT_TTF_AVG:1171			battmgr->status.charge_time = le32_to_cpu(resp->intval.value);1172			break;1173		case BATT_TTE_AVG:1174			battmgr->status.discharge_time = le32_to_cpu(resp->intval.value);1175			break;1176		case BATT_POWER_NOW:1177			battmgr->status.power_now = le32_to_cpu(resp->intval.value);1178			break;1179		default:1180			dev_warn(battmgr->dev, "unknown property %#x\n", property);1181			break;1182		}1183		break;1184	case BATTMGR_USB_PROPERTY_GET:1185		property = le32_to_cpu(resp->intval.property);1186		if (payload_len != sizeof(resp->intval)) {1187			dev_warn(battmgr->dev,1188				 "invalid payload length for %#x request: %zd\n",1189				 property, payload_len);1190			battmgr->error = -ENODATA;1191			return;1192		}1193 1194		battmgr->error = le32_to_cpu(resp->intval.result);1195		if (battmgr->error)1196			goto out_complete;1197 1198		switch (property) {1199		case USB_ONLINE:1200			battmgr->usb.online = le32_to_cpu(resp->intval.value);1201			break;1202		case USB_VOLT_NOW:1203			battmgr->usb.voltage_now = le32_to_cpu(resp->intval.value);1204			break;1205		case USB_VOLT_MAX:1206			battmgr->usb.voltage_max = le32_to_cpu(resp->intval.value);1207			break;1208		case USB_CURR_NOW:1209			battmgr->usb.current_now = le32_to_cpu(resp->intval.value);1210			break;1211		case USB_CURR_MAX:1212			battmgr->usb.current_max = le32_to_cpu(resp->intval.value);1213			break;1214		case USB_INPUT_CURR_LIMIT:1215			battmgr->usb.current_limit = le32_to_cpu(resp->intval.value);1216			break;1217		case USB_TYPE:1218			battmgr->usb.usb_type = le32_to_cpu(resp->intval.value);1219			break;1220		default:1221			dev_warn(battmgr->dev, "unknown property %#x\n", property);1222			break;1223		}1224		break;1225	case BATTMGR_WLS_PROPERTY_GET:1226		property = le32_to_cpu(resp->intval.property);1227		if (payload_len != sizeof(resp->intval)) {1228			dev_warn(battmgr->dev,1229				 "invalid payload length for %#x request: %zd\n",1230				 property, payload_len);1231			battmgr->error = -ENODATA;1232			return;1233		}1234 1235		battmgr->error = le32_to_cpu(resp->intval.result);1236		if (battmgr->error)1237			goto out_complete;1238 1239		switch (property) {1240		case WLS_ONLINE:1241			battmgr->wireless.online = le32_to_cpu(resp->intval.value);1242			break;1243		case WLS_VOLT_NOW:1244			battmgr->wireless.voltage_now = le32_to_cpu(resp->intval.value);1245			break;1246		case WLS_VOLT_MAX:1247			battmgr->wireless.voltage_max = le32_to_cpu(resp->intval.value);1248			break;1249		case WLS_CURR_NOW:1250			battmgr->wireless.current_now = le32_to_cpu(resp->intval.value);1251			break;1252		case WLS_CURR_MAX:1253			battmgr->wireless.current_max = le32_to_cpu(resp->intval.value);1254			break;1255		default:1256			dev_warn(battmgr->dev, "unknown property %#x\n", property);1257			break;1258		}1259		break;1260	case BATTMGR_REQUEST_NOTIFICATION:1261		battmgr->error = 0;1262		break;1263	default:1264		dev_warn(battmgr->dev, "unknown message %#x\n", opcode);1265		break;1266	}1267 1268out_complete:1269	complete(&battmgr->ack);1270}1271 1272static void qcom_battmgr_callback(const void *data, size_t len, void *priv)1273{1274	const struct pmic_glink_hdr *hdr = data;1275	struct qcom_battmgr *battmgr = priv;1276	unsigned int opcode = le32_to_cpu(hdr->opcode);1277 1278	if (opcode == BATTMGR_NOTIFICATION)1279		qcom_battmgr_notification(battmgr, data, len);1280	else if (battmgr->variant == QCOM_BATTMGR_SC8280XP)1281		qcom_battmgr_sc8280xp_callback(battmgr, data, len);1282	else1283		qcom_battmgr_sm8350_callback(battmgr, data, len);1284}1285 1286static void qcom_battmgr_enable_worker(struct work_struct *work)1287{1288	struct qcom_battmgr *battmgr = container_of(work, struct qcom_battmgr, enable_work);1289	struct qcom_battmgr_enable_request req = {1290		.hdr.owner = cpu_to_le32(PMIC_GLINK_OWNER_BATTMGR),1291		.hdr.type = cpu_to_le32(PMIC_GLINK_NOTIFY),1292		.hdr.opcode = cpu_to_le32(BATTMGR_REQUEST_NOTIFICATION),1293	};1294	int ret;1295 1296	ret = qcom_battmgr_request(battmgr, &req, sizeof(req));1297	if (ret)1298		dev_err(battmgr->dev, "failed to request power notifications\n");1299}1300 1301static void qcom_battmgr_pdr_notify(void *priv, int state)1302{1303	struct qcom_battmgr *battmgr = priv;1304 1305	if (state == SERVREG_SERVICE_STATE_UP) {1306		battmgr->service_up = true;1307		schedule_work(&battmgr->enable_work);1308	} else {1309		battmgr->service_up = false;1310	}1311}1312 1313static const struct of_device_id qcom_battmgr_of_variants[] = {1314	{ .compatible = "qcom,sc8180x-pmic-glink", .data = (void *)QCOM_BATTMGR_SC8280XP },1315	{ .compatible = "qcom,sc8280xp-pmic-glink", .data = (void *)QCOM_BATTMGR_SC8280XP },1316	{ .compatible = "qcom,x1e80100-pmic-glink", .data = (void *)QCOM_BATTMGR_SC8280XP },1317	/* Unmatched devices falls back to QCOM_BATTMGR_SM8350 */1318	{}1319};1320 1321static char *qcom_battmgr_battery[] = { "battery" };1322 1323static int qcom_battmgr_probe(struct auxiliary_device *adev,1324			      const struct auxiliary_device_id *id)1325{1326	struct power_supply_config psy_cfg_supply = {};1327	struct power_supply_config psy_cfg = {};1328	const struct of_device_id *match;1329	struct qcom_battmgr *battmgr;1330	struct device *dev = &adev->dev;1331 1332	battmgr = devm_kzalloc(dev, sizeof(*battmgr), GFP_KERNEL);1333	if (!battmgr)1334		return -ENOMEM;1335 1336	battmgr->dev = dev;1337 1338	psy_cfg.drv_data = battmgr;1339	psy_cfg.of_node = adev->dev.of_node;1340 1341	psy_cfg_supply.drv_data = battmgr;1342	psy_cfg_supply.of_node = adev->dev.of_node;1343	psy_cfg_supply.supplied_to = qcom_battmgr_battery;1344	psy_cfg_supply.num_supplicants = 1;1345 1346	INIT_WORK(&battmgr->enable_work, qcom_battmgr_enable_worker);1347	mutex_init(&battmgr->lock);1348	init_completion(&battmgr->ack);1349 1350	match = of_match_device(qcom_battmgr_of_variants, dev->parent);1351	if (match)1352		battmgr->variant = (unsigned long)match->data;1353	else1354		battmgr->variant = QCOM_BATTMGR_SM8350;1355 1356	if (battmgr->variant == QCOM_BATTMGR_SC8280XP) {1357		battmgr->bat_psy = devm_power_supply_register(dev, &sc8280xp_bat_psy_desc, &psy_cfg);1358		if (IS_ERR(battmgr->bat_psy))1359			return dev_err_probe(dev, PTR_ERR(battmgr->bat_psy),1360					     "failed to register battery power supply\n");1361 1362		battmgr->ac_psy = devm_power_supply_register(dev, &sc8280xp_ac_psy_desc, &psy_cfg_supply);1363		if (IS_ERR(battmgr->ac_psy))1364			return dev_err_probe(dev, PTR_ERR(battmgr->ac_psy),1365					     "failed to register AC power supply\n");1366 1367		battmgr->usb_psy = devm_power_supply_register(dev, &sc8280xp_usb_psy_desc, &psy_cfg_supply);1368		if (IS_ERR(battmgr->usb_psy))1369			return dev_err_probe(dev, PTR_ERR(battmgr->usb_psy),1370					     "failed to register USB power supply\n");1371 1372		battmgr->wls_psy = devm_power_supply_register(dev, &sc8280xp_wls_psy_desc, &psy_cfg_supply);1373		if (IS_ERR(battmgr->wls_psy))1374			return dev_err_probe(dev, PTR_ERR(battmgr->wls_psy),1375					     "failed to register wireless charing power supply\n");1376	} else {1377		battmgr->bat_psy = devm_power_supply_register(dev, &sm8350_bat_psy_desc, &psy_cfg);1378		if (IS_ERR(battmgr->bat_psy))1379			return dev_err_probe(dev, PTR_ERR(battmgr->bat_psy),1380					     "failed to register battery power supply\n");1381 1382		battmgr->usb_psy = devm_power_supply_register(dev, &sm8350_usb_psy_desc, &psy_cfg_supply);1383		if (IS_ERR(battmgr->usb_psy))1384			return dev_err_probe(dev, PTR_ERR(battmgr->usb_psy),1385					     "failed to register USB power supply\n");1386 1387		battmgr->wls_psy = devm_power_supply_register(dev, &sm8350_wls_psy_desc, &psy_cfg_supply);1388		if (IS_ERR(battmgr->wls_psy))1389			return dev_err_probe(dev, PTR_ERR(battmgr->wls_psy),1390					     "failed to register wireless charing power supply\n");1391	}1392 1393	battmgr->client = devm_pmic_glink_client_alloc(dev, PMIC_GLINK_OWNER_BATTMGR,1394						       qcom_battmgr_callback,1395						       qcom_battmgr_pdr_notify,1396						       battmgr);1397	if (IS_ERR(battmgr->client))1398		return PTR_ERR(battmgr->client);1399 1400	pmic_glink_client_register(battmgr->client);1401 1402	return 0;1403}1404 1405static const struct auxiliary_device_id qcom_battmgr_id_table[] = {1406	{ .name = "pmic_glink.power-supply", },1407	{},1408};1409MODULE_DEVICE_TABLE(auxiliary, qcom_battmgr_id_table);1410 1411static struct auxiliary_driver qcom_battmgr_driver = {1412	.name = "pmic_glink_power_supply",1413	.probe = qcom_battmgr_probe,1414	.id_table = qcom_battmgr_id_table,1415};1416 1417module_auxiliary_driver(qcom_battmgr_driver);1418 1419MODULE_DESCRIPTION("Qualcomm PMIC GLINK battery manager driver");1420MODULE_LICENSE("GPL");1421