max17050_fuelgauge.c 63 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585
  1. /*
  2. * max17050_fuelgauge.c
  3. * Samsung MAX17050 Fuel Gauge Driver
  4. *
  5. * Copyright (C) 2012 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. #define DEBUG
  13. #include <linux/battery/sec_fuelgauge.h>
  14. #ifdef CONFIG_FUELGAUGE_MAX17050_VOLTAGE_TRACKING
  15. static int max17050_write_reg(struct i2c_client *client, int reg, u8 *buf)
  16. {
  17. int ret;
  18. ret = i2c_smbus_write_i2c_block_data(client, reg, 2, buf);
  19. if (ret < 0)
  20. dev_err(&client->dev, "%s: Error(%d)\n", __func__, ret);
  21. return ret;
  22. }
  23. static int max17050_read_reg(struct i2c_client *client, int reg, u8 *buf)
  24. {
  25. int ret;
  26. ret = i2c_smbus_read_i2c_block_data(client, reg, 2, buf);
  27. if (ret < 0)
  28. dev_err(&client->dev, "%s: Error(%d)\n", __func__, ret);
  29. return ret;
  30. }
  31. static void max17050_write_reg_array(struct i2c_client *client,
  32. u8 *buf, int size)
  33. {
  34. int i;
  35. for (i = 0; i < size; i += 3)
  36. max17050_write_reg(client, (u8) (*(buf + i)), (buf + i) + 1);
  37. }
  38. static void max17050_init_regs(struct i2c_client *client)
  39. {
  40. u8 data[2];
  41. if (max17050_read_reg(client, MAX17050_REG_FILTERCFG, data) < 0)
  42. return;
  43. /* Clear average vcell (12 sec) */
  44. data[0] &= 0x8f;
  45. max17050_write_reg(client, MAX17050_REG_FILTERCFG, data);
  46. }
  47. static void max17050_get_version(struct i2c_client *client)
  48. {
  49. u8 data[2];
  50. if (max17050_read_reg(client, MAX17050_REG_VERSION, data) < 0)
  51. return;
  52. dev_dbg(&client->dev, "MAX17050 Fuel-Gauge Ver %d%d\n",
  53. data[0], data[1]);
  54. }
  55. static void max17050_alert_init(struct i2c_client *client)
  56. {
  57. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  58. u8 data[2];
  59. /* SALRT Threshold setting */
  60. data[0] = fuelgauge->pdata->fuel_alert_soc;
  61. data[1] = 0xff;
  62. max17050_write_reg(client, MAX17050_REG_SALRT_TH, data);
  63. /* VALRT Threshold setting */
  64. data[0] = 0x00;
  65. data[1] = 0xff;
  66. max17050_write_reg(client, MAX17050_REG_VALRT_TH, data);
  67. /* TALRT Threshold setting */
  68. data[0] = 0x80;
  69. data[1] = 0x7f;
  70. max17050_write_reg(client, MAX17050_REG_TALRT_TH, data);
  71. }
  72. static bool max17050_check_status(struct i2c_client *client)
  73. {
  74. u8 data[2];
  75. bool ret = false;
  76. /* check if Smn was generated */
  77. if (max17050_read_reg(client, MAX17050_REG_STATUS, data) < 0)
  78. return ret;
  79. dev_info(&client->dev, "%s: status_reg(%02x%02x)\n",
  80. __func__, data[1], data[0]);
  81. /* minimum SOC threshold exceeded. */
  82. if (data[1] & (0x1 << 2))
  83. ret = true;
  84. /* clear status reg */
  85. if (!ret) {
  86. data[1] = 0;
  87. max17050_write_reg(client, MAX17050_REG_STATUS, data);
  88. msleep(200);
  89. }
  90. return ret;
  91. }
  92. static int max17050_set_temperature(struct i2c_client *client, int temperature)
  93. {
  94. u8 data[2];
  95. data[0] = 0;
  96. data[1] = temperature;
  97. max17050_write_reg(client, MAX17050_REG_TEMPERATURE, data);
  98. dev_dbg(&client->dev, "%s: temperature to (%d)\n",
  99. __func__, temperature);
  100. return temperature;
  101. }
  102. static int max17050_get_temperature(struct i2c_client *client)
  103. {
  104. u8 data[2];
  105. s32 temperature = 0;
  106. if (max17050_read_reg(client, MAX17050_REG_TEMPERATURE, data) < 0)
  107. return -ERANGE;
  108. /* data[] store 2's compliment format number */
  109. if (data[1] & (0x1 << 7)) {
  110. /* Negative */
  111. temperature = ((~(data[1])) & 0xFF) + 1;
  112. temperature *= (-1000);
  113. } else {
  114. temperature = data[1] & 0x7F;
  115. temperature *= 1000;
  116. temperature += data[0] * 39 / 10;
  117. }
  118. dev_dbg(&client->dev, "%s: temperature (%d)\n",
  119. __func__, temperature);
  120. return temperature;
  121. }
  122. /* soc should be 0.01% unit */
  123. static int max17050_get_soc(struct i2c_client *client)
  124. {
  125. u8 data[2];
  126. int soc;
  127. if (max17050_read_reg(client, MAX17050_REG_SOC_VF, data) < 0)
  128. return -EINVAL;
  129. soc = ((data[1] * 100) + (data[0] * 100 / 256));
  130. dev_dbg(&client->dev, "%s: raw capacity (%d)\n", __func__, soc);
  131. return min(soc, 10000);
  132. }
  133. static int max17050_get_vfocv(struct i2c_client *client)
  134. {
  135. u8 data[2];
  136. u32 vfocv = 0;
  137. if (max17050_read_reg(client, MAX17050_REG_VFOCV, data) < 0)
  138. return -EINVAL;
  139. vfocv = ((data[0] >> 3) + (data[1] << 5)) * 625 / 1000;
  140. dev_dbg(&client->dev, "%s: vfocv (%d)\n", __func__, vfocv);
  141. return vfocv;
  142. }
  143. static int max17050_get_vcell(struct i2c_client *client)
  144. {
  145. u8 data[2];
  146. u32 vcell = 0;
  147. if (max17050_read_reg(client, MAX17050_REG_VCELL, data) < 0)
  148. return -EINVAL;
  149. vcell = ((data[0] >> 3) + (data[1] << 5)) * 625 / 1000;
  150. dev_dbg(&client->dev, "%s: vcell (%d)\n", __func__, vcell);
  151. return vcell;
  152. }
  153. static int max17050_get_avgvcell(struct i2c_client *client)
  154. {
  155. u8 data[2];
  156. u32 avgvcell = 0;
  157. if (max17050_read_reg(client, MAX17050_REG_AVGVCELL, data) < 0)
  158. return -EINVAL;
  159. avgvcell = ((data[0] >> 3) + (data[1] << 5)) * 625 / 1000;
  160. dev_dbg(&client->dev, "%s: avgvcell (%d)\n", __func__, avgvcell);
  161. return avgvcell;
  162. }
  163. bool sec_hal_fg_init(struct i2c_client *client)
  164. {
  165. /* initialize fuel gauge registers */
  166. max17050_init_regs(client);
  167. max17050_get_version(client);
  168. return true;
  169. }
  170. bool sec_hal_fg_suspend(struct i2c_client *client)
  171. {
  172. return true;
  173. }
  174. bool sec_hal_fg_resume(struct i2c_client *client)
  175. {
  176. return true;
  177. }
  178. bool sec_hal_fg_fuelalert_init(struct i2c_client *client, int soc)
  179. {
  180. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  181. u8 data[2];
  182. /* 1. Set max17050 alert configuration. */
  183. max17050_alert_init(client);
  184. if (max17050_read_reg(client, MAX17050_REG_CONFIG, data)
  185. < 0)
  186. return -1;
  187. /*Enable Alert (Aen = 1) */
  188. data[0] |= (0x1 << 2);
  189. max17050_write_reg(client, MAX17050_REG_CONFIG, data);
  190. dev_dbg(&client->dev, "%s: config_reg(%02x%02x) irq(%d)\n",
  191. __func__, data[1], data[0], fuelgauge->pdata->fg_gpio_irq);
  192. return true;
  193. }
  194. bool sec_hal_fg_is_fuelalerted(struct i2c_client *client)
  195. {
  196. return max17050_check_status(client);
  197. }
  198. bool sec_hal_fg_fuelalert_process(void *irq_data, bool is_fuel_alerted)
  199. {
  200. struct sec_fuelgauge_info *fuelgauge = irq_data;
  201. u8 data[2];
  202. /* update SOC */
  203. /* max17050_get_soc(fuelgauge->client); */
  204. if (is_fuel_alerted) {
  205. if (max17050_read_reg(fuelgauge->client,
  206. MAX17050_REG_CONFIG, data) < 0)
  207. return false;
  208. data[1] |= (0x1 << 3);
  209. max17050_write_reg(fuelgauge->client,
  210. MAX17050_REG_CONFIG, data);
  211. dev_info(&fuelgauge->client->dev,
  212. "%s: Fuel-alert Alerted!! (%02x%02x)\n",
  213. __func__, data[1], data[0]);
  214. } else {
  215. if (max17050_read_reg(fuelgauge->client,
  216. MAX17050_REG_CONFIG, data)
  217. < 0)
  218. return false;
  219. data[1] &= (~(0x1 << 3));
  220. max17050_write_reg(fuelgauge->client,
  221. MAX17050_REG_CONFIG, data);
  222. dev_info(&fuelgauge->client->dev,
  223. "%s: Fuel-alert Released!! (%02x%02x)\n",
  224. __func__, data[1], data[0]);
  225. }
  226. max17050_read_reg(fuelgauge->client, MAX17050_REG_VCELL, data);
  227. dev_dbg(&fuelgauge->client->dev,
  228. "%s: MAX17050_REG_VCELL(%02x%02x)\n",
  229. __func__, data[1], data[0]);
  230. max17050_read_reg(fuelgauge->client, MAX17050_REG_TEMPERATURE, data);
  231. dev_dbg(&fuelgauge->client->dev,
  232. "%s: MAX17050_REG_TEMPERATURE(%02x%02x)\n",
  233. __func__, data[1], data[0]);
  234. max17050_read_reg(fuelgauge->client, MAX17050_REG_CONFIG, data);
  235. dev_dbg(&fuelgauge->client->dev,
  236. "%s: MAX17050_REG_CONFIG(%02x%02x)\n",
  237. __func__, data[1], data[0]);
  238. max17050_read_reg(fuelgauge->client, MAX17050_REG_VFOCV, data);
  239. dev_dbg(&fuelgauge->client->dev,
  240. "%s: MAX17050_REG_VFOCV(%02x%02x)\n",
  241. __func__, data[1], data[0]);
  242. max17050_read_reg(fuelgauge->client, MAX17050_REG_SOC_VF, data);
  243. dev_dbg(&fuelgauge->client->dev,
  244. "%s: MAX17050_REG_SOC_VF(%02x%02x)\n",
  245. __func__, data[1], data[0]);
  246. dev_dbg(&fuelgauge->client->dev,
  247. "%s: FUEL GAUGE IRQ (%d)\n",
  248. __func__,
  249. gpio_get_value(irq_to_gpio(fuelgauge->pdata->fg_gpio_irq)));
  250. #if 0
  251. max17050_read_reg(fuelgauge->client, MAX17050_REG_STATUS, data);
  252. dev_dbg(&fuelgauge->client->dev,
  253. "%s: MAX17050_REG_STATUS(%02x%02x)\n",
  254. __func__, data[1], data[0]);
  255. max17050_read_reg(fuelgauge->client, MAX17050_REG_VALRT_TH, data);
  256. dev_dbg(&fuelgauge->client->dev,
  257. "%s: MAX17050_REG_VALRT_TH(%02x%02x)\n",
  258. __func__, data[1], data[0]);
  259. max17050_read_reg(fuelgauge->client, MAX17050_REG_TALRT_TH, data);
  260. dev_dbg(&fuelgauge->client->dev,
  261. "%s: MAX17050_REG_TALRT_TH(%02x%02x)\n",
  262. __func__, data[1], data[0]);
  263. max17050_read_reg(fuelgauge->client, MAX17050_REG_SALRT_TH, data);
  264. dev_dbg(&fuelgauge->client->dev,
  265. "%s: MAX17050_REG_SALRT_TH(%02x%02x)\n",
  266. __func__, data[1], data[0]);
  267. max17050_read_reg(fuelgauge->client, MAX17050_REG_AVGVCELL, data);
  268. dev_dbg(&fuelgauge->client->dev,
  269. "%s: MAX17050_REG_AVGVCELL(%02x%02x)\n",
  270. __func__, data[1], data[0]);
  271. max17050_read_reg(fuelgauge->client, MAX17050_REG_VERSION, data);
  272. dev_dbg(&fuelgauge->client->dev,
  273. "%s: MAX17050_REG_VERSION(%02x%02x)\n",
  274. __func__, data[1], data[0]);
  275. max17050_read_reg(fuelgauge->client, MAX17050_REG_LEARNCFG, data);
  276. dev_dbg(&fuelgauge->client->dev,
  277. "%s: MAX17050_REG_LEARNCFG(%02x%02x)\n",
  278. __func__, data[1], data[0]);
  279. max17050_read_reg(fuelgauge->client, MAX17050_REG_MISCCFG, data);
  280. dev_dbg(&fuelgauge->client->dev,
  281. "%s: MAX17050_REG_MISCCFG(%02x%02x)\n",
  282. __func__, data[1], data[0]);
  283. max17050_read_reg(fuelgauge->client, MAX17050_REG_CGAIN, data);
  284. dev_dbg(&fuelgauge->client->dev,
  285. "%s: MAX17050_REG_CGAIN(%02x%02x)\n",
  286. __func__, data[1], data[0]);
  287. max17050_read_reg(fuelgauge->client, MAX17050_REG_RCOMP, data);
  288. dev_dbg(&fuelgauge->client->dev,
  289. "%s: MAX17050_REG_RCOMP(%02x%02x)\n",
  290. __func__, data[1], data[0]);
  291. #endif
  292. return true;
  293. }
  294. bool sec_hal_fg_full_charged(struct i2c_client *client)
  295. {
  296. return true;
  297. }
  298. bool sec_hal_fg_get_property(struct i2c_client *client,
  299. enum power_supply_property psp,
  300. union power_supply_propval *val)
  301. {
  302. switch (psp) {
  303. /* Cell voltage (VCELL, mV) */
  304. case POWER_SUPPLY_PROP_VOLTAGE_NOW:
  305. val->intval = max17050_get_vcell(client);
  306. break;
  307. /* Additional Voltage Information (mV) */
  308. case POWER_SUPPLY_PROP_VOLTAGE_AVG:
  309. switch (val->intval) {
  310. case SEC_BATTEY_VOLTAGE_AVERAGE:
  311. val->intval = max17050_get_avgvcell(client);
  312. break;
  313. case SEC_BATTEY_VOLTAGE_OCV:
  314. val->intval = max17050_get_vfocv(client);
  315. break;
  316. }
  317. break;
  318. /* Current (mA) */
  319. case POWER_SUPPLY_PROP_CURRENT_NOW:
  320. val->intval = 0;
  321. break;
  322. /* Average Current (mA) */
  323. case POWER_SUPPLY_PROP_CURRENT_AVG:
  324. val->intval = 0;
  325. break;
  326. /* SOC (%) */
  327. case POWER_SUPPLY_PROP_CAPACITY:
  328. if (val->intval == SEC_FUELGAUGE_CAPACITY_TYPE_RAW)
  329. val->intval = max17050_get_soc(client);
  330. else
  331. val->intval = max17050_get_soc(client) / 10;
  332. break;
  333. /* Battery Temperature */
  334. case POWER_SUPPLY_PROP_TEMP:
  335. /* Target Temperature */
  336. case POWER_SUPPLY_PROP_TEMP_AMBIENT:
  337. val->intval = max17050_get_temperature(client);
  338. break;
  339. default:
  340. return false;
  341. }
  342. return true;
  343. }
  344. bool sec_hal_fg_set_property(struct i2c_client *client,
  345. enum power_supply_property psp,
  346. const union power_supply_propval *val)
  347. {
  348. switch (psp) {
  349. /* Battery Temperature */
  350. case POWER_SUPPLY_PROP_TEMP:
  351. /* Target Temperature */
  352. case POWER_SUPPLY_PROP_TEMP_AMBIENT:
  353. max17050_set_temperature(client, val->intval);
  354. break;
  355. default:
  356. return false;
  357. }
  358. return true;
  359. }
  360. ssize_t sec_hal_fg_show_attrs(struct device *dev,
  361. const ptrdiff_t offset, char *buf)
  362. {
  363. struct power_supply *psy = dev_get_drvdata(dev);
  364. struct sec_fuelgauge_info *fg =
  365. container_of(psy, struct sec_fuelgauge_info, psy_fg);
  366. int i = 0;
  367. switch (offset) {
  368. /* case FG_REG: */
  369. /* break; */
  370. case FG_DATA:
  371. i += scnprintf(buf + i, PAGE_SIZE - i, "%02x%02x\n",
  372. fg->reg_data[1], fg->reg_data[0]);
  373. break;
  374. default:
  375. i = -EINVAL;
  376. break;
  377. }
  378. return i;
  379. }
  380. ssize_t sec_hal_fg_store_attrs(struct device *dev,
  381. const ptrdiff_t offset,
  382. const char *buf, size_t count)
  383. {
  384. struct power_supply *psy = dev_get_drvdata(dev);
  385. struct sec_fuelgauge_info *fg =
  386. container_of(psy, struct sec_fuelgauge_info, psy_fg);
  387. int ret = 0;
  388. int x = 0;
  389. u8 data[2];
  390. switch (offset) {
  391. case FG_REG:
  392. if (sscanf(buf, "%x\n", &x) == 1) {
  393. fg->reg_addr = x;
  394. max17050_read_reg(fg->client,
  395. fg->reg_addr, fg->reg_data);
  396. dev_dbg(&fg->client->dev,
  397. "%s: (read) addr = 0x%x, data = 0x%02x%02x\n",
  398. __func__, fg->reg_addr,
  399. fg->reg_data[1], fg->reg_data[0]);
  400. ret = count;
  401. }
  402. break;
  403. case FG_DATA:
  404. if (sscanf(buf, "%x\n", &x) == 1) {
  405. data[0] = (x & 0xFF00) >> 8;
  406. data[1] = (x & 0x00FF);
  407. dev_dbg(&fg->client->dev,
  408. "%s: (write) addr = 0x%x, data = 0x%02x%02x\n",
  409. __func__, fg->reg_addr, data[1], data[0]);
  410. max17050_write_reg(fg->client,
  411. fg->reg_addr, data);
  412. ret = count;
  413. }
  414. break;
  415. default:
  416. ret = -EINVAL;
  417. break;
  418. }
  419. return ret;
  420. }
  421. #endif
  422. #ifdef CONFIG_FUELGAUGE_MAX17050_COULOMB_COUNTING
  423. static int fg_i2c_read(struct i2c_client *client,
  424. u8 reg, u8 *data, u8 length)
  425. {
  426. s32 value;
  427. value = i2c_smbus_read_i2c_block_data(client, reg, length, data);
  428. if (value < 0 || value != length) {
  429. dev_err(&client->dev, "%s: Error(%d)\n",
  430. __func__, value);
  431. return -1;
  432. }
  433. return 0;
  434. }
  435. static int fg_i2c_write(struct i2c_client *client,
  436. u8 reg, u8 *data, u8 length)
  437. {
  438. s32 value;
  439. value = i2c_smbus_write_i2c_block_data(client, reg, length, data);
  440. if (value < 0) {
  441. dev_err(&client->dev, "%s: Error(%d)\n",
  442. __func__, value);
  443. return -1;
  444. }
  445. return 0;
  446. }
  447. static int fg_read_register(struct i2c_client *client,
  448. u8 addr)
  449. {
  450. u8 data[2];
  451. if (fg_i2c_read(client, addr, data, 2) < 0) {
  452. dev_err(&client->dev, "%s: Failed to read addr(0x%x)\n",
  453. __func__, addr);
  454. return -1;
  455. }
  456. return (data[1] << 8) | data[0];
  457. }
  458. static int fg_write_register(struct i2c_client *client,
  459. u8 addr, u16 w_data)
  460. {
  461. u8 data[2];
  462. data[0] = w_data & 0xFF;
  463. data[1] = w_data >> 8;
  464. if (fg_i2c_write(client, addr, data, 2) < 0) {
  465. dev_err(&client->dev, "%s: Failed to write addr(0x%x)\n",
  466. __func__, addr);
  467. return -1;
  468. }
  469. return 0;
  470. }
  471. /*static int fg_read_16register(struct i2c_client *client,
  472. u8 addr, u16 *r_data)
  473. {
  474. u8 data[32];
  475. int i = 0;
  476. if (fg_i2c_read(client, addr, data, 32) < 0) {
  477. dev_err(&client->dev, "%s: Failed to read addr(0x%x)\n",
  478. __func__, addr);
  479. return -1;
  480. }
  481. for (i = 0; i < 16; i++)
  482. r_data[i] = (data[2 * i + 1] << 8) | data[2 * i];
  483. return 0;
  484. }*/
  485. static void fg_write_and_verify_register(struct i2c_client *client,
  486. u8 addr, u16 w_data)
  487. {
  488. u16 r_data;
  489. u8 retry_cnt = 2;
  490. while (retry_cnt) {
  491. fg_write_register(client, addr, w_data);
  492. r_data = fg_read_register(client, addr);
  493. if (r_data != w_data) {
  494. dev_err(&client->dev,
  495. "%s: verification failed (addr: 0x%x, w_data: 0x%x, r_data: 0x%x)\n",
  496. __func__, addr, w_data, r_data);
  497. retry_cnt--;
  498. } else
  499. break;
  500. }
  501. }
  502. static void fg_test_print(struct i2c_client *client)
  503. {
  504. u8 data[2];
  505. u32 average_vcell;
  506. u16 w_data;
  507. u32 temp;
  508. u32 temp2;
  509. u16 reg_data;
  510. if (fg_i2c_read(client, AVR_VCELL_REG, data, 2) < 0) {
  511. dev_err(&client->dev, "%s: Failed to read VCELL\n", __func__);
  512. return;
  513. }
  514. w_data = (data[1]<<8) | data[0];
  515. temp = (w_data & 0xFFF) * 78125;
  516. average_vcell = temp / 1000000;
  517. temp = ((w_data & 0xF000) >> 4) * 78125;
  518. temp2 = temp / 1000000;
  519. average_vcell += (temp2 << 4);
  520. dev_info(&client->dev, "%s: AVG_VCELL(%d), data(0x%04x)\n", __func__,
  521. average_vcell, (data[1]<<8) | data[0]);
  522. reg_data = fg_read_register(client, FULLCAP_REG);
  523. dev_info(&client->dev, "%s: FULLCAP(%d), data(0x%04x)\n", __func__,
  524. reg_data/2, reg_data);
  525. reg_data = fg_read_register(client, REMCAP_REP_REG);
  526. dev_info(&client->dev, "%s: REMCAP_REP(%d), data(0x%04x)\n", __func__,
  527. reg_data/2, reg_data);
  528. reg_data = fg_read_register(client, REMCAP_MIX_REG);
  529. dev_info(&client->dev, "%s: REMCAP_MIX(%d), data(0x%04x)\n", __func__,
  530. reg_data/2, reg_data);
  531. reg_data = fg_read_register(client, REMCAP_AV_REG);
  532. dev_info(&client->dev, "%s: REMCAP_AV(%d), data(0x%04x)\n", __func__,
  533. reg_data/2, reg_data);
  534. }
  535. static void fg_periodic_read(struct i2c_client *client)
  536. {
  537. u8 reg;
  538. int i;
  539. int data[0x10];
  540. char *str = NULL;
  541. str = kzalloc(sizeof(char)*1500, GFP_KERNEL);
  542. if (!str)
  543. return;
  544. for (i = 0; i < 16; i++) {
  545. for (reg = 0; reg < 0x10; reg++) {
  546. data[reg] = fg_read_register(client, reg + i * 0x10);
  547. if (data[reg] < 0) {
  548. pr_err("%s: fg read register failed(%d)\n", __func__, data[reg]);
  549. goto periodic_error;
  550. }
  551. }
  552. sprintf(str+strlen(str),
  553. "%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,",
  554. data[0x00], data[0x01], data[0x02], data[0x03],
  555. data[0x04], data[0x05], data[0x06], data[0x07]);
  556. sprintf(str+strlen(str),
  557. "%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,",
  558. data[0x08], data[0x09], data[0x0a], data[0x0b],
  559. data[0x0c], data[0x0d], data[0x0e], data[0x0f]);
  560. if (i == 4)
  561. i = 13;
  562. }
  563. dev_info(&client->dev, "%s", str);
  564. periodic_error:
  565. kfree(str);
  566. }
  567. static void fg_read_regs(struct i2c_client *client, char *str)
  568. {
  569. int data = 0;
  570. u32 addr = 0;
  571. for (addr = 0; addr <= 0x4f; addr++) {
  572. data = fg_read_register(client, addr);
  573. sprintf(str+strlen(str), "0x%04x, ", data);
  574. }
  575. /* "#" considered as new line in application */
  576. sprintf(str+strlen(str), "#");
  577. for (addr = 0xe0; addr <= 0xff; addr++) {
  578. data = fg_read_register(client, addr);
  579. sprintf(str+strlen(str), "0x%04x, ", data);
  580. }
  581. }
  582. static int fg_read_soc(struct i2c_client *client);
  583. static int fg_read_vcell(struct i2c_client *client)
  584. {
  585. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  586. u8 data[2];
  587. u32 vcell;
  588. u16 w_data;
  589. u32 temp;
  590. u32 temp2;
  591. if (fg_i2c_read(client, VCELL_REG, data, 2) < 0) {
  592. dev_err(&client->dev, "%s: Failed to read VCELL\n", __func__);
  593. return -1;
  594. }
  595. w_data = (data[1]<<8) | data[0];
  596. temp = (w_data & 0xFFF) * 78125;
  597. vcell = temp / 1000000;
  598. temp = ((w_data & 0xF000) >> 4) * 78125;
  599. temp2 = temp / 1000000;
  600. vcell += (temp2 << 4);
  601. if (!(fuelgauge->info.pr_cnt % PRINT_COUNT)) {
  602. dev_info(&client->dev, "%s: VCELL(%d), data(0x%04x)\n",
  603. __func__, vcell, (data[1]<<8) | data[0]);
  604. fg_read_soc(client);
  605. }
  606. return vcell;
  607. }
  608. static int fg_read_vfocv(struct i2c_client *client)
  609. {
  610. u8 data[2];
  611. u32 vfocv = 0;
  612. u16 w_data;
  613. u32 temp;
  614. u32 temp2;
  615. if (fg_i2c_read(client, VFOCV_REG, data, 2) < 0) {
  616. dev_err(&client->dev, "%s: Failed to read VFOCV\n", __func__);
  617. return -1;
  618. }
  619. w_data = (data[1]<<8) | data[0];
  620. temp = (w_data & 0xFFF) * 78125;
  621. vfocv = temp / 1000000;
  622. temp = ((w_data & 0xF000) >> 4) * 78125;
  623. temp2 = temp / 1000000;
  624. vfocv += (temp2 << 4);
  625. return vfocv;
  626. }
  627. static int fg_read_avg_vcell(struct i2c_client *client)
  628. {
  629. u8 data[2];
  630. u32 avg_vcell = 0;
  631. u16 w_data;
  632. u32 temp;
  633. u32 temp2;
  634. if (fg_i2c_read(client, AVR_VCELL_REG, data, 2) < 0) {
  635. dev_err(&client->dev,
  636. "%s: Failed to read AVG_VCELL\n", __func__);
  637. return -1;
  638. }
  639. w_data = (data[1]<<8) | data[0];
  640. temp = (w_data & 0xFFF) * 78125;
  641. avg_vcell = temp / 1000000;
  642. temp = ((w_data & 0xF000) >> 4) * 78125;
  643. temp2 = temp / 1000000;
  644. avg_vcell += (temp2 << 4);
  645. return avg_vcell;
  646. }
  647. static int fg_check_battery_present(struct i2c_client *client)
  648. {
  649. u8 status_data[2];
  650. int ret = 1;
  651. /* 1. Check Bst bit */
  652. if (fg_i2c_read(client, STATUS_REG, status_data, 2) < 0) {
  653. dev_err(&client->dev,
  654. "%s: Failed to read STATUS_REG\n", __func__);
  655. return 0;
  656. }
  657. if (status_data[0] & (0x1 << 3)) {
  658. dev_info(&client->dev,
  659. "%s: addr(0x01), data(0x%04x)\n", __func__,
  660. (status_data[1]<<8) | status_data[0]);
  661. dev_info(&client->dev, "%s: battery is absent!!\n", __func__);
  662. ret = 0;
  663. }
  664. return ret;
  665. }
  666. static int fg_adjust_temp (struct i2c_client *client, enum power_supply_property psp, int value)
  667. {
  668. int temp = 0;
  669. int temp_adc;
  670. int low = 0;
  671. int high = 0;
  672. int mid = 0;
  673. static int count = 0;
  674. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  675. const sec_bat_adc_table_data_t *temp_adc_table;
  676. unsigned int temp_adc_table_size;
  677. temp_adc = value;
  678. switch (psp) {
  679. case POWER_SUPPLY_PROP_TEMP:
  680. if (fuelgauge->pdata->temp_adc_table) {
  681. temp_adc_table = fuelgauge->pdata->temp_adc_table;
  682. temp_adc_table_size = fuelgauge->pdata->temp_adc_table_size;
  683. } else {
  684. return temp_adc;
  685. }
  686. break;
  687. case POWER_SUPPLY_PROP_TEMP_AMBIENT:
  688. if (fuelgauge->pdata->temp_amb_adc_table) {
  689. temp_adc_table = fuelgauge->pdata->temp_amb_adc_table;
  690. temp_adc_table_size =
  691. fuelgauge->pdata->temp_amb_adc_table_size;
  692. } else {
  693. return temp_adc;
  694. }
  695. break;
  696. default:
  697. return temp_adc;
  698. }
  699. if (temp_adc_table[0].adc <= temp_adc) {
  700. temp = temp_adc_table[0].data;
  701. goto finish;
  702. } else if (temp_adc_table[temp_adc_table_size-1].adc >= temp_adc) {
  703. temp = temp_adc_table[temp_adc_table_size-1].data;
  704. goto finish;
  705. }
  706. high = temp_adc_table_size - 1;
  707. while (low <= high) {
  708. mid = (low + high) / 2;
  709. if (temp_adc_table[mid].adc > temp_adc)
  710. low = mid + 1;
  711. else if (temp_adc_table[mid].adc < temp_adc)
  712. high = mid - 1;
  713. else {
  714. temp = temp_adc_table[mid].data;
  715. goto finish;
  716. }
  717. }
  718. temp = temp_adc_table[high].data;
  719. temp +=
  720. ((temp_adc_table[low].data -
  721. temp_adc_table[high].data) *
  722. (temp_adc - temp_adc_table[high].adc)) /
  723. (temp_adc_table[low].adc - temp_adc_table[high].adc);
  724. finish:
  725. if (!(count++ % PRINT_COUNT)) {
  726. dev_dbg(&client->dev,
  727. "%s: Temp_org(%d) -> Temp_adj(%d)\n",
  728. __func__, temp_adc, temp);
  729. count = 1;
  730. }
  731. return temp;
  732. }
  733. static int fg_read_temp(struct i2c_client *client)
  734. {
  735. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  736. u8 data[2] = {0, 0};
  737. int temper = 0;
  738. /*int i;*/
  739. if (fg_check_battery_present(client)) {
  740. if (fg_i2c_read(client, TEMPERATURE_REG, data, 2) < 0) {
  741. dev_err(&client->dev,
  742. "%s: Failed to read TEMPERATURE_REG\n",
  743. __func__);
  744. return -1;
  745. }
  746. if (data[1]&(0x1 << 7)) {
  747. temper = ((~(data[1]))&0xFF)+1;
  748. temper *= (-1000);
  749. temper -= ((~((int)data[0]))+1) * 39 / 10;
  750. } else {
  751. temper = data[1] & 0x7f;
  752. temper *= 1000;
  753. temper += data[0] * 39 / 10;
  754. #if 0
  755. /* Adjust temperature */
  756. for (i = 0; i < TEMP_RANGE_MAX_NUM-1; i++) {
  757. if ((temper >= get_battery_data(fuelgauge).
  758. temp_adjust_table[i][RANGE]) &&
  759. (temper < get_battery_data(fuelgauge).
  760. temp_adjust_table[i+1][RANGE])) {
  761. temper = (temper *
  762. get_battery_data(fuelgauge).
  763. temp_adjust_table[i][SLOPE] /
  764. 100) -
  765. get_battery_data(fuelgauge).
  766. temp_adjust_table[i][OFFSET];
  767. break;
  768. }
  769. }
  770. if (i == TEMP_RANGE_MAX_NUM-1)
  771. dev_dbg(&client->dev,
  772. "%s : No adjustment for temperature\n",
  773. __func__);
  774. #endif
  775. }
  776. } else
  777. temper = 20000;
  778. if (!(fuelgauge->info.pr_cnt % PRINT_COUNT))
  779. dev_info(&client->dev, "%s: TEMPERATURE(%d), data(0x%04x)\n",
  780. __func__, temper, (data[1]<<8) | data[0]);
  781. return temper/100;
  782. }
  783. /* soc should be 0.1% unit */
  784. static int fg_read_vfsoc(struct i2c_client *client)
  785. {
  786. u8 data[2];
  787. int soc;
  788. if (fg_i2c_read(client, VFSOC_REG, data, 2) < 0) {
  789. dev_err(&client->dev, "%s: Failed to read VFSOC\n", __func__);
  790. return -1;
  791. }
  792. soc = ((data[1] * 100) + (data[0] * 100 / 256)) / 10;
  793. return min(soc, 1000);
  794. }
  795. /* soc should be 0.1% unit */
  796. static int fg_read_avsoc(struct i2c_client *client)
  797. {
  798. u8 data[2];
  799. int soc;
  800. if (fg_i2c_read(client, SOCAV_REG, data, 2) < 0) {
  801. dev_err(&client->dev, "%s: Failed to read AVSOC\n", __func__);
  802. return -1;
  803. }
  804. soc = ((data[1] * 100) + (data[0] * 100 / 256)) / 10;
  805. return min(soc, 1000);
  806. }
  807. /* soc should be 0.1% unit */
  808. static int fg_read_soc(struct i2c_client *client)
  809. {
  810. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  811. u8 data[2];
  812. int soc;
  813. int rep_soc;
  814. int vf_soc;
  815. if (fg_i2c_read(client, SOCREP_REG, data, 2) < 0) {
  816. dev_err(&client->dev, "%s: Failed to read SOCREP\n", __func__);
  817. return -1;
  818. }
  819. soc = ((data[1] * 100) + (data[0] * 100 / 256)) / 10;
  820. rep_soc = min(soc, 1000);
  821. vf_soc = fg_read_vfsoc(client);
  822. dev_dbg(&client->dev, "%s: raw capacity (0.1%%) (%d)\n", __func__, soc);
  823. if (!(fuelgauge->info.pr_cnt % PRINT_COUNT)) {
  824. dev_dbg(&client->dev, "%s: raw capacity (%d), data(0x%04x)\n",
  825. __func__, soc, (data[1]<<8) | data[0]);
  826. dev_dbg(&client->dev, "%s: RepSOC (%d), VFSOC (%d), data(0x%04x)\n",
  827. __func__, rep_soc/10, vf_soc/10, (data[1]<<8) | data[0]);
  828. }
  829. return rep_soc;
  830. }
  831. /* soc should be 0.01% unit */
  832. static int fg_read_rawsoc(struct i2c_client *client)
  833. {
  834. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  835. u8 data[2];
  836. int soc;
  837. if (fg_i2c_read(client, SOCREP_REG, data, 2) < 0) {
  838. dev_err(&client->dev, "%s: Failed to read SOCREP\n", __func__);
  839. return -1;
  840. }
  841. soc = (data[1] * 100) + (data[0] * 100 / 256);
  842. dev_dbg(&client->dev, "%s: raw capacity (0.01%%) (%d)\n",
  843. __func__, soc);
  844. if (!(fuelgauge->info.pr_cnt % PRINT_COUNT))
  845. dev_dbg(&client->dev, "%s: raw capacity (%d), data(0x%04x)\n",
  846. __func__, soc, (data[1]<<8) | data[0]);
  847. return min(soc, 10000);
  848. }
  849. static int fg_read_fullcap(struct i2c_client *client)
  850. {
  851. u8 data[2];
  852. int ret;
  853. if (fg_i2c_read(client, FULLCAP_REG, data, 2) < 0) {
  854. dev_err(&client->dev, "%s: Failed to read FULLCAP\n", __func__);
  855. return -1;
  856. }
  857. ret = (data[1] << 8) + data[0];
  858. return ret;
  859. }
  860. static int fg_read_mixcap(struct i2c_client *client)
  861. {
  862. u8 data[2];
  863. int ret;
  864. if (fg_i2c_read(client, REMCAP_MIX_REG, data, 2) < 0) {
  865. dev_err(&client->dev, "%s: Failed to read REMCAP_MIX_REG\n",
  866. __func__);
  867. return -1;
  868. }
  869. ret = (data[1] << 8) + data[0];
  870. return ret;
  871. }
  872. static int fg_read_avcap(struct i2c_client *client)
  873. {
  874. u8 data[2];
  875. int ret;
  876. if (fg_i2c_read(client, REMCAP_AV_REG, data, 2) < 0) {
  877. dev_err(&client->dev, "%s: Failed to read REMCAP_AV_REG\n",
  878. __func__);
  879. return -1;
  880. }
  881. ret = (data[1] << 8) + data[0];
  882. return ret;
  883. }
  884. static int fg_read_repcap(struct i2c_client *client)
  885. {
  886. u8 data[2];
  887. int ret;
  888. if (fg_i2c_read(client, REMCAP_REP_REG, data, 2) < 0) {
  889. dev_err(&client->dev, "%s: Failed to read REMCAP_REP_REG\n",
  890. __func__);
  891. return -1;
  892. }
  893. ret = (data[1] << 8) + data[0];
  894. return ret;
  895. }
  896. static int fg_read_current(struct i2c_client *client, int unit)
  897. {
  898. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  899. u8 data1[2], data2[2];
  900. u32 temp, sign;
  901. s32 i_current;
  902. s32 avg_current;
  903. int vcell;
  904. static int cnt;
  905. if (fg_i2c_read(client, CURRENT_REG, data1, 2) < 0) {
  906. dev_err(&client->dev, "%s: Failed to read CURRENT\n",
  907. __func__);
  908. return -1;
  909. }
  910. if (fg_i2c_read(client, AVG_CURRENT_REG, data2, 2) < 0) {
  911. dev_err(&client->dev, "%s: Failed to read AVERAGE CURRENT\n",
  912. __func__);
  913. return -1;
  914. }
  915. temp = ((data1[1]<<8) | data1[0]) & 0xFFFF;
  916. if (temp & (0x1 << 15)) {
  917. sign = NEGATIVE;
  918. temp = (~temp & 0xFFFF) + 1;
  919. } else
  920. sign = POSITIVE;
  921. /* 1.5625uV/0.01Ohm(Rsense) = 156.25uA */
  922. switch (unit) {
  923. case SEC_BATTEY_CURRENT_UA:
  924. i_current = temp * 15625 / 100;
  925. break;
  926. case SEC_BATTEY_CURRENT_MA:
  927. default:
  928. i_current = temp * 15625 / 100000;
  929. }
  930. if (sign)
  931. i_current *= -1;
  932. temp = ((data2[1]<<8) | data2[0]) & 0xFFFF;
  933. if (temp & (0x1 << 15)) {
  934. sign = NEGATIVE;
  935. temp = (~temp & 0xFFFF) + 1;
  936. } else
  937. sign = POSITIVE;
  938. /* 1.5625uV/0.01Ohm(Rsense) = 156.25uA */
  939. avg_current = temp * 15625 / 100000;
  940. if (sign)
  941. avg_current *= -1;
  942. vcell = fg_read_vcell(client);
  943. if ((vcell > 3000) && (vcell < 3500) && (cnt < 5) && (i_current < 0) &&
  944. fuelgauge->is_charging) {
  945. i_current = 1;
  946. cnt++;
  947. }
  948. if (!(fuelgauge->info.pr_cnt++ % PRINT_COUNT)) {
  949. fg_test_print(client);
  950. dev_info(&client->dev, "%s: CURRENT(%dmA), AVG_CURRENT(%dmA)\n",
  951. __func__, i_current, avg_current);
  952. fuelgauge->info.pr_cnt = 1;
  953. /* Read max17050's all registers every 5 minute. */
  954. fg_periodic_read(client);
  955. }
  956. return i_current;
  957. }
  958. static int fg_read_avg_current(struct i2c_client *client, int unit)
  959. {
  960. u8 data2[2];
  961. u32 temp, sign;
  962. s32 avg_current;
  963. int vcell;
  964. static int cnt;
  965. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  966. if (fg_i2c_read(client, AVG_CURRENT_REG, data2, 2) < 0) {
  967. dev_err(&client->dev, "%s: Failed to read AVERAGE CURRENT\n",
  968. __func__);
  969. return -1;
  970. }
  971. temp = ((data2[1]<<8) | data2[0]) & 0xFFFF;
  972. if (temp & (0x1 << 15)) {
  973. sign = NEGATIVE;
  974. temp = (~temp & 0xFFFF) + 1;
  975. } else
  976. sign = POSITIVE;
  977. /* 1.5625uV/0.01Ohm(Rsense) = 156.25uA */
  978. switch (unit) {
  979. case SEC_BATTEY_CURRENT_UA:
  980. avg_current = temp * 15625 / 100;
  981. break;
  982. case SEC_BATTEY_CURRENT_MA:
  983. default:
  984. avg_current = temp * 15625 / 100000;
  985. }
  986. if (sign)
  987. avg_current *= -1;
  988. vcell = fg_read_vcell(client);
  989. if ((vcell > 3000) && (vcell < 3500) && (cnt < 5) && (avg_current < 0) &&
  990. fuelgauge->is_charging) {
  991. avg_current = 1;
  992. cnt++;
  993. }
  994. return avg_current;
  995. }
  996. int fg_reset_soc(struct i2c_client *client)
  997. {
  998. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  999. u8 data[2];
  1000. int vfocv, fullcap;
  1001. /* delay for current stablization */
  1002. msleep(500);
  1003. dev_info(&client->dev,
  1004. "%s: Before quick-start - VCELL(%d), VFOCV(%d), VfSOC(%d), RepSOC(%d)\n",
  1005. __func__, fg_read_vcell(client), fg_read_vfocv(client),
  1006. fg_read_vfsoc(client), fg_read_soc(client));
  1007. dev_info(&client->dev,
  1008. "%s: Before quick-start - current(%d), avg current(%d)\n",
  1009. __func__, fg_read_current(client, SEC_BATTEY_CURRENT_MA),
  1010. fg_read_avg_current(client, SEC_BATTEY_CURRENT_MA));
  1011. if (!sec_bat_check_jig_status()) {
  1012. dev_info(&client->dev,
  1013. "%s : Return by No JIG_ON signal\n", __func__);
  1014. return 0;
  1015. } else if (fuelgauge->pdata->jig_irq &&
  1016. !gpio_get_value(fuelgauge->pdata->jig_irq)) {
  1017. dev_info(&client->dev,
  1018. "%s : Return by No JIG_ON signal\n", __func__);
  1019. return 0;
  1020. }
  1021. fg_write_register(client, CYCLES_REG, 0);
  1022. if (fg_i2c_read(client, MISCCFG_REG, data, 2) < 0) {
  1023. dev_err(&client->dev, "%s: Failed to read MiscCFG\n", __func__);
  1024. return -1;
  1025. }
  1026. data[1] |= (0x1 << 2);
  1027. if (fg_i2c_write(client, MISCCFG_REG, data, 2) < 0) {
  1028. dev_err(&client->dev,
  1029. "%s: Failed to write MiscCFG\n", __func__);
  1030. return -1;
  1031. }
  1032. msleep(250);
  1033. fg_write_register(client, FULLCAP_REG,
  1034. get_battery_data(fuelgauge).Capacity);
  1035. msleep(500);
  1036. dev_info(&client->dev,
  1037. "%s: After quick-start - VCELL(%d), VFOCV(%d), VfSOC(%d), RepSOC(%d)\n",
  1038. __func__, fg_read_vcell(client), fg_read_vfocv(client),
  1039. fg_read_vfsoc(client), fg_read_soc(client));
  1040. dev_info(&client->dev,
  1041. "%s: After quick-start - current(%d), avg current(%d)\n",
  1042. __func__, fg_read_current(client, SEC_BATTEY_CURRENT_MA),
  1043. fg_read_avg_current(client, SEC_BATTEY_CURRENT_MA));
  1044. fg_write_register(client, CYCLES_REG, 0x00a0);
  1045. /* P8 is not turned off by Quickstart @3.4V
  1046. * (It's not a problem, depend on mode data)
  1047. * Power off for factory test(File system, etc..) */
  1048. vfocv = fg_read_vfocv(client);
  1049. if (vfocv < POWER_OFF_VOLTAGE_LOW_MARGIN) {
  1050. dev_info(&client->dev, "%s: Power off condition(%d)\n",
  1051. __func__, vfocv);
  1052. fullcap = fg_read_register(client, FULLCAP_REG);
  1053. /* FullCAP * 0.009 */
  1054. fg_write_register(client, REMCAP_REP_REG,
  1055. (u16)(fullcap * 9 / 1000));
  1056. msleep(200);
  1057. dev_info(&client->dev, "%s: new soc=%d, vfocv=%d\n", __func__,
  1058. fg_read_soc(client), vfocv);
  1059. }
  1060. dev_info(&client->dev,
  1061. "%s: Additional step - VfOCV(%d), VfSOC(%d), RepSOC(%d)\n",
  1062. __func__, fg_read_vfocv(client),
  1063. fg_read_vfsoc(client), fg_read_soc(client));
  1064. return 0;
  1065. }
  1066. int fg_reset_capacity_by_jig_connection(struct i2c_client *client)
  1067. {
  1068. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  1069. union power_supply_propval value;
  1070. dev_info(&client->dev,
  1071. "%s: DesignCap = Capacity - 1 (Jig Connection)\n", __func__);
  1072. /* If JIG is attached, the voltage is set as 1079 */
  1073. value.intval = 1079;
  1074. psy_do_property("battery", set,
  1075. POWER_SUPPLY_PROP_VOLTAGE_NOW, value);
  1076. return fg_write_register(client, DESIGNCAP_REG,
  1077. get_battery_data(fuelgauge).Capacity-1);
  1078. }
  1079. int fg_adjust_capacity(struct i2c_client *client)
  1080. {
  1081. u8 data[2];
  1082. data[0] = 0;
  1083. data[1] = 0;
  1084. /* 1. Write RemCapREP(05h)=0; */
  1085. if (fg_i2c_write(client, REMCAP_REP_REG, data, 2) < 0) {
  1086. dev_err(&client->dev, "%s: Failed to write RemCap_REP\n",
  1087. __func__);
  1088. return -1;
  1089. }
  1090. msleep(200);
  1091. dev_info(&client->dev, "%s: After adjust - RepSOC(%d)\n", __func__,
  1092. fg_read_soc(client));
  1093. return 0;
  1094. }
  1095. void fg_low_batt_compensation(struct i2c_client *client, u32 level)
  1096. {
  1097. int read_val;
  1098. u32 temp;
  1099. dev_info(&client->dev, "%s: Adjust SOCrep to %d!!\n",
  1100. __func__, level);
  1101. read_val = fg_read_register(client, FULLCAP_REG);
  1102. /* RemCapREP (05h) = FullCap(10h) x 0.0090 */
  1103. temp = read_val * (level*90) / 10000;
  1104. fg_write_register(client, REMCAP_REP_REG, (u16)temp);
  1105. }
  1106. #if 0
  1107. static void fg_read_model_data(struct i2c_client *client)
  1108. {
  1109. u16 data0[16], data1[16], data2[16];
  1110. int i;
  1111. int relock_check, relock_count = 0;
  1112. dev_info(&client->dev, "[FG_Model] ");
  1113. /* Unlock model access */
  1114. fg_write_register(client, 0x62, 0x0059);
  1115. fg_write_register(client, 0x63, 0x00C4);
  1116. /* Read model data */
  1117. fg_read_16register(client, 0x80, data0);
  1118. fg_read_16register(client, 0x90, data1);
  1119. fg_read_16register(client, 0xa0, data2);
  1120. /* Print model data */
  1121. for (i = 0; i < 16; i++)
  1122. dev_info(&client->dev, "0x%04x, ", data0[i]);
  1123. for (i = 0; i < 16; i++)
  1124. dev_info(&client->dev, "0x%04x, ", data1[i]);
  1125. for (i = 0; i < 16; i++) {
  1126. if (i == 15)
  1127. dev_info(&client->dev, "0x%04x", data2[i]);
  1128. else
  1129. dev_info(&client->dev, "0x%04x, ", data2[i]);
  1130. }
  1131. do {
  1132. relock_check = 0;
  1133. /* Lock model access */
  1134. fg_write_register(client, 0x62, 0x0000);
  1135. fg_write_register(client, 0x63, 0x0000);
  1136. /* Read model data again */
  1137. fg_read_16register(client, 0x80, data0);
  1138. fg_read_16register(client, 0x90, data1);
  1139. fg_read_16register(client, 0xa0, data2);
  1140. for (i = 0; i < 16; i++) {
  1141. if (data0[i] || data1[i] || data2[i]) {
  1142. dev_dbg(&client->dev,
  1143. "%s: data is non-zero, lock again!!\n",
  1144. __func__);
  1145. relock_check = 1;
  1146. }
  1147. }
  1148. relock_count++;
  1149. if (relock_count > 3)
  1150. relock_check = 0;
  1151. } while (relock_check);
  1152. }
  1153. #endif
  1154. static int fg_check_status_reg(struct i2c_client *client)
  1155. {
  1156. u8 status_data[2];
  1157. int ret = 0;
  1158. /* 1. Check Smn was generatedread */
  1159. if (fg_i2c_read(client, STATUS_REG, status_data, 2) < 0) {
  1160. dev_err(&client->dev, "%s: Failed to read STATUS_REG\n",
  1161. __func__);
  1162. return -1;
  1163. }
  1164. dev_info(&client->dev, "%s: addr(0x00), data(0x%04x)\n", __func__,
  1165. (status_data[1]<<8) | status_data[0]);
  1166. if (status_data[1] & (0x1 << 2))
  1167. ret = 1;
  1168. /* 2. clear Status reg */
  1169. status_data[1] = 0;
  1170. if (fg_i2c_write(client, STATUS_REG, status_data, 2) < 0) {
  1171. dev_info(&client->dev, "%s: Failed to write STATUS_REG\n",
  1172. __func__);
  1173. return -1;
  1174. }
  1175. return ret;
  1176. }
  1177. int get_fuelgauge_value(struct i2c_client *client, int data)
  1178. {
  1179. int ret;
  1180. switch (data) {
  1181. case FG_LEVEL:
  1182. ret = fg_read_soc(client);
  1183. break;
  1184. case FG_TEMPERATURE:
  1185. ret = fg_read_temp(client);
  1186. break;
  1187. case FG_VOLTAGE:
  1188. ret = fg_read_vcell(client);
  1189. break;
  1190. case FG_CURRENT:
  1191. ret = fg_read_current(client, SEC_BATTEY_CURRENT_MA);
  1192. break;
  1193. case FG_CURRENT_AVG:
  1194. ret = fg_read_avg_current(client, SEC_BATTEY_CURRENT_MA);
  1195. break;
  1196. case FG_CHECK_STATUS:
  1197. ret = fg_check_status_reg(client);
  1198. break;
  1199. case FG_RAW_SOC:
  1200. ret = fg_read_rawsoc(client);
  1201. break;
  1202. case FG_VF_SOC:
  1203. ret = fg_read_vfsoc(client);
  1204. break;
  1205. case FG_AV_SOC:
  1206. ret = fg_read_avsoc(client);
  1207. break;
  1208. case FG_FULLCAP:
  1209. ret = fg_read_fullcap(client);
  1210. break;
  1211. case FG_MIXCAP:
  1212. ret = fg_read_mixcap(client);
  1213. break;
  1214. case FG_AVCAP:
  1215. ret = fg_read_avcap(client);
  1216. break;
  1217. case FG_REPCAP:
  1218. ret = fg_read_repcap(client);
  1219. break;
  1220. default:
  1221. ret = -1;
  1222. break;
  1223. }
  1224. return ret;
  1225. }
  1226. int fg_alert_init(struct i2c_client *client, int soc)
  1227. {
  1228. u8 misccgf_data[2];
  1229. u8 salrt_data[2];
  1230. u8 config_data[2];
  1231. u8 valrt_data[2];
  1232. u8 talrt_data[2];
  1233. u16 read_data = 0;
  1234. /* Using RepSOC */
  1235. if (fg_i2c_read(client, MISCCFG_REG, misccgf_data, 2) < 0) {
  1236. dev_err(&client->dev,
  1237. "%s: Failed to read MISCCFG_REG\n", __func__);
  1238. return -1;
  1239. }
  1240. misccgf_data[0] = misccgf_data[0] & ~(0x03);
  1241. if (fg_i2c_write(client, MISCCFG_REG, misccgf_data, 2) < 0) {
  1242. dev_info(&client->dev,
  1243. "%s: Failed to write MISCCFG_REG\n", __func__);
  1244. return -1;
  1245. }
  1246. /* SALRT Threshold setting */
  1247. salrt_data[1] = 0xff;
  1248. salrt_data[0] = soc;
  1249. if (fg_i2c_write(client, SALRT_THRESHOLD_REG, salrt_data, 2) < 0) {
  1250. dev_info(&client->dev,
  1251. "%s: Failed to write SALRT_THRESHOLD_REG\n", __func__);
  1252. return -1;
  1253. }
  1254. /* Reset VALRT Threshold setting (disable) */
  1255. valrt_data[1] = 0xFF;
  1256. valrt_data[0] = 0x00;
  1257. if (fg_i2c_write(client, VALRT_THRESHOLD_REG, valrt_data, 2) < 0) {
  1258. dev_info(&client->dev,
  1259. "%s: Failed to write VALRT_THRESHOLD_REG\n", __func__);
  1260. return -1;
  1261. }
  1262. read_data = fg_read_register(client, (u8)VALRT_THRESHOLD_REG);
  1263. if (read_data != 0xff00)
  1264. dev_err(&client->dev,
  1265. "%s: VALRT_THRESHOLD_REG is not valid (0x%x)\n",
  1266. __func__, read_data);
  1267. /* Reset TALRT Threshold setting (disable) */
  1268. talrt_data[1] = 0x7F;
  1269. talrt_data[0] = 0x80;
  1270. if (fg_i2c_write(client, TALRT_THRESHOLD_REG, talrt_data, 2) < 0) {
  1271. dev_info(&client->dev,
  1272. "%s: Failed to write TALRT_THRESHOLD_REG\n", __func__);
  1273. return -1;
  1274. }
  1275. read_data = fg_read_register(client, (u8)TALRT_THRESHOLD_REG);
  1276. if (read_data != 0x7f80)
  1277. dev_err(&client->dev,
  1278. "%s: TALRT_THRESHOLD_REG is not valid (0x%x)\n",
  1279. __func__, read_data);
  1280. /*mdelay(100);*/
  1281. /* Enable SOC alerts */
  1282. if (fg_i2c_read(client, CONFIG_REG, config_data, 2) < 0) {
  1283. dev_err(&client->dev,
  1284. "%s: Failed to read CONFIG_REG\n", __func__);
  1285. return -1;
  1286. }
  1287. config_data[0] = config_data[0] | (0x1 << 2);
  1288. if (fg_i2c_write(client, CONFIG_REG, config_data, 2) < 0) {
  1289. dev_info(&client->dev,
  1290. "%s: Failed to write CONFIG_REG\n", __func__);
  1291. return -1;
  1292. }
  1293. return 1;
  1294. }
  1295. void fg_fullcharged_compensation(struct i2c_client *client,
  1296. u32 is_recharging, bool pre_update)
  1297. {
  1298. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  1299. static int new_fullcap_data;
  1300. dev_info(&client->dev, "%s: is_recharging(%d), pre_update(%d)\n",
  1301. __func__, is_recharging, pre_update);
  1302. new_fullcap_data =
  1303. fg_read_register(client, FULLCAP_REG);
  1304. if (new_fullcap_data < 0)
  1305. new_fullcap_data = get_battery_data(fuelgauge).Capacity;
  1306. /* compare with initial capacity */
  1307. if (new_fullcap_data >
  1308. (get_battery_data(fuelgauge).Capacity * 110 / 100)) {
  1309. dev_info(&client->dev,
  1310. "%s: [Case 1] capacity = 0x%04x, NewFullCap = 0x%04x\n",
  1311. __func__, get_battery_data(fuelgauge).Capacity,
  1312. new_fullcap_data);
  1313. new_fullcap_data =
  1314. (get_battery_data(fuelgauge).Capacity * 110) / 100;
  1315. fg_write_register(client, REMCAP_REP_REG,
  1316. (u16)(new_fullcap_data));
  1317. fg_write_register(client, FULLCAP_REG,
  1318. (u16)(new_fullcap_data));
  1319. } else if (new_fullcap_data <
  1320. (get_battery_data(fuelgauge).Capacity * 50 / 100)) {
  1321. dev_info(&client->dev,
  1322. "%s: [Case 5] capacity = 0x%04x, NewFullCap = 0x%04x\n",
  1323. __func__, get_battery_data(fuelgauge).Capacity,
  1324. new_fullcap_data);
  1325. new_fullcap_data =
  1326. (get_battery_data(fuelgauge).Capacity * 50) / 100;
  1327. fg_write_register(client, REMCAP_REP_REG,
  1328. (u16)(new_fullcap_data));
  1329. fg_write_register(client, FULLCAP_REG,
  1330. (u16)(new_fullcap_data));
  1331. } else {
  1332. /* compare with previous capacity */
  1333. if (new_fullcap_data >
  1334. (fuelgauge->info.previous_fullcap * 110 / 100)) {
  1335. dev_info(&client->dev,
  1336. "%s: [Case 2] previous_fullcap = 0x%04x, NewFullCap = 0x%04x\n",
  1337. __func__, fuelgauge->info.previous_fullcap,
  1338. new_fullcap_data);
  1339. new_fullcap_data =
  1340. (fuelgauge->info.previous_fullcap * 110) / 100;
  1341. fg_write_register(client, REMCAP_REP_REG,
  1342. (u16)(new_fullcap_data));
  1343. fg_write_register(client, FULLCAP_REG,
  1344. (u16)(new_fullcap_data));
  1345. } else if (new_fullcap_data <
  1346. (fuelgauge->info.previous_fullcap * 90 / 100)) {
  1347. dev_info(&client->dev,
  1348. "%s: [Case 3] previous_fullcap = 0x%04x, NewFullCap = 0x%04x\n",
  1349. __func__, fuelgauge->info.previous_fullcap,
  1350. new_fullcap_data);
  1351. new_fullcap_data =
  1352. (fuelgauge->info.previous_fullcap * 90) / 100;
  1353. fg_write_register(client, REMCAP_REP_REG,
  1354. (u16)(new_fullcap_data));
  1355. fg_write_register(client, FULLCAP_REG,
  1356. (u16)(new_fullcap_data));
  1357. } else {
  1358. dev_info(&client->dev,
  1359. "%s: [Case 4] previous_fullcap = 0x%04x, NewFullCap = 0x%04x\n",
  1360. __func__, fuelgauge->info.previous_fullcap,
  1361. new_fullcap_data);
  1362. }
  1363. }
  1364. /* 4. Write RepSOC(06h)=100%; */
  1365. fg_write_register(client, SOCREP_REG, (u16)(0x64 << 8));
  1366. /* 5. Write MixSOC(0Dh)=100%; */
  1367. fg_write_register(client, SOCMIX_REG, (u16)(0x64 << 8));
  1368. /* 6. Write AVSOC(0Eh)=100%; */
  1369. fg_write_register(client, SOCAV_REG, (u16)(0x64 << 8));
  1370. /* if pre_update case, skip updating PrevFullCAP value. */
  1371. if (!pre_update)
  1372. fuelgauge->info.previous_fullcap =
  1373. fg_read_register(client, FULLCAP_REG);
  1374. dev_info(&client->dev,
  1375. "%s: (A) FullCap = 0x%04x, RemCap = 0x%04x\n", __func__,
  1376. fg_read_register(client, FULLCAP_REG),
  1377. fg_read_register(client, REMCAP_REP_REG));
  1378. fg_periodic_read(client);
  1379. }
  1380. void fg_check_vf_fullcap_range(struct i2c_client *client)
  1381. {
  1382. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  1383. static int new_vffullcap;
  1384. bool is_vffullcap_changed = true;
  1385. if (sec_bat_check_jig_status())
  1386. fg_reset_capacity_by_jig_connection(client);
  1387. else if (fuelgauge->pdata->jig_irq &&
  1388. gpio_get_value(fuelgauge->pdata->jig_irq))
  1389. fg_reset_capacity_by_jig_connection(client);
  1390. new_vffullcap = fg_read_register(client, FULLCAP_NOM_REG);
  1391. if (new_vffullcap < 0)
  1392. new_vffullcap = get_battery_data(fuelgauge).Capacity;
  1393. /* compare with initial capacity */
  1394. if (new_vffullcap >
  1395. (get_battery_data(fuelgauge).Capacity * 110 / 100)) {
  1396. dev_info(&client->dev,
  1397. "%s: [Case 1] capacity = 0x%04x, NewVfFullCap = 0x%04x\n",
  1398. __func__, get_battery_data(fuelgauge).Capacity,
  1399. new_vffullcap);
  1400. new_vffullcap =
  1401. (get_battery_data(fuelgauge).Capacity * 110) / 100;
  1402. fg_write_register(client, DQACC_REG,
  1403. (u16)(new_vffullcap / 4));
  1404. fg_write_register(client, DPACC_REG, (u16)0x3200);
  1405. } else if (new_vffullcap <
  1406. (get_battery_data(fuelgauge).Capacity * 50 / 100)) {
  1407. dev_info(&client->dev,
  1408. "%s: [Case 5] capacity = 0x%04x, NewVfFullCap = 0x%04x\n",
  1409. __func__, get_battery_data(fuelgauge).Capacity,
  1410. new_vffullcap);
  1411. new_vffullcap =
  1412. (get_battery_data(fuelgauge).Capacity * 50) / 100;
  1413. fg_write_register(client, DQACC_REG,
  1414. (u16)(new_vffullcap / 4));
  1415. fg_write_register(client, DPACC_REG, (u16)0x3200);
  1416. } else {
  1417. /* compare with previous capacity */
  1418. if (new_vffullcap >
  1419. (fuelgauge->info.previous_vffullcap * 110 / 100)) {
  1420. dev_info(&client->dev,
  1421. "%s: [Case 2] previous_vffullcap = 0x%04x, NewVfFullCap = 0x%04x\n",
  1422. __func__, fuelgauge->info.previous_vffullcap,
  1423. new_vffullcap);
  1424. new_vffullcap =
  1425. (fuelgauge->info.previous_vffullcap * 110) /
  1426. 100;
  1427. fg_write_register(client, DQACC_REG,
  1428. (u16)(new_vffullcap / 4));
  1429. fg_write_register(client, DPACC_REG, (u16)0x3200);
  1430. } else if (new_vffullcap <
  1431. (fuelgauge->info.previous_vffullcap * 90 / 100)) {
  1432. dev_info(&client->dev,
  1433. "%s: [Case 3] previous_vffullcap = 0x%04x, NewVfFullCap = 0x%04x\n",
  1434. __func__, fuelgauge->info.previous_vffullcap,
  1435. new_vffullcap);
  1436. new_vffullcap =
  1437. (fuelgauge->info.previous_vffullcap * 90) / 100;
  1438. fg_write_register(client, DQACC_REG,
  1439. (u16)(new_vffullcap / 4));
  1440. fg_write_register(client, DPACC_REG, (u16)0x3200);
  1441. } else {
  1442. dev_info(&client->dev,
  1443. "%s: [Case 4] previous_vffullcap = 0x%04x, NewVfFullCap = 0x%04x\n",
  1444. __func__, fuelgauge->info.previous_vffullcap,
  1445. new_vffullcap);
  1446. is_vffullcap_changed = false;
  1447. }
  1448. }
  1449. /* delay for register setting (dQacc, dPacc) */
  1450. if (is_vffullcap_changed)
  1451. msleep(300);
  1452. fuelgauge->info.previous_vffullcap =
  1453. fg_read_register(client, FULLCAP_NOM_REG);
  1454. if (is_vffullcap_changed)
  1455. dev_info(&client->dev,
  1456. "%s : VfFullCap(0x%04x), dQacc(0x%04x), dPacc(0x%04x)\n",
  1457. __func__,
  1458. fg_read_register(client, FULLCAP_NOM_REG),
  1459. fg_read_register(client, DQACC_REG),
  1460. fg_read_register(client, DPACC_REG));
  1461. }
  1462. void fg_set_full_charged(struct i2c_client *client)
  1463. {
  1464. dev_info(&client->dev, "[FG_Set_Full] (B) FullCAP(%d), RemCAP(%d)\n",
  1465. (fg_read_register(client, FULLCAP_REG)/2),
  1466. (fg_read_register(client, REMCAP_REP_REG)/2));
  1467. fg_write_register(client, FULLCAP_REG,
  1468. (u16)fg_read_register(client, REMCAP_REP_REG));
  1469. dev_info(&client->dev, "[FG_Set_Full] (A) FullCAP(%d), RemCAP(%d)\n",
  1470. (fg_read_register(client, FULLCAP_REG)/2),
  1471. (fg_read_register(client, REMCAP_REP_REG)/2));
  1472. }
  1473. static void display_low_batt_comp_cnt(struct i2c_client *client)
  1474. {
  1475. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  1476. pr_info("Check Array(%s): [%d, %d], [%d, %d], ",
  1477. get_battery_data(fuelgauge).type_str,
  1478. fuelgauge->info.low_batt_comp_cnt[0][0],
  1479. fuelgauge->info.low_batt_comp_cnt[0][1],
  1480. fuelgauge->info.low_batt_comp_cnt[1][0],
  1481. fuelgauge->info.low_batt_comp_cnt[1][1]);
  1482. pr_info("[%d, %d], [%d, %d], [%d, %d]\n",
  1483. fuelgauge->info.low_batt_comp_cnt[2][0],
  1484. fuelgauge->info.low_batt_comp_cnt[2][1],
  1485. fuelgauge->info.low_batt_comp_cnt[3][0],
  1486. fuelgauge->info.low_batt_comp_cnt[3][1],
  1487. fuelgauge->info.low_batt_comp_cnt[4][0],
  1488. fuelgauge->info.low_batt_comp_cnt[4][1]);
  1489. }
  1490. static void add_low_batt_comp_cnt(struct i2c_client *client,
  1491. int range, int level)
  1492. {
  1493. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  1494. int i;
  1495. int j;
  1496. /* Increase the requested count value, and reset others. */
  1497. fuelgauge->info.low_batt_comp_cnt[range-1][level/2]++;
  1498. for (i = 0; i < LOW_BATT_COMP_RANGE_NUM; i++) {
  1499. for (j = 0; j < LOW_BATT_COMP_LEVEL_NUM; j++) {
  1500. if (i == range-1 && j == level/2)
  1501. continue;
  1502. else
  1503. fuelgauge->info.low_batt_comp_cnt[i][j] = 0;
  1504. }
  1505. }
  1506. }
  1507. void prevent_early_poweroff(struct i2c_client *client,
  1508. int vcell, int *fg_soc)
  1509. {
  1510. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  1511. int soc = 0;
  1512. int read_val;
  1513. soc = fg_read_soc(client);
  1514. /* No need to write REMCAP_REP in below normal cases */
  1515. if (soc > POWER_OFF_SOC_HIGH_MARGIN || vcell > get_battery_data(fuelgauge).low_battery_comp_voltage)
  1516. return;
  1517. dev_info(&client->dev, "%s: soc=%d, vcell=%d\n", __func__,
  1518. soc, vcell);
  1519. if (vcell > POWER_OFF_VOLTAGE_HIGH_MARGIN) {
  1520. read_val = fg_read_register(client, FULLCAP_REG);
  1521. /* FullCAP * 0.013 */
  1522. fg_write_register(client, REMCAP_REP_REG,
  1523. (u16)(read_val * 13 / 1000));
  1524. msleep(200);
  1525. *fg_soc = fg_read_soc(client);
  1526. dev_info(&client->dev, "%s: new soc=%d, vcell=%d\n",
  1527. __func__, *fg_soc, vcell);
  1528. }
  1529. }
  1530. void reset_low_batt_comp_cnt(struct i2c_client *client)
  1531. {
  1532. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  1533. memset(fuelgauge->info.low_batt_comp_cnt, 0,
  1534. sizeof(fuelgauge->info.low_batt_comp_cnt));
  1535. }
  1536. static int check_low_batt_comp_condition(
  1537. struct i2c_client *client, int *nLevel)
  1538. {
  1539. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  1540. int i;
  1541. int j;
  1542. int ret = 0;
  1543. for (i = 0; i < LOW_BATT_COMP_RANGE_NUM; i++) {
  1544. for (j = 0; j < LOW_BATT_COMP_LEVEL_NUM; j++) {
  1545. if (fuelgauge->info.low_batt_comp_cnt[i][j] >=
  1546. MAX_LOW_BATT_CHECK_CNT) {
  1547. display_low_batt_comp_cnt(client);
  1548. ret = 1;
  1549. *nLevel = j*2 + 1;
  1550. break;
  1551. }
  1552. }
  1553. }
  1554. return ret;
  1555. }
  1556. static int get_low_batt_threshold(struct i2c_client *client,
  1557. int range, int nCurrent, int level)
  1558. {
  1559. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  1560. int ret = 0;
  1561. ret = get_battery_data(fuelgauge).low_battery_table[range][OFFSET] +
  1562. ((nCurrent *
  1563. get_battery_data(fuelgauge).low_battery_table[range][SLOPE]) /
  1564. 1000);
  1565. return ret;
  1566. }
  1567. int low_batt_compensation(struct i2c_client *client,
  1568. int fg_soc, int fg_vcell, int fg_current)
  1569. {
  1570. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  1571. int fg_avg_current = 0;
  1572. int fg_min_current = 0;
  1573. int new_level = 0;
  1574. int i, table_size;
  1575. /* Not charging, Under low battery comp voltage */
  1576. if (fg_vcell <= get_battery_data(fuelgauge).low_battery_comp_voltage) {
  1577. fg_avg_current = fg_read_avg_current(client,
  1578. SEC_BATTEY_CURRENT_MA);
  1579. fg_min_current = min(fg_avg_current, fg_current);
  1580. table_size =
  1581. sizeof(get_battery_data(fuelgauge).low_battery_table) /
  1582. (sizeof(s16)*TABLE_MAX);
  1583. for (i = 1; i < CURRENT_RANGE_MAX_NUM; i++) {
  1584. if ((fg_min_current >= get_battery_data(fuelgauge).
  1585. low_battery_table[i-1][RANGE]) &&
  1586. (fg_min_current < get_battery_data(fuelgauge).
  1587. low_battery_table[i][RANGE])) {
  1588. if (fg_soc >= 10 && fg_vcell <
  1589. get_low_batt_threshold(client,
  1590. i, fg_min_current, 1)) {
  1591. add_low_batt_comp_cnt(
  1592. client, i, 1);
  1593. } else {
  1594. reset_low_batt_comp_cnt(client);
  1595. }
  1596. }
  1597. }
  1598. if (check_low_batt_comp_condition(client, &new_level)) {
  1599. fg_low_batt_compensation(client, new_level);
  1600. reset_low_batt_comp_cnt(client);
  1601. /* Do not update soc right after
  1602. * low battery compensation
  1603. * to prevent from powering-off suddenly
  1604. */
  1605. dev_info(&client->dev,
  1606. "%s: SOC is set to %d by low compensation!!\n",
  1607. __func__, fg_read_soc(client));
  1608. }
  1609. }
  1610. /* Prevent power off over 3500mV */
  1611. prevent_early_poweroff(client, fg_vcell, &fg_soc);
  1612. return fg_soc;
  1613. }
  1614. static bool is_booted_in_low_battery(struct i2c_client *client)
  1615. {
  1616. int fg_vcell = get_fuelgauge_value(client, FG_VOLTAGE);
  1617. int fg_current = get_fuelgauge_value(client, FG_CURRENT);
  1618. int threshold = 0;
  1619. threshold = 3300 + ((fg_current * 17) / 100);
  1620. if (fg_vcell <= threshold)
  1621. return true;
  1622. else
  1623. return false;
  1624. }
  1625. static bool fuelgauge_recovery_handler(struct i2c_client *client)
  1626. {
  1627. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  1628. #if 0
  1629. int current_soc;
  1630. int avsoc;
  1631. int temperature;
  1632. #endif
  1633. if (fuelgauge->info.soc < LOW_BATTERY_SOC_REDUCE_UNIT)
  1634. fuelgauge->info.is_low_batt_alarm = false;
  1635. else {
  1636. dev_err(&client->dev,
  1637. "%s: Reduce the Reported SOC by 1%%\n",
  1638. __func__);
  1639. #if 0
  1640. current_soc =
  1641. get_fuelgauge_value(client, FG_LEVEL) / 10;
  1642. if (current_soc) {
  1643. dev_info(&client->dev,
  1644. "%s: Returning to Normal discharge path\n",
  1645. __func__);
  1646. dev_info(&client->dev,
  1647. "%s: Actual SOC(%d) non-zero\n",
  1648. __func__, current_soc);
  1649. fuelgauge->info.is_low_batt_alarm = false;
  1650. } else {
  1651. temperature =
  1652. get_fuelgauge_value(client, FG_TEMPERATURE);
  1653. avsoc =
  1654. get_fuelgauge_value(client, FG_AV_SOC);
  1655. if ((fuelgauge->info.soc > avsoc) ||
  1656. (temperature < 0)) {
  1657. fuelgauge->info.soc -=
  1658. LOW_BATTERY_SOC_REDUCE_UNIT;
  1659. dev_err(&client->dev,
  1660. "%s: New Reduced RepSOC (%d)\n",
  1661. __func__, fuelgauge->info.soc);
  1662. } else
  1663. dev_info(&client->dev,
  1664. "%s: Waiting for recovery (AvSOC:%d)\n",
  1665. __func__, avsoc);
  1666. }
  1667. }
  1668. #endif
  1669. fuelgauge->info.soc -=
  1670. LOW_BATTERY_SOC_REDUCE_UNIT;
  1671. dev_err(&client->dev,
  1672. "%s: New Reduced RepSOC (%d)\n",
  1673. __func__, fuelgauge->info.soc);
  1674. }
  1675. return fuelgauge->info.is_low_batt_alarm;
  1676. }
  1677. static int get_fuelgauge_soc(struct i2c_client *client)
  1678. {
  1679. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  1680. union power_supply_propval value;
  1681. int fg_soc = 0;
  1682. int fg_vfsoc;
  1683. int fg_vcell;
  1684. int fg_current;
  1685. int avg_current;
  1686. struct timespec ts;
  1687. int fullcap_check_interval;
  1688. if (fuelgauge->info.is_low_batt_alarm)
  1689. if (fuelgauge_recovery_handler(client)) {
  1690. fg_soc = fuelgauge->info.soc;
  1691. goto return_soc;
  1692. }
  1693. get_monotonic_boottime(&ts);
  1694. /* check fullcap range */
  1695. fullcap_check_interval =
  1696. (ts.tv_sec - fuelgauge->info.fullcap_check_interval);
  1697. if (fullcap_check_interval >
  1698. VFFULLCAP_CHECK_INTERVAL) {
  1699. dev_info(&client->dev,
  1700. "%s: check fullcap range (interval:%d)\n",
  1701. __func__, fullcap_check_interval);
  1702. fg_check_vf_fullcap_range(client);
  1703. fuelgauge->info.fullcap_check_interval = ts.tv_sec;
  1704. }
  1705. fg_soc = get_fuelgauge_value(client, FG_LEVEL);
  1706. if (fg_soc < 0) {
  1707. dev_info(&client->dev, "Can't read soc!!!");
  1708. fg_soc = fuelgauge->info.soc;
  1709. }
  1710. if (fuelgauge->info.low_batt_boot_flag) {
  1711. fg_soc = 0;
  1712. if (fuelgauge->pdata->check_cable_callback &&
  1713. fuelgauge->pdata->check_cable_callback() !=
  1714. POWER_SUPPLY_TYPE_BATTERY &&
  1715. !is_booted_in_low_battery(client)) {
  1716. fg_adjust_capacity(client);
  1717. fuelgauge->info.low_batt_boot_flag = 0;
  1718. }
  1719. if (fuelgauge->pdata->check_cable_callback &&
  1720. fuelgauge->pdata->check_cable_callback() ==
  1721. POWER_SUPPLY_TYPE_BATTERY)
  1722. fuelgauge->info.low_batt_boot_flag = 0;
  1723. }
  1724. fg_vcell = get_fuelgauge_value(client, FG_VOLTAGE);
  1725. fg_current = get_fuelgauge_value(client, FG_CURRENT);
  1726. avg_current = get_fuelgauge_value(client, FG_CURRENT_AVG);
  1727. fg_vfsoc = get_fuelgauge_value(client, FG_VF_SOC);
  1728. psy_do_property("battery", get,
  1729. POWER_SUPPLY_PROP_STATUS, value);
  1730. /* Algorithm for reducing time to fully charged (from MAXIM) */
  1731. if (value.intval != POWER_SUPPLY_STATUS_DISCHARGING &&
  1732. value.intval != POWER_SUPPLY_STATUS_FULL &&
  1733. fuelgauge->cable_type != POWER_SUPPLY_TYPE_USB &&
  1734. /* Skip when first check after boot up */
  1735. !fuelgauge->info.is_first_check &&
  1736. (fg_vfsoc > VFSOC_FOR_FULLCAP_LEARNING &&
  1737. (fg_current > LOW_CURRENT_FOR_FULLCAP_LEARNING &&
  1738. fg_current < HIGH_CURRENT_FOR_FULLCAP_LEARNING) &&
  1739. (avg_current > LOW_AVGCURRENT_FOR_FULLCAP_LEARNING &&
  1740. avg_current < HIGH_AVGCURRENT_FOR_FULLCAP_LEARNING))) {
  1741. if (fuelgauge->info.full_check_flag == 2) {
  1742. dev_info(&client->dev,
  1743. "%s: force fully charged SOC !! (%d)",
  1744. __func__, fuelgauge->info.full_check_flag);
  1745. fg_set_full_charged(client);
  1746. fg_soc = get_fuelgauge_value(client, FG_LEVEL);
  1747. } else if (fuelgauge->info.full_check_flag < 2)
  1748. dev_info(&client->dev,
  1749. "%s: full_check_flag (%d)",
  1750. __func__, fuelgauge->info.full_check_flag);
  1751. /* prevent overflow */
  1752. if (fuelgauge->info.full_check_flag++ > 10000)
  1753. fuelgauge->info.full_check_flag = 3;
  1754. } else
  1755. fuelgauge->info.full_check_flag = 0;
  1756. /* Checks vcell level and tries to compensate SOC if needed.*/
  1757. if (fuelgauge->pdata->jig_irq) {
  1758. if (!gpio_get_value(fuelgauge->pdata->jig_irq) &&
  1759. (value.intval == POWER_SUPPLY_STATUS_DISCHARGING))
  1760. fg_soc = low_batt_compensation(
  1761. client, fg_soc, fg_vcell, fg_current);
  1762. } else {
  1763. if(value.intval == POWER_SUPPLY_STATUS_DISCHARGING)
  1764. fg_soc = low_batt_compensation(
  1765. client, fg_soc, fg_vcell, fg_current);
  1766. }
  1767. if (fuelgauge->info.is_first_check)
  1768. fuelgauge->info.is_first_check = false;
  1769. fuelgauge->info.soc = fg_soc;
  1770. return_soc:
  1771. dev_dbg(&client->dev, "%s: soc(%d), low_batt_alarm(%d)\n",
  1772. __func__, fuelgauge->info.soc,
  1773. fuelgauge->info.is_low_batt_alarm);
  1774. return fg_soc;
  1775. }
  1776. static void full_comp_work_handler(struct work_struct *work)
  1777. {
  1778. struct sec_fg_info *fg_info =
  1779. container_of(work, struct sec_fg_info, full_comp_work.work);
  1780. struct sec_fuelgauge_info *fuelgauge =
  1781. container_of(fg_info, struct sec_fuelgauge_info, info);
  1782. int avg_current;
  1783. union power_supply_propval value;
  1784. avg_current = get_fuelgauge_value(fuelgauge->client, FG_CURRENT_AVG);
  1785. psy_do_property("battery", get,
  1786. POWER_SUPPLY_PROP_STATUS, value);
  1787. if (avg_current >= 25) {
  1788. cancel_delayed_work(&fuelgauge->info.full_comp_work);
  1789. schedule_delayed_work(&fuelgauge->info.full_comp_work, 100);
  1790. } else {
  1791. dev_info(&fuelgauge->client->dev,
  1792. "%s: full charge compensation start (avg_current %d)\n",
  1793. __func__, avg_current);
  1794. fg_fullcharged_compensation(fuelgauge->client,
  1795. (int)(value.intval ==
  1796. POWER_SUPPLY_STATUS_FULL), false);
  1797. }
  1798. }
  1799. static irqreturn_t sec_jig_irq_thread(int irq, void *irq_data)
  1800. {
  1801. struct sec_fuelgauge_info *fuelgauge = irq_data;
  1802. if (gpio_get_value(fuelgauge->pdata->jig_irq))
  1803. fg_reset_capacity_by_jig_connection(fuelgauge->client);
  1804. else
  1805. dev_info(&fuelgauge->client->dev,
  1806. "%s: jig removed\n", __func__);
  1807. return IRQ_HANDLED;
  1808. }
  1809. bool sec_hal_fg_init(struct i2c_client *client)
  1810. {
  1811. struct sec_fuelgauge_info *fuelgauge =
  1812. i2c_get_clientdata(client);
  1813. struct timespec ts;
  1814. get_monotonic_boottime(&ts);
  1815. board_fuelgauge_init(fuelgauge);
  1816. fuelgauge->info.fullcap_check_interval = ts.tv_sec;
  1817. fuelgauge->info.is_low_batt_alarm = false;
  1818. fuelgauge->info.is_first_check = true;
  1819. /* Init parameters to prevent wrong compensation. */
  1820. fuelgauge->info.previous_fullcap =
  1821. fg_read_register(client, FULLCAP_REG);
  1822. fuelgauge->info.previous_vffullcap =
  1823. fg_read_register(client, FULLCAP_NOM_REG);
  1824. /*fg_read_model_data(client);*/
  1825. fg_periodic_read(client);
  1826. if (fuelgauge->pdata->check_cable_callback &&
  1827. (fuelgauge->pdata->check_cable_callback() !=
  1828. POWER_SUPPLY_TYPE_BATTERY) &&
  1829. is_booted_in_low_battery(client))
  1830. fuelgauge->info.low_batt_boot_flag = 1;
  1831. if (sec_bat_check_jig_status())
  1832. fg_reset_capacity_by_jig_connection(client);
  1833. else {
  1834. if (fuelgauge->pdata->jig_irq >= 0) {
  1835. int ret;
  1836. ret = request_threaded_irq(
  1837. gpio_to_irq(fuelgauge->pdata->jig_irq),
  1838. NULL, sec_jig_irq_thread,
  1839. fuelgauge->pdata->jig_irq_attr,
  1840. "jig-irq", fuelgauge);
  1841. if (ret) {
  1842. dev_info(&fuelgauge->client->dev,
  1843. "%s: Failed to Reqeust IRQ\n",
  1844. __func__);
  1845. }
  1846. }
  1847. }
  1848. INIT_DELAYED_WORK(&fuelgauge->info.full_comp_work,
  1849. full_comp_work_handler);
  1850. return true;
  1851. }
  1852. bool sec_hal_fg_suspend(struct i2c_client *client)
  1853. {
  1854. return true;
  1855. }
  1856. bool sec_hal_fg_resume(struct i2c_client *client)
  1857. {
  1858. return true;
  1859. }
  1860. bool sec_hal_fg_fuelalert_init(struct i2c_client *client, int soc)
  1861. {
  1862. if (fg_alert_init(client, soc) > 0)
  1863. return true;
  1864. else
  1865. return false;
  1866. }
  1867. bool sec_hal_fg_is_fuelalerted(struct i2c_client *client)
  1868. {
  1869. if (get_fuelgauge_value(client, FG_CHECK_STATUS) > 0)
  1870. return true;
  1871. else
  1872. return false;
  1873. }
  1874. bool sec_hal_fg_fuelalert_process(void *irq_data, bool is_fuel_alerted)
  1875. {
  1876. struct sec_fuelgauge_info *fuelgauge =
  1877. (struct sec_fuelgauge_info *)irq_data;
  1878. union power_supply_propval value;
  1879. int overcurrent_limit_in_soc;
  1880. int current_soc =
  1881. get_fuelgauge_value(fuelgauge->client, FG_LEVEL);
  1882. #if defined(FUELALERT_CHECK_VOLTAGE_FEATURE)
  1883. int fg_vcell = get_fuelgauge_value(fuelgauge->client, FG_VOLTAGE);
  1884. #endif
  1885. psy_do_property("battery", get,
  1886. POWER_SUPPLY_PROP_STATUS, value);
  1887. if (value.intval ==
  1888. POWER_SUPPLY_STATUS_CHARGING)
  1889. return true;
  1890. if ((int)fuelgauge->info.soc - current_soc <= STABLE_LOW_BATTERY_DIFF)
  1891. overcurrent_limit_in_soc = STABLE_LOW_BATTERY_DIFF_LOWBATT;
  1892. else
  1893. overcurrent_limit_in_soc = STABLE_LOW_BATTERY_DIFF;
  1894. if (((int)fuelgauge->info.soc - current_soc) >
  1895. overcurrent_limit_in_soc) {
  1896. dev_info(&fuelgauge->client->dev,
  1897. "%s: Abnormal Current Consumption jump by %d units\n",
  1898. __func__, (((int)fuelgauge->info.soc - current_soc)));
  1899. dev_info(&fuelgauge->client->dev,
  1900. "%s: Last Reported SOC (%d).\n",
  1901. __func__, fuelgauge->info.soc);
  1902. fuelgauge->info.is_low_batt_alarm = true;
  1903. if (fuelgauge->info.soc >=
  1904. LOW_BATTERY_SOC_REDUCE_UNIT)
  1905. return true;
  1906. }
  1907. if (value.intval ==
  1908. POWER_SUPPLY_STATUS_DISCHARGING) {
  1909. #if defined(FUELALERT_CHECK_VOLTAGE_FEATURE)
  1910. if (fg_vcell >= POWER_OFF_VOLTAGE_HIGH_MARGIN) {
  1911. dev_info(&fuelgauge->client->dev,
  1912. "%s: skip setting battery level as 0 (voltage: %d)\n",
  1913. __func__, fg_vcell);
  1914. return true;
  1915. }
  1916. #endif
  1917. dev_err(&fuelgauge->client->dev,
  1918. "Set battery level as 0, power off.\n");
  1919. fuelgauge->info.soc = 0;
  1920. value.intval = 0;
  1921. psy_do_property("battery", set,
  1922. POWER_SUPPLY_PROP_CAPACITY, value);
  1923. }
  1924. return true;
  1925. }
  1926. bool sec_hal_fg_full_charged(struct i2c_client *client)
  1927. {
  1928. struct sec_fuelgauge_info *fuelgauge =
  1929. i2c_get_clientdata(client);
  1930. union power_supply_propval value;
  1931. psy_do_property("battery", get,
  1932. POWER_SUPPLY_PROP_STATUS, value);
  1933. /* full charge compensation algorithm by MAXIM */
  1934. fg_fullcharged_compensation(client,
  1935. (int)(value.intval == POWER_SUPPLY_STATUS_FULL), true);
  1936. cancel_delayed_work(&fuelgauge->info.full_comp_work);
  1937. schedule_delayed_work(&fuelgauge->info.full_comp_work, 100);
  1938. return false;
  1939. }
  1940. bool sec_hal_fg_reset(struct i2c_client *client)
  1941. {
  1942. if (!fg_reset_soc(client))
  1943. return true;
  1944. else
  1945. return false;
  1946. }
  1947. bool sec_hal_fg_get_property(struct i2c_client *client,
  1948. enum power_supply_property psp,
  1949. union power_supply_propval *val)
  1950. {
  1951. struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client);
  1952. switch (psp) {
  1953. /* Cell voltage (VCELL, mV) */
  1954. case POWER_SUPPLY_PROP_VOLTAGE_NOW:
  1955. val->intval = get_fuelgauge_value(client, FG_VOLTAGE);
  1956. break;
  1957. /* Additional Voltage Information (mV) */
  1958. case POWER_SUPPLY_PROP_VOLTAGE_AVG:
  1959. switch (val->intval) {
  1960. case SEC_BATTEY_VOLTAGE_OCV:
  1961. val->intval = fg_read_vfocv(client);
  1962. break;
  1963. case SEC_BATTEY_VOLTAGE_AVERAGE:
  1964. default:
  1965. val->intval = fg_read_avg_vcell(client);
  1966. break;
  1967. }
  1968. break;
  1969. /* Current */
  1970. case POWER_SUPPLY_PROP_CURRENT_NOW:
  1971. switch (val->intval) {
  1972. case SEC_BATTEY_CURRENT_UA:
  1973. val->intval =
  1974. fg_read_current(client, SEC_BATTEY_CURRENT_UA);
  1975. break;
  1976. case SEC_BATTEY_CURRENT_MA:
  1977. default:
  1978. val->intval = get_fuelgauge_value(client, FG_CURRENT);
  1979. break;
  1980. }
  1981. break;
  1982. /* Average Current */
  1983. case POWER_SUPPLY_PROP_CURRENT_AVG:
  1984. switch (val->intval) {
  1985. case SEC_BATTEY_CURRENT_UA:
  1986. val->intval =
  1987. fg_read_avg_current(client,
  1988. SEC_BATTEY_CURRENT_UA);
  1989. break;
  1990. case SEC_BATTEY_CURRENT_MA:
  1991. default:
  1992. val->intval =
  1993. get_fuelgauge_value(client, FG_CURRENT_AVG);
  1994. break;
  1995. }
  1996. break;
  1997. /* Full Capacity */
  1998. case POWER_SUPPLY_PROP_ENERGY_NOW:
  1999. switch (val->intval) {
  2000. case SEC_BATTEY_CAPACITY_DESIGNED:
  2001. val->intval = get_fuelgauge_value(client, FG_FULLCAP);
  2002. break;
  2003. case SEC_BATTEY_CAPACITY_ABSOLUTE:
  2004. val->intval = get_fuelgauge_value(client, FG_MIXCAP);
  2005. break;
  2006. case SEC_BATTEY_CAPACITY_TEMPERARY:
  2007. val->intval = get_fuelgauge_value(client, FG_AVCAP);
  2008. break;
  2009. case SEC_BATTEY_CAPACITY_CURRENT:
  2010. val->intval = get_fuelgauge_value(client, FG_REPCAP);
  2011. break;
  2012. }
  2013. break;
  2014. /* SOC (%) */
  2015. case POWER_SUPPLY_PROP_CAPACITY:
  2016. if (val->intval == SEC_FUELGAUGE_CAPACITY_TYPE_RAW)
  2017. val->intval = get_fuelgauge_value(client, FG_RAW_SOC);
  2018. else
  2019. val->intval = get_fuelgauge_soc(client);
  2020. break;
  2021. /* Battery Temperature */
  2022. case POWER_SUPPLY_PROP_TEMP:
  2023. val->intval = get_fuelgauge_value(client, FG_TEMPERATURE);
  2024. val->intval = fg_adjust_temp(client, psp, val->intval);
  2025. break;
  2026. /* Target Temperature */
  2027. case POWER_SUPPLY_PROP_TEMP_AMBIENT:
  2028. val->intval = get_fuelgauge_value(client, FG_TEMPERATURE);
  2029. break;
  2030. case POWER_SUPPLY_PROP_ENERGY_FULL:
  2031. val->intval = get_fuelgauge_value(client, FG_FULLCAP) * 100 / get_battery_data(fuelgauge).Capacity;
  2032. break;
  2033. default:
  2034. return false;
  2035. }
  2036. return true;
  2037. }
  2038. bool sec_hal_fg_set_property(struct i2c_client *client,
  2039. enum power_supply_property psp,
  2040. const union power_supply_propval *val)
  2041. {
  2042. struct sec_fuelgauge_info *fuelgauge =
  2043. i2c_get_clientdata(client);
  2044. switch (psp) {
  2045. case POWER_SUPPLY_PROP_CHARGE_TYPE:
  2046. fg_reset_capacity_by_jig_connection(client);
  2047. break;
  2048. case POWER_SUPPLY_PROP_ONLINE:
  2049. if (val->intval != POWER_SUPPLY_TYPE_BATTERY) {
  2050. if (fuelgauge->info.is_low_batt_alarm) {
  2051. dev_info(&client->dev,
  2052. "%s: Reset low_batt_alarm\n",
  2053. __func__);
  2054. fuelgauge->info.is_low_batt_alarm = false;
  2055. }
  2056. reset_low_batt_comp_cnt(client);
  2057. }
  2058. break;
  2059. /* Battery Temperature */
  2060. case POWER_SUPPLY_PROP_TEMP:
  2061. /* Target Temperature */
  2062. case POWER_SUPPLY_PROP_TEMP_AMBIENT:
  2063. break;
  2064. default:
  2065. return false;
  2066. }
  2067. return true;
  2068. }
  2069. ssize_t sec_hal_fg_show_attrs(struct device *dev,
  2070. const ptrdiff_t offset, char *buf)
  2071. {
  2072. struct power_supply *psy = dev_get_drvdata(dev);
  2073. struct sec_fuelgauge_info *fg =
  2074. container_of(psy, struct sec_fuelgauge_info, psy_fg);
  2075. int i = 0;
  2076. char *str = NULL;
  2077. switch (offset) {
  2078. /* case FG_REG: */
  2079. /* break; */
  2080. case FG_DATA:
  2081. i += scnprintf(buf + i, PAGE_SIZE - i, "%02x%02x\n",
  2082. fg->reg_data[1], fg->reg_data[0]);
  2083. break;
  2084. case FG_REGS:
  2085. str = kzalloc(sizeof(char)*1024, GFP_KERNEL);
  2086. if (!str)
  2087. return -ENOMEM;
  2088. fg_read_regs(fg->client, str);
  2089. i += scnprintf(buf + i, PAGE_SIZE - i, "%s\n",
  2090. str);
  2091. kfree(str);
  2092. break;
  2093. default:
  2094. i = -EINVAL;
  2095. break;
  2096. }
  2097. return i;
  2098. }
  2099. ssize_t sec_hal_fg_store_attrs(struct device *dev,
  2100. const ptrdiff_t offset,
  2101. const char *buf, size_t count)
  2102. {
  2103. struct power_supply *psy = dev_get_drvdata(dev);
  2104. struct sec_fuelgauge_info *fg =
  2105. container_of(psy, struct sec_fuelgauge_info, psy_fg);
  2106. int ret = 0;
  2107. int x = 0;
  2108. switch (offset) {
  2109. case FG_REG:
  2110. if (sscanf(buf, "%x\n", &x) == 1) {
  2111. fg->reg_addr = x;
  2112. if (fg_i2c_read(fg->client,
  2113. fg->reg_addr, fg->reg_data, 2) < 0) {
  2114. dev_err(dev, "%s: Error in read\n", __func__);
  2115. break;
  2116. }
  2117. dev_dbg(dev,
  2118. "%s: (read) addr = 0x%x, data = 0x%02x%02x\n",
  2119. __func__, fg->reg_addr,
  2120. fg->reg_data[1], fg->reg_data[0]);
  2121. ret = count;
  2122. }
  2123. break;
  2124. case FG_DATA:
  2125. if (sscanf(buf, "%x\n", &x) == 1) {
  2126. dev_dbg(dev, "%s: (write) addr = 0x%x, data = 0x%04x\n",
  2127. __func__, fg->reg_addr, x);
  2128. fg_write_and_verify_register(fg->client,
  2129. fg->reg_addr, (u16)x);
  2130. ret = count;
  2131. }
  2132. break;
  2133. default:
  2134. ret = -EINVAL;
  2135. break;
  2136. }
  2137. return ret;
  2138. }
  2139. #endif