Lines Matching +full:yoga +full:- +full:c630 +full:- +full:ec
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2022-2024, Linaro Ltd
17 #include <linux/platform_data/lenovo-yoga-c630.h>
20 struct yoga_c630_ec *ec; member
73 struct yoga_c630_ec *ec = ecbat->ec; in yoga_c630_psy_update_bat_info() local
76 lockdep_assert_held(&ecbat->lock); in yoga_c630_psy_update_bat_info()
78 val = yoga_c630_ec_read8(ec, LENOVO_EC_BAT_PRESENT); in yoga_c630_psy_update_bat_info()
81 ecbat->bat_present = !!(val & LENOVO_EC_BAT_PRESENT_IS_PRESENT); in yoga_c630_psy_update_bat_info()
82 if (!ecbat->bat_present) in yoga_c630_psy_update_bat_info()
85 val = yoga_c630_ec_read8(ec, LENOVO_EC_BAT_ATTRIBUTES); in yoga_c630_psy_update_bat_info()
88 ecbat->unit_mA = val & LENOVO_EC_BAT_ATTRIBUTES_UNIT_IS_MA; in yoga_c630_psy_update_bat_info()
90 val = yoga_c630_ec_read16(ec, LENOVO_EC_BAT_DESIGN_CAPACITY); in yoga_c630_psy_update_bat_info()
93 ecbat->design_capacity = val * 1000; in yoga_c630_psy_update_bat_info()
96 * DSDT has delays after most of EC reads in these methods. in yoga_c630_psy_update_bat_info()
97 * Having no documentation for the EC we have to follow and sleep here. in yoga_c630_psy_update_bat_info()
101 val = yoga_c630_ec_read16(ec, LENOVO_EC_BAT_DESIGN_VOLTAGE); in yoga_c630_psy_update_bat_info()
104 ecbat->design_voltage = val; in yoga_c630_psy_update_bat_info()
108 val = yoga_c630_ec_read8(ec, LENOVO_EC_BAT_FULL_REGISTER); in yoga_c630_psy_update_bat_info()
111 val = yoga_c630_ec_read16(ec, in yoga_c630_psy_update_bat_info()
118 ecbat->full_charge_capacity = val * 1000; in yoga_c630_psy_update_bat_info()
120 if (!ecbat->unit_mA) { in yoga_c630_psy_update_bat_info()
121 ecbat->design_capacity *= 10; in yoga_c630_psy_update_bat_info()
122 ecbat->full_charge_capacity *= 10; in yoga_c630_psy_update_bat_info()
130 struct yoga_c630_ec *ec = ecbat->ec; in yoga_c630_psy_maybe_update_bat_status() local
134 guard(mutex)(&ecbat->lock); in yoga_c630_psy_maybe_update_bat_status()
135 if (time_before(jiffies, ecbat->last_status_update + LENOVO_EC_CACHE_TIME)) in yoga_c630_psy_maybe_update_bat_status()
138 val = yoga_c630_ec_read8(ec, LENOVO_EC_BAT_STATUS); in yoga_c630_psy_maybe_update_bat_status()
141 ecbat->bat_status = val; in yoga_c630_psy_maybe_update_bat_status()
145 val = yoga_c630_ec_read16(ec, LENOVO_EC_BAT_REMAIN_CAPACITY); in yoga_c630_psy_maybe_update_bat_status()
148 ecbat->capacity_now = val * 1000; in yoga_c630_psy_maybe_update_bat_status()
152 val = yoga_c630_ec_read16(ec, LENOVO_EC_BAT_VOLTAGE); in yoga_c630_psy_maybe_update_bat_status()
155 ecbat->voltage_now = val * 1000; in yoga_c630_psy_maybe_update_bat_status()
159 val = yoga_c630_ec_read16(ec, LENOVO_EC_BAT_CURRENT); in yoga_c630_psy_maybe_update_bat_status()
163 ecbat->current_now = current_mA * 1000; in yoga_c630_psy_maybe_update_bat_status()
164 ecbat->rate_now = current_mA * (ecbat->voltage_now / 1000); in yoga_c630_psy_maybe_update_bat_status()
168 if (!ecbat->unit_mA) in yoga_c630_psy_maybe_update_bat_status()
169 ecbat->capacity_now *= 10; in yoga_c630_psy_maybe_update_bat_status()
171 ecbat->last_status_update = jiffies; in yoga_c630_psy_maybe_update_bat_status()
178 struct yoga_c630_ec *ec = ecbat->ec; in yoga_c630_psy_update_adapter_status() local
181 guard(mutex)(&ecbat->lock); in yoga_c630_psy_update_adapter_status()
183 val = yoga_c630_ec_read8(ec, LENOVO_EC_ADPT_STATUS); in yoga_c630_psy_update_adapter_status()
187 ecbat->adapter_online = !!(val & LENOVO_EC_ADPT_STATUS_PRESENT); in yoga_c630_psy_update_adapter_status()
194 if (ecbat->bat_status != 0) in yoga_c630_psy_is_charged()
197 if (ecbat->full_charge_capacity <= ecbat->capacity_now) in yoga_c630_psy_is_charged()
200 if (ecbat->design_capacity <= ecbat->capacity_now) in yoga_c630_psy_is_charged()
213 if (!ecbat->bat_present && psp != POWER_SUPPLY_PROP_PRESENT) in yoga_c630_psy_bat_get_property()
214 return -ENODEV; in yoga_c630_psy_bat_get_property()
222 if (ecbat->bat_status & LENOVO_EC_BAT_STATUS_DISCHARGING) in yoga_c630_psy_bat_get_property()
223 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; in yoga_c630_psy_bat_get_property()
224 else if (ecbat->bat_status & LENOVO_EC_BAT_STATUS_CHARGING) in yoga_c630_psy_bat_get_property()
225 val->intval = POWER_SUPPLY_STATUS_CHARGING; in yoga_c630_psy_bat_get_property()
227 val->intval = POWER_SUPPLY_STATUS_FULL; in yoga_c630_psy_bat_get_property()
229 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; in yoga_c630_psy_bat_get_property()
232 val->intval = ecbat->bat_present; in yoga_c630_psy_bat_get_property()
235 val->intval = ecbat->design_voltage; in yoga_c630_psy_bat_get_property()
239 val->intval = ecbat->design_capacity; in yoga_c630_psy_bat_get_property()
243 val->intval = ecbat->full_charge_capacity; in yoga_c630_psy_bat_get_property()
247 val->intval = ecbat->capacity_now; in yoga_c630_psy_bat_get_property()
250 val->intval = ecbat->current_now; in yoga_c630_psy_bat_get_property()
253 val->intval = ecbat->rate_now; in yoga_c630_psy_bat_get_property()
256 val->intval = ecbat->voltage_now; in yoga_c630_psy_bat_get_property()
259 val->intval = POWER_SUPPLY_TECHNOLOGY_LION; in yoga_c630_psy_bat_get_property()
262 val->strval = "PABAS0241231"; in yoga_c630_psy_bat_get_property()
265 val->strval = "Compal"; in yoga_c630_psy_bat_get_property()
268 val->intval = POWER_SUPPLY_SCOPE_SYSTEM; in yoga_c630_psy_bat_get_property()
271 rc = -EINVAL; in yoga_c630_psy_bat_get_property()
311 .name = "yoga-c630-battery",
319 .name = "yoga-c630-battery",
339 val->intval = ecbat->adapter_online; in yoga_c630_psy_adpt_get_property()
342 val->intval = POWER_SUPPLY_USB_TYPE_C; in yoga_c630_psy_adpt_get_property()
345 return -EINVAL; in yoga_c630_psy_adpt_get_property()
357 .name = "yoga-c630-adapter",
370 bat_cfg.fwnode = ecbat->fwnode; in yoga_c630_psy_register_bat_psy()
371 ecbat->bat_psy = power_supply_register_no_ws(ecbat->dev, in yoga_c630_psy_register_bat_psy()
372 ecbat->unit_mA ? in yoga_c630_psy_register_bat_psy()
376 if (IS_ERR(ecbat->bat_psy)) { in yoga_c630_psy_register_bat_psy()
377 dev_err(ecbat->dev, "failed to register battery supply\n"); in yoga_c630_psy_register_bat_psy()
378 return PTR_ERR(ecbat->bat_psy); in yoga_c630_psy_register_bat_psy()
388 guard(mutex)(&ecbat->lock); in yoga_c630_ec_refresh_bat_info()
390 current_unit = ecbat->unit_mA; in yoga_c630_ec_refresh_bat_info()
394 if (current_unit != ecbat->unit_mA) { in yoga_c630_ec_refresh_bat_info()
395 power_supply_unregister(ecbat->bat_psy); in yoga_c630_ec_refresh_bat_info()
410 power_supply_changed(ecbat->adp_psy); in yoga_c630_psy_notify()
413 power_supply_changed(ecbat->bat_psy); in yoga_c630_psy_notify()
423 struct yoga_c630_ec *ec = adev->dev.platform_data; in yoga_c630_psy_probe() local
425 struct device *dev = &adev->dev; in yoga_c630_psy_probe()
429 ecbat = devm_kzalloc(&adev->dev, sizeof(*ecbat), GFP_KERNEL); in yoga_c630_psy_probe()
431 return -ENOMEM; in yoga_c630_psy_probe()
433 ecbat->ec = ec; in yoga_c630_psy_probe()
434 ecbat->dev = dev; in yoga_c630_psy_probe()
435 mutex_init(&ecbat->lock); in yoga_c630_psy_probe()
436 ecbat->fwnode = adev->dev.parent->fwnode; in yoga_c630_psy_probe()
437 ecbat->nb.notifier_call = yoga_c630_psy_notify; in yoga_c630_psy_probe()
442 adp_cfg.fwnode = ecbat->fwnode; in yoga_c630_psy_probe()
445 ecbat->adp_psy = devm_power_supply_register_no_ws(dev, &yoga_c630_psy_adpt_psy_desc, &adp_cfg); in yoga_c630_psy_probe()
446 if (IS_ERR(ecbat->adp_psy)) { in yoga_c630_psy_probe()
448 return PTR_ERR(ecbat->adp_psy); in yoga_c630_psy_probe()
451 scoped_guard(mutex, &ecbat->lock) { in yoga_c630_psy_probe()
461 ret = yoga_c630_ec_register_notify(ecbat->ec, &ecbat->nb); in yoga_c630_psy_probe()
468 power_supply_unregister(ecbat->bat_psy); in yoga_c630_psy_probe()
476 yoga_c630_ec_unregister_notify(ecbat->ec, &ecbat->nb); in yoga_c630_psy_remove()
477 power_supply_unregister(ecbat->bat_psy); in yoga_c630_psy_remove()
495 MODULE_DESCRIPTION("Lenovo Yoga C630 psy");