# 通知設計書 32-Battery low-temp/high-temp

## 概要

本ドキュメントは、FreeBSDカーネルのPMU（電源管理ユニット）サブシステムにおけるバッテリー温度異常通知（Battery low-temp/high-temp）の設計を記述する。Allwinner SoC向けX-Powers AXP209/AXP221 PMICドライバが、バッテリーの温度が正常範囲外となったことを検知した際にdevctl経由でユーザランドへ通知を発行する仕組みを対象とする。

### 本通知の処理概要

本通知は、AXP209/AXP221 PMICのバッテリー温度監視機能が温度異常を検出した際に発行されるカーネルレベルの通知である。

**業務上の目的・背景**：リチウムイオンバッテリーは、低温環境では充放電効率が著しく低下し、高温環境ではバッテリーの寿命劣化や発火リスクが増大する。バッテリー温度が異常範囲に入った場合に即座にユーザランドへ通知することで、充電停止や冷却ファン制御、警告メッセージの表示など、適切な熱管理アクションを可能にする。PMICのハードウェアNTCセンサーによる温度監視結果がソフトウェアに伝達される仕組みである。

**通知の送信タイミング**：AXP2XX_IRQ2_STATUSレジスタにおいて、AXP2XX_IRQ2_BATT_TEMP_LOWビットまたはAXP2XX_IRQ2_BATT_TEMP_OVERビットがセットされた際にハードウェア割り込みが発生し、割り込みハンドラaxp2xx_intr内でdevctl_notifyが呼び出される。

**通知の受信者**：devd(8)デーモンおよびdevctl(4)インターフェースを監視するユーザランドプロセス。

**通知内容の概要**：システム名「PMU」、サブシステム名「Battery」、タイプ「low-temp」または「high-temp」の3フィールド。追加データ（data引数）はNULL。

**期待されるアクション**：低温時は充電の一時停止や低温警告の表示、高温時は充電停止と冷却措置、必要に応じたシステムの安全停止が期待される。

## 通知種別

カーネルdevctl通知（devctl_notify経由）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（ハードウェア割り込みハンドラから発行） |
| 優先度 | 高（ハードウェア割り込みレベル） |
| リトライ | 無し |

### 送信先決定ロジック

devctl_notifyはカーネル内のdevctlキューにメッセージを追加し、/dev/devctlを監視しているすべてのプロセスにブロードキャストされる。

## 通知テンプレート

### devctl通知の場合

| 項目 | 内容 |
|-----|------|
| システム名 | PMU |
| サブシステム名 | Battery |
| タイプ | low-temp / high-temp |
| データ | NULL |

### 本文テンプレート

```
!system=PMU subsystem=Battery type=low-temp
!system=PMU subsystem=Battery type=high-temp
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| system | 通知のシステム名 | ハードコード "PMU" | Yes |
| subsystem | サブシステム名 | ハードコード "Battery" | Yes |
| type | イベントタイプ | "low-temp" または "high-temp" | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| ハードウェア割り込み | AXP2XX_IRQ2_BATT_TEMP_LOW ビットセット | IRQ2ステータスレジスタ非ゼロ | バッテリー温度が下限閾値を下回った |
| ハードウェア割り込み | AXP2XX_IRQ2_BATT_TEMP_OVER ビットセット | IRQ2ステータスレジスタ非ゼロ | バッテリー温度が上限閾値を超えた |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| IRQ2が有効化されていない場合 | axp2xx_start関数でIRQ2のBATT_TEMP_OVER/BATT_TEMP_LOWが有効化されていなければ割り込みは発生しない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ハードウェア割り込み発生] --> B[axp2xx_intr 呼び出し]
    B --> C[AXP2XX_IRQ2_STATUS レジスタ読み取り]
    C --> D{reg が非ゼロ?}
    D -->|Yes| E{AXP2XX_IRQ2_BATT_TEMP_LOW?}
    D -->|No| I[終了]
    E -->|Yes| F["devctl_notify(PMU, Battery, low-temp, NULL)"]
    E -->|No| G{AXP2XX_IRQ2_BATT_TEMP_OVER?}
    G -->|Yes| H["devctl_notify(PMU, Battery, high-temp, NULL)"]
    G -->|No| I
    F --> J[IRQ2ステータスACK書き込み]
    H --> J
    J --> I
```

