blob: bb41cc85420e1b7c550534548b47df15d06d986a [file] [log] [blame]
Ken Tsou8acade12020-07-09 03:17:35 +08001/*
2 * Google Battery Management System
3 *
4 * Copyright (C) 2018 Google Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef __GOOGLE_BMS_H_
18#define __GOOGLE_BMS_H_
19
Jenny Ho19112782021-11-24 13:13:36 +080020#include <linux/minmax.h>
Ken Tsou8acade12020-07-09 03:17:35 +080021#include <linux/types.h>
22#include <linux/usb/pd.h>
Jenny Ho08b8a842022-01-19 16:30:54 +080023#include <misc/logbuffer.h>
AleX Pelosi856679c2020-09-01 13:47:28 -070024#include "gbms_power_supply.h"
Ken Tsou8acade12020-07-09 03:17:35 +080025#include "qmath.h"
26#include "gbms_storage.h"
27
28struct device_node;
29
30#define GBMS_CHG_TEMP_NB_LIMITS_MAX 10
31#define GBMS_CHG_VOLT_NB_LIMITS_MAX 5
Jenny Ho171aea12022-10-05 16:57:29 +080032#define GBMS_CHG_ALG_BUF_SZ 500
Jenny Ho312de092021-10-19 15:49:41 +080033#define GBMS_CHG_TOPOFF_NB_LIMITS_MAX 6
Jenny Ho19112782021-11-24 13:13:36 +080034#define GBMS_AACR_DATA_MAX 10
Ken Tsou8acade12020-07-09 03:17:35 +080035
36struct gbms_chg_profile {
37 const char *owner_name;
38
39 int temp_nb_limits;
40 s32 temp_limits[GBMS_CHG_TEMP_NB_LIMITS_MAX];
41 int volt_nb_limits;
42 s32 volt_limits[GBMS_CHG_VOLT_NB_LIMITS_MAX];
Jenny Ho312de092021-10-19 15:49:41 +080043 int topoff_nb_limits;
44 s32 topoff_limits[GBMS_CHG_TOPOFF_NB_LIMITS_MAX];
Ken Tsou8acade12020-07-09 03:17:35 +080045 /* Array of constant current limits */
AleX Pelosi76a3e5b2022-01-06 13:57:18 -080046 u32 *cccm_limits;
Ken Tsou8acade12020-07-09 03:17:35 +080047 /* used to fill table */
48 u32 capacity_ma;
49
50 /* behavior */
51 u32 fv_uv_margin_dpct;
Ken Yangd8456de2023-05-07 12:45:14 +000052 u32 fv_dc_ratio;
Ken Tsou8acade12020-07-09 03:17:35 +080053 u32 cv_range_accuracy;
54 u32 cv_debounce_cnt;
55 u32 cv_update_interval;
56 u32 cv_tier_ov_cnt;
57 u32 cv_tier_switch_cnt;
58 /* taper step */
59 u32 fv_uv_resolution;
60 /* experimental */
61 u32 cv_otv_margin;
Jenny Ho19112782021-11-24 13:13:36 +080062
63 /* AACR feature */
64 u32 reference_cycles[GBMS_AACR_DATA_MAX];
65 u32 reference_fade10[GBMS_AACR_DATA_MAX];
66 u32 aacr_nb_limits;
Ken Tsou8acade12020-07-09 03:17:35 +080067};
68
Jenny Ho6ec4e642022-10-04 08:13:51 +080069#define WLC_BPP_THRESHOLD_UV 7000000
70#define WLC_EPP_THRESHOLD_UV 11000000
Ken Tsou8acade12020-07-09 03:17:35 +080071
72#define FOREACH_CHG_EV_ADAPTER(S) \
73 S(UNKNOWN), \
74 S(USB), \
75 S(USB_SDP), \
76 S(USB_DCP), \
77 S(USB_CDP), \
78 S(USB_ACA), \
79 S(USB_C), \
80 S(USB_PD), \
81 S(USB_PD_DRP), \
82 S(USB_PD_PPS), \
83 S(USB_BRICKID), \
84 S(USB_HVDCP), \
85 S(USB_HVDCP3), \
Prasanna Prapanchamcce2a9b2022-07-08 22:46:01 +000086 S(FLOAT), \
Ken Tsou8acade12020-07-09 03:17:35 +080087 S(WLC), \
88 S(WLC_EPP), \
89 S(WLC_SPP), \
Prasanna Prapanchamcce2a9b2022-07-08 22:46:01 +000090 S(GPP), \
91 S(10W), \
92 S(L7), \
93 S(DL), \
94 S(WPC_EPP), \
95 S(WPC_GPP), \
96 S(WPC_10W), \
97 S(WPC_BPP), \
98 S(WPC_L7), \
99 S(EXT), \
100 S(EXT1), \
101 S(EXT2), \
102 S(EXT_UNKNOWN), \
Ken Tsou8acade12020-07-09 03:17:35 +0800103
104#define CHG_EV_ADAPTER_STRING(s) #s
105#define _CHG_EV_ADAPTER_PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__
106
Jenny Ho2c407222022-04-27 09:29:04 +0800107#define BATTERY_DEBUG_ATTRIBUTE(name, fn_read, fn_write) \
108static const struct file_operations name = { \
109 .open = simple_open, \
110 .llseek = no_llseek, \
111 .read = fn_read, \
112 .write = fn_write, \
113}
114
Ken Tsou8acade12020-07-09 03:17:35 +0800115/* Enums will start with CHG_EV_ADAPTER_TYPE_ */
116#define CHG_EV_ADAPTER_ENUM(e) \
117 _CHG_EV_ADAPTER_PRIMITIVE_CAT(CHG_EV_ADAPTER_TYPE_,e)
118
119enum chg_ev_adapter_type_t {
120 FOREACH_CHG_EV_ADAPTER(CHG_EV_ADAPTER_ENUM)
121};
122
123enum gbms_msc_states_t {
124 MSC_NONE = 0,
125 MSC_SEED,
126 MSC_DSG,
127 MSC_LAST,
128 MSC_VSWITCH,
129 MSC_VOVER,
130 MSC_PULLBACK,
131 MSC_FAST,
132 MSC_TYPE,
133 MSC_DLY, /* in taper */
134 MSC_STEADY, /* in taper */
135 MSC_TIERCNTING, /* in taper */
136 MSC_RAISE, /* in taper */
137 MSC_WAIT, /* in taper */
138 MSC_RSTC, /* in taper */
139 MSC_NEXT, /* in taper */
140 MSC_NYET, /* in taper */
AleX Pelosi0c88ff32020-04-02 01:04:51 -0700141 MSC_HEALTH,
Jenny Ho78dc9112021-05-09 09:54:16 +0800142 MSC_HEALTH_PAUSE,
Jenny Ho1c2ec2b2021-12-10 17:43:14 +0800143 MSC_HEALTH_ALWAYS_ON,
Ken Tsou8acade12020-07-09 03:17:35 +0800144 MSC_STATES_COUNT,
145};
146
147union gbms_ce_adapter_details {
148 uint32_t v;
149 struct {
150 uint8_t ad_type;
151 uint8_t pad;
152 uint8_t ad_voltage;
153 uint8_t ad_amperage;
154 };
155};
156
157struct gbms_ce_stats {
158 uint16_t voltage_in;
159 uint16_t ssoc_in;
160 uint16_t cc_in;
161 uint16_t voltage_out;
162 uint16_t ssoc_out;
163 uint16_t cc_out;
164};
165
166struct ttf_tier_stat {
167 int16_t soc_in;
168 int cc_in;
169 int cc_total;
AleX Pelosiab0e9d42020-09-29 11:13:19 -0700170 ktime_t avg_time;
Ken Tsou8acade12020-07-09 03:17:35 +0800171};
172
173struct gbms_ce_tier_stats {
174 int8_t temp_idx;
AleX Pelosiee22c8e2020-05-07 12:09:08 -0700175 int8_t vtier_idx;
Ken Tsou8acade12020-07-09 03:17:35 +0800176
177 int16_t soc_in; /* 8.8 */
178 uint16_t cc_in;
179 uint16_t cc_total;
180
Jenny Hoe0f94f32020-07-20 10:57:00 +0800181 uint32_t time_fast;
182 uint32_t time_taper;
183 uint32_t time_other;
Ken Tsou8acade12020-07-09 03:17:35 +0800184
185 int16_t temp_in;
186 int16_t temp_min;
187 int16_t temp_max;
188
189 int16_t ibatt_min;
190 int16_t ibatt_max;
191
192 uint16_t icl_min;
193 uint16_t icl_max;
194
195 int64_t icl_sum;
196 int64_t temp_sum;
197 int64_t ibatt_sum;
198 uint32_t sample_count;
199
200 uint16_t msc_cnt[MSC_STATES_COUNT];
201 uint32_t msc_elap[MSC_STATES_COUNT];
202};
203
204#define GBMS_STATS_TIER_COUNT 3
205#define GBMS_SOC_STATS_LEN 101
206
207/* time to full */
208
209/* collected in charging event */
210struct ttf_soc_stats {
211 int ti[GBMS_SOC_STATS_LEN]; /* charge tier at each soc */
212 int cc[GBMS_SOC_STATS_LEN]; /* coulomb count at each soc */
AleX Pelosiab0e9d42020-09-29 11:13:19 -0700213 ktime_t elap[GBMS_SOC_STATS_LEN]; /* time spent at soc */
Ken Tsou8acade12020-07-09 03:17:35 +0800214};
215
216/* reference data for soc estimation */
217struct ttf_adapter_stats {
218 u32 *soc_table;
219 u32 *elap_table;
220 int table_count;
221};
222
223/* updated when the device publish the charge stats
224 * NOTE: soc_stats and tier_stats are only valid for the given chg_profile
225 * since tier, coulumb count and elap time spent at each SOC depends on the
226 * maximum amout of current that can be pushed to the battery.
227 */
228struct batt_ttf_stats {
AleX Pelosiab0e9d42020-09-29 11:13:19 -0700229 ktime_t ttf_fake;
Ken Tsou8acade12020-07-09 03:17:35 +0800230
231 struct ttf_soc_stats soc_ref; /* gold: soc->elap,cc */
232 int ref_temp_idx;
233 int ref_watts;
234
235 struct ttf_soc_stats soc_stats; /* rolling */
236 struct ttf_tier_stat tier_stats[GBMS_STATS_TIER_COUNT];
AleX Pelosid0319472020-02-29 12:42:59 -0800237
238 struct logbuffer *ttf_log;
Ken Tsou8acade12020-07-09 03:17:35 +0800239};
240
AleX Pelosiee22c8e2020-05-07 12:09:08 -0700241/*
AleX Pelosi0d261512020-05-07 12:17:07 -0700242 * health based charging can be enabled from userspace with a deadline
AleX Pelosiee22c8e2020-05-07 12:09:08 -0700243 *
244 * initial state:
245 * deadline = 0, rest_state = CHG_HEALTH_INACTIVE
246 *
247 * deadline = -1 from userspace
Stephane Lee41e87c42020-09-02 23:05:34 -0700248 * CHG_HEALTH_* -> CHG_HEALTH_USER_DISABLED (settings disabled)
AleX Pelosiee22c8e2020-05-07 12:09:08 -0700249 * on deadline = 0 from userspace
Stephane Lee41e87c42020-09-02 23:05:34 -0700250 * CHG_HEALTH_* -> CHG_HEALTH_USER_DISABLED (alarm, plug or misc. disabled)
AleX Pelosiee22c8e2020-05-07 12:09:08 -0700251 * on deadline > 0 from userspace
252 * CHG_HEALTH_* -> CHG_HEALTH_ENABLED
253 *
254 * from CHG_HEALTH_ENABLED, msc_logic_health() can change the state to
255 * CHG_HEALTH_ENABLED <-> CHG_HEALTH_ACTIVE
256 * CHG_HEALTH_ENABLED -> CHG_HEALTH_DISABLED
257 *
258 * from CHG_HEALTH_ACTIVE, msc_logic_health() can change the state to
259 * CHG_HEALTH_ACTIVE <-> CHG_HEALTH_ENABLED
260 * CHG_HEALTH_ACTIVE -> CHG_HEALTH_DISABLED
261 * CHG_HEALTH_ACTIVE -> CHG_HEALTH_DONE
262 */
263enum chg_health_state {
AleX Pelosia6ad6ad2020-10-29 13:05:27 -0700264 CHG_HEALTH_CCLVL_DISABLED = -6,
AleX Pelosi600cb122020-10-29 10:05:47 -0700265 CHG_HEALTH_BD_DISABLED = -5,
AleX Pelosiee22c8e2020-05-07 12:09:08 -0700266 CHG_HEALTH_USER_DISABLED = -3,
267 CHG_HEALTH_DISABLED = -2,
268 CHG_HEALTH_DONE = -1,
269 CHG_HEALTH_INACTIVE = 0,
270 CHG_HEALTH_ENABLED,
271 CHG_HEALTH_ACTIVE,
Jenny Ho78dc9112021-05-09 09:54:16 +0800272 CHG_HEALTH_PAUSE,
AleX Pelosiee22c8e2020-05-07 12:09:08 -0700273};
274
Jenny Ho5ba876c2023-03-19 10:28:51 +0800275#define STATS_TH_SIZE 10
AleX Pelosiee22c8e2020-05-07 12:09:08 -0700276/* tier index used to log the session */
Stephane Leecbb07ee2020-09-14 12:24:09 -0700277enum gbms_stats_tier_idx_t {
Stephane Lee4a984a22022-01-14 15:14:07 -0800278 GBMS_STATS_AC_TI_DISABLE_DIALOG = -6,
AleX Pelosi600cb122020-10-29 10:05:47 -0700279 GBMS_STATS_AC_TI_DEFENDER = -5,
Stephane Lee41e87c42020-09-02 23:05:34 -0700280 GBMS_STATS_AC_TI_DISABLE_SETTING_STOP = -4,
281 GBMS_STATS_AC_TI_DISABLE_MISC = -3,
282 GBMS_STATS_AC_TI_DISABLE_SETTING = -2,
AleX Pelosiee22c8e2020-05-07 12:09:08 -0700283 GBMS_STATS_AC_TI_INVALID = -1,
AleX Pelosia6ad6ad2020-10-29 13:05:27 -0700284
Stephane Leecbb07ee2020-09-14 12:24:09 -0700285 /* Regular charge tiers 0 -> 9 */
AleX Pelosiee22c8e2020-05-07 12:09:08 -0700286 GBMS_STATS_AC_TI_VALID = 10,
Stephane Lee463e85d2021-08-16 14:50:36 -0700287 GBMS_STATS_AC_TI_DISABLED = 11,
288 GBMS_STATS_AC_TI_ENABLED = 12,
289 GBMS_STATS_AC_TI_ACTIVE = 13,
290 GBMS_STATS_AC_TI_ENABLED_AON = 14,
291 GBMS_STATS_AC_TI_ACTIVE_AON = 15,
292 GBMS_STATS_AC_TI_PAUSE = 16,
293 GBMS_STATS_AC_TI_PAUSE_AON = 17,
294 GBMS_STATS_AC_TI_V2_PREDICT = 18,
295 GBMS_STATS_AC_TI_V2_PREDICT_SUCCESS = 19,
Jenny Ho1c2ec2b2021-12-10 17:43:14 +0800296 GBMS_STATS_AC_TI_DONE_AON = 20,
AleX Pelosia6ad6ad2020-10-29 13:05:27 -0700297
Stephane Leefa678232022-10-12 16:55:04 -0700298 /* Thermal stats, reported from google_charger - reserved 50-59 */
Stephane Leee6ccecd2022-04-14 17:23:36 -0700299 GBMS_STATS_TH_LVL0 = 50,
300 GBMS_STATS_TH_LVL1 = 51,
301 GBMS_STATS_TH_LVL2 = 52,
302 GBMS_STATS_TH_LVL3 = 53,
Stephane Leefa678232022-10-12 16:55:04 -0700303 GBMS_STATS_TH_LVL4 = 54,
304 GBMS_STATS_TH_LVL5 = 55,
305 GBMS_STATS_TH_LVL6 = 56,
306 GBMS_STATS_TH_LVL7 = 57,
307 GBMS_STATS_TH_LVL8 = 58,
308 GBMS_STATS_TH_LVL9 = 59,
Stephane Leee6ccecd2022-04-14 17:23:36 -0700309
AleX Pelosia6ad6ad2020-10-29 13:05:27 -0700310 /* TODO: rename, these are not really related to AC */
Stephane Leecbb07ee2020-09-14 12:24:09 -0700311 GBMS_STATS_AC_TI_FULL_CHARGE = 100,
312 GBMS_STATS_AC_TI_HIGH_SOC = 101,
AleX Pelosia6ad6ad2020-10-29 13:05:27 -0700313
314 /* Defender TEMP or DWELL */
315 GBMS_STATS_BD_TI_OVERHEAT_TEMP = 110,
316 GBMS_STATS_BD_TI_CUSTOM_LEVELS = 111,
Stephane Leecacee1f2021-09-22 11:51:38 -0700317 GBMS_STATS_BD_TI_TRICKLE = 112,
Prasanna Prapancham320dcfe2022-06-27 20:20:46 +0000318 GBMS_STATS_BD_TI_DOCK = 113,
Jenny Hoe023ef32023-03-20 14:07:15 +0800319 GBMS_STATS_BD_TI_TEMP_PRETRIGGER = 114,
320 GBMS_STATS_BD_TI_TEMP_RESUME = 115,
Stephane Leecacee1f2021-09-22 11:51:38 -0700321
322 GBMS_STATS_BD_TI_TRICKLE_CLEARED = 122,
Prasanna Prapancham320dcfe2022-06-27 20:20:46 +0000323 GBMS_STATS_BD_TI_DOCK_CLEARED = 123,
Jenny Hof299c742023-02-14 17:58:59 +0800324 GBMS_STATS_TEMP_FILTER = 124,
AleX Pelosiee22c8e2020-05-07 12:09:08 -0700325};
326
AleX Pelosi043ffbe2020-06-24 22:48:30 -0700327/* health state */
328struct batt_chg_health {
329 int rest_soc; /* entry criteria */
330 int rest_voltage; /* entry criteria */
331 int always_on_soc; /* entry criteria */
332
333 ktime_t rest_deadline; /* full by this in seconds */
Stephane Lee463e85d2021-08-16 14:50:36 -0700334 ktime_t dry_run_deadline; /* full by this in seconds (prediction) */
AleX Pelosi043ffbe2020-06-24 22:48:30 -0700335 int rest_rate; /* centirate once enter */
Jenny Ho6ff91bf2022-09-16 15:11:04 +0800336 int rest_rate_before_trigger;
AleX Pelosi043ffbe2020-06-24 22:48:30 -0700337
338 enum chg_health_state rest_state;
339 int rest_cc_max;
340 int rest_fv_uv;
Jenny Hod74a8a42021-10-28 12:58:15 +0800341 ktime_t active_time;
AleX Pelosi043ffbe2020-06-24 22:48:30 -0700342};
343
Jenny Ho6f7ec522020-05-19 09:04:53 +0800344#define CHG_HEALTH_REST_IS_ACTIVE(rest) \
345 ((rest)->rest_state == CHG_HEALTH_ACTIVE)
346
Jenny Ho78dc9112021-05-09 09:54:16 +0800347#define CHG_HEALTH_REST_IS_PAUSE(rest) \
348 ((rest)->rest_state == CHG_HEALTH_PAUSE)
349
Jenny Ho1c2ec2b2021-12-10 17:43:14 +0800350#define CHG_HEALTH_REST_IS_AON(rest, ssoc) \
351 (((rest)->rest_state == CHG_HEALTH_ACTIVE) ? \
352 (((rest)->always_on_soc != -1) ? \
353 (ssoc >= (rest)->always_on_soc) : 0) : 0)
354
Jenny Ho6f7ec522020-05-19 09:04:53 +0800355#define CHG_HEALTH_REST_SOC(rest) (((rest)->always_on_soc != -1) ? \
356 (rest)->always_on_soc : (rest)->rest_soc)
357
AleX Pelosia6ad6ad2020-10-29 13:05:27 -0700358/* reset on every charge session */
Ken Tsou8acade12020-07-09 03:17:35 +0800359struct gbms_charging_event {
360 union gbms_ce_adapter_details adapter_details;
361
362 /* profile used for this charge event */
363 const struct gbms_chg_profile *chg_profile;
364 /* charge event and tier tracking */
365 struct gbms_ce_stats charging_stats;
366 struct gbms_ce_tier_stats tier_stats[GBMS_STATS_TIER_COUNT];
AleX Pelosi0c88ff32020-04-02 01:04:51 -0700367
Ken Tsou8acade12020-07-09 03:17:35 +0800368 /* soc tracking for time to full */
369 struct ttf_soc_stats soc_stats;
370 int last_soc;
371
AleX Pelosiab0e9d42020-09-29 11:13:19 -0700372 ktime_t first_update;
373 ktime_t last_update;
Stephane Leecacee1f2021-09-22 11:51:38 -0700374 bool bd_clear_trickle;
AleX Pelosiee22c8e2020-05-07 12:09:08 -0700375
376 /* health based charging */
Jenny Ho6f7ec522020-05-19 09:04:53 +0800377 struct batt_chg_health ce_health; /* updated on close */
378 struct gbms_ce_tier_stats health_stats; /* updated in HC */
Jenny Ho78dc9112021-05-09 09:54:16 +0800379 struct gbms_ce_tier_stats health_pause_stats; /* updated in HCP */
Stephane Lee463e85d2021-08-16 14:50:36 -0700380 /* updated on sysfs write */
381 struct gbms_ce_tier_stats health_dryrun_stats;
Stephane Leecbb07ee2020-09-14 12:24:09 -0700382
AleX Pelosia6ad6ad2020-10-29 13:05:27 -0700383 /* other stats */
Stephane Leecbb07ee2020-09-14 12:24:09 -0700384 struct gbms_ce_tier_stats full_charge_stats;
385 struct gbms_ce_tier_stats high_soc_stats;
AleX Pelosia6ad6ad2020-10-29 13:05:27 -0700386
387 struct gbms_ce_tier_stats overheat_stats;
388 struct gbms_ce_tier_stats cc_lvl_stats;
Stephane Leecacee1f2021-09-22 11:51:38 -0700389 struct gbms_ce_tier_stats trickle_stats;
Jenny Hof299c742023-02-14 17:58:59 +0800390 struct gbms_ce_tier_stats temp_filter_stats;
Ken Tsou8acade12020-07-09 03:17:35 +0800391};
392
Jenny Hob97a7072022-05-01 21:05:24 +0800393#define GBMS_CCCM_LIMITS_SET(profile, ti, vi) \
Jenny Hob63ed592022-07-21 10:01:24 +0000394 profile->cccm_limits[((ti) * profile->volt_nb_limits) + (vi)]
Ken Tsou8acade12020-07-09 03:17:35 +0800395
Jenny Hob97a7072022-05-01 21:05:24 +0800396#define GBMS_CCCM_LIMITS(profile, ti, vi) \
Jenny Hob63ed592022-07-21 10:01:24 +0000397 (((ti) >= 0 && (vi) >= 0) ? profile->cccm_limits[((ti) * profile->volt_nb_limits) + (vi)] : 0)
Jenny Hob97a7072022-05-01 21:05:24 +0800398
Ken Tsou8acade12020-07-09 03:17:35 +0800399/* newgen charging */
AleX Pelosia6ad6ad2020-10-29 13:05:27 -0700400#define GBMS_CS_FLAG_BUCK_EN BIT(0)
401#define GBMS_CS_FLAG_DONE BIT(1)
402#define GBMS_CS_FLAG_CC BIT(2)
403#define GBMS_CS_FLAG_CV BIT(3)
404#define GBMS_CS_FLAG_ILIM BIT(4)
405#define GBMS_CS_FLAG_CCLVL BIT(5)
Ken Yangd8456de2023-05-07 12:45:14 +0000406#define GBMS_CS_FLAG_DIRECT_CHG BIT(6)
Ken Tsou8acade12020-07-09 03:17:35 +0800407
408union gbms_charger_state {
409 uint64_t v;
410 struct {
411 uint8_t flags;
412 uint8_t pad;
413 uint8_t chg_status;
414 uint8_t chg_type;
415 uint16_t vchrg;
416 uint16_t icl;
417 } f;
418};
419
420int gbms_init_chg_profile_internal(struct gbms_chg_profile *profile,
421 struct device_node *node, const char *owner_name);
422#define gbms_init_chg_profile(p, n) \
423 gbms_init_chg_profile_internal(p, n, KBUILD_MODNAME)
424
Jenny Ho2e583482021-12-01 18:09:40 +0800425void gbms_init_chg_table(struct gbms_chg_profile *profile,
426 struct device_node *node, u32 capacity);
Ken Tsou8acade12020-07-09 03:17:35 +0800427
428void gbms_free_chg_profile(struct gbms_chg_profile *profile);
429
Jenny Ho68183e82021-12-06 17:39:05 +0800430void gbms_dump_raw_profile(char *buff, size_t len, const struct gbms_chg_profile *profile, int scale);
431#define gbms_dump_chg_profile(buff, len, profile) gbms_dump_raw_profile(buff, len, profile, 1000)
Ken Tsou8acade12020-07-09 03:17:35 +0800432
433/* newgen charging: charge profile */
434int gbms_msc_temp_idx(const struct gbms_chg_profile *profile, int temp);
435int gbms_msc_voltage_idx(const struct gbms_chg_profile *profile, int vbatt);
436int gbms_msc_round_fv_uv(const struct gbms_chg_profile *profile,
Ken Yangd8456de2023-05-07 12:45:14 +0000437 int vtier, int fv_uv, int cc_ua);
Ken Tsou8acade12020-07-09 03:17:35 +0800438
439/* newgen charging: charger flags */
440uint8_t gbms_gen_chg_flags(int chg_status, int chg_type);
441/* newgen charging: read/gen charger state */
442int gbms_read_charger_state(union gbms_charger_state *chg_state,
443 struct power_supply *chg_psy);
Jenny Ho19112782021-11-24 13:13:36 +0800444/* calculate aacr reference capacity */
AleX Pelosic10eb8b2021-12-14 13:20:21 -0800445int gbms_aacr_fade10(const struct gbms_chg_profile *profile, int cycles);
Ken Tsou8acade12020-07-09 03:17:35 +0800446
Jenny Ho08b8a842022-01-19 16:30:54 +0800447/* logbuffer and syslog */
448__printf(5,6)
449void gbms_logbuffer_prlog(struct logbuffer *log, int level, int debug_no_logbuffer,
450 int debug_printk_prlog, const char *f, ...);
451
Ken Tsou8acade12020-07-09 03:17:35 +0800452/* debug/print */
453const char *gbms_chg_type_s(int chg_type);
454const char *gbms_chg_status_s(int chg_status);
455const char *gbms_chg_ev_adapter_s(int adapter);
456
457/* Votables */
458#define VOTABLE_MSC_CHG_DISABLE "MSC_CHG_DISABLE"
459#define VOTABLE_MSC_PWR_DISABLE "MSC_PWR_DISABLE"
460#define VOTABLE_MSC_INTERVAL "MSC_INTERVAL"
461#define VOTABLE_MSC_FCC "MSC_FCC"
462#define VOTABLE_MSC_FV "MSC_FV"
yihsiangpeng305623d2021-05-06 15:07:05 +0800463#define VOTABLE_FAN_LEVEL "FAN_LEVEL"
Jack Wubf61d9f2021-06-21 23:02:22 +0800464#define VOTABLE_DEAD_BATTERY "DEAD_BATTERY"
Jenny Ho701a0ea2021-12-08 17:22:05 +0800465#define VOTABLE_TEMP_DRYRUN "MSC_TEMP_DRYRUN"
Stephane Leefa678232022-10-12 16:55:04 -0700466#define VOTABLE_MDIS "CHG_MDIS"
Jenny Hocc3f8072023-04-07 15:23:59 +0800467#define VOTABLE_THERMAL_LVL "CHG_THERM_LVL"
yihsiangpeng305623d2021-05-06 15:07:05 +0800468
AleX Pelosi1c2d9de2022-01-20 18:24:19 -0800469#define VOTABLE_CSI_STATUS "CSI_STATUS"
470#define VOTABLE_CSI_TYPE "CSI_TYPE"
471
Jack Wu6f519872022-12-21 19:56:25 +0800472#define VOTABLE_CHARGING_POLICY "CHARGING_POLICY"
Jenny Ho7ab41842023-03-06 13:43:51 +0800473#define VOTABLE_CHARGING_UISOC "CHARGING_UISOC"
Jack Wu6f519872022-12-21 19:56:25 +0800474
Prasanna Prapancham19203302022-09-09 20:58:11 +0000475#define VOTABLE_DC_CHG_AVAIL "DC_AVAIL"
476#define REASON_DC_DRV "DC_DRV"
477#define REASON_MDIS "MDIS"
478
yihsiangpeng305623d2021-05-06 15:07:05 +0800479#define FAN_LVL_UNKNOWN -1
480#define FAN_LVL_NOT_CARE 0
481#define FAN_LVL_LOW 1
482#define FAN_LVL_MED 2
483#define FAN_LVL_HIGH 3
484#define FAN_LVL_ALARM 4
Ken Tsou8acade12020-07-09 03:17:35 +0800485
486/* Binned cycle count */
Ken Tsou8acade12020-07-09 03:17:35 +0800487#define GBMS_CCBIN_CSTR_SIZE (GBMS_CCBIN_BUCKET_COUNT * 6 + 2)
488
489int gbms_cycle_count_sscan_bc(u16 *ccount, int bcnt, const char *buff);
490int gbms_cycle_count_cstr_bc(char *buff, size_t size,
491 const u16 *ccount, int bcnt);
492
493#define gbms_cycle_count_sscan(cc, buff) \
494 gbms_cycle_count_sscan_bc(cc, GBMS_CCBIN_BUCKET_COUNT, buff)
495
496#define gbms_cycle_count_cstr(buff, size, cc) \
497 gbms_cycle_count_cstr_bc(buff, size, cc, GBMS_CCBIN_BUCKET_COUNT)
498
499
500/* Time to full */
501int ttf_soc_cstr(char *buff, int size, const struct ttf_soc_stats *soc_stats,
502 int start, int end);
503
AleX Pelosiab0e9d42020-09-29 11:13:19 -0700504int ttf_soc_estimate(ktime_t *res,
Ken Tsou8acade12020-07-09 03:17:35 +0800505 const struct batt_ttf_stats *stats,
506 const struct gbms_charging_event *ce_data,
507 qnum_t soc, qnum_t last);
508
509void ttf_soc_init(struct ttf_soc_stats *dst);
510
AleX Pelosi4a9035f2020-02-28 19:09:57 -0800511int ttf_tier_cstr(char *buff, int size, const struct ttf_tier_stat *t_stat);
Ken Tsou8acade12020-07-09 03:17:35 +0800512
AleX Pelosiab0e9d42020-09-29 11:13:19 -0700513int ttf_tier_estimate(ktime_t *res,
Ken Tsou8acade12020-07-09 03:17:35 +0800514 const struct batt_ttf_stats *ttf_stats,
515 int temp_idx, int vbatt_idx,
516 int capacity, int full_capacity);
517
518int ttf_stats_init(struct batt_ttf_stats *stats,
519 struct device *device,
520 int capacity_ma);
521
522void ttf_stats_update(struct batt_ttf_stats *stats,
523 struct gbms_charging_event *ce_data,
524 bool force);
525
526int ttf_stats_cstr(char *buff, int size, const struct batt_ttf_stats *stats,
527 bool verbose);
528
529int ttf_stats_sscan(struct batt_ttf_stats *stats,
530 const char *buff, size_t size);
531
532struct batt_ttf_stats *ttf_stats_dup(struct batt_ttf_stats *dst,
533 const struct batt_ttf_stats *src);
534
AleX Pelosid0319472020-02-29 12:42:59 -0800535void ttf_log(const struct batt_ttf_stats *stats, const char *fmt, ...);
536
AleX Pelosi4a9035f2020-02-28 19:09:57 -0800537ssize_t ttf_dump_details(char *buf, int max_size,
538 const struct batt_ttf_stats *ttf_stats,
539 int last_soc);
540
Jenny Ho915dc482022-03-21 09:13:57 +0800541int ttf_pwr_vtier_idx(const struct batt_ttf_stats *stats, int soc);
542
543int ttf_ref_cc(const struct batt_ttf_stats *stats, int soc);
544
545int ttf_pwr_ibatt(const struct gbms_ce_tier_stats *ts);
546
Jenny Ho1ef60002022-07-24 18:26:51 +0000547void ttf_tier_reset(struct batt_ttf_stats *stats);
548
Jenny Hoa1ad4072022-01-26 10:46:22 +0800549int gbms_read_aacr_limits(struct gbms_chg_profile *profile,
550 struct device_node *node);
551
AleX Pelosi4adb2a12022-04-26 13:16:20 -0700552bool chg_state_is_disconnected(const union gbms_charger_state *chg_state);
Jenny Ho4f2ad702022-03-01 10:56:19 +0800553
Prasanna Prapancham320dcfe2022-06-27 20:20:46 +0000554/* Voltage tier stats */
555void gbms_tier_stats_init(struct gbms_ce_tier_stats *stats, int8_t idx);
556
557void gbms_chg_stats_tier(struct gbms_ce_tier_stats *tier,
558 int msc_state, ktime_t elap);
559
560void gbms_stats_update_tier(int temp_idx, int ibatt_ma, int temp, ktime_t elap,
561 int cc, union gbms_charger_state *chg_state,
562 enum gbms_msc_states_t msc_state, int soc_in,
563 struct gbms_ce_tier_stats *tier);
564
565int gbms_tier_stats_cstr(char *buff, int size,
566 const struct gbms_ce_tier_stats *tier_stat,
567 bool verbose);
568
569void gbms_log_cstr_handler(struct logbuffer *log, char *buf, int len);
570
571
572
573
Ken Tsou8acade12020-07-09 03:17:35 +0800574/*
575 * Charger modes
576 *
577 */
578
579enum gbms_charger_modes {
AleX Pelosiea674a72020-11-02 11:52:51 -0800580 GBMS_CHGR_MODE_CHGR_DC = 0x20,
581
582 GBMS_USB_BUCK_ON = 0x30,
583 GBMS_USB_OTG_ON = 0x31,
584 GBMS_USB_OTG_FRS_ON = 0x32,
yihsiangpeng8ae00b62021-02-01 19:12:31 +0800585
586 GBMS_CHGR_MODE_WLC_TX = 0x40,
Jack Wu71efd602022-07-07 16:22:31 +0800587
Jack Wu15abe932022-11-14 20:11:24 +0800588 GBMS_POGO_VIN = 0x50,
589 GBMS_POGO_VOUT = 0x51,
Ken Tsou8acade12020-07-09 03:17:35 +0800590};
591
592#define GBMS_MODE_VOTABLE "CHARGER_MODE"
593
AleX Pelosi43bec422022-04-27 21:59:19 -0700594/* Battery Health */
595enum bhi_algo {
596 BHI_ALGO_DISABLED = 0,
AleX Pelosib3a1a552022-05-03 17:00:11 -0700597
AleX Pelosic1cd4752022-05-04 02:15:02 -0700598 BHI_ALGO_CYCLE_COUNT = 1, /* bare, just use cycle count */
599 BHI_ALGO_ACHI = 2, /* cap avg from history, no resistance */
600 BHI_ALGO_ACHI_B = 3, /* same as ACHI + bounds check */
601 BHI_ALGO_ACHI_RAVG = 4, /* same as ACHI and google_resistance */
602 BHI_ALGO_ACHI_RAVG_B = 5, /* same as ACHI_RAVG + bounds check */
AleX Pelosi43bec422022-04-27 21:59:19 -0700603
AleX Pelosic1cd4752022-05-04 02:15:02 -0700604 /* TODO:
605 * BHI_ALGO_ACHI_QRES = 4, cap avg from history, qual resistance
606 * BHI_ALGO_ACHI_QRES_B = 21, same ACHI_QRES + bounds check
607 * BHI_ALGO_GCAP_RAVG = 40, google_capacity, google_resistance
608 * BHI_ALGO_GCAP_RAVG_B = 41, same as GCAP_RAVG + bounds check
609 */
610
611 BHI_ALGO_MIX_N_MATCH = 6,
Jenny Hod4bd5bc2022-08-26 16:08:38 +0000612 BHI_ALGO_DEBUG = 7,
Jenny Hoef8e5252022-10-20 12:03:05 +0800613 BHI_ALGO_INDI = 8, /* individual conditions check */
AleX Pelosi43bec422022-04-27 21:59:19 -0700614 BHI_ALGO_MAX,
615};
616
Jack Wu6ac9f042023-04-13 17:15:37 +0800617/*
618 * Report battery health from health status (for health hal aidl v2)
619 * BH_NOMINAL : BATTERY_HEALTH_GOOD
620 * BH_MARGINAL : BATTERY_HEALTH_FAIR
621 * BH_NEEDS_REPLACEMENT : BATTERY_HEALTH_DEAD
622 * BH_FAILED : BATTERY_HEALTH_UNSPECIFIED_FAILURE
623 * BH_NOT_AVAILABLE : BATTERY_HEALTH_NOT_AVAILABLE
624 */
AleX Pelosi1c2d9de2022-01-20 18:24:19 -0800625enum bhi_status {
626 BH_UNKNOWN = -1,
627 BH_NOMINAL,
628 BH_MARGINAL,
629 BH_NEEDS_REPLACEMENT,
630 BH_FAILED,
Jack Wu6ac9f042023-04-13 17:15:37 +0800631 BH_NOT_AVAILABLE,
AleX Pelosi1c2d9de2022-01-20 18:24:19 -0800632};
633
Jenny Hod4bd5bc2022-08-26 16:08:38 +0000634struct bhi_weight {
635 int w_ci;
636 int w_ii;
637 int w_sd;
638};
639
AleX Pelosi43bec422022-04-27 21:59:19 -0700640/* Charging Speed */
AleX Pelosi1c2d9de2022-01-20 18:24:19 -0800641enum csi_type {
642 CSI_TYPE_UNKNOWN = -1,
AleX Pelosi4adb2a12022-04-26 13:16:20 -0700643
AleX Pelosi1c2d9de2022-01-20 18:24:19 -0800644 CSI_TYPE_None = 0, // Disconnected
645 CSI_TYPE_Fault = 1, // Internal Failures
AleX Pelosi1da39c12022-04-26 15:44:44 -0700646 CSI_TYPE_JEITA = 2, // HW limits (will have HOT or COLD)
AleX Pelosi1c2d9de2022-01-20 18:24:19 -0800647 CSI_TYPE_LongLife = 3, // DefenderConditions
648 CSI_TYPE_Adaptive = 4, // AdaptiveCharging
AleX Pelosi1da39c12022-04-26 15:44:44 -0700649 CSI_TYPE_Normal = 5, // All Good
AleX Pelosi1c2d9de2022-01-20 18:24:19 -0800650};
651
652enum csi_status {
653 CSI_STATUS_UNKNOWN = -1,
AleX Pelosi4adb2a12022-04-26 13:16:20 -0700654
AleX Pelosi1da39c12022-04-26 15:44:44 -0700655 CSI_STATUS_Health_Cold = 10, // battery temperature not nominal
656 CSI_STATUS_Health_Hot = 11, // battery temperature not nominal
657 CSI_STATUS_System_Thermals = 20,// Thermal engine
658 CSI_STATUS_System_Load = 21, // Load might eventually become thermals
659 CSI_STATUS_Adapter_Auth = 30, // During authentication
660 CSI_STATUS_Adapter_Power = 31, // Low power adapter
661 CSI_STATUS_Adapter_Quality = 32,// Adapter or cable (low input voltage)
Jenny Ho4f2ad702022-03-01 10:56:19 +0800662 CSI_STATUS_Defender_Temp = 40, // TEMP Defend
663 CSI_STATUS_Defender_Dwell = 41, // DWELL Defend
664 CSI_STATUS_Defender_Trickle = 42,
665 CSI_STATUS_Defender_Dock = 43, // Dock Defend
AleX Pelosi1da39c12022-04-26 15:44:44 -0700666 CSI_STATUS_NotCharging = 100, // There will be a more specific reason
667 CSI_STATUS_Charging = 200, // All good
AleX Pelosi1c2d9de2022-01-20 18:24:19 -0800668};
669
Jenny Ho5ba876c2023-03-19 10:28:51 +0800670#define CSI_TYPE_MASK_UNKNOWN (1 << 0)
671#define CSI_TYPE_MASK_NONE (1 << 1)
672#define CSI_TYPE_MASK_FAULT (1 << 2)
673#define CSI_TYPE_MASK_JEITA (1 << 3)
674#define CSI_TYPE_MASK_LONGLIFE (1 << 4)
675#define CSI_TYPE_MASK_ADAPTIVE (1 << 5)
676#define CSI_TYPE_MASK_NORMAL (1 << 6)
677
678#define CSI_STATUS_MASK_UNKNOWN (1 << 0)
679#define CSI_STATUS_MASK_HEALTH_COLD (1 << 1)
680#define CSI_STATUS_MASK_HEALTH_HOT (1 << 2)
681#define CSI_STATUS_MASK_SYS_THERMALS (1 << 3)
682#define CSI_STATUS_MASK_SYS_LOAD (1 << 4)
683#define CSI_STATUS_MASK_ADA_AUTH (1 << 5)
684#define CSI_STATUS_MASK_ADA_POWER (1 << 6)
685#define CSI_STATUS_MASK_ADA_QUALITY (1 << 7)
686#define CSI_STATUS_MASK_DEFEND_TEMP (1 << 8)
687#define CSI_STATUS_MASK_DEFEND_DWELL (1 << 9)
688#define CSI_STATUS_MASK_DEFEND_TRICLE (1 << 10)
689#define CSI_STATUS_MASK_DEFEND_DOCK (1 << 11)
690#define CSI_STATUS_MASK_NOTCHARGING (1 << 12)
691#define CSI_STATUS_MASK_CHARGING (1 << 13)
692
Jack Wu6f519872022-12-21 19:56:25 +0800693enum charging_state {
694 BATTERY_STATUS_UNKNOWN = -1,
695
696 BATTERY_STATUS_NORMAL = 1,
697 BATTERY_STATUS_TOO_COLD = 2,
698 BATTERY_STATUS_TOO_HOT = 3,
699 BATTERY_STATUS_LONGLIFE = 4,
700 BATTERY_STATUS_ADAPTIVE = 5,
701};
702
703#define LONGLIFE_CHARGE_STOP_LEVEL 80
704#define LONGLIFE_CHARGE_START_LEVEL 70
705#define ADAPTIVE_ALWAYS_ON_SOC 80
706
707enum charging_policy {
708 CHARGING_POLICY_UNKNOWN = -1,
709
710 CHARGING_POLICY_DEFAULT = 1,
711 CHARGING_POLICY_LONGLIFE = 2,
712 CHARGING_POLICY_ADAPTIVE = 3,
713};
714
715/*
716 * LONGLIFE takes precedence over AC or AON limits,
717 * and AC also must take precedence over the AON limit.
718 */
719enum charging_policy_vote {
720 CHARGING_POLICY_VOTE_UNKNOWN = -1,
721
722 CHARGING_POLICY_VOTE_DEFAULT = 1,
723 CHARGING_POLICY_VOTE_ADAPTIVE_AON = 2,
724 CHARGING_POLICY_VOTE_ADAPTIVE_AC = 3,
725 CHARGING_POLICY_VOTE_LONGLIFE = 4,
726};
727
Jack Wud7fe2092022-07-14 21:21:19 +0800728#define to_cooling_device(_dev) \
729 container_of(_dev, struct thermal_cooling_device, device)
730
731#define DEBUG_ATTRIBUTE_WO(name) \
732static const struct file_operations name ## _fops = { \
733 .open = simple_open, \
734 .llseek = no_llseek, \
735 .write = name ## _store, \
736}
AleX Pelosi43bec422022-04-27 21:59:19 -0700737
738
Ken Tsou8acade12020-07-09 03:17:35 +0800739#endif /* __GOOGLE_BMS_H_ */