max17048_fuelgauge.c 24 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036
  1. /*
  2. * max17048_fuelgauge.c
  3. * Samsung MAX17048 Fuel Gauge Driver
  4. *
  5. * Copyright (C) 2012 Samsung Electronics
  6. *
  7. *
  8. * This software is licensed under the terms of the GNU General Public
  9. * License version 2, as published by the Free Software Foundation, and
  10. * may be copied, distributed, and modified under those terms.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. */
  18. #include <linux/battery/sec_fuelgauge.h>
  19. extern int poweroff_charging;
  20. #if defined(CONFIG_SEC_K_PROJECT)
  21. u16 model_data_active_1[8] = {
  22. 0xAB40, 0xB640, 0xBAF0, 0xBC90,
  23. 0xBD00, 0xBE10, 0xBF40, 0xC230
  24. };
  25. u16 model_data_active_2[8] = {
  26. 0xC570, 0xC850, 0xCAB0, 0xCD20,
  27. 0xD110, 0xD510, 0xD6C0, 0xDA00
  28. };
  29. u16 model_data_active_3[8] = {
  30. 0x01C0, 0x19C0, 0x22E0, 0x7700,
  31. 0x3320, 0x3CC0, 0x1900, 0x0E20
  32. };
  33. u16 model_data_active_4[8] = {
  34. 0x1380, 0x1240, 0x1200, 0x0D40,
  35. 0x0D20, 0x0440, 0x10E0, 0x10E0
  36. };
  37. u16 model_rcomp_seg[8] = {0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080};
  38. #elif defined(CONFIG_SEC_S_PROJECT)
  39. u16 model_data_active_1[8] = {
  40. 0xA4F0, 0xB7A0, 0xB810, 0xB870,
  41. 0xBB20, 0xBB90, 0xBCA0, 0xBDF0
  42. };
  43. u16 model_data_active_2[8] = {
  44. 0xC010, 0xC330, 0xC610, 0xC930,
  45. 0xCCE0, 0xCFE0, 0xD320, 0xD9D0
  46. };
  47. u16 model_data_active_3[8] = {
  48. 0x0170, 0x44F0, 0x5940, 0x1200,
  49. 0x2320, 0x5180, 0x3DF0, 0x26D0
  50. };
  51. u16 model_data_active_4[8] = {
  52. 0x0FF0, 0x17E0, 0x10F0, 0x0F10,
  53. 0x0E00, 0x0E20, 0x0C00, 0x0C00
  54. };
  55. u16 model_rcomp_seg[8] = {0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080};
  56. #endif
  57. #if 0
  58. static int max17048_write_reg(struct i2c_client *client, int reg, u8 value)
  59. {
  60. int ret;
  61. ret = i2c_smbus_write_byte_data(client, reg, value);
  62. if (ret < 0)
  63. dev_err(&client->dev, "%s: err %d\n", __func__, ret);
  64. return ret;
  65. }
  66. static int max17048_read_reg(struct i2c_client *client, int reg)
  67. {
  68. int ret;
  69. ret = i2c_smbus_read_byte_data(client, reg);
  70. if (ret < 0)
  71. dev_err(&client->dev, "%s: err %d\n", __func__, ret);
  72. return ret;
  73. }
  74. #endif
  75. static int max17048_write_word(struct i2c_client *client, int reg, u16 buf)
  76. {
  77. int ret;
  78. ret = i2c_smbus_write_word_data(client, reg, buf);
  79. if (ret < 0)
  80. dev_err(&client->dev, "%s: err %d\n", __func__, ret);
  81. return ret;
  82. }
  83. static int max17048_read_word(struct i2c_client *client, int reg)
  84. {
  85. int ret;
  86. ret = i2c_smbus_read_word_data(client, reg);
  87. if (ret < 0)
  88. dev_err(&client->dev, "%s: err %d\n", __func__, ret);
  89. return ret;
  90. }
  91. static void max17048_reset(struct i2c_client *client)
  92. {
  93. u16 reset_cmd;
  94. reset_cmd = swab16(0x4000);
  95. i2c_smbus_write_word_data(client, MAX17048_MODE_MSB, reset_cmd);
  96. msleep(300);
  97. }
  98. #if defined(CONFIG_SEC_K_PROJECT) || defined(CONFIG_SEC_S_PROJECT)
  99. static bool max17048_set_modeldata(struct i2c_client *client)
  100. {
  101. int temp, i = 0;
  102. u16 data;
  103. u16 read_ocv = 0;
  104. u8 read_soc[2] = {0, 0};
  105. u8 config[2];
  106. u32 addr;
  107. union power_supply_propval value;
  108. struct sec_fuelgauge_info *fuelgauge =
  109. i2c_get_clientdata(client);
  110. do {
  111. /* 1. Unlock Model Access */
  112. addr = 0x3E;
  113. data = 0x4A57; /* Send 0x4A, and then send 0x57*/
  114. max17048_write_word(client, addr, swab16(data));
  115. /* 2. Read Config and OCV */
  116. addr = 0x0C;
  117. temp = max17048_read_word(client, addr);
  118. config[1] = temp & 0xff;
  119. config[0] = (temp & 0xff00) >> 8;
  120. pr_info("%s : fuelguage : OriginalRCOMP = 0x%x, OriginalAlert = 0x%x\n",
  121. __func__, config[1], config[0]);
  122. addr = 0x0E;
  123. read_ocv = max17048_read_word(client, addr);
  124. pr_info("%s : fuelguage : OCV_DATA = 0x%4x\n", __func__, read_ocv);
  125. /* 2-5. Verify Model Access unlocked */
  126. } while((read_ocv == 0xFFFF) && (i++ < 10));
  127. /* 3. Write OCV */
  128. /* 4. Write RCOMP to a Maximum value of 0xFF00 */
  129. /* 5. Write the Model */
  130. /* Once the model is unlocked, the host s/w must write 64 bytes model to the max17048.
  131. * The model is located between locations 0x40 ~ 0x7F. */
  132. for (i=0; i<8; i++) {
  133. addr = 0x40 + i*2;
  134. max17048_write_word(client, addr, swab16(model_data_active_1[i]));
  135. }
  136. for (i=0; i<8; i++) {
  137. addr = 0x50 + i*2;
  138. max17048_write_word(client, addr, swab16(model_data_active_2[i]));
  139. }
  140. for (i=0; i<8; i++) {
  141. addr = 0x60 + i*2;
  142. max17048_write_word(client, addr, swab16(model_data_active_3[i]));
  143. }
  144. for (i=0; i<8; i++) {
  145. addr = 0x70 + i*2;
  146. max17048_write_word(client, addr, swab16(model_data_active_4[i]));
  147. }
  148. /*overwrite RCOMP Seg to default values*/
  149. for (i=0; i<8; i++) {
  150. addr = 0x80 + i*2;
  151. max17048_write_word(client, addr, swab16(model_rcomp_seg[i]));
  152. }
  153. for (i=0; i<8; i++) {
  154. addr = 0x90 + i*2;
  155. max17048_write_word(client, addr, swab16(model_rcomp_seg[i]));
  156. }
  157. /* 6. Delay at least 150msec */
  158. /* 7. Write OCV */
  159. addr = 0x0E;
  160. #if defined(CONFIG_SEC_K_PROJECT)
  161. data = 0xE400;
  162. #elif defined(CONFIG_SEC_S_PROJECT)
  163. data = 0xE3D0;
  164. #endif
  165. max17048_write_word(client, addr, swab16(data));
  166. /* 7-1. Disable Hibernation */
  167. addr = 0x0A;
  168. data = 0x0000;
  169. max17048_write_word(client, addr, swab16(data));
  170. /* 7-2. Lock Model Acess */
  171. addr = 0x3E;
  172. data = 0x0000;
  173. max17048_write_word(client, addr, swab16(data));
  174. /* 8. Delay between 150msec and 600msec */
  175. /* This delay must be between 150msec and 600msec.
  176. * Delaying beyond 600msec could cause the verification to fail. */
  177. mdelay(200);
  178. /* 9. Read SOC Register and Compare to expected result */
  179. addr = 0x04;
  180. temp = max17048_read_word(client, addr);
  181. read_soc[1] = temp & 0xff;
  182. read_soc[0] = (temp & 0xff00) >> 8;
  183. pr_info("%s : reg = 0x%4x, SOC_DATA1 = 0x%x, SOC_DATA2 = 0x%x\n",
  184. __func__, temp, read_soc[1], read_soc[0]);
  185. #if defined(CONFIG_SEC_K_PROJECT)
  186. if ((read_soc[1] >= 0xF2) && (read_soc[1] <= 0xF4)) {
  187. #elif defined(CONFIG_SEC_S_PROJECT)
  188. if ((read_soc[1] >= 0xE4) && (read_soc[1] <= 0xE6)) {
  189. #endif
  190. pr_info("%s : model was loaded successful\n", __func__);
  191. } else {
  192. pr_err("%s : error! model was not loaded successful\n", __func__);
  193. return false;
  194. }
  195. /* 9-1. Unlock Model Access */
  196. addr = 0x3E;
  197. data = 0x4A57;
  198. max17048_write_word(client, addr, swab16(data));
  199. /* 10. Restore CONFIG and OCV */
  200. addr = 0x0C;
  201. psy_do_property("battery", get,
  202. POWER_SUPPLY_PROP_STATUS, value);
  203. if (value.intval == POWER_SUPPLY_STATUS_CHARGING) /* in charging */
  204. config[1] = get_battery_data(fuelgauge).RCOMP_charging;
  205. else
  206. config[1] = get_battery_data(fuelgauge).RCOMP0;
  207. data = (0x1C | (config[1] & 0xff) << 8);
  208. pr_info("%s : RCOMP(0x%4x) is applied\n", __func__, data);
  209. max17048_write_word(client, addr, swab16(data));
  210. addr = 0x0E;
  211. max17048_write_word(client, addr, swab16(read_ocv));
  212. read_ocv = 0;
  213. read_ocv = max17048_read_word(client, addr);
  214. pr_info("%s : OCV_DATA = 0x%4x\n", __func__, read_ocv);
  215. /* 11. Lock Model Acess */
  216. addr = 0x3E;
  217. data = 0x0000;
  218. max17048_write_word(client, addr, swab16(data));
  219. /* 11-1. Delay at least 150msec */
  220. mdelay(200);
  221. /* 12. Set Voltage Detector threshold */
  222. addr = 0x18;
  223. data = 0x7D7D;
  224. max17048_write_word(client, addr, swab16(data));
  225. /* 13. Set hibernation*/
  226. addr = 0x0A;
  227. data = 0x0000;
  228. max17048_write_word(client, addr, swab16(data));
  229. /* 14. Set vart */
  230. addr = 0x14;
  231. data = 0x00FF;
  232. max17048_write_word(client, addr, swab16(data));
  233. /* 15. Set Vreset */
  234. addr = 0x18;
  235. data = 0x7D7D;
  236. max17048_write_word(client, addr, swab16(data));
  237. pr_info("%s : load model data complete!\n", __func__);
  238. return true;
  239. }
  240. #endif
  241. static int max17048_get_vcell(struct i2c_client *client)
  242. {
  243. u32 vcell;
  244. u16 w_data;
  245. u32 temp;
  246. temp = max17048_read_word(client, MAX17048_VCELL_MSB);
  247. w_data = swab16(temp);
  248. temp = ((w_data & 0xFFF0) >> 4) * 1250;
  249. vcell = temp / 1000;
  250. dev_dbg(&client->dev,
  251. "%s : vcell (%d)\n", __func__, vcell);
  252. return vcell;
  253. }
  254. static int max17048_get_avg_vcell(struct i2c_client *client)
  255. {
  256. u32 vcell_data = 0;
  257. u32 vcell_max = 0;
  258. u32 vcell_min = 0;
  259. u32 vcell_total = 0;
  260. u32 i;
  261. for (i = 0; i < AVER_SAMPLE_CNT; i++) {
  262. vcell_data = max17048_get_vcell(client);
  263. if (i != 0) {
  264. if (vcell_data > vcell_max)
  265. vcell_max = vcell_data;
  266. else if (vcell_data < vcell_min)
  267. vcell_min = vcell_data;
  268. } else {
  269. vcell_max = vcell_data;
  270. vcell_min = vcell_data;
  271. }
  272. vcell_total += vcell_data;
  273. }
  274. return (vcell_total - vcell_max - vcell_min) / (AVER_SAMPLE_CNT-2);
  275. }
  276. static int max17048_get_ocv(struct i2c_client *client)
  277. {
  278. /*
  279. u32 ocv;
  280. u16 w_data;
  281. u32 temp;
  282. u16 cmd;
  283. cmd = swab16(0x4A57);
  284. max17048_write_word(client, 0x3E, cmd);
  285. temp = max17048_read_word(client, MAX17048_OCV_MSB);
  286. w_data = swab16(temp);
  287. temp = ((w_data & 0xFFF0) >> 4) * 1250;
  288. ocv = temp / 1000;
  289. cmd = swab16(0x0000);
  290. max17048_write_word(client, 0x3E, cmd);
  291. dev_dbg(&client->dev,
  292. "%s : ocv (%d)\n", __func__, ocv);
  293. return ocv;
  294. */
  295. return 1;
  296. }
  297. /* soc should be 0.01% unit */
  298. static int max17048_get_soc(struct i2c_client *client)
  299. {
  300. struct sec_fuelgauge_info *fuelgauge =
  301. i2c_get_clientdata(client);
  302. u8 data[2] = {0, 0};
  303. int temp, soc;
  304. u64 psoc64 = 0;
  305. u64 temp64;
  306. u32 divisor = 10000000;
  307. temp = max17048_read_word(client, MAX17048_SOC_MSB);
  308. if (get_battery_data(fuelgauge).is_using_model_data) {
  309. /* [ TempSOC = ((SOC1 * 256) + SOC2) * 0.001953125 ] */
  310. temp64 = swab16(temp);
  311. psoc64 = temp64 * 1953125;
  312. psoc64 = div_u64(psoc64, divisor);
  313. soc = psoc64 & 0xffff;
  314. } else {
  315. data[0] = temp & 0xff;
  316. data[1] = (temp & 0xff00) >> 8;
  317. soc = (data[0] * 100) + (data[1] * 100 / 256);
  318. }
  319. dev_info(&client->dev,
  320. "%s : raw capacity (%d), data(0x%04x)\n",
  321. __func__, soc, (data[0]<<8) | data[1]);
  322. return soc;
  323. }
  324. static int max17048_get_current(struct i2c_client *client)
  325. {
  326. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  327. union power_supply_propval value;
  328. psy_do_property(fuelgauge->pdata->charger_name, get,
  329. POWER_SUPPLY_PROP_CURRENT_NOW, value);
  330. return value.intval;
  331. }
  332. #define DISCHARGE_SAMPLE_CNT 20
  333. static int discharge_cnt=0;
  334. static int all_vcell[20] = {0,};
  335. /* if ret < 0, discharge */
  336. static int sec_bat_check_discharge(int vcell)
  337. {
  338. int i, cnt, ret = 0;
  339. all_vcell[discharge_cnt++] = vcell;
  340. if (discharge_cnt >= DISCHARGE_SAMPLE_CNT)
  341. discharge_cnt = 0;
  342. cnt = discharge_cnt;
  343. /* check after last value is set */
  344. if (all_vcell[cnt] == 0)
  345. return 0;
  346. for (i = 0; i < DISCHARGE_SAMPLE_CNT; i++) {
  347. if (cnt == i)
  348. continue;
  349. if (all_vcell[cnt] > all_vcell[i])
  350. ret--;
  351. else
  352. ret++;
  353. }
  354. return ret;
  355. }
  356. /* judge power off or not by current_avg */
  357. static int max17048_get_current_average(struct i2c_client *client)
  358. {
  359. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  360. union power_supply_propval value_bat;
  361. union power_supply_propval value_chg;
  362. int vcell, soc, curr_avg;
  363. int check_discharge;
  364. psy_do_property(fuelgauge->pdata->charger_name, get,
  365. POWER_SUPPLY_PROP_CURRENT_NOW, value_chg);
  366. psy_do_property("battery", get,
  367. POWER_SUPPLY_PROP_HEALTH, value_bat);
  368. vcell = max17048_get_vcell(client);
  369. soc = max17048_get_soc(client) / 100;
  370. check_discharge = sec_bat_check_discharge(vcell);
  371. /* if 0% && under 3.4v && low power charging(1000mA), power off */
  372. if (!poweroff_charging && (soc <= 0) && (vcell < 3400) &&
  373. (check_discharge < 0) &&
  374. ((value_chg.intval < 1000) ||
  375. ((value_bat.intval == POWER_SUPPLY_HEALTH_OVERHEAT) ||
  376. (value_bat.intval == POWER_SUPPLY_HEALTH_COLD)))) {
  377. pr_info("%s: SOC(%d), Vnow(%d), Inow(%d)\n",
  378. __func__, soc, vcell, value_chg.intval);
  379. curr_avg = -1;
  380. } else {
  381. curr_avg = value_chg.intval;
  382. }
  383. return curr_avg;
  384. }
  385. void sec_bat_reset_discharge(struct i2c_client *client)
  386. {
  387. int i;
  388. for (i = 0; i < DISCHARGE_SAMPLE_CNT ; i++)
  389. all_vcell[i] = 0;
  390. discharge_cnt = 0;
  391. }
  392. static void max17048_get_version(struct i2c_client *client)
  393. {
  394. u16 w_data;
  395. int temp;
  396. temp = max17048_read_word(client, MAX17048_VER_MSB);
  397. w_data = swab16(temp);
  398. dev_info(&client->dev,
  399. "MAX17048 Fuel-Gauge Ver 0x%04x\n", w_data);
  400. }
  401. #if defined(CONFIG_SEC_K_PROJECT) || defined(CONFIG_SEC_S_PROJECT)
  402. static bool max17048_check_fg_validity(struct i2c_client *client)
  403. {
  404. int temp;
  405. u8 data;
  406. u16 w_data = 0;
  407. /* check status register Reset indicator bit*/
  408. temp = max17048_read_word(client, 0x1A);
  409. data = temp & 0xff;
  410. if (0/* data & 0x01 */) {
  411. dev_err(&client->dev,
  412. "%s : IC is not configured. init modeldata reg(0x%x)\n", __func__, data);
  413. if (!max17048_set_modeldata(client)) {
  414. dev_err(&client->dev,
  415. "%s : fail to set modeldata\n", __func__);
  416. return false;
  417. }
  418. w_data = data & 0xfe;
  419. max17048_write_word(client, 0x1A, swab16(w_data));
  420. }
  421. return true;
  422. }
  423. #endif
  424. static u16 max17048_get_rcomp(struct i2c_client *client)
  425. {
  426. u16 w_data;
  427. int temp;
  428. temp = max17048_read_word(client, MAX17048_RCOMP_MSB);
  429. w_data = swab16(temp);
  430. dev_dbg(&client->dev,
  431. "%s : current rcomp = 0x%04x\n",
  432. __func__, w_data);
  433. return w_data;
  434. }
  435. static void max17048_set_rcomp(struct i2c_client *client, u16 new_rcomp)
  436. {
  437. i2c_smbus_write_word_data(client,
  438. MAX17048_RCOMP_MSB, swab16(new_rcomp));
  439. }
  440. static void max17048_rcomp_update(struct i2c_client *client, int temp)
  441. {
  442. struct sec_fuelgauge_info *fuelgauge =
  443. i2c_get_clientdata(client);
  444. union power_supply_propval value;
  445. int starting_rcomp = 0;
  446. int new_rcomp = 0;
  447. int rcomp_current = 0;
  448. rcomp_current = max17048_get_rcomp(client);
  449. psy_do_property("battery", get,
  450. POWER_SUPPLY_PROP_STATUS, value);
  451. if (value.intval == POWER_SUPPLY_STATUS_CHARGING) /* in charging */
  452. starting_rcomp = get_battery_data(fuelgauge).RCOMP_charging;
  453. else
  454. starting_rcomp = get_battery_data(fuelgauge).RCOMP0;
  455. if (temp > RCOMP0_TEMP)
  456. new_rcomp = starting_rcomp + ((temp - RCOMP0_TEMP) *
  457. get_battery_data(fuelgauge).temp_cohot / 1000);
  458. else if (temp < RCOMP0_TEMP)
  459. new_rcomp = starting_rcomp + ((temp - RCOMP0_TEMP) *
  460. get_battery_data(fuelgauge).temp_cocold / 1000);
  461. else
  462. new_rcomp = starting_rcomp;
  463. if (new_rcomp > 255)
  464. new_rcomp = 255;
  465. else if (new_rcomp < 0)
  466. new_rcomp = 0;
  467. new_rcomp <<= 8;
  468. new_rcomp &= 0xff00;
  469. /* not related to RCOMP */
  470. new_rcomp |= (rcomp_current & 0xff);
  471. if (rcomp_current != new_rcomp) {
  472. dev_dbg(&client->dev,
  473. "%s : RCOMP 0x%04x -> 0x%04x (0x%02x)\n",
  474. __func__, rcomp_current, new_rcomp,
  475. new_rcomp >> 8);
  476. max17048_set_rcomp(client, new_rcomp);
  477. }
  478. }
  479. #ifdef CONFIG_OF
  480. #if 0
  481. static int max17048_parse_dt(struct device *dev,
  482. struct sec_fuelgauge_info *fuelgauge)
  483. {
  484. struct device_node *np = dev->of_node;
  485. int ret;
  486. int value;
  487. if (np == NULL) {
  488. pr_err("%s np NULL\n", __func__);
  489. } else {
  490. ret = of_property_read_u32(np, "fuelgauge,rcomp0",
  491. &value);
  492. pr_err("%s value %d\n",
  493. __func__, value);
  494. get_battery_data(fuelgauge).RCOMP0 = (u8)value;
  495. if (ret < 0)
  496. pr_err("%s error reading rcomp0 %d\n",
  497. __func__, ret);
  498. ret = of_property_read_u32(np, "fuelgauge,rcomp_charging",
  499. &value);
  500. pr_err("%s value %d\n",
  501. __func__, value);
  502. get_battery_data(fuelgauge).RCOMP_charging = (u8)value;
  503. if (ret < 0)
  504. pr_err("%s error reading rcomp_charging %d\n",
  505. __func__, ret);
  506. ret = of_property_read_u32(np, "fuelgauge,temp_cohot",
  507. &get_battery_data(fuelgauge).temp_cohot);
  508. if (ret < 0)
  509. pr_err("%s error reading temp_cohot %d\n",
  510. __func__, ret);
  511. ret = of_property_read_u32(np, "fuelgauge,temp_cocold",
  512. &get_battery_data(fuelgauge).temp_cocold);
  513. if (ret < 0)
  514. pr_err("%s error reading temp_cocold %d\n",
  515. __func__, ret);
  516. get_battery_data(fuelgauge).is_using_model_data = of_property_read_bool(np,
  517. "fuelgauge,is_using_model_data");
  518. ret = of_property_read_string(np, "fuelgauge,type_str",
  519. (const char **)&get_battery_data(fuelgauge).type_str);
  520. if (ret < 0)
  521. pr_err("%s error reading temp_cocold %d\n",
  522. __func__, ret);
  523. pr_info("%s RCOMP0: 0x%x, RCOMP_charging: 0x%x, temp_cohot: %d,"
  524. "temp_cocold: %d, is_using_model_data: %d, "
  525. "type_str: %s,\n", __func__,
  526. get_battery_data(fuelgauge).RCOMP0,
  527. get_battery_data(fuelgauge).RCOMP_charging,
  528. get_battery_data(fuelgauge).temp_cohot,
  529. get_battery_data(fuelgauge).temp_cocold,
  530. get_battery_data(fuelgauge).is_using_model_data,
  531. get_battery_data(fuelgauge).type_str
  532. );
  533. }
  534. return 0;
  535. }
  536. #endif
  537. #endif
  538. static void fg_read_regs(struct i2c_client *client, char *str)
  539. {
  540. int data = 0;
  541. u32 addr = 0;
  542. for (addr = 0x02; addr <= 0x04; addr += 2) {
  543. data = max17048_read_word(client, addr);
  544. sprintf(str + strlen(str), "0x%04x, ", data);
  545. }
  546. /* "#" considered as new line in application */
  547. sprintf(str+strlen(str), "#");
  548. for (addr = 0x08; addr <= 0x1a; addr += 2) {
  549. data = max17048_read_word(client, addr);
  550. sprintf(str + strlen(str), "0x%04x, ", data);
  551. }
  552. }
  553. /* read all the register */
  554. static void fg_read_all_regs(struct i2c_client *client)
  555. {
  556. int data = 0;
  557. u32 addr = 0;
  558. u8 addr1;
  559. u16 data1;
  560. u8 data2[2] = {0, 0};
  561. int i = 0;
  562. char *str = kzalloc(sizeof(char)*2048, GFP_KERNEL);
  563. int count = 0;
  564. addr1 = 0x3E;
  565. data1 = 0x4A57;
  566. max17048_write_word(client, addr1, swab16(data1));
  567. for (addr = 0x02; addr <= 0x1A; addr += 2) {
  568. count++;
  569. data = max17048_read_word(client, addr);
  570. data2[0] = data & 0xff;
  571. data2[1] = (data & 0xff00) >> 8;
  572. for (i = 0; i < 2; i++) {
  573. sprintf(str + strlen(str), "0x%02x(0x%02x), ", addr+i, data2[i]);
  574. }
  575. if((count % 7) == 0)
  576. sprintf(str+strlen(str), "\n");
  577. }
  578. dev_info(&client->dev, "%s\n", str);
  579. str[0] = '\0';
  580. count = 0;
  581. for (addr = 0x40; addr <= 0x7F; addr += 2) {
  582. count++;
  583. data = max17048_read_word(client, addr);
  584. data2[0] = data & 0xff;
  585. data2[1] = (data & 0xff00) >> 8;
  586. for (i = 0; i < 2; i++) {
  587. sprintf(str + strlen(str), "0x%02x(0x%02x), ", addr+i, data2[i]);
  588. }
  589. if((count % 7) == 0)
  590. sprintf(str+strlen(str), "\n");
  591. }
  592. dev_info(&client->dev, "%s\n", str);
  593. str[0] = '\0';
  594. count = 0;
  595. for (addr = 0x80; addr <= 0x9F; addr += 2) {
  596. count++;
  597. data = max17048_read_word(client, addr);
  598. data2[0] = data & 0xff;
  599. data2[1] = (data & 0xff00) >> 8;
  600. for (i = 0; i < 2; i++) {
  601. sprintf(str + strlen(str), "0x%02x(0x%02x), ", addr+i, data2[i]);
  602. }
  603. if((count % 7) == 0)
  604. sprintf(str+strlen(str), "\n");
  605. }
  606. str[strlen(str)] = '\0';
  607. dev_info(&client->dev, "%s\n", str);
  608. addr1 = 0x3E;
  609. data1 = 0x0000;
  610. max17048_write_word(client, addr1, swab16(data1));
  611. kfree(str);
  612. }
  613. /* read the specific address */
  614. #if 0
  615. static void fg_read_address(struct i2c_client *client)
  616. {
  617. int data = 0;
  618. u32 addr = 0;
  619. u8 data1[2] = {0, 0};
  620. int i = 0;
  621. char str[512] = {0,};
  622. int count = 0;
  623. for (addr = 0x02; addr <= 0x0d; addr += 2) {
  624. count++;
  625. data = max17048_read_word(client, addr);
  626. data1[0] = data & 0xff;
  627. data1[1] = (data & 0xff00) >> 8;
  628. for (i = 0; i < 2; i++) {
  629. sprintf(str + strlen(str), "0x%02x(0x%02x), ", addr+i, data1[i]);
  630. }
  631. if((count % 7) == 0)
  632. sprintf(str+strlen(str), "\n");
  633. }
  634. dev_info(&client->dev, "%s\n", str);
  635. str[0] = '\0';
  636. count = 0;
  637. for (addr = 0x14; addr <= 0x1b; addr += 2) {
  638. count++;
  639. data = max17048_read_word(client, addr);
  640. data1[0] = data & 0xff;
  641. data1[1] = (data & 0xff00) >> 8;
  642. for (i = 0; i < 2; i++) {
  643. sprintf(str + strlen(str), "0x%02x(0x%02x), ", addr+i, data1[i]);
  644. }
  645. if((count % 7) == 0)
  646. sprintf(str+strlen(str), "\n");
  647. }
  648. str[strlen(str)] = '\0';
  649. dev_info(&client->dev, "%s\n", str);
  650. }
  651. #endif
  652. bool sec_hal_fg_init(struct i2c_client *client)
  653. {
  654. #ifdef CONFIG_OF
  655. #if 1
  656. struct sec_fuelgauge_info *fuelgauge =
  657. i2c_get_clientdata(client);
  658. board_fuelgauge_init(fuelgauge);
  659. #else
  660. struct sec_fuelgauge_info *fuelgauge =
  661. i2c_get_clientdata(client);
  662. int error;
  663. error = max17048_parse_dt(&client->dev, fuelgauge);
  664. if (error) {
  665. dev_err(&client->dev,
  666. "%s : Failed to get max17048 fuel_init\n", __func__);
  667. return false;
  668. }
  669. #endif
  670. #endif
  671. max17048_get_version(client);
  672. #if defined(CONFIG_SEC_K_PROJECT) || defined(CONFIG_SEC_S_PROJECT)
  673. if (!max17048_check_fg_validity(client))
  674. return false;
  675. #endif
  676. return true;
  677. }
  678. bool sec_hal_fg_suspend(struct i2c_client *client)
  679. {
  680. return true;
  681. }
  682. bool sec_hal_fg_resume(struct i2c_client *client)
  683. {
  684. return true;
  685. }
  686. bool sec_hal_fg_fuelalert_init(struct i2c_client *client, int soc)
  687. {
  688. u16 temp;
  689. u8 data;
  690. temp = max17048_get_rcomp(client);
  691. data = 32 - soc; /* set soc for fuel alert */
  692. temp &= 0xff00;
  693. temp += data;
  694. dev_dbg(&client->dev,
  695. "%s : new rcomp = 0x%04x\n",
  696. __func__, temp);
  697. max17048_set_rcomp(client, temp);
  698. return true;
  699. }
  700. bool sec_hal_fg_is_fuelalerted(struct i2c_client *client)
  701. {
  702. u16 temp;
  703. temp = max17048_get_rcomp(client);
  704. if (temp & 0x20) /* ALRT is asserted */
  705. return true;
  706. return false;
  707. }
  708. bool sec_hal_fg_fuelalert_process(void *irq_data, bool is_fuel_alerted)
  709. {
  710. return true;
  711. }
  712. bool sec_hal_fg_full_charged(struct i2c_client *client)
  713. {
  714. return true;
  715. }
  716. bool sec_hal_fg_reset(struct i2c_client *client)
  717. {
  718. max17048_reset(client);
  719. return true;
  720. }
  721. bool sec_hal_fg_get_property(struct i2c_client *client,
  722. enum power_supply_property psp,
  723. union power_supply_propval *val)
  724. {
  725. union power_supply_propval value_bat;
  726. switch (psp) {
  727. /* Cell voltage (VCELL, mV) */
  728. case POWER_SUPPLY_PROP_VOLTAGE_NOW:
  729. val->intval = max17048_get_vcell(client);
  730. break;
  731. /* Additional Voltage Information (mV) */
  732. case POWER_SUPPLY_PROP_VOLTAGE_AVG:
  733. switch (val->intval) {
  734. case SEC_BATTEY_VOLTAGE_AVERAGE:
  735. val->intval = max17048_get_avg_vcell(client);
  736. break;
  737. case SEC_BATTEY_VOLTAGE_OCV:
  738. val->intval = max17048_get_ocv(client);
  739. break;
  740. }
  741. break;
  742. /* Current (mA) */
  743. case POWER_SUPPLY_PROP_CURRENT_NOW:
  744. psy_do_property("battery", get,
  745. POWER_SUPPLY_PROP_STATUS, value_bat);
  746. if(value_bat.intval == POWER_SUPPLY_STATUS_DISCHARGING)
  747. val->intval = -max17048_get_current(client);
  748. else
  749. val->intval = max17048_get_current(client);
  750. break;
  751. /* Average Current (mA) */
  752. case POWER_SUPPLY_PROP_CURRENT_AVG:
  753. val->intval = max17048_get_current_average(client);
  754. break;
  755. /* SOC (%) */
  756. case POWER_SUPPLY_PROP_CAPACITY:
  757. if (val->intval == SEC_FUELGAUGE_CAPACITY_TYPE_RAW)
  758. val->intval = max17048_get_soc(client);
  759. else
  760. val->intval = max17048_get_soc(client) / 10;
  761. /* fg_read_address(client); */
  762. break;
  763. /* Battery Temperature */
  764. case POWER_SUPPLY_PROP_TEMP:
  765. /* Target Temperature */
  766. case POWER_SUPPLY_PROP_TEMP_AMBIENT:
  767. break;
  768. case POWER_SUPPLY_PROP_MANUFACTURER:
  769. fg_read_all_regs(client);
  770. break;
  771. case POWER_SUPPLY_PROP_ENERGY_NOW:
  772. break;
  773. default:
  774. return false;
  775. }
  776. return true;
  777. }
  778. bool sec_hal_fg_set_property(struct i2c_client *client,
  779. enum power_supply_property psp,
  780. const union power_supply_propval *val)
  781. {
  782. switch (psp) {
  783. case POWER_SUPPLY_PROP_ONLINE:
  784. sec_bat_reset_discharge(client);
  785. break;
  786. /* Battery Temperature */
  787. case POWER_SUPPLY_PROP_TEMP:
  788. /* temperature is 0.1 degree, should be divide by 10 */
  789. max17048_rcomp_update(client, val->intval / 10);
  790. break;
  791. /* Target Temperature */
  792. case POWER_SUPPLY_PROP_TEMP_AMBIENT:
  793. break;
  794. default:
  795. return false;
  796. }
  797. return true;
  798. }
  799. ssize_t sec_hal_fg_show_attrs(struct device *dev,
  800. const ptrdiff_t offset, char *buf)
  801. {
  802. struct power_supply *psy = dev_get_drvdata(dev);
  803. struct sec_fuelgauge_info *fg =
  804. container_of(psy, struct sec_fuelgauge_info, psy_fg);
  805. int i = 0;
  806. char *str = NULL;
  807. switch (offset) {
  808. case FG_DATA:
  809. i += scnprintf(buf + i, PAGE_SIZE - i, "%02x%02x\n",
  810. fg->reg_data[1], fg->reg_data[0]);
  811. break;
  812. case FG_REGS:
  813. str = kzalloc(sizeof(char)*1024, GFP_KERNEL);
  814. if (!str)
  815. return -ENOMEM;
  816. fg_read_regs(fg->client, str);
  817. i += scnprintf(buf + i, PAGE_SIZE - i, "%s\n",
  818. str);
  819. kfree(str);
  820. break;
  821. default:
  822. i = -EINVAL;
  823. break;
  824. }
  825. return i;
  826. }
  827. ssize_t sec_hal_fg_store_attrs(struct device *dev,
  828. const ptrdiff_t offset,
  829. const char *buf, size_t count)
  830. {
  831. struct power_supply *psy = dev_get_drvdata(dev);
  832. struct sec_fuelgauge_info *fg =
  833. container_of(psy, struct sec_fuelgauge_info, psy_fg);
  834. int ret = 0;
  835. int x = 0;
  836. u16 data;
  837. switch (offset) {
  838. case FG_REG:
  839. if (sscanf(buf, "%x\n", &x) == 1) {
  840. fg->reg_addr = x;
  841. data = max17048_read_word(
  842. fg->client, fg->reg_addr);
  843. fg->reg_data[0] = (data & 0xff00) >> 8;
  844. fg->reg_data[1] = (data & 0x00ff);
  845. dev_dbg(&fg->client->dev,
  846. "%s: (read) addr = 0x%x, data = 0x%02x%02x\n",
  847. __func__, fg->reg_addr,
  848. fg->reg_data[1], fg->reg_data[0]);
  849. ret = count;
  850. }
  851. break;
  852. case FG_DATA:
  853. if (sscanf(buf, "%x\n", &x) == 1) {
  854. dev_dbg(&fg->client->dev,
  855. "%s: (write) addr = 0x%x, data = 0x%04x\n",
  856. __func__, fg->reg_addr, x);
  857. i2c_smbus_write_word_data(fg->client,
  858. fg->reg_addr, swab16(x));
  859. ret = count;
  860. }
  861. break;
  862. default:
  863. ret = -EINVAL;
  864. break;
  865. }
  866. return ret;
  867. }