Galaxy note 7 の充電ドライバを読んでみる - (4) MAX77854 の設定をアプリから変更して解決しようとした?
(3) DA9155M の VBAT_OV が 5.0V 固定の続き。MAX77854 の充電終止電圧設定関数を探してみる。初期化関数 max77854_charger_initialize() の中で次のような記述を見つける。max77854_set_float_voltage() だろう。※ 関数その他のリンク先で複数のパスが表示された場合は、drivers/battery_v2 の方を選択して下さい。/* * cv voltage 4.2V or 4.35V * MINVSYS 3.6V(default) */max77854_set_float_voltage(charger, charger->pdata->chg_float_voltage);充電電流の設定も重要だ。調査している。kernel source code の中から使用している可能性が高い設定値が見つからない。今の結論は電流 (total_current) の方はアプリから設定関数 sec_multi_chg_set_property(), POWER_SUPPLY_PROP_CURRENT_NOW を通して設定している。※ 関数その他のリンク先で複数のパスが表示された場合は、drivers/battery_v2 の方を選択して下さい。max77854_set_float_voltage() が絡むメンバ chg_float_voltage を読んでみる。max77854_set_float_voltage() には初期値、アプリ設定値が渡される。初期値は状況に応じていくつか選択肢がある。ソースを読むと Open Firmware (参考: Open Firmware, Device Tree) の API から初期値を得ている。max77854_charger.c:max77854_charger_parse_dt()ret = of_property_read_u32(np, "battery,chg_float_voltage", &pdata->chg_float_voltage);if (ret) { pr_info("%s: battery,chg_float_voltage is Empty\n", __func__); pdata->chg_float_voltage = 42000;}pr_info("%s: battery,chg_float_voltage is %d\n", __func__, pdata->chg_float_voltage);charger->float_voltage = pdata->chg_float_voltage;初期値は arch/arm64/boot/dts/exynos8890-universal8890_common_battery_01.dtsi に書かれている。arch/arm64/boot/dts/Makefile を読んでの推測だ。dtb-$(CONFIG_ARCH_THUNDER) += thunder-88xx.dtbdtb-$(CONFIG_ARCH_VEXPRESS) += rtsm_ve-aemv8a.dtb foundation-v8.dtbdtb-$(CONFIG_ARCH_XGENE) += apm-mustang.dtbdtb-$(CONFIG_SOC_EXYNOS8890) += exynos8890-smdk8890.dtb exynos8890-universal8890.dtbexynos8890-universal8890.dtb にて、次のように書かれている。/dts-v1/;#include "exynos8890.dtsi"#include "exynos8890-rmem.dtsi"#include "exynos8890-universal8890_common_battery_01.dtsi"#include "modem-ss335ap-pdata.dtsi"#include "exynos8890-display-lcd.dtsi"もしかしたら、これは読み間違えている可能性がある。exynos8890-universal8890_common_battery_01.dtsi に書かれた値 (例えば swelling_drop_float_voltage) の桁がソースコードの fail safe 値と合っていない。そもそも、必要とされる記述がない(例えば battery,age_data)など、解釈に困る点がある。battery,swelling_drop_float_voltage = <42000>;battery,swelling_high_rechg_voltage = <4150>;battery,swelling_low_rechg_voltage = <4050>;swelling_drop_float_voltage を取得する処理は次の通りだ。sec_battery.c:sec_bat_parse_dt()ret = of_property_read_u32(np, "battery,swelling_drop_float_voltage", (unsigned int *)&pdata->swelling_drop_float_voltage);if (ret) { pr_info("%s: swelling drop float voltage is Empty, Default value 4250mV \n", __func__); pdata->swelling_drop_float_voltage = 4250;}最も高い充電終止電圧は次の記述だろう。4.3625V と読める。MAX77854 の兄弟チップ MAX77818 の電圧設定確度 (BATT Regulation Voltage Accuracy) +-1% を当てはめて出力される電圧を計算すると 4.3625V * 1.01 = 4.4061V となる。僅かに電池仕様 4.4V を超える。深刻に考える程ではないだろう。battery,chg_float_voltage = <43625>;アプリから充電終止電圧を設定できる。ノードは /sys の下の device_attribute sec_battery_attrs からと、/sys/class/power_supply/SupplyDevice がある。正確な path は解析していない。sec_battery.c:sec_bat_store_attrs() (統合ドライバ)case BATT_TUNE_FLOAT_VOLTAGE: sscanf(buf, "%d\n", &x); pr_info("%s float voltage = %d mV",__func__, x); if(x > 4000 && x <= 4400 ){ union power_supply_propval value; value.intval = x; psy_do_property(battery->pdata->charger_name, set, POWER_SUPPLY_PROP_VOLTAGE_MAX, value); } break;max77854_charger.c:max77854_chg_set_property() (MAX77854 ドライバ)#if defined(CONFIG_BATTERY_SWELLING)case POWER_SUPPLY_PROP_VOLTAGE_MAX: charger->float_voltage = val->intval; pr_info("%s: float voltage(%d)\n", __func__, val->intval); max77854_set_float_voltage(charger, val->intval); break;#endif統合ドライバ sec_battery.c から設定すると max77854_charger.c と桁が合わない。sec_battery.c の判定は if(x > 4000 && x <= 4400 ) だ。max77854_charger.c の POWER_SUPPLY_PROP_VOLTAGE_MAX で受ける方は max77854_set_float_voltage() に実装された変換式により 40500 .. 45000 の範囲が定義域だ。max77854_set_float_voltage()static void max77854_set_float_voltage(struct max77854_charger_data *charger, int float_voltage){ u8 reg_data = 0; reg_data = float_voltage <= 40500 ? 0x0 : float_voltage >= 45000 ? 0x24 : (float_voltage - 40500) / 125; max77854_update_reg(charger->i2c, MAX77854_CHG_REG_CNFG_04, (reg_data << CHG_CNFG_04_CHG_CV_PRM_SHIFT), CHG_CNFG_04_CHG_CV_PRM_MASK); max77854_read_reg(charger->i2c, MAX77854_CHG_REG_CNFG_04, ®_data); pr_info("%s: battery cv voltage 0x%x\n", __func__, reg_data);}アプリから充電終止電圧を設定できるように修正を加えたのだろうか? CONFIG_BATTERY_SWELLING (参考 _defconfig ファイル)が定義されていると MAX77854 ドライバの POWER_SUPPLY_PROP_VOLTAGE_MAX ノード voltage_max (ノード名一覧) の書き込みができる。DA9155 の da9155_chg_set_property() はどうだろうか? ノード(API) を実装していない。da9155_charger.c:da9155_chg_set_property()case POWER_SUPPLY_PROP_VOLTAGE_MAX:case POWER_SUPPLY_PROP_STATUS:case POWER_SUPPLY_PROP_CURRENT_FULL: break;case POWER_SUPPLY_PROP_CURRENT_MAX:case POWER_SUPPLY_PROP_HEALTH: return -ENODATA;論理的な構造が一致しない実装があちこちに見つかる。背景は何だろうか?レビューをしていない?担当者が交代した?複数の担当者間で連絡が取れていない?コードの癖に時間に追われていた?と思われるところがある。コメント量にムラが有る。定数マクロを使ったところと、直接マジックナンバーを使ったところがある。printk 類の 書式が一定ではない。Linux Kernel のコーディング・ルールに良く従っている。所々プログラマ本来の癖が見える。MAX77854 のドライバに原因があると考えて修正を続けていたのだろうか?誰かが DA9155のドライバに問題があることを指摘しなかったか、詳細や現状の理解を得られずに「MAX77854 のドライバを修正しろ」と言われ続けたのか?2016.10.25 追記 (5) 充電加速停止信号線がある?