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