## データベース参照・更新仕様

該当なし（カーネルドライバのため）

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| I2Cバス読み取りエラー | IRQ2ステータスレジスタの読み取り失敗 | 暗黙的に無視 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0 |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし（ハードウェアイベント駆動） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし

## セキュリティ考慮事項

/dev/devctlへのアクセスはデフォルトでrootのみに制限されている。通知にはバッテリー温度異常の種別のみが含まれ、具体的な温度値は含まれない。

## 備考

- 温度閾値はAXP209/AXP221のハードウェアレジスタで設定されており、PMICのNTC（負の温度係数）サーミスタ端子で測定される
- 同一割り込みハンドラ内でバッテリー接続/切断、充電状態変更等の他のイベントも処理される
- axp2xx_start関数の1243行目でAXP2XX_IRQ2_BATT_TEMP_OVERとAXP2XX_IRQ2_BATT_TEMP_LOWが有効化されている

---

## コードリーディングガイド

本通知を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | axp209reg.h | `sys/arm/allwinner/axp209reg.h` | AXP2XX_IRQ2_BATT_TEMP_LOW, AXP2XX_IRQ2_BATT_TEMP_OVERビットマスク定義 |
| 1-2 | axp209.c | `sys/arm/allwinner/axp209.c` | axp2xx_softc構造体（598-619行目） |

**読解のコツ**: IRQ2関連の定数はすべてAXP2XX_IRQ2_プレフィックスを持つ。TEMP_LOWは低温、TEMP_OVERは高温を示す。

#### Step 2: 割り込み有効化を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | axp209.c | `sys/arm/allwinner/axp209.c` | axp2xx_start関数 1235-1243行目でのIRQ2イネーブル設定 |

**主要処理フロー**:
1. **1235-1243行目**: AXP2XX_IRQ2_ENABLEにBATT_TEMP_OVER | BATT_TEMP_LOWを含むビットマスクを書き込み

#### Step 3: 割り込みハンドラを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | axp209.c | `sys/arm/allwinner/axp209.c` | axp2xx_intr関数 853-868行目のIRQ2処理部分 |

**主要処理フロー**:
- **863行目**: AXP2XX_IRQ2_BATT_TEMP_LOWビット検出時に `devctl_notify("PMU", "Battery", "low-temp", NULL)`
- **865行目**: AXP2XX_IRQ2_BATT_TEMP_OVERビット検出時に `devctl_notify("PMU", "Battery", "high-temp", NULL)`
- **867行目**: IRQ2ステータスへのACK書き込み

### プログラム呼び出し階層図

```
ハードウェア割り込み（NTCセンサー温度閾値超過）
    |
    +-- axp2xx_intr(sc)                          [sys/arm/allwinner/axp209.c:827]
            |
            +-- axp2xx_read(AXP2XX_IRQ2_STATUS)  [853]
            |
            +-- devctl_notify("PMU","Battery","low-temp",NULL)  [863]
            |
            +-- devctl_notify("PMU","Battery","high-temp",NULL) [865]
            |
            +-- axp2xx_write(AXP2XX_IRQ2_STATUS, ACK) [867]
```

### データフロー図

```
[入力]                     [処理]                        [出力]

AXP209/221 NTC          axp2xx_intr()              /dev/devctl
温度センサー ---------> IRQ2ビット判定 -----------> devctl_notify()
(TEMP_LOW/TEMP_OVER)    devctl_notify呼出          devdデーモン
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| axp209.c | `sys/arm/allwinner/axp209.c` | ソース | AXP209/AXP221 PMICドライバ本体 |
| axp209reg.h | `sys/arm/allwinner/axp209reg.h` | ヘッダ | レジスタアドレスとビットマスク定義 |
| subr_bus.c | `sys/kern/subr_bus.c` | ソース | devctl_notify関数の実装 |
