pmic8058-charger.c 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048
  1. /* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. */
  13. #include <linux/module.h>
  14. #include <linux/moduleparam.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/errno.h>
  17. #include <linux/interrupt.h>
  18. #include <linux/delay.h>
  19. #include <linux/bitops.h>
  20. #include <linux/workqueue.h>
  21. #include <linux/msm-charger.h>
  22. #include <linux/debugfs.h>
  23. #include <linux/slab.h>
  24. #include <linux/msm_adc.h>
  25. #include <linux/notifier.h>
  26. #include <linux/mfd/pm8xxx/core.h>
  27. #include <linux/mfd/pmic8058.h>
  28. #include <linux/pmic8058-charger.h>
  29. #include <linux/mfd/pm8xxx/batt-alarm.h>
  30. #include <mach/msm_xo.h>
  31. #include <mach/msm_hsusb.h>
  32. /* Config Regs and their bits*/
  33. #define PM8058_CHG_TEST 0x75
  34. #define IGNORE_LL 2
  35. #define PM8058_CHG_TEST_2 0xEA
  36. #define PM8058_CHG_TEST_3 0xEB
  37. #define PM8058_OVP_TEST_REG 0xF6
  38. #define FORCE_OVP_OFF 3
  39. #define PM8058_CHG_CNTRL 0x1E
  40. #define CHG_TRICKLE_EN 7
  41. #define CHG_USB_SUSPEND 6
  42. #define CHG_IMON_CAL 5
  43. #define CHG_IMON_GAIN 4
  44. #define CHG_CHARGE_BAT 3
  45. #define CHG_VBUS_FROM_BOOST_OVRD 2
  46. #define CHG_CHARGE_DIS 1
  47. #define CHG_VCP_EN 0
  48. #define PM8058_CHG_CNTRL_2 0xD8
  49. #define ATC_DIS 7 /* coincell backed */
  50. #define CHARGE_AUTO_DIS 6
  51. #define DUMB_CHG_OVRD 5 /* coincell backed */
  52. #define ENUM_DONE 4
  53. #define CHG_TEMP_MODE 3
  54. #define CHG_BATT_TEMP_DIS 1 /* coincell backed */
  55. #define CHG_FAILED_CLEAR 0
  56. #define PM8058_CHG_VMAX_SEL 0x21
  57. #define PM8058_CHG_VBAT_DET 0xD9
  58. #define PM8058_CHG_IMAX 0x1F
  59. #define PM8058_CHG_TRICKLE 0xDB
  60. #define PM8058_CHG_ITERM 0xDC
  61. #define PM8058_CHG_TTRKL_MAX 0xE1
  62. #define PM8058_CHG_TCHG_MAX 0xE4
  63. #define PM8058_CHG_TEMP_THRESH 0xE2
  64. #define PM8058_CHG_TEMP_REG 0xE3
  65. #define PM8058_CHG_PULSE 0x22
  66. /* IRQ STATUS and CLEAR */
  67. #define PM8058_CHG_STATUS_CLEAR_IRQ_1 0x31
  68. #define PM8058_CHG_STATUS_CLEAR_IRQ_3 0x33
  69. #define PM8058_CHG_STATUS_CLEAR_IRQ_10 0xB3
  70. #define PM8058_CHG_STATUS_CLEAR_IRQ_11 0xB4
  71. /* IRQ MASKS */
  72. #define PM8058_CHG_MASK_IRQ_1 0x38
  73. #define PM8058_CHG_MASK_IRQ_3 0x3A
  74. #define PM8058_CHG_MASK_IRQ_10 0xBA
  75. #define PM8058_CHG_MASK_IRQ_11 0xBB
  76. /* IRQ Real time status regs */
  77. #define PM8058_CHG_STATUS_RT_1 0x3F
  78. #define STATUS_RTCHGVAL 7
  79. #define STATUS_RTCHGINVAL 6
  80. #define STATUS_RTBATT_REPLACE 5
  81. #define STATUS_RTVBATDET_LOW 4
  82. #define STATUS_RTCHGILIM 3
  83. #define STATUS_RTPCTDONE 1
  84. #define STATUS_RTVCP 0
  85. #define PM8058_CHG_STATUS_RT_3 0x41
  86. #define PM8058_CHG_STATUS_RT_10 0xC1
  87. #define PM8058_CHG_STATUS_RT_11 0xC2
  88. /* VTRIM */
  89. #define PM8058_CHG_VTRIM 0x1D
  90. #define PM8058_CHG_VBATDET_TRIM 0x1E
  91. #define PM8058_CHG_ITRIM 0x1F
  92. #define PM8058_CHG_TTRIM 0x20
  93. #define AUTO_CHARGING_VMAXSEL 4200
  94. #define AUTO_CHARGING_FAST_TIME_MAX_MINUTES 512
  95. #define AUTO_CHARGING_TRICKLE_TIME_MINUTES 30
  96. #define AUTO_CHARGING_VEOC_ITERM 100
  97. #define AUTO_CHARGING_IEOC_ITERM 160
  98. #define AUTO_CHARGING_RESUME_MV 4100
  99. #define AUTO_CHARGING_VBATDET 4150
  100. #define AUTO_CHARGING_VBATDET_DEBOUNCE_TIME_MS 3000
  101. #define AUTO_CHARGING_VEOC_VBATDET 4100
  102. #define AUTO_CHARGING_VEOC_TCHG 16
  103. #define AUTO_CHARGING_VEOC_TCHG_FINAL_CYCLE 32
  104. #define AUTO_CHARGING_VEOC_BEGIN_TIME_MS 5400000
  105. #define AUTO_CHARGING_VEOC_VBAT_LOW_CHECK_TIME_MS 60000
  106. #define AUTO_CHARGING_RESUME_CHARGE_DETECTION_COUNTER 5
  107. #define AUTO_CHARGING_DONE_CHECK_TIME_MS 1000
  108. #define PM8058_CHG_I_STEP_MA 50
  109. #define PM8058_CHG_I_MIN_MA 50
  110. #define PM8058_CHG_T_TCHG_SHIFT 2
  111. #define PM8058_CHG_I_TERM_STEP_MA 10
  112. #define PM8058_CHG_V_STEP_MV 25
  113. #define PM8058_CHG_V_MIN_MV 2400
  114. /*
  115. * enum pmic_chg_interrupts: pmic interrupts
  116. * @CHGVAL_IRQ: charger V between 3.3 and 7.9
  117. * @CHGINVAL_IRQ: charger V outside 3.3 and 7.9
  118. * @VBATDET_LOW_IRQ: VBAT < VBATDET
  119. * @VCP_IRQ: VDD went below VBAT: BAT_FET is turned on
  120. * @CHGILIM_IRQ: mA consumed>IMAXSEL: chgloop draws less mA
  121. * @ATC_DONE_IRQ: Auto Trickle done
  122. * @ATCFAIL_IRQ: Auto Trickle fail
  123. * @AUTO_CHGDONE_IRQ: Auto chg done
  124. * @AUTO_CHGFAIL_IRQ: time exceeded w/o reaching term current
  125. * @CHGSTATE_IRQ: something happend causing a state change
  126. * @FASTCHG_IRQ: trkl charging completed: moving to fastchg
  127. * @CHG_END_IRQ: mA has dropped to termination current
  128. * @BATTTEMP_IRQ: batt temp is out of range
  129. * @CHGHOT_IRQ: the pass device is too hot
  130. * @CHGTLIMIT_IRQ: unused
  131. * @CHG_GONE_IRQ: charger was removed
  132. * @VCPMAJOR_IRQ: vcp major
  133. * @VBATDET_IRQ: VBAT >= VBATDET
  134. * @BATFET_IRQ: BATFET closed
  135. * @BATT_REPLACE_IRQ:
  136. * @BATTCONNECT_IRQ:
  137. */
  138. enum pmic_chg_interrupts {
  139. CHGVAL_IRQ,
  140. CHGINVAL_IRQ,
  141. VBATDET_LOW_IRQ,
  142. VCP_IRQ,
  143. CHGILIM_IRQ,
  144. ATC_DONE_IRQ,
  145. ATCFAIL_IRQ,
  146. AUTO_CHGDONE_IRQ,
  147. AUTO_CHGFAIL_IRQ,
  148. CHGSTATE_IRQ,
  149. FASTCHG_IRQ,
  150. CHG_END_IRQ,
  151. BATTTEMP_IRQ,
  152. CHGHOT_IRQ,
  153. CHGTLIMIT_IRQ,
  154. CHG_GONE_IRQ,
  155. VCPMAJOR_IRQ,
  156. VBATDET_IRQ,
  157. BATFET_IRQ,
  158. BATT_REPLACE_IRQ,
  159. BATTCONNECT_IRQ,
  160. PMIC_CHG_MAX_INTS
  161. };
  162. struct pm8058_charger {
  163. struct pmic_charger_pdata *pdata;
  164. struct device *dev;
  165. int pmic_chg_irq[PMIC_CHG_MAX_INTS];
  166. DECLARE_BITMAP(enabled_irqs, PMIC_CHG_MAX_INTS);
  167. struct delayed_work chg_done_check_work;
  168. struct delayed_work check_vbat_low_work;
  169. struct delayed_work veoc_begin_work;
  170. struct delayed_work charging_check_work;
  171. int waiting_for_topoff;
  172. int waiting_for_veoc;
  173. int vbatdet;
  174. struct msm_hardware_charger hw_chg;
  175. int current_charger_current;
  176. int disabled;
  177. struct msm_xo_voter *voter;
  178. struct dentry *dent;
  179. int inited;
  180. int present;
  181. };
  182. static struct pm8058_charger pm8058_chg;
  183. static struct msm_hardware_charger usb_hw_chg;
  184. static struct pmic8058_charger_data chg_data;
  185. static int msm_battery_gauge_alarm_notify(struct notifier_block *nb,
  186. unsigned long status, void *unused);
  187. static struct notifier_block alarm_notifier = {
  188. .notifier_call = msm_battery_gauge_alarm_notify,
  189. };
  190. static int resume_mv = AUTO_CHARGING_RESUME_MV;
  191. static DEFINE_MUTEX(batt_alarm_lock);
  192. static int resume_mv_set(const char *val, struct kernel_param *kp);
  193. module_param_call(resume_mv, resume_mv_set, param_get_int,
  194. &resume_mv, S_IRUGO | S_IWUSR);
  195. static int resume_mv_set(const char *val, struct kernel_param *kp)
  196. {
  197. int rc;
  198. mutex_lock(&batt_alarm_lock);
  199. rc = param_set_int(val, kp);
  200. if (rc)
  201. goto out;
  202. rc = pm8xxx_batt_alarm_threshold_set(
  203. PM8XXX_BATT_ALARM_LOWER_COMPARATOR, resume_mv);
  204. if (!rc)
  205. rc = pm8xxx_batt_alarm_threshold_set(
  206. PM8XXX_BATT_ALARM_UPPER_COMPARATOR, 4300);
  207. out:
  208. mutex_unlock(&batt_alarm_lock);
  209. return rc;
  210. }
  211. static void pm8058_chg_enable_irq(int interrupt)
  212. {
  213. if (!__test_and_set_bit(interrupt, pm8058_chg.enabled_irqs)) {
  214. dev_dbg(pm8058_chg.dev, "%s %d\n", __func__,
  215. pm8058_chg.pmic_chg_irq[interrupt]);
  216. enable_irq(pm8058_chg.pmic_chg_irq[interrupt]);
  217. }
  218. }
  219. static void pm8058_chg_disable_irq(int interrupt)
  220. {
  221. if (__test_and_clear_bit(interrupt, pm8058_chg.enabled_irqs)) {
  222. dev_dbg(pm8058_chg.dev, "%s %d\n", __func__,
  223. pm8058_chg.pmic_chg_irq[interrupt]);
  224. disable_irq_nosync(pm8058_chg.pmic_chg_irq[interrupt]);
  225. }
  226. }
  227. static int pm_chg_get_rt_status(int irq)
  228. {
  229. int ret;
  230. ret = pm8xxx_read_irq_stat(pm8058_chg.dev->parent, irq);
  231. if (ret == -EAGAIN)
  232. return 0;
  233. else
  234. return ret;
  235. }
  236. static int is_chg_plugged_in(void)
  237. {
  238. return pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[CHGVAL_IRQ]);
  239. }
  240. #ifdef DEBUG
  241. static void __dump_chg_regs(void)
  242. {
  243. u8 temp;
  244. int temp2;
  245. pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, &temp);
  246. dev_dbg(pm8058_chg.dev, "PM8058_CHG_CNTRL = 0x%x\n", temp);
  247. pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, &temp);
  248. dev_dbg(pm8058_chg.dev, "PM8058_CHG_CNTRL_2 = 0x%x\n", temp);
  249. pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_VMAX_SEL, &temp);
  250. dev_dbg(pm8058_chg.dev, "PM8058_CHG_VMAX_SEL = 0x%x\n", temp);
  251. pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_VBAT_DET, &temp);
  252. dev_dbg(pm8058_chg.dev, "PM8058_CHG_VBAT_DET = 0x%x\n", temp);
  253. pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_IMAX, &temp);
  254. dev_dbg(pm8058_chg.dev, "PM8058_CHG_IMAX = 0x%x\n", temp);
  255. pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TRICKLE, &temp);
  256. dev_dbg(pm8058_chg.dev, "PM8058_CHG_TRICKLE = 0x%x\n", temp);
  257. pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_ITERM, &temp);
  258. dev_dbg(pm8058_chg.dev, "PM8058_CHG_ITERM = 0x%x\n", temp);
  259. pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TTRKL_MAX, &temp);
  260. dev_dbg(pm8058_chg.dev, "PM8058_CHG_TTRKL_MAX = 0x%x\n", temp);
  261. pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TCHG_MAX, &temp);
  262. dev_dbg(pm8058_chg.dev, "PM8058_CHG_TCHG_MAX = 0x%x\n", temp);
  263. pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TEMP_THRESH, &temp);
  264. dev_dbg(pm8058_chg.dev, "PM8058_CHG_TEMP_THRESH = 0x%x\n", temp);
  265. pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TEMP_REG, &temp);
  266. dev_dbg(pm8058_chg.dev, "PM8058_CHG_TEMP_REG = 0x%x\n", temp);
  267. pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_PULSE, &temp);
  268. dev_dbg(pm8058_chg.dev, "PM8058_CHG_PULSE = 0x%x\n", temp);
  269. pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_STATUS_CLEAR_IRQ_1,
  270. &temp);
  271. dev_dbg(pm8058_chg.dev, "PM8058_CHG_STATUS_CLEAR_IRQ_1 = 0x%x\n", temp);
  272. pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_STATUS_CLEAR_IRQ_3,
  273. &temp);
  274. dev_dbg(pm8058_chg.dev, "PM8058_CHG_STATUS_CLEAR_IRQ_3 = 0x%x\n", temp);
  275. pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_STATUS_CLEAR_IRQ_10,
  276. &temp);
  277. dev_dbg(pm8058_chg.dev, "PM8058_CHG_STATUS_CLEAR_IRQ_10 = 0x%x\n",
  278. temp);
  279. pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_STATUS_CLEAR_IRQ_11,
  280. &temp);
  281. dev_dbg(pm8058_chg.dev, "PM8058_CHG_STATUS_CLEAR_IRQ_11 = 0x%x\n",
  282. temp);
  283. pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_MASK_IRQ_1, &temp);
  284. dev_dbg(pm8058_chg.dev, "PM8058_CHG_MASK_IRQ_1 = 0x%x\n", temp);
  285. pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_MASK_IRQ_3, &temp);
  286. dev_dbg(pm8058_chg.dev, "PM8058_CHG_MASK_IRQ_3 = 0x%x\n", temp);
  287. pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_MASK_IRQ_10, &temp);
  288. dev_dbg(pm8058_chg.dev, "PM8058_CHG_MASK_IRQ_10 = 0x%x\n", temp);
  289. pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_MASK_IRQ_11, &temp);
  290. dev_dbg(pm8058_chg.dev, "PM8058_CHG_MASK_IRQ_11 = 0x%x\n", temp);
  291. temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[CHGVAL_IRQ]);
  292. dev_dbg(pm8058_chg.dev, "CHGVAL_IRQ = %d\n", temp2);
  293. temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[CHGINVAL_IRQ]);
  294. dev_dbg(pm8058_chg.dev, "CHGINVAL_IRQ = %d\n", temp2);
  295. temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[VBATDET_LOW_IRQ]);
  296. dev_dbg(pm8058_chg.dev, "VBATDET_LOW_IRQ= %d\n", temp2);
  297. temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[VCP_IRQ]);
  298. dev_dbg(pm8058_chg.dev, "VCP_IRQ= %d\n", temp2);
  299. temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[CHGILIM_IRQ]);
  300. dev_dbg(pm8058_chg.dev, "CHGILIM_IRQ= %d\n", temp2);
  301. temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[ATC_DONE_IRQ]);
  302. dev_dbg(pm8058_chg.dev, "ATC_DONE_IRQ= %d\n", temp2);
  303. temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[ATCFAIL_IRQ]);
  304. dev_dbg(pm8058_chg.dev, "ATCFAIL_IRQ= %d\n", temp2);
  305. temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[AUTO_CHGDONE_IRQ]);
  306. dev_dbg(pm8058_chg.dev, "AUTO_CHGDONE_IRQ= %d\n", temp2);
  307. temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[AUTO_CHGFAIL_IRQ]);
  308. dev_dbg(pm8058_chg.dev, "AUTO_CHGFAIL_IRQ= %d\n", temp2);
  309. temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[CHGSTATE_IRQ]);
  310. dev_dbg(pm8058_chg.dev, "CHGSTATE_IRQ= %d\n", temp2);
  311. temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[FASTCHG_IRQ]);
  312. dev_dbg(pm8058_chg.dev, "FASTCHG_IRQ= %d\n", temp2);
  313. temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[CHG_END_IRQ]);
  314. dev_dbg(pm8058_chg.dev, "CHG_END_IRQ= %d\n", temp2);
  315. temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[BATTTEMP_IRQ]);
  316. dev_dbg(pm8058_chg.dev, "BATTTEMP_IRQ= %d\n", temp2);
  317. temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[CHGHOT_IRQ]);
  318. dev_dbg(pm8058_chg.dev, "CHGHOT_IRQ= %d\n", temp2);
  319. temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[CHGTLIMIT_IRQ]);
  320. dev_dbg(pm8058_chg.dev, "CHGTLIMIT_IRQ= %d\n", temp2);
  321. temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[CHG_GONE_IRQ]);
  322. dev_dbg(pm8058_chg.dev, "CHG_GONE_IRQ= %d\n", temp2);
  323. temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[VCPMAJOR_IRQ]);
  324. dev_dbg(pm8058_chg.dev, "VCPMAJOR_IRQ= %d\n", temp2);
  325. temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[VBATDET_IRQ]);
  326. dev_dbg(pm8058_chg.dev, "VBATDET_IRQ= %d\n", temp2);
  327. temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[BATFET_IRQ]);
  328. dev_dbg(pm8058_chg.dev, "BATFET_IRQ= %d\n", temp2);
  329. temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[BATT_REPLACE_IRQ]);
  330. dev_dbg(pm8058_chg.dev, "BATT_REPLACE_IRQ= %d\n", temp2);
  331. temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[BATTCONNECT_IRQ]);
  332. dev_dbg(pm8058_chg.dev, "BATTCONNECT_IRQ= %d\n", temp2);
  333. }
  334. #else
  335. static inline void __dump_chg_regs(void)
  336. {
  337. }
  338. #endif
  339. /* SSBI register access helper functions */
  340. static int pm_chg_suspend(int value)
  341. {
  342. u8 temp;
  343. int ret;
  344. ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, &temp);
  345. if (ret)
  346. return ret;
  347. if (value)
  348. temp |= BIT(CHG_USB_SUSPEND);
  349. else
  350. temp &= ~BIT(CHG_USB_SUSPEND);
  351. return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, temp);
  352. }
  353. static int pm_chg_auto_disable(int value)
  354. {
  355. u8 temp;
  356. int ret;
  357. ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, &temp);
  358. if (ret)
  359. return ret;
  360. if (value)
  361. temp |= BIT(CHARGE_AUTO_DIS);
  362. else
  363. temp &= ~BIT(CHARGE_AUTO_DIS);
  364. return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, temp);
  365. }
  366. static int pm_chg_batt_temp_disable(int value)
  367. {
  368. u8 temp;
  369. int ret;
  370. ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, &temp);
  371. if (ret)
  372. return ret;
  373. if (value)
  374. temp |= BIT(CHG_BATT_TEMP_DIS);
  375. else
  376. temp &= ~BIT(CHG_BATT_TEMP_DIS);
  377. return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, temp);
  378. }
  379. static int pm_chg_vbatdet_set(int voltage)
  380. {
  381. u8 temp;
  382. int diff;
  383. diff = (voltage - PM8058_CHG_V_MIN_MV);
  384. if (diff < 0) {
  385. dev_warn(pm8058_chg.dev, "%s bad mV=%d asked to set\n",
  386. __func__, voltage);
  387. return -EINVAL;
  388. }
  389. temp = diff / PM8058_CHG_V_STEP_MV;
  390. dev_dbg(pm8058_chg.dev, "%s voltage=%d setting %02x\n", __func__,
  391. voltage, temp);
  392. return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_VBAT_DET, temp);
  393. }
  394. static int pm_chg_imaxsel_set(int chg_current)
  395. {
  396. u8 temp;
  397. int diff;
  398. diff = chg_current - PM8058_CHG_I_MIN_MA;
  399. if (diff < 0) {
  400. dev_warn(pm8058_chg.dev, "%s bad mA=%d asked to set\n",
  401. __func__, chg_current);
  402. return -EINVAL;
  403. }
  404. temp = diff / PM8058_CHG_I_STEP_MA;
  405. /* make sure we arent writing more than 5 bits of data */
  406. if (temp > 31) {
  407. dev_warn(pm8058_chg.dev, "%s max mA=1500 requested mA=%d\n",
  408. __func__, chg_current);
  409. temp = 31;
  410. }
  411. return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_IMAX, temp);
  412. }
  413. #define PM8058_CHG_VMAX_MIN 3300
  414. #define PM8058_CHG_VMAX_MAX 5500
  415. static int pm_chg_vmaxsel_set(int voltage)
  416. {
  417. u8 temp;
  418. if (voltage < PM8058_CHG_VMAX_MIN || voltage > PM8058_CHG_VMAX_MAX) {
  419. dev_warn(pm8058_chg.dev, "%s bad mV=%d asked to set\n",
  420. __func__, voltage);
  421. return -EINVAL;
  422. }
  423. temp = (voltage - PM8058_CHG_V_MIN_MV) / PM8058_CHG_V_STEP_MV;
  424. dev_dbg(pm8058_chg.dev, "%s mV=%d setting %02x\n", __func__, voltage,
  425. temp);
  426. return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_VMAX_SEL, temp);
  427. }
  428. static int pm_chg_failed_clear(int value)
  429. {
  430. u8 temp;
  431. int ret;
  432. ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, &temp);
  433. if (ret)
  434. return ret;
  435. if (value)
  436. temp |= BIT(CHG_FAILED_CLEAR);
  437. else
  438. temp &= ~BIT(CHG_FAILED_CLEAR);
  439. return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, temp);
  440. }
  441. static int pm_chg_iterm_set(int chg_current)
  442. {
  443. u8 temp;
  444. temp = (chg_current / PM8058_CHG_I_TERM_STEP_MA) - 1;
  445. return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_ITERM, temp);
  446. }
  447. static int pm_chg_tchg_set(int minutes)
  448. {
  449. u8 temp;
  450. temp = (minutes >> PM8058_CHG_T_TCHG_SHIFT) - 1;
  451. return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TCHG_MAX, temp);
  452. }
  453. static int pm_chg_ttrkl_set(int minutes)
  454. {
  455. u8 temp;
  456. temp = minutes - 1;
  457. return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TTRKL_MAX,
  458. temp);
  459. }
  460. static int pm_chg_enum_done_enable(int value)
  461. {
  462. u8 temp;
  463. int ret;
  464. ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, &temp);
  465. if (ret)
  466. return ret;
  467. if (value)
  468. temp |= BIT(ENUM_DONE);
  469. else
  470. temp &= ~BIT(ENUM_DONE);
  471. return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, temp);
  472. }
  473. static uint32_t get_fsm_state(void)
  474. {
  475. u8 temp;
  476. temp = 0x00;
  477. pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST_3, temp);
  478. pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TEST_3, &temp);
  479. return (uint32_t)temp;
  480. }
  481. static int get_fsm_status(void *data, u64 * val)
  482. {
  483. *val = get_fsm_state();
  484. return 0;
  485. }
  486. enum pmic8058_chg_state pmic8058_get_fsm_state(void)
  487. {
  488. if (!pm8058_chg.inited) {
  489. pr_err("%s: called when not inited\n", __func__);
  490. return -EINVAL;
  491. }
  492. return get_fsm_state();
  493. }
  494. static int pm_chg_disable(int value)
  495. {
  496. u8 temp;
  497. int ret;
  498. ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, &temp);
  499. if (ret)
  500. return ret;
  501. if (value)
  502. temp |= BIT(CHG_CHARGE_DIS);
  503. else
  504. temp &= ~BIT(CHG_CHARGE_DIS);
  505. return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, temp);
  506. }
  507. static void pm8058_start_system_current(struct msm_hardware_charger *hw_chg,
  508. int max_current)
  509. {
  510. int ret = 0;
  511. if (pm8058_chg.disabled)
  512. return;
  513. ret = pm_chg_imaxsel_set(max_current);
  514. ret |= pm_chg_enum_done_enable(1);
  515. ret |= pm_chg_disable(0);
  516. if (ret)
  517. pr_err("%s: failed to turn on system power err=%d",
  518. __func__, ret);
  519. }
  520. static void pm8058_stop_system_current(struct msm_hardware_charger *hw_chg)
  521. {
  522. int ret = 0;
  523. ret = pm_chg_enum_done_enable(0);
  524. ret |= pm_chg_disable(1);
  525. if (ret)
  526. pr_err("%s: failed to turn off system power err=%d",
  527. __func__, ret);
  528. }
  529. static int __pm8058_start_charging(int chg_current, int termination_current,
  530. int time)
  531. {
  532. int ret = 0;
  533. if (pm8058_chg.disabled)
  534. goto out;
  535. dev_info(pm8058_chg.dev, "%s %dmA %dmin\n",
  536. __func__, chg_current, time);
  537. ret = pm_chg_auto_disable(1);
  538. if (ret)
  539. goto out;
  540. ret = pm_chg_suspend(0);
  541. if (ret)
  542. goto out;
  543. ret = pm_chg_imaxsel_set(chg_current);
  544. if (ret)
  545. goto out;
  546. ret = pm_chg_failed_clear(1);
  547. if (ret)
  548. goto out;
  549. ret = pm_chg_iterm_set(termination_current);
  550. if (ret)
  551. goto out;
  552. ret = pm_chg_tchg_set(time);
  553. if (ret)
  554. goto out;
  555. ret = pm_chg_ttrkl_set(AUTO_CHARGING_TRICKLE_TIME_MINUTES);
  556. if (ret)
  557. goto out;
  558. ret = pm_chg_batt_temp_disable(0);
  559. if (ret)
  560. goto out;
  561. if (pm8058_chg.voter == NULL)
  562. pm8058_chg.voter = msm_xo_get(MSM_XO_TCXO_D1, "pm8058_charger");
  563. msm_xo_mode_vote(pm8058_chg.voter, MSM_XO_MODE_ON);
  564. ret = pm_chg_enum_done_enable(1);
  565. if (ret)
  566. goto out;
  567. wmb();
  568. ret = pm_chg_auto_disable(0);
  569. if (ret)
  570. goto out;
  571. /* wait for the enable to update interrupt status*/
  572. msleep(20);
  573. pm8058_chg_enable_irq(AUTO_CHGFAIL_IRQ);
  574. pm8058_chg_enable_irq(CHGHOT_IRQ);
  575. pm8058_chg_enable_irq(AUTO_CHGDONE_IRQ);
  576. pm8058_chg_enable_irq(CHG_END_IRQ);
  577. pm8058_chg_enable_irq(CHGSTATE_IRQ);
  578. out:
  579. return ret;
  580. }
  581. static void chg_done_cleanup(void)
  582. {
  583. dev_info(pm8058_chg.dev, "%s notify pm8058 charging completion"
  584. "\n", __func__);
  585. pm8058_chg_disable_irq(AUTO_CHGDONE_IRQ);
  586. cancel_delayed_work_sync(&pm8058_chg.veoc_begin_work);
  587. cancel_delayed_work_sync(&pm8058_chg.check_vbat_low_work);
  588. pm8058_chg_disable_irq(CHG_END_IRQ);
  589. pm8058_chg_disable_irq(VBATDET_LOW_IRQ);
  590. pm8058_chg_disable_irq(VBATDET_IRQ);
  591. pm8058_chg.waiting_for_veoc = 0;
  592. pm8058_chg.waiting_for_topoff = 0;
  593. pm_chg_auto_disable(1);
  594. msm_charger_notify_event(&usb_hw_chg, CHG_DONE_EVENT);
  595. }
  596. static void chg_done_check_work(struct work_struct *work)
  597. {
  598. chg_done_cleanup();
  599. }
  600. static void charging_check_work(struct work_struct *work)
  601. {
  602. uint32_t fsm_state = get_fsm_state();
  603. int rc;
  604. switch (fsm_state) {
  605. /* We're charging, so disarm alarm */
  606. case PMIC8058_CHG_STATE_ATC:
  607. case PMIC8058_CHG_STATE_FAST_CHG:
  608. case PMIC8058_CHG_STATE_TRKL_CHG:
  609. rc = pm8xxx_batt_alarm_disable(
  610. PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
  611. if (!rc)
  612. rc = pm8xxx_batt_alarm_disable(
  613. PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
  614. if (rc)
  615. dev_err(pm8058_chg.dev,
  616. "%s: unable to set alarm state\n", __func__);
  617. break;
  618. default:
  619. /* Still not charging, so update driver state */
  620. chg_done_cleanup();
  621. break;
  622. };
  623. }
  624. static int pm8058_start_charging(struct msm_hardware_charger *hw_chg,
  625. int chg_voltage, int chg_current)
  626. {
  627. int vbat_higher_than_vbatdet;
  628. int ret = 0;
  629. cancel_delayed_work_sync(&pm8058_chg.charging_check_work);
  630. /*
  631. * adjust the max current for PC USB connection - set the higher limit
  632. * to 450 and make sure we never cross it
  633. */
  634. if (chg_current == 500)
  635. chg_current = 450;
  636. if (hw_chg->type == CHG_TYPE_AC && chg_data.max_source_current)
  637. chg_current = chg_data.max_source_current;
  638. pm8058_chg.current_charger_current = chg_current;
  639. pm8058_chg_enable_irq(FASTCHG_IRQ);
  640. ret = pm_chg_vmaxsel_set(chg_voltage);
  641. if (ret)
  642. goto out;
  643. /* set vbat to CC to CV threshold */
  644. ret = pm_chg_vbatdet_set(AUTO_CHARGING_VBATDET);
  645. if (ret)
  646. goto out;
  647. pm8058_chg.vbatdet = AUTO_CHARGING_VBATDET;
  648. /*
  649. * get the state of vbat and if it is higher than
  650. * AUTO_CHARGING_VBATDET we start the veoc start timer
  651. * else wait for the voltage to go to AUTO_CHARGING_VBATDET
  652. * and then start the 90 min timer
  653. */
  654. vbat_higher_than_vbatdet =
  655. pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[VBATDET_IRQ]);
  656. if (vbat_higher_than_vbatdet) {
  657. /*
  658. * we are in constant voltage phase of charging
  659. * IEOC should happen withing 90 mins of this instant
  660. * else we enable VEOC
  661. */
  662. dev_info(pm8058_chg.dev, "%s begin veoc timer\n", __func__);
  663. schedule_delayed_work(&pm8058_chg.veoc_begin_work,
  664. round_jiffies_relative(msecs_to_jiffies
  665. (AUTO_CHARGING_VEOC_BEGIN_TIME_MS)));
  666. } else
  667. pm8058_chg_enable_irq(VBATDET_IRQ);
  668. ret = __pm8058_start_charging(chg_current, AUTO_CHARGING_IEOC_ITERM,
  669. AUTO_CHARGING_FAST_TIME_MAX_MINUTES);
  670. pm8058_chg.current_charger_current = chg_current;
  671. /*
  672. * We want to check the FSM state to verify we're charging. We must
  673. * wait before doing this to allow the VBATDET to settle. The worst
  674. * case for this is two seconds. The batt alarm does not have this
  675. * delay.
  676. */
  677. schedule_delayed_work(&pm8058_chg.charging_check_work,
  678. round_jiffies_relative(msecs_to_jiffies
  679. (AUTO_CHARGING_VBATDET_DEBOUNCE_TIME_MS)));
  680. out:
  681. return ret;
  682. }
  683. static void veoc_begin_work(struct work_struct *work)
  684. {
  685. /* we have been doing CV for 90mins with no signs of IEOC
  686. * start checking for VEOC in addition with 16min charges*/
  687. dev_info(pm8058_chg.dev, "%s begin veoc detection\n", __func__);
  688. pm8058_chg.waiting_for_veoc = 1;
  689. /*
  690. * disable VBATDET irq we dont need it unless we are at the end of
  691. * charge cycle
  692. */
  693. pm8058_chg_disable_irq(VBATDET_IRQ);
  694. __pm8058_start_charging(pm8058_chg.current_charger_current,
  695. AUTO_CHARGING_VEOC_ITERM,
  696. AUTO_CHARGING_VEOC_TCHG);
  697. }
  698. static void vbat_low_work(struct work_struct *work)
  699. {
  700. /*
  701. * It has been one minute and the battery still holds voltage
  702. * start the final topoff - charging is almost done
  703. */
  704. dev_info(pm8058_chg.dev, "%s vbatt maintains for a minute"
  705. "starting topoff\n", __func__);
  706. pm8058_chg.waiting_for_veoc = 0;
  707. pm8058_chg.waiting_for_topoff = 1;
  708. pm8058_chg_disable_irq(VBATDET_LOW_IRQ);
  709. pm8058_chg_disable_irq(VBATDET_IRQ);
  710. __pm8058_start_charging(pm8058_chg.current_charger_current,
  711. AUTO_CHARGING_VEOC_ITERM,
  712. AUTO_CHARGING_VEOC_TCHG_FINAL_CYCLE);
  713. }
  714. static irqreturn_t pm8058_chg_chgval_handler(int irq, void *dev_id)
  715. {
  716. u8 old, temp;
  717. int ret;
  718. if (is_chg_plugged_in()) { /* this debounces it */
  719. if (!pm8058_chg.present) {
  720. msm_charger_notify_event(&usb_hw_chg,
  721. CHG_INSERTED_EVENT);
  722. pm8058_chg.present = 1;
  723. }
  724. } else {
  725. if (pm8058_chg.present) {
  726. ret = pm8xxx_readb(pm8058_chg.dev->parent,
  727. PM8058_OVP_TEST_REG,
  728. &old);
  729. temp = old | BIT(FORCE_OVP_OFF);
  730. ret = pm8xxx_writeb(pm8058_chg.dev->parent,
  731. PM8058_OVP_TEST_REG,
  732. temp);
  733. temp = 0xFC;
  734. ret = pm8xxx_writeb(pm8058_chg.dev->parent,
  735. PM8058_CHG_TEST, temp);
  736. /* 10 ms sleep is for the VCHG to discharge */
  737. msleep(10);
  738. temp = 0xF0;
  739. ret = pm8xxx_writeb(pm8058_chg.dev->parent,
  740. PM8058_CHG_TEST,
  741. temp);
  742. ret = pm8xxx_writeb(pm8058_chg.dev->parent,
  743. PM8058_OVP_TEST_REG,
  744. old);
  745. pm_chg_enum_done_enable(0);
  746. pm_chg_auto_disable(1);
  747. msm_charger_notify_event(&usb_hw_chg,
  748. CHG_REMOVED_EVENT);
  749. pm8058_chg.present = 0;
  750. }
  751. }
  752. return IRQ_HANDLED;
  753. }
  754. static irqreturn_t pm8058_chg_chginval_handler(int irq, void *dev_id)
  755. {
  756. u8 old, temp;
  757. int ret;
  758. if (pm8058_chg.present) {
  759. pm8058_chg_disable_irq(CHGINVAL_IRQ);
  760. pm_chg_enum_done_enable(0);
  761. pm_chg_auto_disable(1);
  762. ret = pm8xxx_readb(pm8058_chg.dev->parent,
  763. PM8058_OVP_TEST_REG, &old);
  764. temp = old | BIT(FORCE_OVP_OFF);
  765. ret = pm8xxx_writeb(pm8058_chg.dev->parent,
  766. PM8058_OVP_TEST_REG, temp);
  767. temp = 0xFC;
  768. ret = pm8xxx_writeb(pm8058_chg.dev->parent,
  769. PM8058_CHG_TEST, temp);
  770. /* 10 ms sleep is for the VCHG to discharge */
  771. msleep(10);
  772. temp = 0xF0;
  773. ret = pm8xxx_writeb(pm8058_chg.dev->parent,
  774. PM8058_CHG_TEST, temp);
  775. ret = pm8xxx_writeb(pm8058_chg.dev->parent,
  776. PM8058_OVP_TEST_REG, old);
  777. if (!is_chg_plugged_in()) {
  778. msm_charger_notify_event(&usb_hw_chg,
  779. CHG_REMOVED_EVENT);
  780. pm8058_chg.present = 0;
  781. } else {
  782. /* was a fake */
  783. pm8058_chg_enable_irq(CHGINVAL_IRQ);
  784. }
  785. }
  786. return IRQ_HANDLED;
  787. }
  788. static irqreturn_t pm8058_chg_auto_chgdone_handler(int irq, void *dev_id)
  789. {
  790. dev_info(pm8058_chg.dev, "%s waiting a sec to confirm\n",
  791. __func__);
  792. pm8058_chg_disable_irq(AUTO_CHGDONE_IRQ);
  793. pm8058_chg_disable_irq(VBATDET_IRQ);
  794. if (!delayed_work_pending(&pm8058_chg.chg_done_check_work)) {
  795. schedule_delayed_work(&pm8058_chg.chg_done_check_work,
  796. round_jiffies_relative(msecs_to_jiffies
  797. (AUTO_CHARGING_DONE_CHECK_TIME_MS)));
  798. }
  799. return IRQ_HANDLED;
  800. }
  801. /* can only happen with the pmic charger when it has been charing
  802. * for either 16 mins wating for VEOC or 32 mins for topoff
  803. * without a IEOC indication */
  804. static irqreturn_t pm8058_chg_auto_chgfail_handler(int irq, void *dev_id)
  805. {
  806. pm8058_chg_disable_irq(AUTO_CHGFAIL_IRQ);
  807. if (pm8058_chg.waiting_for_topoff == 1) {
  808. dev_info(pm8058_chg.dev, "%s topoff done, charging done\n",
  809. __func__);
  810. pm8058_chg.waiting_for_topoff = 0;
  811. /* notify we are done charging */
  812. msm_charger_notify_event(&usb_hw_chg, CHG_DONE_EVENT);
  813. } else {
  814. /* start one minute timer and monitor VBATDET_LOW */
  815. dev_info(pm8058_chg.dev, "%s monitoring vbat_low for a"
  816. "minute\n", __func__);
  817. schedule_delayed_work(&pm8058_chg.check_vbat_low_work,
  818. round_jiffies_relative(msecs_to_jiffies
  819. (AUTO_CHARGING_VEOC_VBAT_LOW_CHECK_TIME_MS)));
  820. /* note we are waiting on veoc */
  821. pm8058_chg.waiting_for_veoc = 1;
  822. pm_chg_vbatdet_set(AUTO_CHARGING_VEOC_VBATDET);
  823. pm8058_chg.vbatdet = AUTO_CHARGING_VEOC_VBATDET;
  824. pm8058_chg_enable_irq(VBATDET_LOW_IRQ);
  825. }
  826. return IRQ_HANDLED;
  827. }
  828. static irqreturn_t pm8058_chg_chgstate_handler(int irq, void *dev_id)
  829. {
  830. u8 temp;
  831. temp = 0x00;
  832. if (!pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST_3, temp)) {
  833. pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TEST_3, &temp);
  834. dev_dbg(pm8058_chg.dev, "%s state=%d\n", __func__, temp);
  835. }
  836. return IRQ_HANDLED;
  837. }
  838. static irqreturn_t pm8058_chg_fastchg_handler(int irq, void *dev_id)
  839. {
  840. pm8058_chg_disable_irq(FASTCHG_IRQ);
  841. /* we have begun the fast charging state */
  842. dev_info(pm8058_chg.dev, "%s begin fast charging"
  843. , __func__);
  844. msm_charger_notify_event(&usb_hw_chg, CHG_BATT_BEGIN_FAST_CHARGING);
  845. return IRQ_HANDLED;
  846. }
  847. static irqreturn_t pm8058_chg_batttemp_handler(int irq, void *dev_id)
  848. {
  849. int ret;
  850. /* we could get temperature
  851. * interrupt when the battery is plugged out
  852. */
  853. ret = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[BATTCONNECT_IRQ]);
  854. if (ret) {
  855. msm_charger_notify_event(&usb_hw_chg, CHG_BATT_REMOVED);
  856. } else {
  857. /* read status to determine we are inrange or outofrange */
  858. ret =
  859. pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[BATTTEMP_IRQ]);
  860. if (ret)
  861. msm_charger_notify_event(&usb_hw_chg,
  862. CHG_BATT_TEMP_OUTOFRANGE);
  863. else
  864. msm_charger_notify_event(&usb_hw_chg,
  865. CHG_BATT_TEMP_INRANGE);
  866. }
  867. return IRQ_HANDLED;
  868. }
  869. static irqreturn_t pm8058_chg_vbatdet_handler(int irq, void *dev_id)
  870. {
  871. int ret;
  872. /* settling time */
  873. msleep(20);
  874. ret = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[VBATDET_IRQ]);
  875. if (ret) {
  876. if (pm8058_chg.vbatdet == AUTO_CHARGING_VBATDET
  877. && !delayed_work_pending(&pm8058_chg.veoc_begin_work)) {
  878. /*
  879. * we are in constant voltage phase of charging
  880. * IEOC should happen withing 90 mins of this instant
  881. * else we enable VEOC
  882. */
  883. dev_info(pm8058_chg.dev, "%s entered constant voltage"
  884. "begin veoc timer\n", __func__);
  885. schedule_delayed_work(&pm8058_chg.veoc_begin_work,
  886. round_jiffies_relative
  887. (msecs_to_jiffies
  888. (AUTO_CHARGING_VEOC_BEGIN_TIME_MS)));
  889. }
  890. } else {
  891. if (pm8058_chg.vbatdet == AUTO_CHARGING_VEOC_VBATDET) {
  892. cancel_delayed_work_sync(
  893. &pm8058_chg.check_vbat_low_work);
  894. if (pm8058_chg.waiting_for_topoff
  895. || pm8058_chg.waiting_for_veoc) {
  896. /*
  897. * the battery dropped its voltage below 4100
  898. * around a minute charge the battery for 16
  899. * mins and check vbat again for a minute
  900. */
  901. dev_info(pm8058_chg.dev, "%s batt dropped vlt"
  902. "within a minute\n", __func__);
  903. pm8058_chg.waiting_for_topoff = 0;
  904. pm8058_chg.waiting_for_veoc = 1;
  905. pm8058_chg_disable_irq(VBATDET_IRQ);
  906. __pm8058_start_charging(pm8058_chg.
  907. current_charger_current,
  908. AUTO_CHARGING_VEOC_ITERM,
  909. AUTO_CHARGING_VEOC_TCHG);
  910. }
  911. }
  912. }
  913. return IRQ_HANDLED;
  914. }
  915. static irqreturn_t pm8058_chg_batt_replace_handler(int irq, void *dev_id)
  916. {
  917. int ret;
  918. pm8058_chg_disable_irq(BATT_REPLACE_IRQ);
  919. ret = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[BATT_REPLACE_IRQ]);
  920. if (ret) {
  921. msm_charger_notify_event(&usb_hw_chg, CHG_BATT_INSERTED);
  922. /*
  923. * battery is present enable batt removal
  924. * and batt temperatture interrupt
  925. */
  926. pm8058_chg_enable_irq(BATTCONNECT_IRQ);
  927. }
  928. return IRQ_HANDLED;
  929. }
  930. static irqreturn_t pm8058_chg_battconnect_handler(int irq, void *dev_id)
  931. {
  932. int ret;
  933. ret = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[BATTCONNECT_IRQ]);
  934. if (ret) {
  935. msm_charger_notify_event(&usb_hw_chg, CHG_BATT_REMOVED);
  936. } else {
  937. msm_charger_notify_event(&usb_hw_chg, CHG_BATT_INSERTED);
  938. pm8058_chg_enable_irq(BATTTEMP_IRQ);
  939. }
  940. return IRQ_HANDLED;
  941. }
  942. static int get_rt_status(void *data, u64 * val)
  943. {
  944. int i = (int)data;
  945. int ret;
  946. ret = pm_chg_get_rt_status(i);
  947. *val = ret;
  948. return 0;
  949. }
  950. DEFINE_SIMPLE_ATTRIBUTE(rt_fops, get_rt_status, NULL, "%llu\n");
  951. DEFINE_SIMPLE_ATTRIBUTE(fsm_fops, get_fsm_status, NULL, "%llu\n");
  952. static void free_irqs(void)
  953. {
  954. int i;
  955. for (i = 0; i < PMIC_CHG_MAX_INTS; i++)
  956. if (pm8058_chg.pmic_chg_irq[i]) {
  957. free_irq(pm8058_chg.pmic_chg_irq[i], NULL);
  958. pm8058_chg.pmic_chg_irq[i] = 0;
  959. }
  960. }
  961. static int __devinit request_irqs(struct platform_device *pdev)
  962. {
  963. struct resource *res;
  964. int ret;
  965. ret = 0;
  966. bitmap_fill(pm8058_chg.enabled_irqs, PMIC_CHG_MAX_INTS);
  967. res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "CHGVAL");
  968. if (res == NULL) {
  969. dev_err(pm8058_chg.dev,
  970. "%s:couldnt find resource CHGVAL\n", __func__);
  971. goto err_out;
  972. } else {
  973. ret = request_threaded_irq(res->start, NULL,
  974. pm8058_chg_chgval_handler,
  975. IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
  976. res->name, NULL);
  977. if (ret < 0) {
  978. dev_err(pm8058_chg.dev, "%s:couldnt request %d %d\n",
  979. __func__, res->start, ret);
  980. goto err_out;
  981. } else {
  982. pm8058_chg.pmic_chg_irq[CHGVAL_IRQ] = res->start;
  983. pm8058_chg_disable_irq(CHGVAL_IRQ);
  984. enable_irq_wake(pm8058_chg.pmic_chg_irq[CHGVAL_IRQ]);
  985. }
  986. }
  987. res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "CHGINVAL");
  988. if (res == NULL) {
  989. dev_err(pm8058_chg.dev,
  990. "%s:couldnt find resource CHGINVAL\n", __func__);
  991. goto err_out;
  992. } else {
  993. ret = request_threaded_irq(res->start, NULL,
  994. pm8058_chg_chginval_handler,
  995. IRQF_TRIGGER_RISING, res->name, NULL);
  996. if (ret < 0) {
  997. dev_err(pm8058_chg.dev, "%s:couldnt request %d %d\n",
  998. __func__, res->start, ret);
  999. goto err_out;
  1000. } else {
  1001. pm8058_chg.pmic_chg_irq[CHGINVAL_IRQ] = res->start;
  1002. pm8058_chg_disable_irq(CHGINVAL_IRQ);
  1003. }
  1004. }
  1005. res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
  1006. "AUTO_CHGDONE");
  1007. if (res == NULL) {
  1008. dev_err(pm8058_chg.dev,
  1009. "%s:couldnt find resource AUTO_CHGDONE\n", __func__);
  1010. goto err_out;
  1011. } else {
  1012. ret = request_irq(res->start,
  1013. pm8058_chg_auto_chgdone_handler,
  1014. IRQF_TRIGGER_RISING,
  1015. res->name, NULL);
  1016. if (ret < 0) {
  1017. dev_err(pm8058_chg.dev, "%s:couldnt request %d %d\n",
  1018. __func__, res->start, ret);
  1019. goto err_out;
  1020. } else {
  1021. pm8058_chg.pmic_chg_irq[AUTO_CHGDONE_IRQ] = res->start;
  1022. pm8058_chg_disable_irq(AUTO_CHGDONE_IRQ);
  1023. }
  1024. }
  1025. res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
  1026. "AUTO_CHGFAIL");
  1027. if (res == NULL) {
  1028. dev_err(pm8058_chg.dev,
  1029. "%s:couldnt find resource AUTO_CHGFAIL\n", __func__);
  1030. goto err_out;
  1031. } else {
  1032. ret = request_irq(res->start,
  1033. pm8058_chg_auto_chgfail_handler,
  1034. IRQF_TRIGGER_RISING, res->name, NULL);
  1035. if (ret < 0) {
  1036. dev_err(pm8058_chg.dev, "%s:couldnt request %d %d\n",
  1037. __func__, res->start, ret);
  1038. goto err_out;
  1039. } else {
  1040. pm8058_chg.pmic_chg_irq[AUTO_CHGFAIL_IRQ] = res->start;
  1041. pm8058_chg_disable_irq(AUTO_CHGFAIL_IRQ);
  1042. }
  1043. }
  1044. res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "CHGSTATE");
  1045. if (res == NULL) {
  1046. dev_err(pm8058_chg.dev,
  1047. "%s:couldnt find resource CHGSTATE\n", __func__);
  1048. goto err_out;
  1049. } else {
  1050. ret = request_irq(res->start,
  1051. pm8058_chg_chgstate_handler,
  1052. IRQF_TRIGGER_RISING, res->name, NULL);
  1053. if (ret < 0) {
  1054. dev_err(pm8058_chg.dev, "%s:couldnt request %d %d\n",
  1055. __func__, res->start, ret);
  1056. goto err_out;
  1057. } else {
  1058. pm8058_chg.pmic_chg_irq[CHGSTATE_IRQ] = res->start;
  1059. pm8058_chg_disable_irq(CHGSTATE_IRQ);
  1060. }
  1061. }
  1062. res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "FASTCHG");
  1063. if (res == NULL) {
  1064. dev_err(pm8058_chg.dev,
  1065. "%s:couldnt find resource FASTCHG\n", __func__);
  1066. goto err_out;
  1067. } else {
  1068. ret = request_irq(res->start,
  1069. pm8058_chg_fastchg_handler,
  1070. IRQF_TRIGGER_RISING, res->name, NULL);
  1071. if (ret < 0) {
  1072. dev_err(pm8058_chg.dev, "%s:couldnt request %d %d\n",
  1073. __func__, res->start, ret);
  1074. goto err_out;
  1075. } else {
  1076. pm8058_chg.pmic_chg_irq[FASTCHG_IRQ] = res->start;
  1077. pm8058_chg_disable_irq(FASTCHG_IRQ);
  1078. }
  1079. }
  1080. res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "BATTTEMP");
  1081. if (res == NULL) {
  1082. dev_err(pm8058_chg.dev,
  1083. "%s:couldnt find resource CHG_END\n", __func__);
  1084. goto err_out;
  1085. } else {
  1086. ret = request_irq(res->start,
  1087. pm8058_chg_batttemp_handler,
  1088. IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
  1089. res->name, NULL);
  1090. if (ret < 0) {
  1091. dev_err(pm8058_chg.dev, "%s:couldnt request %d %d\n",
  1092. __func__, res->start, ret);
  1093. goto err_out;
  1094. } else {
  1095. pm8058_chg.pmic_chg_irq[BATTTEMP_IRQ] = res->start;
  1096. pm8058_chg_disable_irq(BATTTEMP_IRQ);
  1097. }
  1098. }
  1099. res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
  1100. "BATT_REPLACE");
  1101. if (res == NULL) {
  1102. dev_err(pm8058_chg.dev,
  1103. "%s:couldnt find resource BATT_REPLACE\n", __func__);
  1104. goto err_out;
  1105. } else {
  1106. ret = request_irq(res->start,
  1107. pm8058_chg_batt_replace_handler,
  1108. IRQF_TRIGGER_RISING, res->name, NULL);
  1109. if (ret < 0) {
  1110. dev_err(pm8058_chg.dev, "%s:couldnt request %d %d\n",
  1111. __func__, res->start, ret);
  1112. goto err_out;
  1113. } else {
  1114. pm8058_chg.pmic_chg_irq[BATT_REPLACE_IRQ] = res->start;
  1115. pm8058_chg_disable_irq(BATT_REPLACE_IRQ);
  1116. }
  1117. }
  1118. res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "BATTCONNECT");
  1119. if (res == NULL) {
  1120. dev_err(pm8058_chg.dev,
  1121. "%s:couldnt find resource BATTCONNECT\n", __func__);
  1122. goto err_out;
  1123. } else {
  1124. ret = request_irq(res->start,
  1125. pm8058_chg_battconnect_handler,
  1126. IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
  1127. res->name, NULL);
  1128. if (ret < 0) {
  1129. dev_err(pm8058_chg.dev, "%s:couldnt request %d %d\n",
  1130. __func__, res->start, ret);
  1131. goto err_out;
  1132. } else {
  1133. pm8058_chg.pmic_chg_irq[BATTCONNECT_IRQ] = res->start;
  1134. pm8058_chg_disable_irq(BATTCONNECT_IRQ);
  1135. }
  1136. }
  1137. res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "VBATDET");
  1138. if (res == NULL) {
  1139. dev_err(pm8058_chg.dev,
  1140. "%s:couldnt find resource VBATDET\n", __func__);
  1141. goto err_out;
  1142. } else {
  1143. ret = request_threaded_irq(res->start, NULL,
  1144. pm8058_chg_vbatdet_handler,
  1145. IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
  1146. res->name, NULL);
  1147. if (ret < 0) {
  1148. dev_err(pm8058_chg.dev, "%s:couldnt request %d %d\n",
  1149. __func__, res->start, ret);
  1150. goto err_out;
  1151. } else {
  1152. pm8058_chg.pmic_chg_irq[VBATDET_IRQ] = res->start;
  1153. pm8058_chg_disable_irq(VBATDET_IRQ);
  1154. }
  1155. }
  1156. return 0;
  1157. err_out:
  1158. free_irqs();
  1159. return -EINVAL;
  1160. }
  1161. static int pm8058_get_charge_batt(void)
  1162. {
  1163. u8 temp;
  1164. int rc;
  1165. rc = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, &temp);
  1166. if (rc)
  1167. return rc;
  1168. temp &= BIT(CHG_CHARGE_BAT);
  1169. if (temp)
  1170. temp = 1;
  1171. return temp;
  1172. }
  1173. EXPORT_SYMBOL(pm8058_get_charge_batt);
  1174. static int pm8058_set_charge_batt(int on)
  1175. {
  1176. u8 temp;
  1177. int rc;
  1178. rc = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, &temp);
  1179. if (rc)
  1180. return rc;
  1181. if (on)
  1182. temp |= BIT(CHG_CHARGE_BAT);
  1183. else
  1184. temp &= ~BIT(CHG_CHARGE_BAT);
  1185. return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, temp);
  1186. }
  1187. EXPORT_SYMBOL(pm8058_set_charge_batt);
  1188. static int get_charge_batt(void *data, u64 * val)
  1189. {
  1190. int ret;
  1191. ret = pm8058_get_charge_batt();
  1192. if (ret < 0)
  1193. return ret;
  1194. *val = ret;
  1195. return 0;
  1196. }
  1197. static int set_charge_batt(void *data, u64 val)
  1198. {
  1199. return pm8058_set_charge_batt(val);
  1200. }
  1201. DEFINE_SIMPLE_ATTRIBUTE(fet_fops, get_charge_batt, set_charge_batt, "%llu\n");
  1202. static void pm8058_chg_determine_initial_state(void)
  1203. {
  1204. if (is_chg_plugged_in()) {
  1205. pm8058_chg.present = 1;
  1206. msm_charger_notify_event(&usb_hw_chg, CHG_INSERTED_EVENT);
  1207. dev_info(pm8058_chg.dev, "%s charger present\n", __func__);
  1208. } else {
  1209. pm8058_chg.present = 0;
  1210. dev_info(pm8058_chg.dev, "%s charger absent\n", __func__);
  1211. }
  1212. pm8058_chg_enable_irq(CHGVAL_IRQ);
  1213. }
  1214. static int pm8058_stop_charging(struct msm_hardware_charger *hw_chg)
  1215. {
  1216. int ret;
  1217. dev_info(pm8058_chg.dev, "%s stopping charging\n", __func__);
  1218. /* disable the irqs enabled while charging */
  1219. pm8058_chg_disable_irq(AUTO_CHGFAIL_IRQ);
  1220. pm8058_chg_disable_irq(CHGHOT_IRQ);
  1221. pm8058_chg_disable_irq(AUTO_CHGDONE_IRQ);
  1222. pm8058_chg_disable_irq(FASTCHG_IRQ);
  1223. pm8058_chg_disable_irq(CHG_END_IRQ);
  1224. pm8058_chg_disable_irq(VBATDET_IRQ);
  1225. pm8058_chg_disable_irq(VBATDET_LOW_IRQ);
  1226. cancel_delayed_work_sync(&pm8058_chg.veoc_begin_work);
  1227. cancel_delayed_work_sync(&pm8058_chg.check_vbat_low_work);
  1228. cancel_delayed_work_sync(&pm8058_chg.chg_done_check_work);
  1229. cancel_delayed_work_sync(&pm8058_chg.charging_check_work);
  1230. ret = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[FASTCHG_IRQ]);
  1231. if (ret == 1)
  1232. pm_chg_suspend(1);
  1233. else
  1234. dev_err(pm8058_chg.dev,
  1235. "%s called when not fast-charging\n", __func__);
  1236. pm_chg_failed_clear(1);
  1237. pm8058_chg.waiting_for_veoc = 0;
  1238. pm8058_chg.waiting_for_topoff = 0;
  1239. if (pm8058_chg.voter)
  1240. msm_xo_mode_vote(pm8058_chg.voter, MSM_XO_MODE_OFF);
  1241. return 0;
  1242. }
  1243. static int get_status(void *data, u64 * val)
  1244. {
  1245. *val = pm8058_chg.current_charger_current;
  1246. return 0;
  1247. }
  1248. static int set_status(void *data, u64 val)
  1249. {
  1250. pm8058_chg.current_charger_current = val;
  1251. if (pm8058_chg.current_charger_current)
  1252. pm8058_start_charging(NULL,
  1253. AUTO_CHARGING_VMAXSEL,
  1254. pm8058_chg.current_charger_current);
  1255. else
  1256. pm8058_stop_charging(NULL);
  1257. return 0;
  1258. }
  1259. DEFINE_SIMPLE_ATTRIBUTE(chg_fops, get_status, set_status, "%llu\n");
  1260. static int set_disable_status_param(const char *val, struct kernel_param *kp)
  1261. {
  1262. int ret;
  1263. ret = param_set_int(val, kp);
  1264. if (ret)
  1265. return ret;
  1266. if (pm8058_chg.inited && pm8058_chg.disabled) {
  1267. /*
  1268. * stop_charging is called during usb suspend
  1269. * act as the usb is removed by disabling auto and enum
  1270. */
  1271. pm_chg_enum_done_enable(0);
  1272. pm_chg_auto_disable(1);
  1273. pm8058_stop_charging(NULL);
  1274. }
  1275. return 0;
  1276. }
  1277. module_param_call(disabled, set_disable_status_param, param_get_uint,
  1278. &(pm8058_chg.disabled), 0644);
  1279. static int pm8058_charging_switched(struct msm_hardware_charger *hw_chg)
  1280. {
  1281. u8 temp;
  1282. temp = 0xA3;
  1283. pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST_2, temp);
  1284. temp = 0x84;
  1285. pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST_2, temp);
  1286. msleep(2);
  1287. temp = 0x80;
  1288. pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST_2, temp);
  1289. return 0;
  1290. }
  1291. static int get_reg(void *data, u64 * val)
  1292. {
  1293. int i = (int)data;
  1294. int ret;
  1295. u8 temp;
  1296. ret = pm8xxx_readb(pm8058_chg.dev->parent, i, &temp);
  1297. if (ret)
  1298. return -EAGAIN;
  1299. *val = temp;
  1300. return 0;
  1301. }
  1302. static int set_reg(void *data, u64 val)
  1303. {
  1304. int i = (int)data;
  1305. int ret;
  1306. u8 temp;
  1307. temp = (u8) val;
  1308. ret = pm8xxx_writeb(pm8058_chg.dev->parent, i, temp);
  1309. mb();
  1310. if (ret)
  1311. return -EAGAIN;
  1312. return 0;
  1313. }
  1314. DEFINE_SIMPLE_ATTRIBUTE(reg_fops, get_reg, set_reg, "%llu\n");
  1315. #ifdef CONFIG_DEBUG_FS
  1316. static void create_debugfs_entries(void)
  1317. {
  1318. pm8058_chg.dent = debugfs_create_dir("pm8058_usb_chg", NULL);
  1319. if (IS_ERR(pm8058_chg.dent)) {
  1320. pr_err("pmic charger couldnt create debugfs dir\n");
  1321. return;
  1322. }
  1323. debugfs_create_file("CHG_CNTRL", 0644, pm8058_chg.dent,
  1324. (void *)PM8058_CHG_CNTRL, &reg_fops);
  1325. debugfs_create_file("CHG_CNTRL_2", 0644, pm8058_chg.dent,
  1326. (void *)PM8058_CHG_CNTRL_2, &reg_fops);
  1327. debugfs_create_file("CHG_VMAX_SEL", 0644, pm8058_chg.dent,
  1328. (void *)PM8058_CHG_VMAX_SEL, &reg_fops);
  1329. debugfs_create_file("CHG_VBAT_DET", 0644, pm8058_chg.dent,
  1330. (void *)PM8058_CHG_VBAT_DET, &reg_fops);
  1331. debugfs_create_file("CHG_IMAX", 0644, pm8058_chg.dent,
  1332. (void *)PM8058_CHG_IMAX, &reg_fops);
  1333. debugfs_create_file("CHG_TRICKLE", 0644, pm8058_chg.dent,
  1334. (void *)PM8058_CHG_TRICKLE, &reg_fops);
  1335. debugfs_create_file("CHG_ITERM", 0644, pm8058_chg.dent,
  1336. (void *)PM8058_CHG_ITERM, &reg_fops);
  1337. debugfs_create_file("CHG_TTRKL_MAX", 0644, pm8058_chg.dent,
  1338. (void *)PM8058_CHG_TTRKL_MAX, &reg_fops);
  1339. debugfs_create_file("CHG_TCHG_MAX", 0644, pm8058_chg.dent,
  1340. (void *)PM8058_CHG_TCHG_MAX, &reg_fops);
  1341. debugfs_create_file("CHG_TEMP_THRESH", 0644, pm8058_chg.dent,
  1342. (void *)PM8058_CHG_TEMP_THRESH, &reg_fops);
  1343. debugfs_create_file("CHG_TEMP_REG", 0644, pm8058_chg.dent,
  1344. (void *)PM8058_CHG_TEMP_REG, &reg_fops);
  1345. debugfs_create_file("FSM_STATE", 0644, pm8058_chg.dent, NULL,
  1346. &fsm_fops);
  1347. debugfs_create_file("stop", 0644, pm8058_chg.dent, NULL,
  1348. &chg_fops);
  1349. if (pm8058_chg.pmic_chg_irq[CHGVAL_IRQ])
  1350. debugfs_create_file("CHGVAL", 0444, pm8058_chg.dent,
  1351. (void *)pm8058_chg.pmic_chg_irq[CHGVAL_IRQ],
  1352. &rt_fops);
  1353. if (pm8058_chg.pmic_chg_irq[CHGINVAL_IRQ])
  1354. debugfs_create_file("CHGINVAL", 0444, pm8058_chg.dent, (void *)
  1355. pm8058_chg.pmic_chg_irq[CHGINVAL_IRQ],
  1356. &rt_fops);
  1357. if (pm8058_chg.pmic_chg_irq[CHGILIM_IRQ])
  1358. debugfs_create_file("CHGILIM", 0444, pm8058_chg.dent, (void *)
  1359. pm8058_chg.pmic_chg_irq[CHGILIM_IRQ],
  1360. &rt_fops);
  1361. if (pm8058_chg.pmic_chg_irq[VCP_IRQ])
  1362. debugfs_create_file("VCP", 0444, pm8058_chg.dent,
  1363. (void *)pm8058_chg.pmic_chg_irq[VCP_IRQ],
  1364. &rt_fops);
  1365. if (pm8058_chg.pmic_chg_irq[ATC_DONE_IRQ])
  1366. debugfs_create_file("ATC_DONE", 0444, pm8058_chg.dent, (void *)
  1367. pm8058_chg.pmic_chg_irq[ATC_DONE_IRQ],
  1368. &rt_fops);
  1369. if (pm8058_chg.pmic_chg_irq[ATCFAIL_IRQ])
  1370. debugfs_create_file("ATCFAIL", 0444, pm8058_chg.dent, (void *)
  1371. pm8058_chg.pmic_chg_irq[ATCFAIL_IRQ],
  1372. &rt_fops);
  1373. if (pm8058_chg.pmic_chg_irq[AUTO_CHGDONE_IRQ])
  1374. debugfs_create_file("AUTO_CHGDONE", 0444, pm8058_chg.dent,
  1375. (void *)
  1376. pm8058_chg.pmic_chg_irq[AUTO_CHGDONE_IRQ],
  1377. &rt_fops);
  1378. if (pm8058_chg.pmic_chg_irq[AUTO_CHGFAIL_IRQ])
  1379. debugfs_create_file("AUTO_CHGFAIL", 0444, pm8058_chg.dent,
  1380. (void *)
  1381. pm8058_chg.pmic_chg_irq[AUTO_CHGFAIL_IRQ],
  1382. &rt_fops);
  1383. if (pm8058_chg.pmic_chg_irq[CHGSTATE_IRQ])
  1384. debugfs_create_file("CHGSTATE", 0444, pm8058_chg.dent, (void *)
  1385. pm8058_chg.pmic_chg_irq[CHGSTATE_IRQ],
  1386. &rt_fops);
  1387. if (pm8058_chg.pmic_chg_irq[FASTCHG_IRQ])
  1388. debugfs_create_file("FASTCHG", 0444, pm8058_chg.dent, (void *)
  1389. pm8058_chg.pmic_chg_irq[FASTCHG_IRQ],
  1390. &rt_fops);
  1391. if (pm8058_chg.pmic_chg_irq[CHG_END_IRQ])
  1392. debugfs_create_file("CHG_END", 0444, pm8058_chg.dent, (void *)
  1393. pm8058_chg.pmic_chg_irq[CHG_END_IRQ],
  1394. &rt_fops);
  1395. if (pm8058_chg.pmic_chg_irq[BATTTEMP_IRQ])
  1396. debugfs_create_file("BATTTEMP", 0444, pm8058_chg.dent, (void *)
  1397. pm8058_chg.pmic_chg_irq[BATTTEMP_IRQ],
  1398. &rt_fops);
  1399. if (pm8058_chg.pmic_chg_irq[CHGHOT_IRQ])
  1400. debugfs_create_file("CHGHOT", 0444, pm8058_chg.dent,
  1401. (void *)pm8058_chg.pmic_chg_irq[CHGHOT_IRQ],
  1402. &rt_fops);
  1403. if (pm8058_chg.pmic_chg_irq[CHGTLIMIT_IRQ])
  1404. debugfs_create_file("CHGTLIMIT", 0444, pm8058_chg.dent, (void *)
  1405. pm8058_chg.pmic_chg_irq[CHGTLIMIT_IRQ],
  1406. &rt_fops);
  1407. if (pm8058_chg.pmic_chg_irq[CHG_GONE_IRQ])
  1408. debugfs_create_file("CHG_GONE", 0444, pm8058_chg.dent, (void *)
  1409. pm8058_chg.pmic_chg_irq[CHG_GONE_IRQ],
  1410. &rt_fops);
  1411. if (pm8058_chg.pmic_chg_irq[VCPMAJOR_IRQ])
  1412. debugfs_create_file("VCPMAJOR", 0444, pm8058_chg.dent, (void *)
  1413. pm8058_chg.pmic_chg_irq[VCPMAJOR_IRQ],
  1414. &rt_fops);
  1415. if (pm8058_chg.pmic_chg_irq[BATFET_IRQ])
  1416. debugfs_create_file("BATFET", 0444, pm8058_chg.dent,
  1417. (void *)pm8058_chg.pmic_chg_irq[BATFET_IRQ],
  1418. &rt_fops);
  1419. if (pm8058_chg.pmic_chg_irq[BATT_REPLACE_IRQ])
  1420. debugfs_create_file("BATT_REPLACE", 0444, pm8058_chg.dent,
  1421. (void *)
  1422. pm8058_chg.pmic_chg_irq[BATT_REPLACE_IRQ],
  1423. &rt_fops);
  1424. if (pm8058_chg.pmic_chg_irq[BATTCONNECT_IRQ])
  1425. debugfs_create_file("BATTCONNECT", 0444, pm8058_chg.dent,
  1426. (void *)
  1427. pm8058_chg.pmic_chg_irq[BATTCONNECT_IRQ],
  1428. &rt_fops);
  1429. if (pm8058_chg.pmic_chg_irq[VBATDET_IRQ])
  1430. debugfs_create_file("VBATDET", 0444, pm8058_chg.dent, (void *)
  1431. pm8058_chg.pmic_chg_irq[VBATDET_IRQ],
  1432. &rt_fops);
  1433. if (pm8058_chg.pmic_chg_irq[VBATDET_LOW_IRQ])
  1434. debugfs_create_file("VBATDET_LOW", 0444, pm8058_chg.dent,
  1435. (void *)
  1436. pm8058_chg.pmic_chg_irq[VBATDET_LOW_IRQ],
  1437. &rt_fops);
  1438. debugfs_create_file("CHARGE_BATT", 0444, pm8058_chg.dent,
  1439. NULL,
  1440. &fet_fops);
  1441. }
  1442. #else
  1443. static inline void create_debugfs_entries(void)
  1444. {
  1445. }
  1446. #endif
  1447. static void remove_debugfs_entries(void)
  1448. {
  1449. debugfs_remove_recursive(pm8058_chg.dent);
  1450. }
  1451. static struct msm_hardware_charger usb_hw_chg = {
  1452. .type = CHG_TYPE_USB,
  1453. .rating = 1,
  1454. .name = "pm8058-usb",
  1455. .start_charging = pm8058_start_charging,
  1456. .stop_charging = pm8058_stop_charging,
  1457. .charging_switched = pm8058_charging_switched,
  1458. .start_system_current = pm8058_start_system_current,
  1459. .stop_system_current = pm8058_stop_system_current,
  1460. };
  1461. static int batt_read_adc(int channel, int *mv_reading)
  1462. {
  1463. int ret;
  1464. void *h;
  1465. struct adc_chan_result adc_chan_result;
  1466. struct completion conv_complete_evt;
  1467. pr_debug("%s: called for %d\n", __func__, channel);
  1468. ret = adc_channel_open(channel, &h);
  1469. if (ret) {
  1470. pr_err("%s: couldnt open channel %d ret=%d\n",
  1471. __func__, channel, ret);
  1472. goto out;
  1473. }
  1474. init_completion(&conv_complete_evt);
  1475. ret = adc_channel_request_conv(h, &conv_complete_evt);
  1476. if (ret) {
  1477. pr_err("%s: couldnt request conv channel %d ret=%d\n",
  1478. __func__, channel, ret);
  1479. goto out;
  1480. }
  1481. wait_for_completion(&conv_complete_evt);
  1482. ret = adc_channel_read_result(h, &adc_chan_result);
  1483. if (ret) {
  1484. pr_err("%s: couldnt read result channel %d ret=%d\n",
  1485. __func__, channel, ret);
  1486. goto out;
  1487. }
  1488. ret = adc_channel_close(h);
  1489. if (ret) {
  1490. pr_err("%s: couldnt close channel %d ret=%d\n",
  1491. __func__, channel, ret);
  1492. }
  1493. if (mv_reading)
  1494. *mv_reading = adc_chan_result.measurement;
  1495. pr_debug("%s: done for %d\n", __func__, channel);
  1496. return adc_chan_result.physical;
  1497. out:
  1498. pr_debug("%s: done for %d\n", __func__, channel);
  1499. return -EINVAL;
  1500. }
  1501. #define BATT_THERM_OPEN_MV 2000
  1502. static int pm8058_is_battery_present(void)
  1503. {
  1504. int mv_reading;
  1505. mv_reading = 0;
  1506. batt_read_adc(CHANNEL_ADC_BATT_THERM, &mv_reading);
  1507. pr_debug("%s: therm_raw is %d\n", __func__, mv_reading);
  1508. if (mv_reading > 0 && mv_reading < BATT_THERM_OPEN_MV)
  1509. return 1;
  1510. return 0;
  1511. }
  1512. static int pm8058_get_battery_temperature(void)
  1513. {
  1514. return batt_read_adc(CHANNEL_ADC_BATT_THERM, NULL);
  1515. }
  1516. #define BATT_THERM_OPERATIONAL_MAX_CELCIUS 40
  1517. #define BATT_THERM_OPERATIONAL_MIN_CELCIUS 0
  1518. static int pm8058_is_battery_temp_within_range(void)
  1519. {
  1520. int therm_celcius;
  1521. therm_celcius = pm8058_get_battery_temperature();
  1522. pr_debug("%s: therm_celcius is %d\n", __func__, therm_celcius);
  1523. if (therm_celcius > 0
  1524. && therm_celcius > BATT_THERM_OPERATIONAL_MIN_CELCIUS
  1525. && therm_celcius < BATT_THERM_OPERATIONAL_MAX_CELCIUS)
  1526. return 1;
  1527. return 0;
  1528. }
  1529. #define BATT_ID_MAX_MV 800
  1530. #define BATT_ID_MIN_MV 600
  1531. static int pm8058_is_battery_id_valid(void)
  1532. {
  1533. int batt_id_mv;
  1534. batt_id_mv = batt_read_adc(CHANNEL_ADC_BATT_ID, NULL);
  1535. pr_debug("%s: batt_id_mv is %d\n", __func__, batt_id_mv);
  1536. /*
  1537. * The readings are not in range
  1538. * assume battery is present for now
  1539. */
  1540. return 1;
  1541. if (batt_id_mv > 0
  1542. && batt_id_mv > BATT_ID_MIN_MV
  1543. && batt_id_mv < BATT_ID_MAX_MV)
  1544. return 1;
  1545. return 0;
  1546. }
  1547. /* returns voltage in mV */
  1548. static int pm8058_get_battery_mvolts(void)
  1549. {
  1550. int vbatt_mv;
  1551. vbatt_mv = batt_read_adc(CHANNEL_ADC_VBATT, NULL);
  1552. pr_debug("%s: vbatt_mv is %d\n", __func__, vbatt_mv);
  1553. if (vbatt_mv > 0)
  1554. return vbatt_mv;
  1555. /*
  1556. * return 0 to tell the upper layers
  1557. * we couldnt read the battery voltage
  1558. */
  1559. return 0;
  1560. }
  1561. static int msm_battery_gauge_alarm_notify(struct notifier_block *nb,
  1562. unsigned long status, void *unused)
  1563. {
  1564. int rc;
  1565. pr_info("%s: status: %lu\n", __func__, status);
  1566. switch (status) {
  1567. case 0:
  1568. dev_err(pm8058_chg.dev,
  1569. "%s: spurious interrupt\n", __func__);
  1570. break;
  1571. /* expected case - trip of low threshold */
  1572. case 1:
  1573. rc = pm8xxx_batt_alarm_disable(
  1574. PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
  1575. if (!rc)
  1576. rc = pm8xxx_batt_alarm_disable(
  1577. PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
  1578. if (rc)
  1579. dev_err(pm8058_chg.dev,
  1580. "%s: unable to set alarm state\n", __func__);
  1581. msm_charger_notify_event(NULL, CHG_BATT_NEEDS_RECHARGING);
  1582. break;
  1583. case 2:
  1584. dev_err(pm8058_chg.dev,
  1585. "%s: trip of high threshold\n", __func__);
  1586. break;
  1587. default:
  1588. dev_err(pm8058_chg.dev,
  1589. "%s: error received\n", __func__);
  1590. };
  1591. return 0;
  1592. }
  1593. static int pm8058_monitor_for_recharging(void)
  1594. {
  1595. int rc;
  1596. /* enable low comparator */
  1597. rc = pm8xxx_batt_alarm_disable(PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
  1598. if (!rc)
  1599. return pm8xxx_batt_alarm_enable(
  1600. PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
  1601. return rc;
  1602. }
  1603. static struct msm_battery_gauge pm8058_batt_gauge = {
  1604. .get_battery_mvolts = pm8058_get_battery_mvolts,
  1605. .get_battery_temperature = pm8058_get_battery_temperature,
  1606. .is_battery_present = pm8058_is_battery_present,
  1607. .is_battery_temp_within_range = pm8058_is_battery_temp_within_range,
  1608. .is_battery_id_valid = pm8058_is_battery_id_valid,
  1609. .monitor_for_recharging = pm8058_monitor_for_recharging,
  1610. };
  1611. static int pm8058_usb_voltage_lower_limit(void)
  1612. {
  1613. u8 temp, old;
  1614. int ret = 0;
  1615. temp = 0x10;
  1616. ret |= pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST, temp);
  1617. ret |= pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TEST, &old);
  1618. old = old & ~BIT(IGNORE_LL);
  1619. temp = 0x90 | (0xF & old);
  1620. ret |= pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST, temp);
  1621. return ret;
  1622. }
  1623. static int __devinit pm8058_charger_probe(struct platform_device *pdev)
  1624. {
  1625. struct pmic8058_charger_data *pdata;
  1626. int rc = 0;
  1627. pm8058_chg.pdata = pdev->dev.platform_data;
  1628. pm8058_chg.dev = &pdev->dev;
  1629. pdata = (struct pmic8058_charger_data *) pm8058_chg.pdata;
  1630. if (pdata == NULL) {
  1631. pr_err("%s: pdata not present\n", __func__);
  1632. return -EINVAL;
  1633. }
  1634. if (pdata->charger_data_valid) {
  1635. usb_hw_chg.type = pdata->charger_type;
  1636. chg_data.charger_type = pdata->charger_type;
  1637. chg_data.max_source_current = pdata->max_source_current;
  1638. }
  1639. rc = request_irqs(pdev);
  1640. if (rc) {
  1641. pr_err("%s: couldnt register interrupts\n", __func__);
  1642. goto out;
  1643. }
  1644. rc = pm8058_usb_voltage_lower_limit();
  1645. if (rc) {
  1646. pr_err("%s: couldnt set ignore lower limit bit to 0\n",
  1647. __func__);
  1648. goto free_irq;
  1649. }
  1650. rc = msm_charger_register(&usb_hw_chg);
  1651. if (rc) {
  1652. pr_err("%s: msm_charger_register failed ret=%d\n",
  1653. __func__, rc);
  1654. goto free_irq;
  1655. }
  1656. pm_chg_batt_temp_disable(0);
  1657. msm_battery_gauge_register(&pm8058_batt_gauge);
  1658. __dump_chg_regs();
  1659. create_debugfs_entries();
  1660. INIT_DELAYED_WORK(&pm8058_chg.veoc_begin_work, veoc_begin_work);
  1661. INIT_DELAYED_WORK(&pm8058_chg.check_vbat_low_work, vbat_low_work);
  1662. INIT_DELAYED_WORK(&pm8058_chg.chg_done_check_work, chg_done_check_work);
  1663. INIT_DELAYED_WORK(&pm8058_chg.charging_check_work, charging_check_work);
  1664. /* determine what state the charger is in */
  1665. pm8058_chg_determine_initial_state();
  1666. pm8058_chg_enable_irq(BATTTEMP_IRQ);
  1667. pm8058_chg_enable_irq(BATTCONNECT_IRQ);
  1668. rc = pm8xxx_batt_alarm_disable(PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
  1669. if (!rc)
  1670. rc = pm8xxx_batt_alarm_disable(
  1671. PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
  1672. if (rc) {
  1673. pr_err("%s: unable to set batt alarm state\n", __func__);
  1674. goto free_irq;
  1675. }
  1676. /*
  1677. * The batt-alarm driver requires sane values for both min / max,
  1678. * regardless of whether they're both activated.
  1679. */
  1680. rc = pm8xxx_batt_alarm_threshold_set(
  1681. PM8XXX_BATT_ALARM_LOWER_COMPARATOR, resume_mv);
  1682. if (!rc)
  1683. rc = pm8xxx_batt_alarm_threshold_set(
  1684. PM8XXX_BATT_ALARM_UPPER_COMPARATOR, 4300);
  1685. if (rc) {
  1686. pr_err("%s: unable to set batt alarm threshold\n", __func__);
  1687. goto free_irq;
  1688. }
  1689. rc = pm8xxx_batt_alarm_hold_time_set(
  1690. PM8XXX_BATT_ALARM_HOLD_TIME_16_MS);
  1691. if (rc) {
  1692. pr_err("%s: unable to set batt alarm hold time\n", __func__);
  1693. goto free_irq;
  1694. }
  1695. /* PWM enabled at 2Hz */
  1696. rc = pm8xxx_batt_alarm_pwm_rate_set(1, 7, 4);
  1697. if (rc) {
  1698. pr_err("%s: unable to set batt alarm pwm rate\n", __func__);
  1699. goto free_irq;
  1700. }
  1701. rc = pm8xxx_batt_alarm_register_notifier(&alarm_notifier);
  1702. if (rc) {
  1703. pr_err("%s: unable to register alarm notifier\n", __func__);
  1704. goto free_irq;
  1705. }
  1706. pm8058_chg.inited = 1;
  1707. return 0;
  1708. free_irq:
  1709. free_irqs();
  1710. out:
  1711. return rc;
  1712. }
  1713. static int __devexit pm8058_charger_remove(struct platform_device *pdev)
  1714. {
  1715. struct pm8058_charger_chip *chip = platform_get_drvdata(pdev);
  1716. int rc;
  1717. msm_charger_notify_event(&usb_hw_chg, CHG_REMOVED_EVENT);
  1718. msm_charger_unregister(&usb_hw_chg);
  1719. cancel_delayed_work_sync(&pm8058_chg.veoc_begin_work);
  1720. cancel_delayed_work_sync(&pm8058_chg.check_vbat_low_work);
  1721. cancel_delayed_work_sync(&pm8058_chg.charging_check_work);
  1722. free_irqs();
  1723. remove_debugfs_entries();
  1724. kfree(chip);
  1725. rc = pm8xxx_batt_alarm_disable(PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
  1726. if (!rc)
  1727. rc = pm8xxx_batt_alarm_disable(
  1728. PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
  1729. if (rc)
  1730. pr_err("%s: unable to set batt alarm state\n", __func__);
  1731. rc |= pm8xxx_batt_alarm_unregister_notifier(&alarm_notifier);
  1732. if (rc)
  1733. pr_err("%s: unable to register alarm notifier\n", __func__);
  1734. return rc;
  1735. }
  1736. static struct platform_driver pm8058_charger_driver = {
  1737. .probe = pm8058_charger_probe,
  1738. .remove = __devexit_p(pm8058_charger_remove),
  1739. .driver = {
  1740. .name = "pm8058-charger",
  1741. .owner = THIS_MODULE,
  1742. },
  1743. };
  1744. static int __init pm8058_charger_init(void)
  1745. {
  1746. return platform_driver_register(&pm8058_charger_driver);
  1747. }
  1748. static void __exit pm8058_charger_exit(void)
  1749. {
  1750. platform_driver_unregister(&pm8058_charger_driver);
  1751. }
  1752. late_initcall(pm8058_charger_init);
  1753. module_exit(pm8058_charger_exit);
  1754. MODULE_LICENSE("GPL v2");
  1755. MODULE_DESCRIPTION("PMIC8058 BATTERY driver");
  1756. MODULE_VERSION("1.0");
  1757. MODULE_ALIAS("platform:pm8058_charger");