充电器管理器

  1. 2011 MyungJoo Ham <myungjoo.ham@samsung.com>,GPL

充电器管理器提供内核中的电池充电器管理功能,该功能需要在挂起到 RAM 状态期间进行温度监控,并且每个电池可能连接多个充电器,用户空间希望查看多个充电器的聚合信息。

充电器管理器是一个具有电源类条目的 platform_driver。充电器管理器的实例(使用充电器管理器创建的 platform_device)表示带有充电器的独立电池。如果系统中存在多个具有独立充电器的电池,则系统可能需要多个充电器管理器实例。

1. 简介

充电器管理器支持以下功能

  • 支持多个充电器(例如,具有 USB、AC 和太阳能电池板的设备)

    系统可能具有多个充电器(或电源),并且其中一些充电器可能同时激活。每个充电器可能有自己的电源类,并且每个电源类可以提供有关电池状态的不同信息。此框架聚合来自多个来源的充电器相关信息,并将组合信息显示为单个电源类。

  • 支持在挂起到 RAM 时轮询(带有 suspend_again 回调)

    当电池正在充电并且系统处于挂起到 RAM 状态时,我们可能需要通过查看环境温度或电池温度来监控电池健康状况。我们可以通过定期唤醒系统来实现这一点。但是,这种方法会不必要地唤醒设备以监控电池健康状况和任务,以及应该保持挂起的user进程。反过来,这会导致不必要的功耗并减慢充电过程。甚至,这种峰值功耗可能会在充电过程中停止充电器(外部电源输入 < 设备功耗),这不仅会影响充电时间,还会影响电池的寿命。

    充电器管理器提供了一个函数“cm_suspend_again”,可以用作 platform_suspend_ops 的 suspend_again 回调。如果平台需要 cm_suspend_again 之外的任务,则它可以实现自己的 suspend_again 回调,并在中间调用 cm_suspend_again。通常,平台需要恢复和挂起充电器管理器使用的一些设备。

  • 支持过早的电池充满事件处理

    如果在电池充满事件发生后“fullbatt_vchkdrop_ms”后,电池电压下降了“fullbatt_vchkdrop_uV”,则框架将重新启动充电。此检查也在挂起时执行,方法是相应地设置唤醒时间并使用 suspend_again。

  • 支持 uevent 通知

    对于充电器相关事件,设备会使用 UEVENT 向用户发送通知。

3. 如何设置 suspend_again

充电器管理器提供了一个函数“extern bool cm_suspend_again(void)”。当调用 cm_suspend_again 时,它会监控每个电池。系统的 platform_suspend_ops 的 suspend_ops 回调可以调用 cm_suspend_again 函数,以了解充电器管理器是否想要再次挂起。如果没有其他想要使用 suspend_again 功能的设备或任务,则 platform_suspend_ops 可以直接引用 cm_suspend_again 作为其 suspend_again 回调。

如果系统被充电器管理器唤醒并且轮询(挂起时监控)结果为“正常”,则 cm_suspend_again() 返回 true(表示“我想再次挂起”)。

4. 充电器管理器数据(struct charger_desc)

对于每个独立于其他电池充电的电池(如果一组电池由单个充电器充电,则将其计为一个独立电池),会将一个充电器管理器实例附加到该电池。以下是

struct charger_desc 元素

char *psy_name;

电池的电源类名称。如果 psy_name 为 NULL,则默认为“battery”。用户可以在“/sys/class/power_supply/[psy_name]/”处访问 psy 条目。

enum polling_modes polling_mode;
CM_POLL_DISABLE

不轮询此电池。

CM_POLL_ALWAYS

始终轮询此电池。

CM_POLL_EXTERNAL_POWER_ONLY

当且仅当连接外部电源时才轮询此电池。

CM_POLL_CHARGING_ONLY

当且仅当电池正在充电时才轮询此电池。

unsigned int fullbatt_vchkdrop_ms; / unsigned int fullbatt_vchkdrop_uV;

如果两者都具有非零值,则充电器管理器将在电池充满电后检查电池电压下降 fullbatt_vchkdrop_ms。如果电压降超过 fullbatt_vchkdrop_uV,则充电器管理器将尝试通过禁用和启用充电器来为电池充电。仅使用电压降条件(没有延迟条件)重新充电需要使用来自电量计或充电器设备/芯片的硬件中断来实现。

unsigned int fullbatt_uV;

如果指定了非零值,则如果电池未充电且电池电压等于或大于 fullbatt_uV,则充电器管理器假定电池已满(容量 = 100)。

unsigned int polling_interval_ms;

所需的轮询间隔(以毫秒为单位)。充电器管理器将以每 polling_interval_ms 或更频繁的时间间隔轮询此电池。

enum data_source battery_present;
CM_BATTERY_PRESENT

假定电池存在。

CM_NO_BATTERY

假定电池不存在。

CM_FUEL_GAUGE

从电量计获取电池存在信息。

CM_CHARGER_STAT

从充电器获取电池存在信息。

char **psy_charger_stat;

以 NULL 结尾的数组,其中包含充电器的电源类名称。每个电源类应提供“PRESENT”(如果 battery_present 为“CM_CHARGER_STAT”)、“ONLINE”(显示是否连接了外部电源)和“STATUS”(显示电池是 {“FULL”或 not FULL} 还是 {“FULL”、“Charging”、“Discharging”、“NotCharging”})。

int num_charger_regulators; / struct regulator_bulk_data *charger_regulators;

以监管框架的批量函数的形式表示充电器的稳压器。

char *psy_fuel_gauge;

电量计的电源类名称。

int (*temperature_out_of_range)(int *mC); / bool measure_battery_temp;

如果温度对于充电安全,则此回调返回 0;如果温度太高而无法充电,则返回正数;如果温度太低而无法充电,则返回负数。使用变量 mC,回调将返回以百分之一摄氏度为单位的温度。温度的来源可以是电池温度或环境温度,具体取决于 measure_battery_temp 的值。

5. 通知充电器管理器充电器事件:cm_notify_event()

如果需要通知充电器管理器充电器事件,则触发事件的充电器设备驱动程序可以调用 cm_notify_event(psy, type, msg) 以通知相应的充电器管理器。在该函数中,psy 是充电器驱动程序的 power_supply 指针,它与充电器管理器关联。“type”参数与 irq 的类型 (enum cm_event_types) 相同。事件消息“msg”是可选的,仅当事件类型为“UNDESCRIBED”或“OTHERS”时才有效。

6. 其他注意事项

在诸如电池拔出、充电器拔出、充电器插入、DCIN 过压/欠压、充电器停止以及其他对充电器至关重要的充电器/电池相关事件发生时,应将系统配置为唤醒。至少以下事件应从挂起状态唤醒系统:a) 充电器开/关 b) 外部电源输入/输出 c) 电池插入/拔出(充电时)

这通常通过将 PMIC 配置为唤醒源来实现。