充電管理器

  1. 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 配置為喚醒源來實現。