sec_step_charging.c 62 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774
  1. /*
  2. * sec_step_charging.c
  3. * Samsung Mobile Battery Driver
  4. *
  5. * Copyright (C) 2018 Samsung Electronics
  6. *
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. */
  12. #include "sec_battery.h"
  13. #define STEP_CHARGING_CONDITION_VOLTAGE 0x01
  14. #define STEP_CHARGING_CONDITION_SOC 0x02
  15. #define STEP_CHARGING_CONDITION_CHARGE_POWER 0x04
  16. #define STEP_CHARGING_CONDITION_ONLINE 0x08
  17. #define STEP_CHARGING_CONDITION_CURRENT_NOW 0x10
  18. #define STEP_CHARGING_CONDITION_FLOAT_VOLTAGE 0x20
  19. #define STEP_CHARGING_CONDITION_INPUT_CURRENT 0x40
  20. #define STEP_CHARGING_CONDITION_SOC_INIT_ONLY 0x80 /* use this to consider SOC to decide starting step only */
  21. #define STEP_CHARGING_CONDITION_FORCE_SOC 0x100
  22. #define STEP_CHARGING_CONDITION_FG_CURRENT 0x200
  23. #define STEP_CHARGING_CONDITION_DC_INIT (STEP_CHARGING_CONDITION_VOLTAGE | STEP_CHARGING_CONDITION_SOC | STEP_CHARGING_CONDITION_SOC_INIT_ONLY)
  24. #define DIRECT_CHARGING_FLOAT_VOLTAGE_MARGIN 20
  25. #define DIRECT_CHARGING_FORCE_SOC_MARGIN 10
  26. void sec_bat_reset_step_charging(struct sec_battery_info *battery)
  27. {
  28. pr_info("%s\n", __func__);
  29. battery->step_chg_status = -1;
  30. #if IS_ENABLED(CONFIG_WIRELESS_CHARGING)
  31. battery->wpc_step_chg_status = -1;
  32. #endif
  33. #if IS_ENABLED(CONFIG_DIRECT_CHARGING)
  34. battery->dc_float_voltage_set = false;
  35. #endif
  36. }
  37. EXPORT_SYMBOL(sec_bat_reset_step_charging);
  38. void sec_bat_exit_step_charging(struct sec_battery_info *battery)
  39. {
  40. sec_vote(battery->fcc_vote, VOTER_STEP_CHARGE, false, 0);
  41. if (battery->step_chg_type & STEP_CHARGING_CONDITION_FLOAT_VOLTAGE)
  42. sec_vote(battery->fv_vote, VOTER_STEP_CHARGE, false, 0);
  43. sec_bat_reset_step_charging(battery);
  44. }
  45. EXPORT_SYMBOL(sec_bat_exit_step_charging);
  46. void sec_bat_exit_wpc_step_charging(struct sec_battery_info *battery)
  47. {
  48. sec_vote(battery->fcc_vote, VOTER_WPC_STEP_CHARGE, false, 0);
  49. if (battery->step_chg_type & STEP_CHARGING_CONDITION_FLOAT_VOLTAGE)
  50. sec_vote(battery->fv_vote, VOTER_WPC_STEP_CHARGE, false, 0);
  51. sec_bat_reset_step_charging(battery);
  52. }
  53. EXPORT_SYMBOL(sec_bat_exit_wpc_step_charging);
  54. /*
  55. * true: step is changed
  56. * false: not changed
  57. */
  58. bool sec_bat_check_step_charging(struct sec_battery_info *battery)
  59. {
  60. int i = 0, value = 0, step_condition = 0, lcd_status = 0;
  61. #if IS_ENABLED(CONFIG_DUAL_BATTERY)
  62. int value_sub = 0, step_condition_sub = 0;
  63. #endif
  64. static int curr_cnt;
  65. static bool skip_lcd_on_changed;
  66. int age_step = battery->pdata->age_step;
  67. union power_supply_propval val = {0, };
  68. int fpdo_sc = 0;
  69. #if IS_ENABLED(CONFIG_WIRELESS_CHARGING)
  70. if (is_wireless_all_type(battery->cable_type)) {
  71. sec_vote(battery->fv_vote, VOTER_STEP_CHARGE, false, 0);
  72. sec_vote(battery->fcc_vote, VOTER_STEP_CHARGE, false, 0);
  73. return false;
  74. }
  75. #endif
  76. #if defined(CONFIG_SEC_FACTORY)
  77. if (!battery->step_chg_en_in_factory)
  78. return false;
  79. #endif
  80. if (!battery->step_chg_type)
  81. return false;
  82. #if defined(CONFIG_ENG_BATTERY_CONCEPT)
  83. if (battery->test_charge_current)
  84. return false;
  85. if (battery->test_step_condition <= 4500)
  86. battery->pdata->step_chg_cond[0][0] = battery->test_step_condition;
  87. #endif
  88. if (battery->siop_level < 100 || battery->lcd_status)
  89. lcd_status = 1;
  90. else
  91. lcd_status = 0;
  92. if (battery->cable_type == SEC_BATTERY_CABLE_FPDO_DC) {
  93. psy_do_property(battery->pdata->charger_name, get,
  94. POWER_SUPPLY_EXT_PROP_CHARGING_ENABLED_DC, val);
  95. fpdo_sc = val.intval;
  96. pr_info("%s: SC for FPDO_DC(%d)", __func__, fpdo_sc);
  97. if (!fpdo_sc && battery->step_chg_status >= 0)
  98. sec_bat_reset_step_charging(battery);
  99. }
  100. if (battery->step_chg_type & STEP_CHARGING_CONDITION_ONLINE) {
  101. #if IS_ENABLED(CONFIG_DIRECT_CHARGING)
  102. if ((is_pd_apdo_wire_type(battery->cable_type) && !fpdo_sc) &&
  103. !((battery->current_event & SEC_BAT_CURRENT_EVENT_DC_ERR) &&
  104. (battery->ta_alert_mode == OCP_NONE))) {
  105. sec_vote(battery->fv_vote, VOTER_STEP_CHARGE, false, 0);
  106. sec_vote(battery->fcc_vote, VOTER_STEP_CHARGE, false, 0);
  107. return false;
  108. }
  109. if (((is_pd_apdo_wire_type(battery->cable_type) || is_pd_apdo_wire_type(battery->wire_status)) &&
  110. !fpdo_sc) &&
  111. (battery->sink_status.rp_currentlvl == RP_CURRENT_LEVEL3)) {
  112. pr_info("%s: This cable type should be checked in dc step check\n", __func__);
  113. sec_vote(battery->fv_vote, VOTER_STEP_CHARGE, false, 0);
  114. sec_vote(battery->fcc_vote, VOTER_STEP_CHARGE, false, 0);
  115. return false;
  116. }
  117. #endif
  118. if (!is_hv_wire_type(battery->cable_type) && !is_pd_wire_type(battery->cable_type) &&
  119. (battery->sink_status.rp_currentlvl != RP_CURRENT_LEVEL3)) {
  120. sec_vote(battery->fv_vote, VOTER_STEP_CHARGE, false, 0);
  121. sec_vote(battery->fcc_vote, VOTER_STEP_CHARGE, false, 0);
  122. return false;
  123. }
  124. }
  125. pr_info("%s\n", __func__);
  126. if (battery->step_chg_type & STEP_CHARGING_CONDITION_CHARGE_POWER) {
  127. if (battery->max_charge_power < battery->step_chg_charge_power) {
  128. /* In case of max_charge_power falling by AICL during step-charging ongoing */
  129. sec_bat_exit_step_charging(battery);
  130. return false;
  131. }
  132. }
  133. if (battery->step_charging_skip_lcd_on && lcd_status) {
  134. if (!skip_lcd_on_changed) {
  135. if (battery->step_chg_status != (battery->step_chg_step - 1)) {
  136. sec_vote(battery->fcc_vote, VOTER_STEP_CHARGE, true,
  137. battery->pdata->step_chg_curr[age_step][battery->step_chg_step - 1]);
  138. if (battery->step_chg_type & STEP_CHARGING_CONDITION_FLOAT_VOLTAGE) {
  139. pr_info("%s : float voltage = %d\n", __func__,
  140. battery->pdata->step_chg_vfloat[age_step][battery->step_chg_step - 1]);
  141. sec_vote(battery->fv_vote, VOTER_STEP_CHARGE, true,
  142. battery->pdata->step_chg_vfloat[age_step][battery->step_chg_step - 1]);
  143. }
  144. pr_info("%s : skip step charging because lcd on\n", __func__);
  145. skip_lcd_on_changed = true;
  146. return true;
  147. }
  148. }
  149. return false;
  150. }
  151. if (battery->step_chg_status < 0) {
  152. i = 0;
  153. /* this is only for step enter condition and do not use STEP_CHARGING_CONDITION_SOC at the same time */
  154. if (battery->step_chg_type & STEP_CHARGING_CONDITION_SOC_INIT_ONLY) {
  155. int soc_condition;
  156. value = battery->capacity;
  157. while (i < battery->step_chg_step - 1) {
  158. soc_condition = battery->pdata->step_chg_cond_soc[age_step][i];
  159. if (value < soc_condition)
  160. break;
  161. i++;
  162. }
  163. pr_info("%s : set initial step(%d) by soc\n", __func__, i);
  164. goto check_step_change;
  165. }
  166. } else
  167. i = battery->step_chg_status;
  168. step_condition = battery->pdata->step_chg_cond[age_step][i];
  169. if (battery->step_chg_type & STEP_CHARGING_CONDITION_VOLTAGE) {
  170. #if IS_ENABLED(CONFIG_DUAL_BATTERY)
  171. step_condition_sub = battery->pdata->step_chg_cond_sub[age_step][i];
  172. value = battery->voltage_avg_main;
  173. value_sub = battery->voltage_avg_sub;
  174. #else
  175. value = battery->voltage_avg;
  176. #endif
  177. } else if (battery->step_chg_type & STEP_CHARGING_CONDITION_SOC) {
  178. value = battery->capacity;
  179. if (lcd_status) {
  180. step_condition = battery->pdata->step_chg_cond[age_step][i] + 15;
  181. curr_cnt = 0;
  182. }
  183. } else {
  184. return false;
  185. }
  186. while (i < battery->step_chg_step - 1) {
  187. #if IS_ENABLED(CONFIG_DUAL_BATTERY)
  188. if (battery->step_chg_type & STEP_CHARGING_CONDITION_VOLTAGE) {
  189. if ((value < step_condition) && (value_sub < step_condition_sub))
  190. break;
  191. } else {
  192. if (value < step_condition)
  193. break;
  194. }
  195. #else
  196. if (value < step_condition)
  197. break;
  198. #endif
  199. i++;
  200. if ((battery->step_chg_type & STEP_CHARGING_CONDITION_SOC) &&
  201. lcd_status)
  202. step_condition = battery->pdata->step_chg_cond[age_step][i] + 15;
  203. else {
  204. step_condition = battery->pdata->step_chg_cond[age_step][i];
  205. #if IS_ENABLED(CONFIG_DUAL_BATTERY)
  206. if (battery->step_chg_type & STEP_CHARGING_CONDITION_VOLTAGE)
  207. step_condition_sub = battery->pdata->step_chg_cond_sub[age_step][i];
  208. #endif
  209. }
  210. if (battery->step_chg_status != -1)
  211. break;
  212. }
  213. check_step_change:
  214. if ((i != battery->step_chg_status) || skip_lcd_on_changed) {
  215. /* this is only for no consuming current */
  216. if ((battery->step_chg_type & STEP_CHARGING_CONDITION_CURRENT_NOW) &&
  217. !lcd_status &&
  218. battery->step_chg_status >= 0) {
  219. int condition_curr;
  220. condition_curr = max(battery->current_avg, battery->current_now);
  221. if (condition_curr < battery->pdata->step_chg_cond_curr[battery->step_chg_status]) {
  222. curr_cnt++;
  223. pr_info("%s : cnt = %d, curr(%d)mA < curr cond(%d)mA\n",
  224. __func__, curr_cnt, condition_curr,
  225. battery->pdata->step_chg_cond_curr[battery->step_chg_status]);
  226. if (curr_cnt < 3)
  227. return false;
  228. } else {
  229. pr_info("%s : clear cnt, curr(%d)mA >= curr cond(%d)mA or < 0mA\n",
  230. __func__, condition_curr,
  231. battery->pdata->step_chg_cond_curr[battery->step_chg_status]);
  232. curr_cnt = 0;
  233. return false;
  234. }
  235. }
  236. pr_info("%s : prev=%d, new=%d, value=%d, current=%d, curr_cnt=%d\n", __func__,
  237. battery->step_chg_status, i, value,
  238. battery->pdata->step_chg_curr[age_step][i], curr_cnt);
  239. battery->step_chg_status = i;
  240. skip_lcd_on_changed = false;
  241. sec_vote(battery->fcc_vote, VOTER_STEP_CHARGE, true,
  242. battery->pdata->step_chg_curr[age_step][i]);
  243. if (battery->step_chg_type & STEP_CHARGING_CONDITION_FLOAT_VOLTAGE) {
  244. pr_info("%s : float voltage = %d\n", __func__,
  245. battery->pdata->step_chg_vfloat[age_step][i]);
  246. sec_vote(battery->fv_vote, VOTER_STEP_CHARGE, true,
  247. battery->pdata->step_chg_vfloat[age_step][i]);
  248. }
  249. return true;
  250. }
  251. return false;
  252. }
  253. EXPORT_SYMBOL(sec_bat_check_step_charging);
  254. #if IS_ENABLED(CONFIG_WIRELESS_CHARGING)
  255. bool sec_bat_check_wpc_step_charging(struct sec_battery_info *battery)
  256. {
  257. int i = 0, value = 0, step_condition = 0, lcd_status = 0;
  258. static int curr_cnt;
  259. static bool skip_lcd_on_changed;
  260. int age_step = battery->pdata->age_step;
  261. #if defined(CONFIG_SEC_FACTORY)
  262. if (!battery->step_chg_en_in_factory)
  263. return false;
  264. #endif
  265. if (!battery->wpc_step_chg_type)
  266. return false;
  267. if (is_not_wireless_type(battery->cable_type)) {
  268. sec_vote(battery->fv_vote, VOTER_WPC_STEP_CHARGE, false, 0);
  269. sec_vote(battery->fcc_vote, VOTER_WPC_STEP_CHARGE, false, 0);
  270. return false;
  271. }
  272. #if defined(CONFIG_ENG_BATTERY_CONCEPT)
  273. if (battery->test_charge_current)
  274. return false;
  275. if (battery->test_step_condition <= 4500)
  276. battery->pdata->wpc_step_chg_cond[0][0] = battery->test_step_condition;
  277. #endif
  278. if (battery->siop_level < 100 || battery->lcd_status)
  279. lcd_status = 1;
  280. else
  281. lcd_status = 0;
  282. if (battery->wpc_step_chg_type & STEP_CHARGING_CONDITION_CHARGE_POWER) {
  283. if (battery->max_charge_power < battery->wpc_step_chg_charge_power) {
  284. /* In case of max_charge_power falling by AICL during step-charging ongoing */
  285. sec_bat_exit_wpc_step_charging(battery);
  286. return false;
  287. }
  288. }
  289. if (battery->step_charging_skip_lcd_on && lcd_status) {
  290. if (!skip_lcd_on_changed) {
  291. if (battery->wpc_step_chg_status != (battery->wpc_step_chg_step - 1)) {
  292. sec_vote(battery->fcc_vote, VOTER_WPC_STEP_CHARGE, true,
  293. battery->pdata->wpc_step_chg_curr[age_step][battery->wpc_step_chg_step - 1]);
  294. if (battery->wpc_step_chg_type & STEP_CHARGING_CONDITION_FLOAT_VOLTAGE) {
  295. pr_info("%s : float voltage = %d\n", __func__,
  296. battery->pdata->wpc_step_chg_vfloat[age_step][battery->wpc_step_chg_step - 1]);
  297. sec_vote(battery->fv_vote, VOTER_WPC_STEP_CHARGE, true,
  298. battery->pdata->wpc_step_chg_vfloat[age_step][battery->wpc_step_chg_step - 1]);
  299. }
  300. pr_info("%s : skip step charging because lcd on\n", __func__);
  301. skip_lcd_on_changed = true;
  302. return true;
  303. }
  304. }
  305. return false;
  306. }
  307. if (battery->wpc_step_chg_status < 0)
  308. i = 0;
  309. else
  310. i = battery->wpc_step_chg_status;
  311. step_condition = battery->pdata->wpc_step_chg_cond[age_step][i];
  312. if (battery->wpc_step_chg_type & STEP_CHARGING_CONDITION_VOLTAGE) {
  313. value = battery->voltage_avg;
  314. } else if (battery->wpc_step_chg_type & STEP_CHARGING_CONDITION_SOC) {
  315. value = battery->capacity;
  316. if (lcd_status) {
  317. step_condition = battery->pdata->wpc_step_chg_cond[age_step][i] + 15;
  318. curr_cnt = 0;
  319. }
  320. } else {
  321. return false;
  322. }
  323. while (i < battery->wpc_step_chg_step - 1) {
  324. if (value < step_condition)
  325. break;
  326. i++;
  327. if ((battery->wpc_step_chg_type & STEP_CHARGING_CONDITION_SOC) &&
  328. lcd_status)
  329. step_condition = battery->pdata->wpc_step_chg_cond[age_step][i] + 15;
  330. else {
  331. step_condition = battery->pdata->wpc_step_chg_cond[age_step][i];
  332. }
  333. if (battery->wpc_step_chg_status != -1)
  334. break;
  335. }
  336. /* this is only for no consuming current */
  337. if ((battery->wpc_step_chg_type & STEP_CHARGING_CONDITION_CURRENT_NOW) &&
  338. !lcd_status &&
  339. battery->wpc_step_chg_status >= 0) {
  340. int condition_curr;
  341. condition_curr = max(battery->current_avg, battery->current_now);
  342. if (condition_curr < battery->pdata->wpc_step_chg_cond_curr[battery->wpc_step_chg_status]) {
  343. curr_cnt++;
  344. pr_info("%s : cnt = %d, curr(%d)mA < curr cond(%d)mA\n",
  345. __func__, curr_cnt, condition_curr,
  346. battery->pdata->wpc_step_chg_cond_curr[battery->wpc_step_chg_status]);
  347. if (curr_cnt < 3)
  348. return false;
  349. } else {
  350. pr_info("%s : clear cnt, curr(%d)mA >= curr cond(%d)mA or < 0mA\n",
  351. __func__, condition_curr,
  352. battery->pdata->wpc_step_chg_cond_curr[battery->wpc_step_chg_status]);
  353. curr_cnt = 0;
  354. return false;
  355. }
  356. }
  357. pr_info("%s : prev=%d, new=%d, value=%d, current=%d, curr_cnt=%d\n", __func__,
  358. battery->wpc_step_chg_status, i, value,
  359. battery->pdata->wpc_step_chg_curr[age_step][i], curr_cnt);
  360. battery->wpc_step_chg_status = i;
  361. skip_lcd_on_changed = false;
  362. sec_vote(battery->fcc_vote, VOTER_WPC_STEP_CHARGE, true,
  363. battery->pdata->wpc_step_chg_curr[age_step][i]);
  364. if (battery->wpc_step_chg_type & STEP_CHARGING_CONDITION_FLOAT_VOLTAGE) {
  365. pr_info("%s : float voltage = %d\n", __func__,
  366. battery->pdata->wpc_step_chg_vfloat[age_step][i]);
  367. sec_vote(battery->fv_vote, VOTER_WPC_STEP_CHARGE, true,
  368. battery->pdata->wpc_step_chg_vfloat[age_step][i]);
  369. }
  370. return true;
  371. }
  372. EXPORT_SYMBOL(sec_bat_check_wpc_step_charging);
  373. #endif
  374. #if IS_ENABLED(CONFIG_DIRECT_CHARGING)
  375. bool skip_check_dc_step(struct sec_battery_info *battery)
  376. {
  377. if (battery->dchg_dc_in_swelling) {
  378. if (battery->current_event & SEC_BAT_CURRENT_EVENT_LOW_TEMP_MODE)
  379. return true;
  380. } else {
  381. if (battery->current_event & SEC_BAT_CURRENT_EVENT_SWELLING_MODE)
  382. return true;
  383. }
  384. if (battery->current_event & SEC_BAT_CURRENT_EVENT_HV_DISABLE ||
  385. ((battery->current_event & SEC_BAT_CURRENT_EVENT_DC_ERR) &&
  386. (battery->ta_alert_mode == OCP_NONE)) ||
  387. battery->current_event & SEC_BAT_CURRENT_EVENT_SIOP_LIMIT ||
  388. battery->wc_tx_enable ||
  389. battery->uno_en ||
  390. battery->mix_limit ||
  391. battery->lrp_chg_src == SEC_CHARGING_SOURCE_SWITCHING)
  392. return true;
  393. else
  394. return false;
  395. }
  396. bool sec_bat_check_dc_step_charging(struct sec_battery_info *battery)
  397. {
  398. int i, value;
  399. int step = -1, step_vol = -1, step_input = -1, step_soc = -1, soc_condition = 0;
  400. int force_step_soc = 0, step_fg_current = -1;
  401. bool force_change_step = false;
  402. union power_supply_propval val = {0, };
  403. int age_step = battery->pdata->age_step;
  404. unsigned int dc_step_chg_type;
  405. if (battery->cable_type == SEC_BATTERY_CABLE_FPDO_DC) {
  406. sec_vote(battery->dc_fv_vote, VOTER_DC_STEP_CHARGE, false, 0);
  407. sec_vote(battery->fcc_vote, VOTER_CABLE, true,
  408. battery->pdata->charging_current[SEC_BATTERY_CABLE_FPDO_DC].fast_charging_current);
  409. sec_vote_refresh(battery->fcc_vote);
  410. return false;
  411. }
  412. i = (battery->step_chg_status < 0 ? 0 : battery->step_chg_status);
  413. dc_step_chg_type = battery->dc_step_chg_type[i];
  414. if (!dc_step_chg_type) {
  415. sec_vote(battery->dc_fv_vote, VOTER_DC_STEP_CHARGE, false, 0);
  416. return false;
  417. }
  418. if (dc_step_chg_type & STEP_CHARGING_CONDITION_CHARGE_POWER)
  419. if (battery->charge_power < battery->dc_step_chg_charge_power) {
  420. sec_vote(battery->dc_fv_vote, VOTER_DC_STEP_CHARGE, false, 0);
  421. return false;
  422. }
  423. if (dc_step_chg_type & STEP_CHARGING_CONDITION_ONLINE) {
  424. if (!is_pd_apdo_wire_type(battery->cable_type)) {
  425. sec_vote(battery->dc_fv_vote, VOTER_DC_STEP_CHARGE, false, 0);
  426. return false;
  427. }
  428. }
  429. if (skip_check_dc_step(battery)) {
  430. if (battery->step_chg_status >= 0)
  431. sec_bat_reset_step_charging(battery);
  432. sec_vote(battery->dc_fv_vote, VOTER_DC_STEP_CHARGE, false, 0);
  433. return false;
  434. }
  435. if (!(dc_step_chg_type & STEP_CHARGING_CONDITION_DC_INIT)) {
  436. pr_info("%s : cond_vol and cond_soc are both empty\n", __func__);
  437. sec_vote(battery->dc_fv_vote, VOTER_DC_STEP_CHARGE, false, 0);
  438. return false;
  439. }
  440. /* this is only for step enter condition and do not use STEP_CHARGING_CONDITION_SOC at the same time */
  441. if (dc_step_chg_type & STEP_CHARGING_CONDITION_SOC_INIT_ONLY) {
  442. if (battery->step_chg_status < 0) {
  443. step_soc = i;
  444. value = battery->capacity;
  445. while (step_soc < battery->dc_step_chg_step - 1) {
  446. soc_condition = battery->pdata->dc_step_chg_cond_soc[age_step][step_soc];
  447. if (value < soc_condition)
  448. break;
  449. step_soc++;
  450. }
  451. if ((step_soc < step) || (step < 0))
  452. step = step_soc;
  453. pr_info("%s : set initial step(%d) by soc\n", __func__, step_soc);
  454. goto check_dc_step_change;
  455. } else
  456. step_soc = battery->dc_step_chg_step - 1;
  457. }
  458. if (dc_step_chg_type & STEP_CHARGING_CONDITION_SOC) {
  459. step_soc = i;
  460. value = battery->capacity;
  461. while (step_soc < battery->dc_step_chg_step - 1) {
  462. soc_condition = battery->pdata->dc_step_chg_cond_soc[age_step][step_soc];
  463. if (battery->step_chg_status >= 0 &&
  464. (battery->siop_level < 100 || battery->lcd_status)) {
  465. soc_condition += DIRECT_CHARGING_FORCE_SOC_MARGIN;
  466. force_change_step = true;
  467. }
  468. if (value < soc_condition)
  469. break;
  470. step_soc++;
  471. if (battery->step_chg_status >= 0)
  472. break;
  473. }
  474. if ((step_soc < step) || (step < 0))
  475. step = step_soc;
  476. if (battery->step_chg_status < 0) {
  477. pr_info("%s : set initial step(%d) by soc\n", __func__, step_soc);
  478. goto check_dc_step_change;
  479. }
  480. if (force_change_step) {
  481. pr_info("%s : force check step(%d) by soc\n", __func__, step_soc);
  482. step_vol = step_input = step_soc;
  483. battery->dc_step_chg_iin_cnt = battery->pdata->dc_step_chg_iin_check_cnt;
  484. goto check_dc_step_change;
  485. }
  486. } else
  487. step_soc = battery->dc_step_chg_step - 1;
  488. if (dc_step_chg_type & STEP_CHARGING_CONDITION_VOLTAGE) {
  489. step_vol = i;
  490. #if IS_ENABLED(CONFIG_DUAL_BATTERY)
  491. value = max((battery->voltage_avg_main - battery->pdata->dc_step_cond_v_margin_main),
  492. (battery->voltage_avg_sub - battery->pdata->dc_step_cond_v_margin_sub));
  493. /* (charging current)step down when main or sub voltage condition meets */
  494. while (step_vol < battery->dc_step_chg_step - 1) {
  495. if (battery->voltage_avg_main < battery->pdata->dc_step_chg_cond_vol[age_step][step_vol] &&
  496. battery->voltage_avg_sub < battery->pdata->dc_step_chg_cond_vol_sub[age_step][step_vol])
  497. break;
  498. step_vol++;
  499. if (battery->step_chg_status >= 0)
  500. break;
  501. }
  502. #else
  503. if (dc_step_chg_type & STEP_CHARGING_CONDITION_FLOAT_VOLTAGE)
  504. value = battery->voltage_now + battery->pdata->dc_step_chg_cond_v_margin;
  505. else
  506. value = battery->voltage_avg;
  507. while (step_vol < battery->dc_step_chg_step - 1) {
  508. if (value < battery->pdata->dc_step_chg_cond_vol[age_step][step_vol])
  509. break;
  510. step_vol++;
  511. if (battery->step_chg_status >= 0)
  512. break;
  513. }
  514. #endif
  515. if ((step_vol < step) || (step < 0))
  516. step = step_vol;
  517. if (battery->step_chg_status < 0) {
  518. pr_info("%s : set initial step(%d) by vol\n", __func__, step_vol);
  519. goto check_dc_step_change;
  520. }
  521. } else
  522. step_vol = battery->dc_step_chg_step - 1;
  523. if (dc_step_chg_type & STEP_CHARGING_CONDITION_INPUT_CURRENT) {
  524. step_input = i;
  525. psy_do_property(battery->pdata->charger_name, get,
  526. POWER_SUPPLY_EXT_PROP_DIRECT_CHARGER_MODE, val);
  527. if (val.intval != SEC_DIRECT_CHG_MODE_DIRECT_ON) {
  528. pr_info("%s : dc no charging status = %d\n", __func__, val.intval);
  529. battery->dc_step_chg_iin_cnt = 0;
  530. return false;
  531. } else if (battery->siop_level >= 100 && !battery->lcd_status) {
  532. val.intval = SEC_BATTERY_IIN_MA;
  533. psy_do_property(battery->pdata->charger_name, get,
  534. POWER_SUPPLY_EXT_PROP_MEASURE_INPUT, val);
  535. value = val.intval;
  536. while (step_input < battery->dc_step_chg_step - 1) {
  537. if (value > battery->pdata->dc_step_chg_cond_iin[step_input])
  538. break;
  539. step_input++;
  540. if (battery->step_chg_status >= 0) {
  541. battery->dc_step_chg_iin_cnt++;
  542. break;
  543. } else {
  544. battery->dc_step_chg_iin_cnt = 0;
  545. }
  546. }
  547. } else {
  548. /*
  549. * Do not check input current when lcd is on or siop is not 100
  550. * since there might be quite big system current
  551. */
  552. step_input = battery->dc_step_chg_step - 1;
  553. }
  554. if ((step_input < step) || (step < 0))
  555. step = step_input;
  556. } else
  557. step_input = battery->dc_step_chg_step - 1;
  558. if (dc_step_chg_type & STEP_CHARGING_CONDITION_FG_CURRENT) {
  559. step_fg_current = i;
  560. psy_do_property(battery->pdata->charger_name, get,
  561. POWER_SUPPLY_EXT_PROP_DIRECT_CHARGER_MODE, val);
  562. if (val.intval != SEC_DIRECT_CHG_MODE_DIRECT_ON) {
  563. pr_info("%s : dc no charging status = %d\n", __func__, val.intval);
  564. battery->dc_step_chg_iin_cnt = 0;
  565. return false;
  566. } else if (battery->siop_level >= 100 && !battery->lcd_status) {
  567. int current_now, current_avg;
  568. val.intval = SEC_BATTERY_CURRENT_MA;
  569. psy_do_property(battery->pdata->fuelgauge_name, get,
  570. POWER_SUPPLY_PROP_CURRENT_NOW, val);
  571. current_now = val.intval;
  572. val.intval = SEC_BATTERY_CURRENT_MA;
  573. psy_do_property(battery->pdata->fuelgauge_name, get,
  574. POWER_SUPPLY_PROP_CURRENT_AVG, val);
  575. current_avg = val.intval;
  576. value = max(current_now, current_avg) / 2;
  577. while (step_fg_current < battery->dc_step_chg_step - 1) {
  578. if (value > battery->pdata->dc_step_chg_cond_iin[step_fg_current])
  579. break;
  580. step_fg_current++;
  581. if (battery->step_chg_status >= 0) {
  582. battery->dc_step_chg_iin_cnt++;
  583. break;
  584. }
  585. battery->dc_step_chg_iin_cnt = 0;
  586. }
  587. } else {
  588. /*
  589. * Do not check input current when lcd is on or siop is not 100
  590. * since there might be quite big system current
  591. */
  592. step_fg_current = battery->dc_step_chg_step - 1;
  593. }
  594. if ((step_fg_current < step) || (step < 0))
  595. step = step_fg_current;
  596. } else
  597. step_fg_current = battery->dc_step_chg_step - 1;
  598. if (dc_step_chg_type & STEP_CHARGING_CONDITION_FORCE_SOC) {
  599. force_step_soc = i;
  600. if (battery->capacity >= battery->pdata->dc_step_chg_cond_soc[age_step][i]) {
  601. if (++force_step_soc > step)
  602. step = force_step_soc;
  603. pr_info("%s : SOC(%d) cond_soc(%d) step(%d) force_step_soc(%d)\n", __func__,
  604. battery->capacity, battery->pdata->dc_step_chg_cond_soc[age_step][i],
  605. step, force_step_soc);
  606. } else
  607. force_step_soc = 0;
  608. } else
  609. force_step_soc = 0;
  610. check_dc_step_change:
  611. pr_info("%s : curr_step(%d), step_vol(%d), step_soc(%d), step_input(%d, %d), curr_cnt(%d/%d) force_step_soc(%d)\n",
  612. __func__, step, step_vol, step_soc, step_input, step_fg_current,
  613. battery->dc_step_chg_iin_cnt, battery->pdata->dc_step_chg_iin_check_cnt, force_step_soc);
  614. if (battery->step_chg_status < 0 || force_step_soc ||
  615. (step != battery->step_chg_status &&
  616. step == min(min(step_vol, step_soc), min(step_input, step_fg_current)))) {
  617. if ((dc_step_chg_type &
  618. (STEP_CHARGING_CONDITION_INPUT_CURRENT | STEP_CHARGING_CONDITION_FG_CURRENT)) &&
  619. (battery->step_chg_status >= 0)) {
  620. if ((battery->dc_step_chg_iin_cnt < battery->pdata->dc_step_chg_iin_check_cnt) &&
  621. (battery->siop_level >= 100 && !battery->lcd_status) && !force_step_soc) {
  622. pr_info("%s : keep step(%d), curr_cnt(%d/%d)\n",
  623. __func__, battery->step_chg_status,
  624. battery->dc_step_chg_iin_cnt, battery->pdata->dc_step_chg_iin_check_cnt);
  625. return false;
  626. }
  627. }
  628. pr_info("%s : cable(%d), soc(%d), step changed(%d->%d), current(%dmA) force_step_soc(%d)\n",
  629. __func__, battery->cable_type, battery->capacity, battery->step_chg_status, step,
  630. battery->pdata->dc_step_chg_val_iout[age_step][step], force_step_soc);
  631. /* set charging current */
  632. battery->pdata->charging_current[battery->cable_type].fast_charging_current =
  633. battery->pdata->dc_step_chg_val_iout[age_step][step];
  634. if (dc_step_chg_type & STEP_CHARGING_CONDITION_FLOAT_VOLTAGE) {
  635. if (battery->step_chg_status < 0) {
  636. pr_info("%s : step float voltage = %d\n", __func__,
  637. battery->pdata->dc_step_chg_val_vfloat[age_step][step]);
  638. sec_vote(battery->dc_fv_vote, VOTER_DC_STEP_CHARGE, true,
  639. battery->pdata->dc_step_chg_val_vfloat[age_step][step]);
  640. }
  641. battery->dc_float_voltage_set = true;
  642. }
  643. if (battery->step_chg_status < 0) {
  644. pr_info("%s : step input current = %d\n", __func__,
  645. battery->pdata->dc_step_chg_val_iout[age_step][step] / 2);
  646. val.intval = battery->pdata->dc_step_chg_val_iout[age_step][step] / 2;
  647. psy_do_property(battery->pdata->charger_name, set,
  648. POWER_SUPPLY_EXT_PROP_DIRECT_CURRENT_MAX, val);
  649. }
  650. battery->step_chg_status = step;
  651. battery->dc_step_chg_iin_cnt = 0;
  652. sec_vote(battery->fcc_vote, VOTER_CABLE, true,
  653. battery->pdata->dc_step_chg_val_iout[age_step][step]);
  654. sec_vote_refresh(battery->fcc_vote);
  655. return true;
  656. } else {
  657. battery->dc_step_chg_iin_cnt = 0;
  658. }
  659. return false;
  660. }
  661. EXPORT_SYMBOL(sec_bat_check_dc_step_charging);
  662. int sec_dc_step_charging_dt(struct sec_battery_info *battery, struct device *dev)
  663. {
  664. struct device_node *np = dev->of_node;
  665. int ret = 0, len = 0;
  666. sec_battery_platform_data_t *pdata = battery->pdata;
  667. unsigned int i = 0, j = 0, dc_step_chg_type = 0;
  668. const u32 *p;
  669. char str[128] = {0,};
  670. u32 *soc_cond_temp, *vol_cond_temp, *vfloat_temp, *iout_temp;
  671. int age_step = battery->pdata->age_step;
  672. int num_age_step = battery->pdata->num_age_step;
  673. battery->dchg_dc_in_swelling = of_property_read_bool(np,
  674. "battery,dchg_dc_in_swelling");
  675. pr_info("%s: dchg_dc_in_swelling(%d)\n", __func__, battery->dchg_dc_in_swelling);
  676. ret = of_property_read_u32(np, "battery,dc_step_chg_step",
  677. &battery->dc_step_chg_step);
  678. if (ret) {
  679. pr_err("%s: dc_step_chg_step is Empty\n", __func__);
  680. battery->dc_step_chg_step = 0;
  681. goto dc_step_charging_dt_error;
  682. } else {
  683. pr_err("%s: dc_step_chg_step is %d\n",
  684. __func__, battery->dc_step_chg_step);
  685. }
  686. battery->dc_step_chg_type = kcalloc(battery->dc_step_chg_step, sizeof(u32), GFP_KERNEL);
  687. p = of_get_property(np, "battery,dc_step_chg_type", &len);
  688. if (!p) {
  689. pr_info("%s: dc_step_chg_type is Empty\n", __func__);
  690. return -1;
  691. }
  692. len = len / sizeof(u32);
  693. ret = of_property_read_u32_array(np, "battery,dc_step_chg_type",
  694. battery->dc_step_chg_type, len);
  695. if (len != battery->dc_step_chg_step) {
  696. pr_err("%s not match size of dc_step_chg_type: %d\n", __func__, len);
  697. for (i = 1; i < battery->dc_step_chg_step; i++)
  698. battery->dc_step_chg_type[i] = battery->dc_step_chg_type[0];
  699. dc_step_chg_type = battery->dc_step_chg_type[0];
  700. } else {
  701. for (i = 0; i < battery->dc_step_chg_step; i++)
  702. dc_step_chg_type |= battery->dc_step_chg_type[i];
  703. }
  704. memset(str, 0x0, sizeof(str));
  705. sprintf(str + strlen(str), "dc_step_chg_type arr :");
  706. for (i = 0; i < battery->dc_step_chg_step; i++)
  707. sprintf(str + strlen(str), " 0x%x", battery->dc_step_chg_type[i]);
  708. pr_info("%s: %s 0x%x\n", __func__, str, dc_step_chg_type);
  709. ret = of_property_read_u32(np, "battery,dc_step_chg_charge_power",
  710. &battery->dc_step_chg_charge_power);
  711. if (ret) {
  712. pr_err("%s: dc_step_chg_charge_power is Empty\n", __func__);
  713. battery->dc_step_chg_charge_power = 20000;
  714. }
  715. if (dc_step_chg_type & STEP_CHARGING_CONDITION_VOLTAGE) {
  716. p = of_get_property(np, "battery,dc_step_chg_cond_vol", &len);
  717. if (!p) {
  718. pr_err("%s: dc_step_chg_cond_vol is Empty, type(0x%X->0x%X)\n",
  719. __func__, dc_step_chg_type,
  720. dc_step_chg_type & ~STEP_CHARGING_CONDITION_VOLTAGE);
  721. for (i = 0; i < battery->dc_step_chg_step; i++)
  722. battery->dc_step_chg_type[i] &= ~STEP_CHARGING_CONDITION_VOLTAGE;
  723. } else {
  724. len = len / sizeof(u32);
  725. pr_info("%s: step(%d) * age_step(%d), dc_step_chg_cond_vol len(%d)\n",
  726. __func__, battery->dc_step_chg_step, num_age_step, len);
  727. vol_cond_temp = kcalloc(battery->dc_step_chg_step * num_age_step, sizeof(u32), GFP_KERNEL);
  728. ret = of_property_read_u32_array(np, "battery,dc_step_chg_cond_vol",
  729. vol_cond_temp, battery->dc_step_chg_step * num_age_step);
  730. /* copy buff to 2d arr */
  731. pdata->dc_step_chg_cond_vol = kcalloc(num_age_step, sizeof(u32 *), GFP_KERNEL);
  732. for (i = 0; i < num_age_step; i++) {
  733. pdata->dc_step_chg_cond_vol[i] =
  734. kcalloc(battery->dc_step_chg_step, sizeof(u32), GFP_KERNEL);
  735. for (j = 0; j < battery->dc_step_chg_step; j++)
  736. pdata->dc_step_chg_cond_vol[i][j] =
  737. vol_cond_temp[i*battery->dc_step_chg_step + j];
  738. }
  739. /* if there are only 1 dimentional array of value, get the same value */
  740. if (battery->dc_step_chg_step * num_age_step != len) {
  741. pr_err("%s: len of dc_step_chg_cond_vol is not matched\n", __func__);
  742. ret = of_property_read_u32_array(np, "battery,dc_step_chg_cond_vol",
  743. *pdata->dc_step_chg_cond_vol, battery->dc_step_chg_step);
  744. for (i = 1; i < num_age_step; i++) {
  745. for (j = 0; j < battery->dc_step_chg_step; j++)
  746. pdata->dc_step_chg_cond_vol[i][j] =
  747. pdata->dc_step_chg_cond_vol[0][j];
  748. }
  749. }
  750. /* debug log */
  751. for (i = 0; i < num_age_step; i++) {
  752. memset(str, 0x0, sizeof(str));
  753. sprintf(str + strlen(str), "vol arr[%d]:", i);
  754. for (j = 0; j < battery->dc_step_chg_step; j++)
  755. sprintf(str + strlen(str), " %d", pdata->dc_step_chg_cond_vol[i][j]);
  756. pr_info("%s: %s\n", __func__, str);
  757. }
  758. #if IS_ENABLED(CONFIG_DUAL_BATTERY)
  759. len = len / sizeof(u32);
  760. pr_info("%s: step(%d) * age_step(%d), dc_step_chg_cond_vol_sub len(%d)\n",
  761. __func__, battery->dc_step_chg_step, num_age_step, len);
  762. vol_cond_temp = kcalloc(battery->dc_step_chg_step * num_age_step, sizeof(u32), GFP_KERNEL);
  763. ret = of_property_read_u32_array(np, "battery,dc_step_chg_cond_vol_sub",
  764. vol_cond_temp, battery->dc_step_chg_step * num_age_step);
  765. /* copy buff to 2d arr */
  766. pdata->dc_step_chg_cond_vol_sub = kcalloc(num_age_step, sizeof(u32 *), GFP_KERNEL);
  767. for (i = 0; i < num_age_step; i++) {
  768. pdata->dc_step_chg_cond_vol_sub[i] =
  769. kcalloc(battery->dc_step_chg_step, sizeof(u32), GFP_KERNEL);
  770. for (j = 0; j < battery->dc_step_chg_step; j++)
  771. pdata->dc_step_chg_cond_vol_sub[i][j] =
  772. vol_cond_temp[i*battery->dc_step_chg_step + j];
  773. }
  774. /* if there are only 1 dimentional array of value, get the same value */
  775. if (battery->dc_step_chg_step * num_age_step != len) {
  776. pr_err("%s: len of dc_step_chg_cond_vol_sub is not matched\n", __func__);
  777. ret = of_property_read_u32_array(np, "battery,dc_step_chg_cond_vol_sub",
  778. *pdata->dc_step_chg_cond_vol_sub, battery->dc_step_chg_step);
  779. for (i = 1; i < num_age_step; i++) {
  780. for (j = 0; j < battery->dc_step_chg_step; j++)
  781. pdata->dc_step_chg_cond_vol_sub[i][j] =
  782. pdata->dc_step_chg_cond_vol_sub[0][j];
  783. }
  784. }
  785. /* debug log */
  786. for (i = 0; i < num_age_step; i++) {
  787. memset(str, 0x0, sizeof(str));
  788. sprintf(str + strlen(str), "vol_sub arr[%d]:", i);
  789. for (j = 0; j < battery->dc_step_chg_step; j++)
  790. sprintf(str + strlen(str), " %d", pdata->dc_step_chg_cond_vol_sub[i][j]);
  791. pr_info("%s: %s\n", __func__, str);
  792. }
  793. #endif
  794. if (ret) {
  795. pr_info("%s : dc_step_chg_cond_vol read fail\n", __func__);
  796. for (i = 0; i < battery->dc_step_chg_step; i++)
  797. battery->dc_step_chg_type[i] &= ~STEP_CHARGING_CONDITION_VOLTAGE;
  798. }
  799. kfree(vol_cond_temp);
  800. #if IS_ENABLED(CONFIG_DUAL_BATTERY)
  801. ret = of_property_read_u32(np, "battery,dc_step_cond_v_margin_main",
  802. &battery->pdata->dc_step_cond_v_margin_main);
  803. if (ret)
  804. battery->pdata->dc_step_cond_v_margin_main = 0;
  805. ret = of_property_read_u32(np, "battery,dc_step_cond_v_margin_sub",
  806. &battery->pdata->dc_step_cond_v_margin_sub);
  807. if (ret)
  808. battery->pdata->dc_step_cond_v_margin_sub = 0;
  809. ret = of_property_read_u32(np, "battery,sc_vbat_thresh_main",
  810. &battery->pdata->sc_vbat_thresh_main);
  811. if (ret)
  812. battery->pdata->sc_vbat_thresh_main = 4420;
  813. ret = of_property_read_u32(np, "battery,sc_vbat_thresh_sub",
  814. &battery->pdata->sc_vbat_thresh_sub);
  815. if (ret)
  816. battery->pdata->sc_vbat_thresh_sub = battery->pdata->sc_vbat_thresh_main;
  817. #endif
  818. }
  819. }
  820. if (dc_step_chg_type & STEP_CHARGING_CONDITION_SOC ||
  821. dc_step_chg_type & STEP_CHARGING_CONDITION_SOC_INIT_ONLY) {
  822. p = of_get_property(np, "battery,dc_step_chg_cond_soc", &len);
  823. if (!p) {
  824. pr_err("%s: dc_step_chg_cond_soc is Empty, type(0x%X->0x%x)\n",
  825. __func__, dc_step_chg_type,
  826. dc_step_chg_type & ~(STEP_CHARGING_CONDITION_SOC |
  827. STEP_CHARGING_CONDITION_SOC_INIT_ONLY));
  828. for (i = 0; i < battery->dc_step_chg_step; i++)
  829. battery->dc_step_chg_type[i] &= ~(STEP_CHARGING_CONDITION_SOC |
  830. STEP_CHARGING_CONDITION_SOC_INIT_ONLY);
  831. } else {
  832. len = len / sizeof(u32);
  833. pr_info("%s: step(%d) * age_step(%d), dc_step_chg_cond_soc len(%d)\n",
  834. __func__, battery->dc_step_chg_step, num_age_step, len);
  835. /* get dt to buff */
  836. soc_cond_temp = kcalloc(battery->dc_step_chg_step * num_age_step, sizeof(u32), GFP_KERNEL);
  837. ret = of_property_read_u32_array(np, "battery,dc_step_chg_cond_soc",
  838. soc_cond_temp, battery->dc_step_chg_step * num_age_step);
  839. /* copy buff to 2d arr */
  840. pdata->dc_step_chg_cond_soc = kcalloc(num_age_step, sizeof(u32 *), GFP_KERNEL);
  841. for (i = 0; i < num_age_step; i++) {
  842. pdata->dc_step_chg_cond_soc[i] =
  843. kcalloc(battery->dc_step_chg_step, sizeof(u32), GFP_KERNEL);
  844. for (j = 0; j < battery->dc_step_chg_step; j++)
  845. pdata->dc_step_chg_cond_soc[i][j] = soc_cond_temp[i*battery->dc_step_chg_step + j];
  846. }
  847. /* if there are only 1 dimentional array of value, get the same value */
  848. if (battery->dc_step_chg_step * num_age_step != len) {
  849. pr_err("%s: len of dc_step_chg_cond_soc is not matched\n", __func__);
  850. ret = of_property_read_u32_array(np, "battery,dc_step_chg_cond_soc",
  851. *pdata->dc_step_chg_cond_soc, battery->dc_step_chg_step);
  852. for (i = 1; i < num_age_step; i++) {
  853. for (j = 0; j < battery->dc_step_chg_step; j++)
  854. pdata->dc_step_chg_cond_soc[i][j] = pdata->dc_step_chg_cond_soc[0][j];
  855. }
  856. }
  857. /* debug log */
  858. for (i = 0; i < num_age_step; i++) {
  859. memset(str, 0x0, sizeof(str));
  860. sprintf(str + strlen(str), "soc arr[%d]:", i);
  861. for (j = 0; j < battery->dc_step_chg_step; j++)
  862. sprintf(str + strlen(str), " %d", pdata->dc_step_chg_cond_soc[i][j]);
  863. pr_info("%s: %s\n", __func__, str);
  864. }
  865. if (ret) {
  866. pr_info("%s : dc_step_chg_cond_soc read fail\n", __func__);
  867. for (i = 0; i < battery->dc_step_chg_step; i++)
  868. battery->dc_step_chg_type[i] &= ~STEP_CHARGING_CONDITION_SOC;
  869. }
  870. kfree(soc_cond_temp);
  871. if (dc_step_chg_type & STEP_CHARGING_CONDITION_SOC &&
  872. dc_step_chg_type & STEP_CHARGING_CONDITION_SOC_INIT_ONLY) {
  873. pr_info("%s : do not set SOC and SOC_INIT_ONLY at the same time\n", __func__);
  874. for (i = 0; i < battery->dc_step_chg_step; i++)
  875. battery->dc_step_chg_type[i] &= ~STEP_CHARGING_CONDITION_SOC;
  876. }
  877. }
  878. }
  879. if (dc_step_chg_type & STEP_CHARGING_CONDITION_FLOAT_VOLTAGE) {
  880. p = of_get_property(np, "battery,dc_step_chg_val_vfloat", &len);
  881. if (!p) {
  882. pr_err("%s: dc_step_chg_val_vfloat is Empty, type(0x%X->0x%x)\n",
  883. __func__, dc_step_chg_type,
  884. dc_step_chg_type & ~STEP_CHARGING_CONDITION_FLOAT_VOLTAGE);
  885. for (i = 0; i < battery->dc_step_chg_step; i++)
  886. battery->dc_step_chg_type[i] &= ~STEP_CHARGING_CONDITION_FLOAT_VOLTAGE;
  887. } else {
  888. ret = of_property_read_u32(np, "battery,dc_step_chg_cond_v_margin",
  889. &battery->pdata->dc_step_chg_cond_v_margin);
  890. if (ret)
  891. battery->pdata->dc_step_chg_cond_v_margin = DIRECT_CHARGING_FLOAT_VOLTAGE_MARGIN;
  892. pr_err("%s: dc_step_chg_cond_v_margin is %d\n",
  893. __func__, battery->pdata->dc_step_chg_cond_v_margin);
  894. len = len / sizeof(u32);
  895. pr_info("%s: step(%d) * age_step(%d), dc_step_chg_val_vfloat len(%d)\n",
  896. __func__, battery->dc_step_chg_step, num_age_step, len);
  897. vfloat_temp = kcalloc(battery->dc_step_chg_step * num_age_step, sizeof(u32), GFP_KERNEL);
  898. ret = of_property_read_u32_array(np, "battery,dc_step_chg_val_vfloat",
  899. vfloat_temp, battery->dc_step_chg_step * num_age_step);
  900. /* copy buff to 2d arr */
  901. pdata->dc_step_chg_val_vfloat = kcalloc(num_age_step, sizeof(u32 *), GFP_KERNEL);
  902. for (i = 0; i < num_age_step; i++) {
  903. pdata->dc_step_chg_val_vfloat[i] =
  904. kcalloc(battery->dc_step_chg_step, sizeof(u32), GFP_KERNEL);
  905. for (j = 0; j < battery->dc_step_chg_step; j++)
  906. pdata->dc_step_chg_val_vfloat[i][j] =
  907. vfloat_temp[i*battery->dc_step_chg_step + j];
  908. }
  909. /* if there are only 1 dimentional array of value, get the same value */
  910. if (battery->dc_step_chg_step * num_age_step != len) {
  911. pr_err("%s: len of dc_step_chg_val_vfloat is not matched\n", __func__);
  912. ret = of_property_read_u32_array(np, "battery,dc_step_chg_val_vfloat",
  913. *pdata->dc_step_chg_val_vfloat, battery->dc_step_chg_step);
  914. for (i = 1; i < num_age_step; i++) {
  915. for (j = 0; j < battery->dc_step_chg_step; j++)
  916. pdata->dc_step_chg_val_vfloat[i][j] =
  917. pdata->dc_step_chg_val_vfloat[0][j];
  918. }
  919. }
  920. /* debug log */
  921. for (i = 0; i < num_age_step; i++) {
  922. memset(str, 0x0, sizeof(str));
  923. sprintf(str + strlen(str), "vfloat arr[%d]:", i);
  924. for (j = 0; j < battery->dc_step_chg_step; j++)
  925. sprintf(str + strlen(str), " %d", pdata->dc_step_chg_val_vfloat[i][j]);
  926. pr_info("%s: %s\n", __func__, str);
  927. }
  928. if (ret) {
  929. pr_info("%s : dc_step_chg_val_vfloat read fail\n", __func__);
  930. for (i = 0; i < battery->dc_step_chg_step; i++)
  931. battery->dc_step_chg_type[i] &= ~STEP_CHARGING_CONDITION_FLOAT_VOLTAGE;
  932. }
  933. kfree(vfloat_temp);
  934. pdata->dc_step_chg_vol_offset = kcalloc(battery->dc_step_chg_step, sizeof(u32), GFP_KERNEL);
  935. ret = of_property_read_u32_array(np, "battery,dc_step_chg_vol_offset",
  936. pdata->dc_step_chg_vol_offset, battery->dc_step_chg_step);
  937. if (ret) {
  938. pr_info("%s: dc_step_chg_vol_offset is empty\n", __func__);
  939. /* Fill-up use one-dimensional offset table */
  940. for (j = 0; j < battery->dc_step_chg_step; j++)
  941. if (pdata->dc_step_chg_val_vfloat[0][j] > battery->pdata->chg_float_voltage)
  942. pdata->dc_step_chg_vol_offset[j] =
  943. pdata->dc_step_chg_val_vfloat[0][j] -
  944. battery->pdata->chg_float_voltage;
  945. }
  946. memset(str, 0x0, sizeof(str));
  947. sprintf(str + strlen(str), "dc_step_chg_vol_offset arr :");
  948. for (i = 0; i < battery->dc_step_chg_step; i++)
  949. sprintf(str + strlen(str), " %d", pdata->dc_step_chg_vol_offset[i]);
  950. pr_info("%s: %s\n", __func__, str);
  951. }
  952. }
  953. p = of_get_property(np, "battery,dc_step_chg_val_iout", &len);
  954. if (!p) {
  955. pr_err("%s: dc_step_chg_val_iout is Empty\n", __func__);
  956. for (i = 0; i < battery->dc_step_chg_step; i++)
  957. battery->dc_step_chg_type[i] = 0;
  958. return -1;
  959. } else {
  960. len = len / sizeof(u32);
  961. pr_info("%s: step(%d) * age_step(%d), dc_step_chg_val_iout len(%d)\n",
  962. __func__, battery->dc_step_chg_step, num_age_step, len);
  963. iout_temp = kcalloc(battery->dc_step_chg_step * num_age_step, sizeof(u32), GFP_KERNEL);
  964. ret = of_property_read_u32_array(np, "battery,dc_step_chg_val_iout",
  965. iout_temp, battery->dc_step_chg_step * num_age_step);
  966. /* copy buff to 2d arr */
  967. pdata->dc_step_chg_val_iout = kcalloc(num_age_step, sizeof(u32 *), GFP_KERNEL);
  968. for (i = 0; i < num_age_step; i++) {
  969. pdata->dc_step_chg_val_iout[i] =
  970. kcalloc(battery->dc_step_chg_step, sizeof(u32), GFP_KERNEL);
  971. for (j = 0; j < battery->dc_step_chg_step; j++)
  972. pdata->dc_step_chg_val_iout[i][j] = iout_temp[i*battery->dc_step_chg_step + j];
  973. }
  974. /* if there are only 1 dimentional array of value, get the same value */
  975. if (battery->dc_step_chg_step * num_age_step != len) {
  976. pr_err("%s: len of dc_step_chg_val_iout is not matched\n", __func__);
  977. ret = of_property_read_u32_array(np, "battery,dc_step_chg_val_iout",
  978. *pdata->dc_step_chg_val_iout, battery->dc_step_chg_step);
  979. for (i = 1; i < num_age_step; i++) {
  980. for (j = 0; j < battery->dc_step_chg_step; j++)
  981. pdata->dc_step_chg_val_iout[i][j] = pdata->dc_step_chg_val_iout[0][j];
  982. }
  983. }
  984. /* debug log */
  985. for (i = 0; i < num_age_step; i++) {
  986. memset(str, 0x0, sizeof(str));
  987. sprintf(str + strlen(str), "iout arr[%d]:", i);
  988. for (j = 0; j < battery->dc_step_chg_step; j++)
  989. sprintf(str + strlen(str), " %d", pdata->dc_step_chg_val_iout[i][j]);
  990. pr_info("%s: %s\n", __func__, str);
  991. }
  992. if (ret) {
  993. pr_info("%s : dc_step_chg_val_iout read fail\n", __func__);
  994. }
  995. kfree(iout_temp);
  996. }
  997. if ((dc_step_chg_type & STEP_CHARGING_CONDITION_INPUT_CURRENT) ||
  998. (dc_step_chg_type & STEP_CHARGING_CONDITION_FG_CURRENT)) {
  999. p = of_get_property(np, "battery,dc_step_chg_cond_iin", &len);
  1000. if (!p) {
  1001. pr_info("%s: dc_step_chg_cond_iin is Empty, set default (Iout / 2)\n", __func__);
  1002. pdata->dc_step_chg_cond_iin =
  1003. kcalloc(battery->dc_step_chg_step, sizeof(u32), GFP_KERNEL);
  1004. for (i = 0; i < (battery->dc_step_chg_step - 1); i++) {
  1005. pdata->dc_step_chg_cond_iin[i] = pdata->dc_step_chg_val_iout[age_step][i+1] / 2;
  1006. pr_info("%s: Condition Iin [step %d] %dmA",
  1007. __func__, i, pdata->dc_step_chg_cond_iin[i]);
  1008. }
  1009. pdata->dc_step_chg_cond_iin[i] = 0;
  1010. } else {
  1011. len = len / sizeof(u32);
  1012. if (len != battery->dc_step_chg_step) {
  1013. /* [dchg] TODO: do some error handling */
  1014. pr_err("%s: len of dc_step_chg_cond_iin is not matched, len(%d/%d)\n",
  1015. __func__, len, battery->dc_step_chg_step);
  1016. }
  1017. pdata->dc_step_chg_cond_iin = kcalloc(len, sizeof(u32), GFP_KERNEL);
  1018. ret = of_property_read_u32_array(np, "battery,dc_step_chg_cond_iin",
  1019. pdata->dc_step_chg_cond_iin, len);
  1020. if (ret) {
  1021. pr_info("%s : dc_step_chg_cond_iin read fail\n", __func__);
  1022. for (i = 0; i < battery->dc_step_chg_step; i++)
  1023. battery->dc_step_chg_type[i] &= ~STEP_CHARGING_CONDITION_INPUT_CURRENT;
  1024. }
  1025. }
  1026. ret = of_property_read_u32(np, "battery,dc_step_chg_iin_check_cnt",
  1027. &battery->pdata->dc_step_chg_iin_check_cnt);
  1028. if (ret) {
  1029. pr_err("%s: dc_step_chg_iin_check_cnt is Empty\n", __func__);
  1030. battery->pdata->dc_step_chg_iin_check_cnt = 2;
  1031. } else {
  1032. pr_err("%s: dc_step_chg_iin_check_cnt is %d\n",
  1033. __func__, battery->pdata->dc_step_chg_iin_check_cnt);
  1034. }
  1035. }
  1036. // print dc step charging information
  1037. for (i = 0; i < battery->dc_step_chg_step; i++) {
  1038. memset(str, 0x0, sizeof(str));
  1039. if (battery->dc_step_chg_type[i] & STEP_CHARGING_CONDITION_VOLTAGE)
  1040. sprintf(str + strlen(str), "cond_vol: %dmV, ", pdata->dc_step_chg_cond_vol[age_step][i]);
  1041. if (battery->dc_step_chg_type[i] & STEP_CHARGING_CONDITION_SOC)
  1042. sprintf(str + strlen(str), "cond_soc: %d%%, ", pdata->dc_step_chg_cond_soc[age_step][i]);
  1043. if (battery->dc_step_chg_type[i] & STEP_CHARGING_CONDITION_INPUT_CURRENT)
  1044. sprintf(str + strlen(str), "cond_iin: %dmA, ", pdata->dc_step_chg_cond_iin[i]);
  1045. if (battery->dc_step_chg_type[i] & STEP_CHARGING_CONDITION_FLOAT_VOLTAGE)
  1046. sprintf(str + strlen(str), "vfloat: %dmV, ", pdata->dc_step_chg_val_vfloat[age_step][i]);
  1047. sprintf(str + strlen(str), "iout: %dmA,", pdata->dc_step_chg_val_iout[age_step][i]);
  1048. pr_info("%s : step [%d] %s\n", __func__, i, str);
  1049. }
  1050. return 0;
  1051. dc_step_charging_dt_error:
  1052. return -1;
  1053. } /* sec_dc_step_charging_dt */
  1054. #endif
  1055. void sec_bat_set_aging_info_step_charging(struct sec_battery_info *battery)
  1056. {
  1057. #if IS_ENABLED(CONFIG_DIRECT_CHARGING)
  1058. union power_supply_propval val;
  1059. int i = 0;
  1060. unsigned int max_fv = 0;
  1061. int float_volt;
  1062. #endif
  1063. int age_step = battery->pdata->age_step;
  1064. #if IS_ENABLED(CONFIG_DIRECT_CHARGING)
  1065. i = (battery->step_chg_status < 0 ? 0 : battery->step_chg_status);
  1066. if (!battery->dc_step_chg_type[i]) {
  1067. pr_info("%s : invalid dc step chg type\n", __func__);
  1068. return;
  1069. }
  1070. #endif
  1071. if (battery->step_chg_type) {
  1072. if (battery->step_chg_type & STEP_CHARGING_CONDITION_FLOAT_VOLTAGE)
  1073. battery->pdata->step_chg_vfloat[age_step][battery->step_chg_step-1] =
  1074. battery->pdata->chg_float_voltage;
  1075. dev_info(battery->dev, "%s: float_v(%d)\n",
  1076. __func__, battery->pdata->step_chg_vfloat[age_step][battery->step_chg_step-1]);
  1077. }
  1078. #if IS_ENABLED(CONFIG_DIRECT_CHARGING)
  1079. for (i = 0; i < battery->dc_step_chg_step; i++) {
  1080. float_volt = battery->pdata->dc_step_chg_vol_offset[i] + battery->pdata->chg_float_voltage;
  1081. if (battery->dc_step_chg_type[i] & STEP_CHARGING_CONDITION_FLOAT_VOLTAGE)
  1082. if (battery->pdata->dc_step_chg_val_vfloat[age_step][i] > float_volt)
  1083. battery->pdata->dc_step_chg_val_vfloat[age_step][i] = float_volt;
  1084. max_fv = max(max_fv, battery->pdata->dc_step_chg_val_vfloat[age_step][i]);
  1085. if (battery->dc_step_chg_type[i] & STEP_CHARGING_CONDITION_VOLTAGE)
  1086. if (battery->pdata->dc_step_chg_cond_vol[age_step][i] > float_volt)
  1087. battery->pdata->dc_step_chg_cond_vol[age_step][i] = float_volt;
  1088. }
  1089. for (i = 0; i < battery->dc_step_chg_step; i++) {
  1090. dev_info(battery->dev, "%s: cond_vol: %dmV, vfloat: %dmV, cond_iin: %dmA, iout: %dmA\n", __func__,
  1091. battery->dc_step_chg_type[i] & STEP_CHARGING_CONDITION_VOLTAGE ?
  1092. battery->pdata->dc_step_chg_cond_vol[age_step][i] : 0,
  1093. battery->dc_step_chg_type[i] & STEP_CHARGING_CONDITION_FLOAT_VOLTAGE ?
  1094. battery->pdata->dc_step_chg_val_vfloat[age_step][i] : 0,
  1095. battery->dc_step_chg_type[i] & STEP_CHARGING_CONDITION_INPUT_CURRENT ?
  1096. battery->pdata->dc_step_chg_cond_iin[i] : 0,
  1097. battery->pdata->dc_step_chg_val_iout[age_step][i]);
  1098. }
  1099. i = (battery->step_chg_status < 0 ? 0 : battery->step_chg_status);
  1100. if (battery->dc_step_chg_type[i] & STEP_CHARGING_CONDITION_FLOAT_VOLTAGE) {
  1101. val.intval = battery->pdata->dc_step_chg_val_vfloat[age_step][battery->dc_step_chg_step-1];
  1102. psy_do_property(battery->pdata->charger_name, set,
  1103. POWER_SUPPLY_EXT_PROP_DIRECT_CONSTANT_CHARGE_VOLTAGE_MAX, val);
  1104. }
  1105. sec_vote(battery->dc_fv_vote, VOTER_AGING_STEP, true, max_fv);
  1106. sec_bat_reset_step_charging(battery);
  1107. sec_bat_check_dc_step_charging(battery);
  1108. #endif
  1109. }
  1110. EXPORT_SYMBOL(sec_bat_set_aging_info_step_charging);
  1111. void sec_step_charging_dt(struct sec_battery_info *battery, struct device *dev)
  1112. {
  1113. struct device_node *np = dev->of_node;
  1114. int ret, len;
  1115. sec_battery_platform_data_t *pdata = battery->pdata;
  1116. unsigned int i = 0, j = 0;
  1117. const u32 *p;
  1118. char str[128] = {0,};
  1119. u32 *soc_cond_temp, *vfloat_temp, *curr_temp;
  1120. int num_age_step = battery->pdata->num_age_step;
  1121. battery->step_charging_skip_lcd_on = of_property_read_bool(np,
  1122. "battery,step_charging_skip_lcd_on");
  1123. battery->step_chg_en_in_factory = of_property_read_bool(np,
  1124. "battery,step_chg_en_in_factory");
  1125. ret = of_property_read_u32(np, "battery,step_chg_step",
  1126. &battery->step_chg_step);
  1127. if (ret) {
  1128. pr_err("%s: step_chg_step is Empty\n", __func__);
  1129. battery->step_chg_step = 0;
  1130. } else {
  1131. pr_err("%s: step_chg_step is %d\n",
  1132. __func__, battery->step_chg_step);
  1133. }
  1134. ret = of_property_read_u32(np, "battery,step_chg_charge_power",
  1135. &battery->step_chg_charge_power);
  1136. if (ret) {
  1137. pr_err("%s: step_chg_charge_power is Empty\n", __func__);
  1138. battery->step_chg_charge_power = 20000;
  1139. }
  1140. p = of_get_property(np, "battery,step_chg_cond", &len);
  1141. if (!p) {
  1142. battery->step_chg_step = 0;
  1143. } else {
  1144. len = len / sizeof(u32);
  1145. pr_info("%s: step(%d) * age_step(%d), step_chg_cond len(%d)\n",
  1146. __func__, battery->step_chg_step, num_age_step, len);
  1147. /* get dt to buff */
  1148. soc_cond_temp = kcalloc(battery->step_chg_step * num_age_step, sizeof(u32), GFP_KERNEL);
  1149. ret = of_property_read_u32_array(np, "battery,step_chg_cond",
  1150. soc_cond_temp, battery->step_chg_step * num_age_step);
  1151. /* copy buff to 2d arr */
  1152. pdata->step_chg_cond = kcalloc(num_age_step, sizeof(u32 *), GFP_KERNEL);
  1153. for (i = 0; i < num_age_step; i++) {
  1154. pdata->step_chg_cond[i] =
  1155. kcalloc(battery->step_chg_step, sizeof(u32), GFP_KERNEL);
  1156. for (j = 0; j < battery->step_chg_step; j++)
  1157. pdata->step_chg_cond[i][j] = soc_cond_temp[i*battery->step_chg_step + j];
  1158. }
  1159. /* if there are only 1 dimentional array of value, get the same value */
  1160. if (battery->step_chg_step * num_age_step != len) {
  1161. ret = of_property_read_u32_array(np, "battery,step_chg_cond",
  1162. *pdata->step_chg_cond, battery->step_chg_step);
  1163. for (i = 0; i < num_age_step; i++) {
  1164. for (j = 0; j < battery->step_chg_step; j++)
  1165. pdata->step_chg_cond[i][j] = pdata->step_chg_cond[0][j];
  1166. }
  1167. }
  1168. /* debug log */
  1169. for (i = 0; i < num_age_step; i++) {
  1170. memset(str, 0x0, sizeof(str));
  1171. sprintf(str + strlen(str), "step_chg_cond arr[%d]:", i);
  1172. for (j = 0; j < battery->step_chg_step; j++)
  1173. sprintf(str + strlen(str), " %d", pdata->step_chg_cond[i][j]);
  1174. pr_info("%s: %s\n", __func__, str);
  1175. }
  1176. if (ret) {
  1177. pr_info("%s : step_chg_cond read fail\n", __func__);
  1178. battery->step_chg_step = 0;
  1179. }
  1180. kfree(soc_cond_temp);
  1181. #if IS_ENABLED(CONFIG_DUAL_BATTERY)
  1182. if (battery->step_chg_type & STEP_CHARGING_CONDITION_VOLTAGE) {
  1183. /* get dt to buff */
  1184. soc_cond_temp = kcalloc(battery->step_chg_step * num_age_step, sizeof(u32), GFP_KERNEL);
  1185. ret = of_property_read_u32_array(np, "battery,step_chg_cond_sub",
  1186. soc_cond_temp, battery->step_chg_step * num_age_step);
  1187. /* copy buff to 2d arr */
  1188. pdata->step_chg_cond_sub = kcalloc(num_age_step, sizeof(u32 *), GFP_KERNEL);
  1189. for (i = 0; i < num_age_step; i++) {
  1190. pdata->step_chg_cond_sub[i] =
  1191. kcalloc(battery->step_chg_step, sizeof(u32), GFP_KERNEL);
  1192. for (j = 0; j < battery->step_chg_step; j++)
  1193. pdata->step_chg_cond_sub[i][j] = soc_cond_temp[i*battery->step_chg_step + j];
  1194. }
  1195. /* if there are only 1 dimentional array of value, get the same value */
  1196. if (battery->step_chg_step * num_age_step != len) {
  1197. ret = of_property_read_u32_array(np, "battery,step_chg_cond",
  1198. *pdata->step_chg_cond_sub, battery->step_chg_step);
  1199. for (i = 0; i < num_age_step; i++) {
  1200. for (j = 0; j < battery->step_chg_step; j++)
  1201. pdata->step_chg_cond_sub[i][j] = pdata->step_chg_cond[0][j];
  1202. }
  1203. }
  1204. /* debug log */
  1205. for (i = 0; i < num_age_step; i++) {
  1206. memset(str, 0x0, sizeof(str));
  1207. sprintf(str + strlen(str), "step_chg_cond_sub arr[%d]:", i);
  1208. for (j = 0; j < battery->step_chg_step; j++)
  1209. sprintf(str + strlen(str), " %d", pdata->step_chg_cond_sub[i][j]);
  1210. pr_info("%s: %s\n", __func__, str);
  1211. }
  1212. if (ret)
  1213. pr_info("%s : step_chg_cond_sub read fail\n", __func__);
  1214. kfree(soc_cond_temp);
  1215. }
  1216. #endif
  1217. p = of_get_property(np, "battery,step_chg_cond_curr", &len);
  1218. if (!p) {
  1219. pr_err("%s: step_chg_cond_curr is Empty\n", __func__);
  1220. } else {
  1221. len = len / sizeof(u32);
  1222. pdata->step_chg_cond_curr = kcalloc(len, sizeof(u32), GFP_KERNEL);
  1223. ret = of_property_read_u32_array(np, "battery,step_chg_cond_curr",
  1224. pdata->step_chg_cond_curr, len);
  1225. if (ret) {
  1226. pr_info("%s : step_chg_cond_curr read fail\n", __func__);
  1227. battery->step_chg_step = 0;
  1228. }
  1229. }
  1230. p = of_get_property(np, "battery,step_chg_vfloat", &len);
  1231. if (!p) {
  1232. pr_err("%s: step_chg_vfloat is Empty\n", __func__);
  1233. } else {
  1234. len = len / sizeof(u32);
  1235. pr_info("%s: step(%d) * age_step(%d), step_chg_vfloat len(%d)\n",
  1236. __func__, battery->step_chg_step, num_age_step, len);
  1237. vfloat_temp = kcalloc(battery->step_chg_step * num_age_step, sizeof(u32), GFP_KERNEL);
  1238. ret = of_property_read_u32_array(np, "battery,step_chg_vfloat",
  1239. vfloat_temp, battery->step_chg_step * num_age_step);
  1240. /* copy buff to 2d arr */
  1241. pdata->step_chg_vfloat = kcalloc(num_age_step, sizeof(u32 *), GFP_KERNEL);
  1242. for (i = 0; i < num_age_step; i++) {
  1243. pdata->step_chg_vfloat[i] =
  1244. kcalloc(battery->step_chg_step, sizeof(u32), GFP_KERNEL);
  1245. for (j = 0; j < battery->step_chg_step; j++)
  1246. pdata->step_chg_vfloat[i][j] =
  1247. vfloat_temp[i*battery->step_chg_step + j];
  1248. }
  1249. /* if there are only 1 dimentional array of value, get the same value */
  1250. if (battery->step_chg_step * num_age_step != len) {
  1251. ret = of_property_read_u32_array(np, "battery,step_chg_vfloat",
  1252. *pdata->step_chg_vfloat, battery->step_chg_step);
  1253. for (i = 1; i < num_age_step; i++) {
  1254. for (j = 0; j < battery->step_chg_step; j++)
  1255. pdata->step_chg_vfloat[i][j] = pdata->step_chg_vfloat[0][j];
  1256. }
  1257. }
  1258. /* debug log */
  1259. for (i = 0; i < num_age_step; i++) {
  1260. memset(str, 0x0, sizeof(str));
  1261. sprintf(str + strlen(str), "step_chg_vfloat arr[%d]:", i);
  1262. for (j = 0; j < battery->step_chg_step; j++)
  1263. sprintf(str + strlen(str), " %d", pdata->step_chg_vfloat[i][j]);
  1264. pr_info("%s: %s\n", __func__, str);
  1265. }
  1266. if (ret)
  1267. pr_info("%s : step_chg_vfloat read fail\n", __func__);
  1268. kfree(vfloat_temp);
  1269. }
  1270. p = of_get_property(np, "battery,step_chg_curr", &len);
  1271. if (!p) {
  1272. pr_err("%s: step_chg_curr is Empty\n", __func__);
  1273. } else {
  1274. len = len / sizeof(u32);
  1275. pr_info("%s: step(%d) * age_step(%d), step_chg_curr len(%d)\n",
  1276. __func__, battery->step_chg_step, num_age_step, len);
  1277. curr_temp = kcalloc(battery->step_chg_step * num_age_step, sizeof(u32), GFP_KERNEL);
  1278. ret = of_property_read_u32_array(np, "battery,step_chg_curr",
  1279. curr_temp, battery->step_chg_step * num_age_step);
  1280. /* copy buff to 2d arr */
  1281. pdata->step_chg_curr = kcalloc(num_age_step, sizeof(u32 *), GFP_KERNEL);
  1282. for (i = 0; i < num_age_step; i++) {
  1283. pdata->step_chg_curr[i] =
  1284. kcalloc(battery->step_chg_step, sizeof(u32), GFP_KERNEL);
  1285. for (j = 0; j < battery->step_chg_step; j++)
  1286. pdata->step_chg_curr[i][j] = curr_temp[i*battery->step_chg_step + j];
  1287. }
  1288. /* if there are only 1 dimentional array of value, get the same value */
  1289. if (battery->step_chg_step * num_age_step != len) {
  1290. ret = of_property_read_u32_array(np, "battery,step_chg_curr",
  1291. *pdata->step_chg_curr, battery->step_chg_step);
  1292. for (i = 1; i < num_age_step; i++) {
  1293. for (j = 0; j < battery->step_chg_step; j++)
  1294. pdata->step_chg_curr[i][j] = pdata->step_chg_curr[0][j];
  1295. }
  1296. }
  1297. /* debug log */
  1298. for (i = 0; i < num_age_step; i++) {
  1299. memset(str, 0x0, sizeof(str));
  1300. sprintf(str + strlen(str), "step_chg_curr arr[%d]:", i);
  1301. for (j = 0; j < battery->step_chg_step; j++)
  1302. sprintf(str + strlen(str), " %d", pdata->step_chg_curr[i][j]);
  1303. pr_info("%s: %s\n", __func__, str);
  1304. }
  1305. if (ret)
  1306. pr_info("%s : step_chg_curr read fail\n", __func__);
  1307. kfree(curr_temp);
  1308. }
  1309. p = of_get_property(np, "battery,step_chg_cond_soc", &len);
  1310. if (!p) {
  1311. pr_err("%s: step_chg_cond_soc is Empty\n", __func__);
  1312. battery->step_chg_type =
  1313. (battery->step_chg_type) & (~STEP_CHARGING_CONDITION_SOC_INIT_ONLY);
  1314. } else {
  1315. len = len / sizeof(u32);
  1316. pr_info("%s: step(%d) * age_step(%d), step_chg_soc len(%d)\n",
  1317. __func__, battery->step_chg_step, num_age_step, len);
  1318. if (battery->step_chg_step * num_age_step != len) {
  1319. pr_err("%s: mis-match len!!\n", __func__);
  1320. battery->step_chg_type =
  1321. (battery->step_chg_type) & (~STEP_CHARGING_CONDITION_SOC_INIT_ONLY);
  1322. goto err_soc;
  1323. }
  1324. curr_temp = kcalloc(battery->step_chg_step * num_age_step, sizeof(u32), GFP_KERNEL);
  1325. if (!curr_temp)
  1326. goto err_soc;
  1327. ret = of_property_read_u32_array(np, "battery,step_chg_cond_soc",
  1328. curr_temp, battery->step_chg_step * num_age_step);
  1329. if (ret) {
  1330. pr_err("%s: failed to read chg_cond_soc(ret = %d)\n", __func__, ret);
  1331. kfree(curr_temp);
  1332. battery->step_chg_type =
  1333. (battery->step_chg_type) & (~STEP_CHARGING_CONDITION_SOC_INIT_ONLY);
  1334. goto err_soc;
  1335. }
  1336. pdata->step_chg_cond_soc = kcalloc(num_age_step, sizeof(u32 *), GFP_KERNEL);
  1337. for (i = 0; i < num_age_step; i++) {
  1338. pdata->step_chg_cond_soc[i] =
  1339. kcalloc(battery->step_chg_step, sizeof(u32), GFP_KERNEL);
  1340. for (j = 0; j < battery->step_chg_step; j++)
  1341. pdata->step_chg_cond_soc[i][j] = curr_temp[i*battery->step_chg_step + j];
  1342. }
  1343. for (i = 0; i < num_age_step; i++) {
  1344. memset(str, 0x0, sizeof(str));
  1345. sprintf(str + strlen(str), "step_chg_cond_soc arr[%d]:", i);
  1346. for (j = 0; j < battery->step_chg_step; j++)
  1347. sprintf(str + strlen(str), " %d", pdata->step_chg_cond_soc[i][j]);
  1348. pr_info("%s: %s\n", __func__, str);
  1349. }
  1350. err_soc:
  1351. pr_info("%s: step_chg_soc end\n", __func__);
  1352. }
  1353. }
  1354. }
  1355. #if IS_ENABLED(CONFIG_WIRELESS_CHARGING)
  1356. void sec_wpc_step_charging_dt(struct sec_battery_info *battery, struct device *dev)
  1357. {
  1358. struct device_node *np = dev->of_node;
  1359. int ret, len;
  1360. sec_battery_platform_data_t *pdata = battery->pdata;
  1361. unsigned int i = 0, j = 0;
  1362. const u32 *p;
  1363. char str[128] = {0,};
  1364. u32 *soc_cond_temp, *vfloat_temp, *curr_temp;
  1365. int num_age_step = battery->pdata->num_age_step;
  1366. ret = of_property_read_u32(np, "battery,wpc_step_chg_step",
  1367. &battery->wpc_step_chg_step);
  1368. if (ret) {
  1369. pr_err("%s: wpc_step_chg_step is Empty\n", __func__);
  1370. battery->wpc_step_chg_step = 0;
  1371. } else {
  1372. pr_err("%s: wpc_step_chg_step is %d\n",
  1373. __func__, battery->wpc_step_chg_step);
  1374. }
  1375. ret = of_property_read_u32(np, "battery,wpc_step_chg_charge_power",
  1376. &battery->wpc_step_chg_charge_power);
  1377. if (ret) {
  1378. pr_err("%s: wpc_step_chg_charge_power is Empty\n", __func__);
  1379. battery->wpc_step_chg_charge_power = 7500;
  1380. }
  1381. p = of_get_property(np, "battery,wpc_step_chg_cond", &len);
  1382. if (!p) {
  1383. battery->wpc_step_chg_step = 0;
  1384. } else {
  1385. len = len / sizeof(u32);
  1386. pr_info("%s: step(%d) * age_step(%d), step_chg_cond len(%d)\n",
  1387. __func__, battery->wpc_step_chg_step, num_age_step, len);
  1388. /* get dt to buff */
  1389. soc_cond_temp = kcalloc(battery->wpc_step_chg_step * num_age_step, sizeof(u32), GFP_KERNEL);
  1390. ret = of_property_read_u32_array(np, "battery,wpc_step_chg_cond",
  1391. soc_cond_temp, battery->wpc_step_chg_step * num_age_step);
  1392. /* copy buff to 2d arr */
  1393. pdata->wpc_step_chg_cond = kcalloc(num_age_step, sizeof(u32 *), GFP_KERNEL);
  1394. for (i = 0; i < num_age_step; i++) {
  1395. pdata->wpc_step_chg_cond[i] =
  1396. kcalloc(battery->wpc_step_chg_step, sizeof(u32), GFP_KERNEL);
  1397. for (j = 0; j < battery->wpc_step_chg_step; j++)
  1398. pdata->wpc_step_chg_cond[i][j] = soc_cond_temp[i*battery->wpc_step_chg_step + j];
  1399. }
  1400. /* if there are only 1 dimentional array of value, get the same value */
  1401. if (battery->wpc_step_chg_step * num_age_step != len) {
  1402. ret = of_property_read_u32_array(np, "battery,wpc_step_chg_cond",
  1403. *pdata->wpc_step_chg_cond, battery->wpc_step_chg_step);
  1404. for (i = 0; i < num_age_step; i++) {
  1405. for (j = 0; j < battery->wpc_step_chg_step; j++)
  1406. pdata->wpc_step_chg_cond[i][j] = pdata->wpc_step_chg_cond[0][j];
  1407. }
  1408. }
  1409. /* debug log */
  1410. for (i = 0; i < num_age_step; i++) {
  1411. memset(str, 0x0, sizeof(str));
  1412. sprintf(str + strlen(str), "wpc_step_chg_cond arr[%d]:", i);
  1413. for (j = 0; j < battery->wpc_step_chg_step; j++)
  1414. sprintf(str + strlen(str), " %d", pdata->wpc_step_chg_cond[i][j]);
  1415. pr_info("%s: %s\n", __func__, str);
  1416. }
  1417. if (ret) {
  1418. pr_info("%s : wpc_step_chg_cond read fail\n", __func__);
  1419. battery->wpc_step_chg_step = 0;
  1420. }
  1421. kfree(soc_cond_temp);
  1422. p = of_get_property(np, "battery,wpc_step_chg_cond_curr", &len);
  1423. if (!p) {
  1424. pr_err("%s: wpc_step_chg_cond_curr is Empty\n", __func__);
  1425. } else {
  1426. len = len / sizeof(u32);
  1427. pdata->wpc_step_chg_cond_curr = kcalloc(len, sizeof(u32), GFP_KERNEL);
  1428. ret = of_property_read_u32_array(np, "battery,wpc_step_chg_cond_curr",
  1429. pdata->wpc_step_chg_cond_curr, len);
  1430. if (ret) {
  1431. pr_info("%s : wpc_step_chg_cond_curr read fail\n", __func__);
  1432. battery->wpc_step_chg_step = 0;
  1433. }
  1434. }
  1435. p = of_get_property(np, "battery,wpc_step_chg_vfloat", &len);
  1436. if (!p) {
  1437. pr_err("%s: wpc_step_chg_vfloat is Empty\n", __func__);
  1438. } else {
  1439. len = len / sizeof(u32);
  1440. pr_info("%s: step(%d) * age_step(%d), wpc_step_chg_vfloat len(%d)\n",
  1441. __func__, battery->wpc_step_chg_step, num_age_step, len);
  1442. vfloat_temp = kcalloc(battery->wpc_step_chg_step * num_age_step, sizeof(u32), GFP_KERNEL);
  1443. ret = of_property_read_u32_array(np, "battery,wpc_step_chg_vfloat",
  1444. vfloat_temp, battery->wpc_step_chg_step * num_age_step);
  1445. /* copy buff to 2d arr */
  1446. pdata->wpc_step_chg_vfloat = kcalloc(num_age_step, sizeof(u32 *), GFP_KERNEL);
  1447. for (i = 0; i < num_age_step; i++) {
  1448. pdata->wpc_step_chg_vfloat[i] =
  1449. kcalloc(battery->wpc_step_chg_step, sizeof(u32), GFP_KERNEL);
  1450. for (j = 0; j < battery->wpc_step_chg_step; j++)
  1451. pdata->wpc_step_chg_vfloat[i][j] =
  1452. vfloat_temp[i*battery->wpc_step_chg_step + j];
  1453. }
  1454. /* if there are only 1 dimentional array of value, get the same value */
  1455. if (battery->wpc_step_chg_step * num_age_step != len) {
  1456. ret = of_property_read_u32_array(np, "battery,wpc_step_chg_vfloat",
  1457. *pdata->wpc_step_chg_vfloat, battery->wpc_step_chg_step);
  1458. for (i = 1; i < num_age_step; i++) {
  1459. for (j = 0; j < battery->wpc_step_chg_step; j++)
  1460. pdata->wpc_step_chg_vfloat[i][j] = pdata->wpc_step_chg_vfloat[0][j];
  1461. }
  1462. }
  1463. /* debug log */
  1464. for (i = 0; i < num_age_step; i++) {
  1465. memset(str, 0x0, sizeof(str));
  1466. sprintf(str + strlen(str), "wpc_step_chg_vfloat arr[%d]:", i);
  1467. for (j = 0; j < battery->wpc_step_chg_step; j++)
  1468. sprintf(str + strlen(str), " %d", pdata->wpc_step_chg_vfloat[i][j]);
  1469. pr_info("%s: %s\n", __func__, str);
  1470. }
  1471. if (ret)
  1472. pr_info("%s : wpc_step_chg_vfloat read fail\n", __func__);
  1473. kfree(vfloat_temp);
  1474. }
  1475. p = of_get_property(np, "battery,wpc_step_chg_curr", &len);
  1476. if (!p) {
  1477. pr_err("%s: wpc_step_chg_curr is Empty\n", __func__);
  1478. } else {
  1479. len = len / sizeof(u32);
  1480. pr_info("%s: step(%d) * age_step(%d), wpc_step_chg_curr len(%d)\n",
  1481. __func__, battery->wpc_step_chg_step, num_age_step, len);
  1482. curr_temp = kcalloc(battery->wpc_step_chg_step * num_age_step, sizeof(u32), GFP_KERNEL);
  1483. ret = of_property_read_u32_array(np, "battery,wpc_step_chg_curr",
  1484. curr_temp, battery->wpc_step_chg_step * num_age_step);
  1485. /* copy buff to 2d arr */
  1486. pdata->wpc_step_chg_curr = kcalloc(num_age_step, sizeof(u32 *), GFP_KERNEL);
  1487. for (i = 0; i < num_age_step; i++) {
  1488. pdata->wpc_step_chg_curr[i] =
  1489. kcalloc(battery->wpc_step_chg_step, sizeof(u32), GFP_KERNEL);
  1490. for (j = 0; j < battery->wpc_step_chg_step; j++)
  1491. pdata->wpc_step_chg_curr[i][j] = curr_temp[i*battery->wpc_step_chg_step + j];
  1492. }
  1493. /* if there are only 1 dimentional array of value, get the same value */
  1494. if (battery->wpc_step_chg_step * num_age_step != len) {
  1495. ret = of_property_read_u32_array(np, "battery,wpc_step_chg_curr",
  1496. *pdata->wpc_step_chg_curr, battery->wpc_step_chg_step);
  1497. for (i = 1; i < num_age_step; i++) {
  1498. for (j = 0; j < battery->wpc_step_chg_step; j++)
  1499. pdata->wpc_step_chg_curr[i][j] = pdata->wpc_step_chg_curr[0][j];
  1500. }
  1501. }
  1502. /* debug log */
  1503. for (i = 0; i < num_age_step; i++) {
  1504. memset(str, 0x0, sizeof(str));
  1505. sprintf(str + strlen(str), "wpc_step_chg_curr arr[%d]:", i);
  1506. for (j = 0; j < battery->wpc_step_chg_step; j++)
  1507. sprintf(str + strlen(str), " %d", pdata->wpc_step_chg_curr[i][j]);
  1508. pr_info("%s: %s\n", __func__, str);
  1509. }
  1510. if (ret)
  1511. pr_info("%s : wpc_step_chg_curr read fail\n", __func__);
  1512. kfree(curr_temp);
  1513. }
  1514. }
  1515. }
  1516. #endif
  1517. void sec_step_charging_init(struct sec_battery_info *battery, struct device *dev)
  1518. {
  1519. struct device_node *np = dev->of_node;
  1520. int ret;
  1521. battery->step_chg_status = -1;
  1522. ret = of_property_read_u32(np, "battery,step_chg_type",
  1523. &battery->step_chg_type);
  1524. pr_err("%s: step_chg_type 0x%x\n", __func__, battery->step_chg_type);
  1525. if (ret) {
  1526. pr_err("%s: step_chg_type is Empty\n", __func__);
  1527. battery->step_chg_type = 0;
  1528. }
  1529. if (battery->step_chg_type)
  1530. sec_step_charging_dt(battery, dev);
  1531. #if IS_ENABLED(CONFIG_WIRELESS_CHARGING)
  1532. ret = of_property_read_u32(np, "battery,wpc_step_chg_type",
  1533. &battery->wpc_step_chg_type);
  1534. pr_err("%s: wpc_step_chg_type 0x%x\n", __func__, battery->wpc_step_chg_type);
  1535. if (ret) {
  1536. pr_err("%s: wpc_step_chg_type is Empty\n", __func__);
  1537. battery->wpc_step_chg_type = 0;
  1538. }
  1539. if (battery->wpc_step_chg_type)
  1540. sec_wpc_step_charging_dt(battery, dev);
  1541. #endif
  1542. #if IS_ENABLED(CONFIG_DIRECT_CHARGING)
  1543. sec_dc_step_charging_dt(battery, dev);
  1544. #endif
  1545. }
  1546. EXPORT_SYMBOL(sec_step_charging_init);