if (psp >= ARRAY_SIZE(sm8350_bat_prop_map)) return -EINVAL;
prop = sm8350_bat_prop_map[psp];
mutex_lock(&battmgr->lock);
ret = qcom_battmgr_request_property(battmgr, BATTMGR_BAT_PROPERTY_GET, prop, 0);
mutex_unlock(&battmgr->lock);
return ret;
}
staticint qcom_battmgr_bat_sc8280xp_update(struct qcom_battmgr *battmgr, enum power_supply_property psp)
{ int ret;
mutex_lock(&battmgr->lock);
if (!battmgr->info.valid) {
ret = qcom_battmgr_update_info(battmgr); if (ret < 0) goto out_unlock;
battmgr->info.valid = true;
}
ret = qcom_battmgr_update_status(battmgr); if (ret < 0) goto out_unlock;
if (psp == POWER_SUPPLY_PROP_TIME_TO_FULL_AVG) {
ret = qcom_battmgr_update_charge_time(battmgr); if (ret < 0) {
ret = -ENODATA; goto out_unlock;
}
}
if (psp == POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG) {
ret = qcom_battmgr_update_discharge_time(battmgr); if (ret < 0) {
ret = -ENODATA; goto out_unlock;
}
}
staticint qcom_battmgr_bat_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val)
{ struct qcom_battmgr *battmgr = power_supply_get_drvdata(psy); enum qcom_battmgr_unit unit = battmgr->unit; int ret;
if (!battmgr->service_up) return -EAGAIN;
if (battmgr->variant == QCOM_BATTMGR_SC8280XP)
ret = qcom_battmgr_bat_sc8280xp_update(battmgr, psp); else
ret = qcom_battmgr_bat_sm8350_update(battmgr, psp); if (ret < 0) return ret;
switch (psp) { case POWER_SUPPLY_PROP_STATUS:
val->intval = battmgr->status.status; break; case POWER_SUPPLY_PROP_CHARGE_TYPE:
val->intval = battmgr->info.charge_type; break; case POWER_SUPPLY_PROP_HEALTH:
val->intval = battmgr->status.health; break; case POWER_SUPPLY_PROP_PRESENT:
val->intval = battmgr->info.present; break; case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = battmgr->info.technology; break; case POWER_SUPPLY_PROP_CYCLE_COUNT:
val->intval = battmgr->info.cycle_count; break; case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
val->intval = battmgr->info.voltage_max_design; break; case POWER_SUPPLY_PROP_VOLTAGE_MAX:
val->intval = battmgr->info.voltage_max; break; case POWER_SUPPLY_PROP_VOLTAGE_NOW:
val->intval = battmgr->status.voltage_now; break; case POWER_SUPPLY_PROP_VOLTAGE_OCV:
val->intval = battmgr->status.voltage_ocv; break; case POWER_SUPPLY_PROP_CURRENT_NOW:
val->intval = battmgr->status.current_now; break; case POWER_SUPPLY_PROP_POWER_NOW:
val->intval = battmgr->status.power_now; break; case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: if (unit != QCOM_BATTMGR_UNIT_mAh) return -ENODATA;
val->intval = battmgr->info.design_capacity; break; case POWER_SUPPLY_PROP_CHARGE_FULL: if (unit != QCOM_BATTMGR_UNIT_mAh) return -ENODATA;
val->intval = battmgr->info.last_full_capacity; break; case POWER_SUPPLY_PROP_CHARGE_EMPTY: if (unit != QCOM_BATTMGR_UNIT_mAh) return -ENODATA;
val->intval = battmgr->info.capacity_low; break; case POWER_SUPPLY_PROP_CHARGE_NOW: if (unit != QCOM_BATTMGR_UNIT_mAh) return -ENODATA;
val->intval = battmgr->status.capacity; break; case POWER_SUPPLY_PROP_CHARGE_COUNTER:
val->intval = battmgr->info.charge_count; break; case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: if (unit != QCOM_BATTMGR_UNIT_mWh) return -ENODATA;
val->intval = battmgr->info.design_capacity; break; case POWER_SUPPLY_PROP_ENERGY_FULL: if (unit != QCOM_BATTMGR_UNIT_mWh) return -ENODATA;
val->intval = battmgr->info.last_full_capacity; break; case POWER_SUPPLY_PROP_ENERGY_EMPTY: if (unit != QCOM_BATTMGR_UNIT_mWh) return -ENODATA;
val->intval = battmgr->info.capacity_low; break; case POWER_SUPPLY_PROP_ENERGY_NOW: if (unit != QCOM_BATTMGR_UNIT_mWh) return -ENODATA;
val->intval = battmgr->status.capacity; break; case POWER_SUPPLY_PROP_CAPACITY: if (battmgr->status.percent == (unsignedint)-1) return -ENODATA;
val->intval = battmgr->status.percent; break; case POWER_SUPPLY_PROP_TEMP:
val->intval = battmgr->status.temperature; break; case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
val->intval = battmgr->status.discharge_time; break; case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
val->intval = battmgr->status.charge_time; break; case POWER_SUPPLY_PROP_MANUFACTURE_YEAR:
val->intval = battmgr->info.year; break; case POWER_SUPPLY_PROP_MANUFACTURE_MONTH:
val->intval = battmgr->info.month; break; case POWER_SUPPLY_PROP_MANUFACTURE_DAY:
val->intval = battmgr->info.day; break; case POWER_SUPPLY_PROP_MODEL_NAME:
val->strval = battmgr->info.model_number; break; case POWER_SUPPLY_PROP_MANUFACTURER:
val->strval = battmgr->info.oem_info; break; case POWER_SUPPLY_PROP_SERIAL_NUMBER:
val->strval = battmgr->info.serial_number; break; default: return -EINVAL;
}
if (psp >= ARRAY_SIZE(sm8350_usb_prop_map)) return -EINVAL;
prop = sm8350_usb_prop_map[psp];
mutex_lock(&battmgr->lock);
ret = qcom_battmgr_request_property(battmgr, BATTMGR_USB_PROPERTY_GET, prop, 0);
mutex_unlock(&battmgr->lock);
return ret;
}
staticint qcom_battmgr_usb_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val)
{ struct qcom_battmgr *battmgr = power_supply_get_drvdata(psy); int ret;
if (!battmgr->service_up) return -EAGAIN;
if (battmgr->variant == QCOM_BATTMGR_SC8280XP)
ret = qcom_battmgr_bat_sc8280xp_update(battmgr, psp); else
ret = qcom_battmgr_usb_sm8350_update(battmgr, psp); if (ret) return ret;
switch (psp) { case POWER_SUPPLY_PROP_ONLINE:
val->intval = battmgr->usb.online; break; case POWER_SUPPLY_PROP_VOLTAGE_NOW:
val->intval = battmgr->usb.voltage_now; break; case POWER_SUPPLY_PROP_VOLTAGE_MAX:
val->intval = battmgr->usb.voltage_max; break; case POWER_SUPPLY_PROP_CURRENT_NOW:
val->intval = battmgr->usb.current_now; break; case POWER_SUPPLY_PROP_CURRENT_MAX:
val->intval = battmgr->usb.current_max; break; case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
val->intval = battmgr->usb.current_limit; break; case POWER_SUPPLY_PROP_USB_TYPE:
val->intval = battmgr->usb.usb_type; break; default: return -EINVAL;
}
if (psp >= ARRAY_SIZE(sm8350_wls_prop_map)) return -EINVAL;
prop = sm8350_wls_prop_map[psp];
mutex_lock(&battmgr->lock);
ret = qcom_battmgr_request_property(battmgr, BATTMGR_WLS_PROPERTY_GET, prop, 0);
mutex_unlock(&battmgr->lock);
return ret;
}
staticint qcom_battmgr_wls_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val)
{ struct qcom_battmgr *battmgr = power_supply_get_drvdata(psy); int ret;
if (!battmgr->service_up) return -EAGAIN;
if (battmgr->variant == QCOM_BATTMGR_SC8280XP)
ret = qcom_battmgr_bat_sc8280xp_update(battmgr, psp); else
ret = qcom_battmgr_wls_sm8350_update(battmgr, psp); if (ret < 0) return ret;
switch (psp) { case POWER_SUPPLY_PROP_ONLINE:
val->intval = battmgr->wireless.online; break; case POWER_SUPPLY_PROP_VOLTAGE_NOW:
val->intval = battmgr->wireless.voltage_now; break; case POWER_SUPPLY_PROP_VOLTAGE_MAX:
val->intval = battmgr->wireless.voltage_max; break; case POWER_SUPPLY_PROP_CURRENT_NOW:
val->intval = battmgr->wireless.current_now; break; case POWER_SUPPLY_PROP_CURRENT_MAX:
val->intval = battmgr->wireless.current_max; break; default: return -EINVAL;
}
if (payload_len < sizeof(__le32)) {
dev_warn(battmgr->dev, "invalid payload length for %#x: %zd\n",
opcode, len); return;
}
switch (opcode) { case BATTMGR_REQUEST_NOTIFICATION:
battmgr->error = 0; break; case BATTMGR_BAT_INFO: /* some firmware versions report an extra __le32 at the end of the payload */ if (payload_len != sizeof(resp->info) &&
payload_len != (sizeof(resp->info) + sizeof(__le32))) {
dev_warn(battmgr->dev, "invalid payload length for battery information request: %zd\n",
payload_len);
battmgr->error = -ENODATA; return;
}
source = le32_to_cpu(resp->status.charging_source);
battmgr->ac.online = source == BATTMGR_CHARGING_SOURCE_AC;
battmgr->usb.online = source == BATTMGR_CHARGING_SOURCE_USB;
battmgr->wireless.online = source == BATTMGR_CHARGING_SOURCE_WIRELESS; if (battmgr->info.last_full_capacity != 0) { /* * 100 * battmgr->status.capacity can overflow a 32bit * unsigned integer. FW readings are in m{W/A}h, which * are multiplied by 1000 converting them to u{W/A}h, * the format the power_supply API expects. * To avoid overflow use the original value for dividend * and convert the divider back to m{W/A}h, which can be * done without any loss of precision.
*/
battmgr->status.percent =
(100 * le32_to_cpu(resp->status.capacity)) /
(battmgr->info.last_full_capacity / 1000);
} else { /* * Let the sysfs handler know no data is available at * this time.
*/
battmgr->status.percent = (unsignedint)-1;
} break; case BATTMGR_BAT_DISCHARGE_TIME:
battmgr->status.discharge_time = le32_to_cpu(resp->time); break; case BATTMGR_BAT_CHARGE_TIME:
battmgr->status.charge_time = le32_to_cpu(resp->time); break; default:
dev_warn(battmgr->dev, "unknown message %#x\n", opcode); break;
}
match = of_match_device(qcom_battmgr_of_variants, dev->parent); if (match)
battmgr->variant = (unsignedlong)match->data; else
battmgr->variant = QCOM_BATTMGR_SM8350;
if (battmgr->variant == QCOM_BATTMGR_SC8280XP) {
battmgr->bat_psy = devm_power_supply_register(dev, &sc8280xp_bat_psy_desc, &psy_cfg); if (IS_ERR(battmgr->bat_psy)) return dev_err_probe(dev, PTR_ERR(battmgr->bat_psy), "failed to register battery power supply\n");
battmgr->ac_psy = devm_power_supply_register(dev, &sc8280xp_ac_psy_desc, &psy_cfg_supply); if (IS_ERR(battmgr->ac_psy)) return dev_err_probe(dev, PTR_ERR(battmgr->ac_psy), "failed to register AC power supply\n");
battmgr->usb_psy = devm_power_supply_register(dev, &sc8280xp_usb_psy_desc, &psy_cfg_supply); if (IS_ERR(battmgr->usb_psy)) return dev_err_probe(dev, PTR_ERR(battmgr->usb_psy), "failed to register USB power supply\n");
battmgr->wls_psy = devm_power_supply_register(dev, &sc8280xp_wls_psy_desc, &psy_cfg_supply); if (IS_ERR(battmgr->wls_psy)) return dev_err_probe(dev, PTR_ERR(battmgr->wls_psy), "failed to register wireless charing power supply\n");
} else {
battmgr->bat_psy = devm_power_supply_register(dev, &sm8350_bat_psy_desc, &psy_cfg); if (IS_ERR(battmgr->bat_psy)) return dev_err_probe(dev, PTR_ERR(battmgr->bat_psy), "failed to register battery power supply\n");
battmgr->usb_psy = devm_power_supply_register(dev, &sm8350_usb_psy_desc, &psy_cfg_supply); if (IS_ERR(battmgr->usb_psy)) return dev_err_probe(dev, PTR_ERR(battmgr->usb_psy), "failed to register USB power supply\n");
battmgr->wls_psy = devm_power_supply_register(dev, &sm8350_wls_psy_desc, &psy_cfg_supply); if (IS_ERR(battmgr->wls_psy)) return dev_err_probe(dev, PTR_ERR(battmgr->wls_psy), "failed to register wireless charing power supply\n");
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.