充电管理器¶
2011 MyungJoo Ham <myungjoo.ham@samsung.com>, GPL
充电管理器提供内核级电池充电管理,它要求在挂起到内存 (suspend-to-RAM) 状态期间进行温度监测,并且每个电池可以连接多个充电器,用户空间希望查看这些多个充电器的聚合信息。
充电管理器是一个带有电源类(power-supply-class)条目的 `platform_driver`。充电管理器的一个实例(一个使用充电管理器创建的 `platform-device`)代表一个带有充电器的独立电池。如果系统中存在多个带有各自独立充电器的电池,系统可能需要多个充电管理器的实例。
1. 简介¶
充电管理器支持以下功能
- 支持多个充电器(例如,带有 USB、交流电源和太阳能电池板的设备)
一个系统可能拥有多个充电器(或电源),其中一些可能同时激活。每个充电器可能都有自己的电源类(power-supply-class),并且每个电源类可以提供关于电池状态的不同信息。该框架聚合来自多个源的充电器相关信息,并将其组合信息显示为一个单一的电源类。
- 支持挂起到内存状态下的轮询(带 `suspend_again` 回调)
当电池正在充电且系统处于挂起到内存状态时,我们可能需要通过监测环境或电池温度来监控电池健康状况。我们可以通过周期性地唤醒系统来实现这一点。然而,这种方法会不必要地唤醒设备以监测电池健康状况和任务,以及本应保持挂起的用户进程。这反过来会导致不必要的功耗,并减慢充电过程。甚至,这种峰值功耗可能在充电过程中停止充电器(外部电源输入 < 设备功耗),这不仅影响充电时间,还会影响电池寿命。
充电管理器提供了一个函数“`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”或非 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. 其他注意事项¶
在充电器/电池相关事件(例如电池拔出、充电器拔出、充电器插入、直流输入过压/欠压、充电器停止以及其他对充电器至关重要的事件)发生时,系统应配置为唤醒。至少以下情况应使系统从挂起状态唤醒:a) 充电器开/关 b) 外部电源接入/拔出 c) 电池插入/拔出(充电时)
这通常通过将 PMIC 配置为唤醒源来实现。