axp19-sply.c 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582
  1. /*
  2. * Battery charger driver for Dialog Semiconductor DA9030
  3. *
  4. * Copyright (C) 2008 Compulab, Ltd.
  5. * Mike Rapoport <mike@compulab.co.il>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. */
  11. #include <linux/kernel.h>
  12. #include <linux/init.h>
  13. #include <linux/types.h>
  14. #include <linux/device.h>
  15. #include <linux/workqueue.h>
  16. #include <linux/module.h>
  17. #include <linux/platform_device.h>
  18. #include <linux/power_supply.h>
  19. #include <linux/delay.h>
  20. #include <linux/kthread.h>
  21. #include <linux/slab.h>
  22. #include <linux/debugfs.h>
  23. #include <linux/seq_file.h>
  24. #include <linux/input.h>
  25. #include "axp-mfd.h"
  26. #include "axp-cfg.h"
  27. #include "axp-sply.h"
  28. static inline int axp199_vbat_to_mV(uint16_t reg)
  29. {
  30. return ((int)((( reg >> 8) << 4 ) | (reg & 0x000F))) * 1100 / 1000;
  31. }
  32. static inline int axp199_vdc_to_mV(uint16_t reg)
  33. {
  34. return ((int)(((reg >> 8) << 4 ) | (reg & 0x000F))) * 1700 / 1000;
  35. }
  36. static inline int axp199_ibat_to_mA(uint16_t reg)
  37. {
  38. return ((int)(((reg >> 8) << 5 ) | (reg & 0x001F))) * 500 / 1000;
  39. }
  40. static inline int axp199_iac_to_mA(uint16_t reg)
  41. {
  42. return ((int)(((reg >> 8) << 4 ) | (reg & 0x000F))) * 625 / 1000;
  43. }
  44. static inline int axp199_iusb_to_mA(uint16_t reg)
  45. {
  46. return ((int)(((reg >> 8) << 4 ) | (reg & 0x000F))) * 375 / 1000;
  47. }
  48. static inline void axp_read_adc(struct axp_charger *charger,
  49. struct axp_adc_res *adc)
  50. {
  51. uint8_t tmp[8];
  52. axp_reads(charger->master,AXP19_VACH_RES,8,tmp);
  53. adc->vac_res = ((uint16_t) tmp[0] << 8 )| tmp[1];
  54. adc->iac_res = ((uint16_t) tmp[2] << 8 )| tmp[3];
  55. adc->vusb_res = ((uint16_t) tmp[4] << 8 )| tmp[5];
  56. adc->iusb_res = ((uint16_t) tmp[6] << 8 )| tmp[7];
  57. axp_reads(charger->master,AXP19_VBATH_RES,6,tmp);
  58. adc->vbat_res = ((uint16_t) tmp[0] << 8 )| tmp[1];
  59. adc->ichar_res = ((uint16_t) tmp[2] << 8 )| tmp[3];
  60. adc->idischar_res = ((uint16_t) tmp[4] << 8 )| tmp[5];
  61. }
  62. static void axp_charger_update_state(struct axp_charger *charger)
  63. {
  64. uint8_t val[2];
  65. uint16_t tmp;
  66. axp_reads(charger->master,AXP19_CHARGE_STATUS,2,val);
  67. tmp = (val[1] << 8 )+ val[0];
  68. //printk("tmp = 0x%x\n",tmp);
  69. charger->is_on = (val[1] & AXP19_IN_CHARGE) ? 1 : 0;
  70. charger->fault = val[1];
  71. charger->bat_det = (tmp & AXP19_STATUS_BATEN)?1:0;
  72. charger->ac_det = (tmp & AXP19_STATUS_ACEN)?1:0;
  73. charger->usb_det = (tmp & AXP19_STATUS_USBEN)?1:0;
  74. charger->usb_valid = (tmp & AXP19_STATUS_USBVA)?1:0;
  75. charger->ac_valid = (tmp & AXP19_STATUS_ACVA)?1:0;
  76. charger->ext_valid = charger->ac_valid | charger->usb_valid;
  77. charger->bat_current_direction = (tmp & AXP19_STATUS_BATCURDIR)?1:0;
  78. charger->in_short = (tmp& AXP19_STATUS_ACUSBSH)?1:0;
  79. charger->batery_active = (tmp & AXP19_STATUS_BATINACT)?1:0;
  80. charger->low_charge_current = (tmp & AXP19_STATUS_CHACURLOEXP)?1:0;
  81. charger->int_over_temp = (tmp & AXP19_STATUS_ICTEMOV)?1:0;
  82. }
  83. static void axp_charger_update(struct axp_charger *charger)
  84. {
  85. uint16_t tmp;
  86. struct axp_adc_res adc;
  87. charger->adc = &adc;
  88. axp_read_adc(charger, &adc);
  89. tmp = charger->adc->vbat_res;
  90. charger->vbat = axp199_vbat_to_mV(tmp);
  91. //tmp = charger->adc->ichar_res + charger->adc->idischar_res;
  92. charger->ibat = ABS(axp199_ibat_to_mA(charger->adc->ichar_res)-axp199_ibat_to_mA(charger->adc->idischar_res));
  93. tmp = charger->adc->vac_res;
  94. charger->vac = axp199_vdc_to_mV(tmp);
  95. tmp = charger->adc->iac_res;
  96. charger->iac = axp199_iac_to_mA(tmp);
  97. tmp = charger->adc->vusb_res;
  98. charger->vusb = axp199_vdc_to_mV(tmp);
  99. tmp = charger->adc->iusb_res;
  100. charger->iusb = axp199_iusb_to_mA(tmp);
  101. }
  102. #if defined (CONFIG_AXP_CHARGEINIT)
  103. static void axp_set_charge(struct axp_charger *charger)
  104. {
  105. uint8_t val=0x00;
  106. uint8_t tmp=0x00;
  107. uint8_t var[3];
  108. if(charger->chgvol < 4150)
  109. val &= ~(3 << 5);
  110. else if (charger->chgvol<4200){
  111. val &= ~(3 << 5);
  112. val |= 1 << 5;
  113. }
  114. else if (charger->chgvol<4360){
  115. val &= ~(3 << 5);
  116. val |= 1 << 6;
  117. }
  118. else
  119. val |= 3 << 5;
  120. if(charger->chgcur< 100)
  121. charger->chgcur =100;
  122. val |= (charger->chgcur - 100) / 100 ;
  123. if(charger ->chgend == 10){
  124. val &= ~(1 << 4);
  125. }
  126. else {
  127. val |= 1 << 4;
  128. }
  129. val &= 0x7F;
  130. val |= charger->chgen << 7;
  131. if(charger->chgpretime < 30)
  132. charger->chgpretime = 30;
  133. if(charger->chgcsttime < 420)
  134. charger->chgcsttime = 420;
  135. if(charger->chgextcur < 300)
  136. charger->chgextcur = 300;
  137. tmp = ((charger->chgpretime - 30) / 10) << 6 \
  138. | (charger->chgcsttime - 420) / 60 | \
  139. (charger->chgexten << 2) | ((charger->chgextcur - 300) / 100 << 3);
  140. var[0] = val;
  141. var[1] = AXP19_CHARGE_CONTROL2;
  142. var[2] = tmp;
  143. axp_writes(charger->master, AXP19_CHARGE_CONTROL1,3, var);
  144. }
  145. #else
  146. static void axp_set_charge(struct axp_charger *charger)
  147. {
  148. }
  149. #endif
  150. static enum power_supply_property axp_battery_props[] = {
  151. POWER_SUPPLY_PROP_MODEL_NAME,
  152. POWER_SUPPLY_PROP_STATUS,
  153. POWER_SUPPLY_PROP_PRESENT,
  154. POWER_SUPPLY_PROP_ONLINE,
  155. POWER_SUPPLY_PROP_HEALTH,
  156. POWER_SUPPLY_PROP_TECHNOLOGY,
  157. POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
  158. POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
  159. POWER_SUPPLY_PROP_VOLTAGE_NOW,
  160. POWER_SUPPLY_PROP_CURRENT_NOW,
  161. POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
  162. POWER_SUPPLY_PROP_CHARGE_FULL,
  163. POWER_SUPPLY_PROP_CAPACITY,
  164. POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
  165. POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
  166. };
  167. static enum power_supply_property axp_ac_props[] = {
  168. POWER_SUPPLY_PROP_MODEL_NAME,
  169. POWER_SUPPLY_PROP_PRESENT,
  170. POWER_SUPPLY_PROP_ONLINE,
  171. POWER_SUPPLY_PROP_VOLTAGE_NOW,
  172. POWER_SUPPLY_PROP_CURRENT_NOW,
  173. };
  174. static enum power_supply_property axp_usb_props[] = {
  175. POWER_SUPPLY_PROP_MODEL_NAME,
  176. POWER_SUPPLY_PROP_PRESENT,
  177. POWER_SUPPLY_PROP_ONLINE,
  178. POWER_SUPPLY_PROP_VOLTAGE_NOW,
  179. POWER_SUPPLY_PROP_CURRENT_NOW,
  180. };
  181. static void axp_battery_check_status(struct axp_charger *charger,
  182. union power_supply_propval *val)
  183. {
  184. if (charger->bat_det) {
  185. if (charger->is_on)
  186. val->intval = POWER_SUPPLY_STATUS_CHARGING;
  187. else if( charger->rest_vol == 100 && charger->ext_valid)
  188. val->intval = POWER_SUPPLY_STATUS_FULL;
  189. else if( charger->ext_valid )
  190. val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
  191. else
  192. val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
  193. }
  194. else
  195. val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
  196. }
  197. static void axp_battery_check_health(struct axp_charger *charger,
  198. union power_supply_propval *val)
  199. {
  200. if (charger->fault & AXP19_FAULT_LOG_BATINACT)
  201. val->intval = POWER_SUPPLY_HEALTH_DEAD;
  202. else if (charger->fault & AXP19_FAULT_LOG_OVER_TEMP)
  203. val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
  204. else if (charger->fault & AXP19_FAULT_LOG_COLD)
  205. val->intval = POWER_SUPPLY_HEALTH_COLD;
  206. else
  207. val->intval = POWER_SUPPLY_HEALTH_GOOD;
  208. }
  209. static int axp_battery_get_property(struct power_supply *psy,
  210. enum power_supply_property psp,
  211. union power_supply_propval *val)
  212. {
  213. struct axp_charger *charger;
  214. int ret = 0;
  215. charger = container_of(psy, struct axp_charger, batt);
  216. switch (psp) {
  217. case POWER_SUPPLY_PROP_STATUS:
  218. axp_battery_check_status(charger, val);
  219. break;
  220. case POWER_SUPPLY_PROP_HEALTH:
  221. axp_battery_check_health(charger, val);
  222. break;
  223. case POWER_SUPPLY_PROP_TECHNOLOGY:
  224. val->intval = charger->battery_info->technology;
  225. break;
  226. case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
  227. val->intval = charger->battery_info->voltage_max_design;
  228. break;
  229. case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
  230. val->intval = charger->battery_info->voltage_min_design;
  231. break;
  232. case POWER_SUPPLY_PROP_VOLTAGE_NOW:
  233. val->intval = charger->vbat * 1000;
  234. break;
  235. case POWER_SUPPLY_PROP_CURRENT_NOW:
  236. val->intval = charger->ibat * 1000;
  237. break;
  238. case POWER_SUPPLY_PROP_MODEL_NAME:
  239. val->strval = charger->batt.name;
  240. break;
  241. case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
  242. case POWER_SUPPLY_PROP_CHARGE_FULL:
  243. val->intval = charger->battery_info->charge_full_design;
  244. break;
  245. case POWER_SUPPLY_PROP_CAPACITY:
  246. val->intval = charger->rest_vol;
  247. break;
  248. case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
  249. if(charger->bat_det && !(charger->is_on) && !(charger->ext_valid))
  250. val->intval = charger->rest_time;
  251. else
  252. val->intval = 0;
  253. break;
  254. case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:
  255. if(charger->bat_det && charger->is_on)
  256. val->intval = charger->rest_time;
  257. else
  258. val->intval = 0;
  259. break;
  260. case POWER_SUPPLY_PROP_ONLINE:
  261. val->intval = (!charger->is_on)&&(charger->bat_det) && (! charger->ext_valid);
  262. break;
  263. case POWER_SUPPLY_PROP_PRESENT:
  264. val->intval = charger->bat_det;
  265. break;
  266. default:
  267. ret = -EINVAL;
  268. break;
  269. }
  270. return ret;
  271. }
  272. static int axp_ac_get_property(struct power_supply *psy,
  273. enum power_supply_property psp,
  274. union power_supply_propval *val)
  275. {
  276. struct axp_charger *charger;
  277. int ret = 0;
  278. charger = container_of(psy, struct axp_charger, ac);
  279. switch(psp){
  280. case POWER_SUPPLY_PROP_MODEL_NAME:
  281. val->strval = charger->ac.name;break;
  282. case POWER_SUPPLY_PROP_PRESENT:
  283. val->intval = charger->ac_det;
  284. break;
  285. case POWER_SUPPLY_PROP_ONLINE:
  286. val->intval = charger->ac_valid;break;
  287. case POWER_SUPPLY_PROP_VOLTAGE_NOW:
  288. val->intval = charger->vac * 1000;
  289. break;
  290. case POWER_SUPPLY_PROP_CURRENT_NOW:
  291. val->intval = charger->iac * 1000;
  292. break;
  293. default:
  294. ret = -EINVAL;
  295. break;
  296. }
  297. return ret;
  298. }
  299. static int axp_usb_get_property(struct power_supply *psy,
  300. enum power_supply_property psp,
  301. union power_supply_propval *val)
  302. {
  303. struct axp_charger *charger;
  304. int ret = 0;
  305. charger = container_of(psy, struct axp_charger, usb);
  306. switch(psp){
  307. case POWER_SUPPLY_PROP_MODEL_NAME:
  308. val->strval = charger->usb.name;break;
  309. case POWER_SUPPLY_PROP_PRESENT:
  310. val->intval = charger->usb_det;
  311. break;
  312. case POWER_SUPPLY_PROP_ONLINE:
  313. val->intval = charger->usb_valid;
  314. break;
  315. case POWER_SUPPLY_PROP_VOLTAGE_NOW:
  316. val->intval = charger->vusb * 1000;
  317. break;
  318. case POWER_SUPPLY_PROP_CURRENT_NOW:
  319. val->intval = charger->iusb * 1000;
  320. break;
  321. default:
  322. ret = -EINVAL;
  323. break;
  324. }
  325. return ret;
  326. }
  327. static int axp_battery_event(struct notifier_block *nb, unsigned long event,
  328. void *data)
  329. {
  330. struct axp_charger *charger =
  331. container_of(nb, struct axp_charger, nb);
  332. axp_charger_update_state(charger);
  333. switch (event) {
  334. case AXP19_IRQ_BATIN:
  335. case AXP19_IRQ_ACIN:
  336. case AXP19_IRQ_USBIN:
  337. axp_set_bits(charger->master,AXP19_CHARGE_CONTROL1,0x80);
  338. break;
  339. case AXP19_IRQ_BATRE:
  340. case AXP19_IRQ_ACOV:
  341. case AXP19_IRQ_ACRE:
  342. case AXP19_IRQ_USBOV:
  343. case AXP19_IRQ_USBRE:
  344. case AXP19_IRQ_TEMOV:
  345. case AXP19_IRQ_TEMLO:
  346. axp_clr_bits(charger->master,AXP19_CHARGE_CONTROL1,0x80);
  347. break;
  348. default:
  349. break;
  350. }
  351. return 0;
  352. }
  353. static char *supply_list[] = {
  354. "battery",
  355. };
  356. static void axp_battery_setup_psy(struct axp_charger *charger)
  357. {
  358. struct power_supply *batt = &charger->batt;
  359. struct power_supply *ac = &charger->ac;
  360. struct power_supply *usb = &charger->usb;
  361. struct power_supply_info *info = charger->battery_info;
  362. batt->name = "battery";
  363. batt->use_for_apm = info->use_for_apm;
  364. batt->type = POWER_SUPPLY_TYPE_BATTERY;
  365. batt->get_property = axp_battery_get_property;
  366. batt->properties = axp_battery_props;
  367. batt->num_properties = ARRAY_SIZE(axp_battery_props);
  368. ac->name = "ac";
  369. ac->type = POWER_SUPPLY_TYPE_MAINS;
  370. ac->get_property = axp_ac_get_property;
  371. ac->supplied_to = supply_list,
  372. ac->num_supplicants = ARRAY_SIZE(supply_list),
  373. ac->properties = axp_ac_props;
  374. ac->num_properties = ARRAY_SIZE(axp_ac_props);
  375. usb->name = "usb";
  376. usb->type = POWER_SUPPLY_TYPE_USB;
  377. usb->get_property = axp_usb_get_property;
  378. usb->supplied_to = supply_list,
  379. usb->num_supplicants = ARRAY_SIZE(supply_list),
  380. usb->properties = axp_usb_props;
  381. usb->num_properties = ARRAY_SIZE(axp_usb_props);
  382. };
  383. #if defined (CONFIG_AXP_CHARGEINIT)
  384. static int axp_battery_adc_set(struct axp_charger *charger)
  385. {
  386. int ret ;
  387. uint8_t val;
  388. /*enable adc and set adc */
  389. val= AXP19_ADC_BATVOL_ENABLE | AXP19_ADC_BATCUR_ENABLE
  390. | AXP19_ADC_DCINCUR_ENABLE | AXP19_ADC_DCINVOL_ENABLE
  391. | AXP19_ADC_USBVOL_ENABLE | AXP19_ADC_USBCUR_ENABLE;
  392. ret = axp_write(charger->master, AXP19_ADC_CONTROL1, val);
  393. if (ret)
  394. return ret;
  395. ret = axp_read(charger->master, AXP19_ADC_CONTROL3, &val);
  396. switch (charger->sample_time/25){
  397. case 1: val &= ~(3 << 6);break;
  398. case 2: val &= ~(3 << 6);val |= 1 << 6;break;
  399. case 4: val &= ~(3 << 6);val |= 2 << 6;break;
  400. case 8: val |= 3 << 6;break;
  401. default: break;
  402. }
  403. ret = axp_write(charger->master, AXP19_ADC_CONTROL3, val);
  404. if (ret)
  405. return ret;
  406. return 0;
  407. }
  408. #else
  409. static int axp_battery_adc_set(struct axp_charger *charger)
  410. {
  411. return 0;
  412. }
  413. #endif
  414. static int axp_battery_first_init(struct axp_charger *charger)
  415. {
  416. int ret;
  417. uint8_t val;
  418. axp_set_charge(charger);
  419. ret = axp_battery_adc_set(charger);
  420. if(ret)
  421. return ret;
  422. ret = axp_read(charger->master, AXP19_ADC_CONTROL3, &val);
  423. switch ((val >> 6) & 0x03){
  424. case 0: charger->sample_time = 25;break;
  425. case 1: charger->sample_time = 50;break;
  426. case 2: charger->sample_time = 100;break;
  427. case 3: charger->sample_time = 200;break;
  428. default:break;
  429. }
  430. return ret;
  431. }
  432. static int axp_get_rdc(struct axp_charger *charger)
  433. {
  434. uint8_t val[2];
  435. unsigned int i,temp,pre_temp;
  436. int averPreVol = 0, averPreCur = 0,averNextVol = 0,averNextCur = 0;
  437. axp_reads(charger->master,AXP19_DATA_BUFFER2,2,val);
  438. pre_temp = (((val[0] & 0x07) << 8 ) + val[1]);
  439. if(!charger->bat_det){
  440. return pre_temp;
  441. }
  442. if( charger->ext_valid){
  443. for(i = 0; i< AXP19_RDC_COUNT; i++){
  444. axp_charger_update(charger);
  445. averPreVol += charger->vbat;
  446. averPreCur += charger->ibat;
  447. msleep(200);
  448. }
  449. averPreVol /= AXP19_RDC_COUNT;
  450. averPreCur /= AXP19_RDC_COUNT;
  451. axp_clr_bits(charger->master,AXP20_CHARGE_CONTROL1,0x80);
  452. msleep(3000);
  453. for(i = 0; i< AXP19_RDC_COUNT; i++){
  454. axp_charger_update(charger);
  455. averNextVol += charger->vbat;
  456. averNextCur += charger->ibat;
  457. msleep(200);
  458. }
  459. averNextVol /= AXP19_RDC_COUNT;
  460. averNextCur /= AXP19_RDC_COUNT;
  461. axp_set_bits(charger->master,AXP20_CHARGE_CONTROL1,0x80);
  462. if(ABS(averPreCur - averNextCur) > 200){
  463. temp = 1000 * ABS(averPreVol - averNextVol) / ABS(averPreCur - averNextCur);
  464. if((temp < 5) || (temp > 5000)){
  465. return pre_temp;
  466. }
  467. else {
  468. temp += pre_temp;
  469. temp >>= 1;
  470. axp_write(charger->master,AXP19_DATA_BUFFER2,((temp & 0xFF00) | 0x800) >> 8);
  471. axp_write(charger->master,AXP19_DATA_BUFFER3,temp & 0x00FF);
  472. return temp;
  473. }
  474. }
  475. else {
  476. return pre_temp;
  477. }
  478. }
  479. else {
  480. return pre_temp;
  481. }
  482. }
  483. static int axp_bat_vol(bool Flag,int Bat_Vol,int Bat_Cur,uint16_t Rdc)
  484. {
  485. if(Flag)
  486. {
  487. return Bat_Vol- (Bat_Cur*(int)Rdc/1000);
  488. }
  489. else
  490. {
  491. return Bat_Vol+ (Bat_Cur*(int)Rdc/1000);
  492. }
  493. }
  494. static int axp_get_coulomb(struct axp_charger *charger)
  495. {
  496. uint64_t rValue1,rValue2,rValue;
  497. uint8_t IC_type;
  498. uint8_t temp[8];
  499. axp_read(charger->master,03, &temp[0]);
  500. if( (temp[0] & 0x0f) == 0x03){
  501. IC_type = 1;
  502. }
  503. else{
  504. IC_type = 0;
  505. }
  506. axp_reads(charger->master,AXP19_CCHAR3_RES,8,temp);
  507. if(IC_type){
  508. rValue1 = 65536 * ((((uint64_t)temp[0]) << 24) + (((uint64_t)temp[1]) << 16) +
  509. (((uint64_t)temp[2]) << 8) + ((uint64_t)temp[3]));
  510. rValue2 = 65536 * ((((uint64_t)temp[4] )<< 24) + (((uint64_t)temp[5]) << 16) +
  511. (((uint64_t)temp[6]) << 8) + ((uint64_t)temp[7]));
  512. }
  513. else{
  514. rValue1 = ((((uint64_t)temp[0]) << 24) + (((uint64_t)temp[1]) << 16) +
  515. (((uint64_t)temp[2]) << 8) + ((uint64_t)temp[3]));
  516. rValue2 = ((((uint64_t)temp[4] )<< 24) + (((uint64_t)temp[5]) << 16) +
  517. (((uint64_t)temp[6]) << 8) + ((uint64_t)temp[7]));
  518. }
  519. if(rValue1 > rValue2){
  520. coulomb_flag = 1;
  521. rValue = rValue1 - rValue2 ;
  522. }
  523. else{
  524. coulomb_flag = 0;
  525. rValue = rValue2 - rValue1 ;
  526. }
  527. return (int) rValue /charger->sample_time/ 3600 / 2;
  528. }
  529. static uint8_t axp_vol_rate(int Bat_Ocv_Vol)
  530. {
  531. if(Bat_Ocv_Vol > FUELGUAGE_TOP_VOL) //4160
  532. {
  533. return FUELGUAGE_TOP_LEVEL;
  534. }
  535. else if(Bat_Ocv_Vol < FUELGUAGE_LOW_VOL) //<3400
  536. {
  537. return FUELGUAGE_LOW_LEVEL;
  538. }
  539. else if(Bat_Ocv_Vol < FUELGUAGE_VOL1) //3500
  540. {
  541. return FUELGUAGE_LOW_LEVEL + (FUELGUAGE_LEVEL1 - FUELGUAGE_LOW_LEVEL) * ((int)Bat_Ocv_Vol - FUELGUAGE_LOW_VOL) / (FUELGUAGE_VOL1 - FUELGUAGE_LOW_VOL);
  542. }
  543. else if(Bat_Ocv_Vol < FUELGUAGE_VOL2) //3600
  544. {
  545. return FUELGUAGE_LEVEL1 + (FUELGUAGE_LEVEL2 - FUELGUAGE_LEVEL1) * ((int)Bat_Ocv_Vol - FUELGUAGE_VOL1) / (FUELGUAGE_VOL2 - FUELGUAGE_VOL1);
  546. }
  547. else if(Bat_Ocv_Vol < FUELGUAGE_VOL3) //3700
  548. {
  549. return FUELGUAGE_LEVEL2 + (FUELGUAGE_LEVEL3 - FUELGUAGE_LEVEL2) * ((int)Bat_Ocv_Vol - FUELGUAGE_VOL2) / (FUELGUAGE_VOL3 - FUELGUAGE_VOL2);
  550. }
  551. else if(Bat_Ocv_Vol < FUELGUAGE_VOL4) //3800
  552. {
  553. return FUELGUAGE_LEVEL3 + (FUELGUAGE_LEVEL4 - FUELGUAGE_LEVEL3) * ((int)Bat_Ocv_Vol - FUELGUAGE_VOL3) / (FUELGUAGE_VOL4 - FUELGUAGE_VOL3);
  554. }
  555. else if(Bat_Ocv_Vol < FUELGUAGE_VOL5) //3900
  556. {
  557. return FUELGUAGE_LEVEL4 + (FUELGUAGE_LEVEL5 - FUELGUAGE_LEVEL4) * ((int)Bat_Ocv_Vol - FUELGUAGE_VOL4) / (FUELGUAGE_VOL5 - FUELGUAGE_VOL4);
  558. }
  559. else if(Bat_Ocv_Vol < FUELGUAGE_VOL6) //4000
  560. {
  561. return FUELGUAGE_LEVEL5 + (FUELGUAGE_LEVEL6 - FUELGUAGE_LEVEL5) * ((int)Bat_Ocv_Vol - FUELGUAGE_VOL5) / (FUELGUAGE_VOL6 - FUELGUAGE_VOL5);
  562. }
  563. else if(Bat_Ocv_Vol < FUELGUAGE_VOL7) //4100
  564. {
  565. return FUELGUAGE_LEVEL6 + (FUELGUAGE_LEVEL7 - FUELGUAGE_LEVEL6) * ((int)Bat_Ocv_Vol - FUELGUAGE_VOL6) / (FUELGUAGE_VOL7 - FUELGUAGE_VOL6);
  566. }
  567. else if(Bat_Ocv_Vol < FUELGUAGE_TOP_VOL) //4100
  568. {
  569. return FUELGUAGE_LEVEL7 + (FUELGUAGE_TOP_LEVEL - FUELGUAGE_LEVEL7) * ((int)Bat_Ocv_Vol - FUELGUAGE_VOL7) / (FUELGUAGE_TOP_VOL - FUELGUAGE_VOL7);
  570. }
  571. else
  572. {
  573. return 0;
  574. }
  575. }
  576. static int axp_cal_resttime(struct axp_charger *charger,uint8_t chg_status, uint16_t Bat_Ocv_Vol, uint16_t Rdc)
  577. {
  578. uint8_t Tcv_Rest_Vol = 0;
  579. uint16_t Iconst_current = 1;
  580. unsigned int rest_time = 0;
  581. int Tcv = 0;
  582. if(charger->ibat == 0) charger->ibat = 1;
  583. if(chg_status > 0x03){
  584. if(charger->vbat < 4195){
  585. Tcv_Rest_Vol = axp_vol_rate(4200 - charger->ibat *(int) Rdc / 1000);
  586. Iconst_current = charger->ibat;
  587. if(Tcv_Rest_Vol < 70){
  588. Tcv = 60 * (100 - (int)Tcv_Rest_Vol) * charger->battery_info->energy_full_design/ (45 * charger->ibat);
  589. }
  590. else{
  591. Tcv = 60 * (100 - (int)Tcv_Rest_Vol) * charger->battery_info->energy_full_design / (35 * charger->ibat);
  592. }
  593. rest_time = 6 * charger->battery_info->energy_full_design * ABS(Tcv_Rest_Vol - charger->rest_vol) / charger->ibat / 10 + Tcv ;
  594. }
  595. else{
  596. if(Iconst_current == 1){
  597. Iconst_current = charger->chgcur;
  598. }
  599. if(Tcv == 0){
  600. Tcv_Rest_Vol =axp_vol_rate(4200 - charger->chgcur * (int)Rdc / 1000);
  601. if(Tcv_Rest_Vol < 70){
  602. Tcv = 60 * (100 - (int)Tcv_Rest_Vol) * charger->chgcur / (45 * charger->chgcur);
  603. }
  604. else{
  605. Tcv = 60 * (100 - (int)Tcv_Rest_Vol) * charger->chgcur / (35 * charger->chgcur);
  606. }
  607. }
  608. if(charger->ibat < (charger->chgcur *charger->chgend/100)){
  609. rest_time = 1;
  610. }
  611. else{
  612. rest_time = (unsigned int)Tcv * (90 + 110 * (charger->chgcur *charger->chgend/100) / (unsigned int)charger->ibat) * (90 +100 * (charger->chgcur *charger->chgend/100)
  613. / (unsigned int)charger->ibat) * ABS(charger->ibat - (charger->chgcur *charger->chgend/100)) / (unsigned int)Iconst_current /10000;
  614. }
  615. }
  616. }
  617. else //放电
  618. {
  619. __u8 End_Vol_Rate = axp_vol_rate(END_VOLTAGE_APS + (charger->ibat * ((int)Rdc + 110) / 1000));
  620. if(charger->pbat)
  621. {
  622. rest_time = BAT_AVER_VOL * charger->battery_info->energy_full_design
  623. * ABS(charger->rest_vol- (int)End_Vol_Rate) / charger->pbat * 6 / 10 ;
  624. }
  625. if(Bat_Ocv_Vol)
  626. {
  627. rest_time *= charger->vbat; //对OCV功率修正
  628. rest_time /= (unsigned int)Bat_Ocv_Vol;
  629. }
  630. rest_time *= 100; //对电池电压变低后效率提高的修正
  631. rest_time /= 99;
  632. }
  633. return rest_time;
  634. }
  635. static int axp_main_task(void *arg)
  636. {
  637. struct axp_charger *charger = arg;
  638. uint8_t temp_value[8];
  639. uint8_t Bat_Cap_Buffer[AXP19_VOL_MAX];
  640. uint16_t Bat_Time_Buffer[AXP19_TIME_MAX];
  641. uint32_t Bat_Power_Buffer[AXP19_AVER_MAX];
  642. int Cur_CoulombCounter;
  643. uint8_t Pre_rest_cap=0,Pre_ocv_rest_cap=0,Pre_Cur_Cal_rest_cap=0;
  644. uint16_t Bat_Rdc,Bat_Vol,Bat_Ocv_Vol;
  645. uint16_t i = 0,j = 0,k = 0,m = 0;
  646. uint32_t Total_Cap = 0,Total_Time = 0,Total_Power = 0;
  647. uint8_t Rdc_Flag = 0,Pre_Rdc_Flag = 0;
  648. uint8_t Cou_Correction_Flag = 0;
  649. uint8_t Real_Cou_Flag = 0;
  650. int rt_rest_vol, ocv_rest_vol, cou_rest_vol;
  651. uint8_t rt_charge_status;
  652. uint8_t v[4] = {0, 0, 0,0};
  653. uint8_t w[7];
  654. int events;
  655. bool peklong;
  656. bool pekshort;
  657. uint8_t long_cnt = 0;
  658. bool status_usb, pre_status_usb;
  659. bool status_ac, pre_status_ac;
  660. bool status_bat, pre_status_bat;
  661. int pre_rest_vol;
  662. pre_rest_vol = 0;
  663. status_usb = 0;
  664. pre_status_usb = 0;
  665. status_ac = 0;
  666. pre_status_ac = 0;
  667. status_bat = 0;
  668. pre_status_bat =0;
  669. axp_write(charger->master,AXP19_TIMER_CTL,0x80);
  670. axp_reads(charger->master,AXP19_DATA_BUFFER1,2,temp_value);
  671. Real_Cou_Flag = (temp_value[0] & 0x80);
  672. if(Real_Cou_Flag)
  673. charger->battery_info->energy_full_design=5 * (((temp_value[0] & 0x7f) << 4) + ((temp_value[1] & 0xf0) >> 4));
  674. axp_reads(charger->master,AXP19_DATA_BUFFER2,2,temp_value);
  675. Bat_Rdc = ((temp_value[0] & 0x07) << 8) + temp_value[1];
  676. Pre_Rdc_Flag = temp_value[0] & 0x08;
  677. if(Pre_Rdc_Flag){
  678. // Bat_Rdc = (Bat_Rdc & 0x7ff) * 3;
  679. }
  680. else{
  681. Bat_Rdc = 250;
  682. }
  683. memset(Bat_Cap_Buffer, 0, sizeof(Bat_Cap_Buffer));
  684. memset(Bat_Time_Buffer, 0, sizeof(Bat_Time_Buffer));
  685. memset(Bat_Power_Buffer, 0, sizeof(Bat_Power_Buffer));
  686. while(1){
  687. if(kthread_should_stop()) break;
  688. axp_charger_update_state(charger);
  689. axp_charger_update(charger);
  690. axp_reads(charger->master,POWER19_INTSTS1, 4, v);
  691. events = (v[3] << 24 )|(v[2] << 16) | (v[1] << 8) | v[0];
  692. w[0] = v[0];
  693. w[1] = POWER19_INTSTS2;
  694. w[2] = v[1];
  695. w[3] = POWER19_INTSTS3;
  696. w[4] = v[2];
  697. w[5] = POWER19_INTSTS4;
  698. w[6] = v[3];
  699. peklong = (events & AXP19_IRQ_PEKLO)? 1 : 0;
  700. pekshort = (events & AXP19_IRQ_PEKSH )? 1 : 0;
  701. status_ac = charger->ac_valid;
  702. status_usb = charger->usb_valid;
  703. status_bat = (!charger->is_on)&&(charger->bat_det);
  704. if(status_usb != pre_status_usb || status_ac != pre_status_ac || status_bat != pre_status_bat )
  705. {
  706. power_supply_changed(&charger->batt);
  707. pre_status_ac = status_ac;
  708. pre_status_usb = status_usb;
  709. pre_status_bat = status_bat;
  710. }
  711. if(long_cnt){
  712. long_cnt--;
  713. if(long_cnt == 0 ){
  714. printk("press long up\n");
  715. input_report_key(powerkeydev, KEY_POWER, 0);
  716. input_sync(powerkeydev);
  717. }
  718. }
  719. if(peklong)
  720. {
  721. printk("press long\n");
  722. axp_writes(charger->master,POWER19_INTSTS1,7,w);
  723. input_report_key(powerkeydev, KEY_POWER, 1);
  724. input_sync(powerkeydev);
  725. long_cnt = 2;
  726. //msleep(100);
  727. //input_report_key(powerkeydev, KEY_POWER, 0);
  728. //input_sync(powerkeydev);
  729. }
  730. if(pekshort)
  731. {
  732. printk("press short\n");
  733. axp_writes(charger->master,POWER19_INTSTS1,7,w);
  734. input_report_key(powerkeydev, KEY_POWER, 1);
  735. input_sync(powerkeydev);
  736. msleep(100);
  737. input_report_key(powerkeydev, KEY_POWER, 0);
  738. input_sync(powerkeydev);
  739. }
  740. if(charger->bat_current_direction && charger->is_on \
  741. && (charger->ibat > 100) && (!Rdc_Flag)){
  742. if(Pre_Rdc_Flag){
  743. Bat_Rdc += axp_get_rdc(charger);
  744. Bat_Rdc /= 2;
  745. }
  746. else{
  747. Bat_Rdc = axp_get_rdc(charger);
  748. }
  749. Rdc_Flag = 1;
  750. }
  751. charger->pbat = charger->ibat * charger->vbat;
  752. Total_Power -= Bat_Power_Buffer[m];
  753. Bat_Power_Buffer[m] = charger->pbat;
  754. Total_Power += Bat_Power_Buffer[m];
  755. m++;
  756. if(m == AXP19_AVER_MAX)
  757. {
  758. m = 0;
  759. }
  760. charger->pbat = (int)Total_Power / AXP19_AVER_MAX;
  761. Bat_Vol = (uint16_t)charger->vbat;
  762. Bat_Ocv_Vol =(uint16_t) axp_bat_vol(charger->ext_valid && charger->bat_current_direction,\
  763. (int) Bat_Vol,charger->ibat,Bat_Rdc);//获取开路电压
  764. rt_rest_vol = axp_vol_rate( Bat_Ocv_Vol);
  765. rt_charge_status = (charger->ext_valid << 2 )| (charger->bat_det << 1) | \
  766. (charger->is_on);
  767. Total_Cap -= Bat_Cap_Buffer[i];
  768. Bat_Cap_Buffer[i] = rt_rest_vol;
  769. Total_Cap += Bat_Cap_Buffer[i];
  770. i++;
  771. if(i == AXP19_VOL_MAX){
  772. i = 0;
  773. }
  774. if(j < AXP19_VOL_MAX){
  775. j++;
  776. }
  777. ocv_rest_vol = Total_Cap / j;
  778. if((j == AXP19_VOL_MAX) && (charger->bat_det == 1)){
  779. Cur_CoulombCounter = axp_get_coulomb(charger);
  780. if((ocv_rest_vol < 10) && Rdc_Flag && (rt_charge_status == 7) \
  781. && (!Cou_Correction_Flag)) {
  782. Cou_Correction_Flag = 0x01;
  783. axp_set_bits(charger->master,AXP19_COULOMB_CONTROL,AXP19_COULOMB_CLEAR);
  784. Pre_rest_cap = ocv_rest_vol;
  785. Pre_Cur_Cal_rest_cap = ocv_rest_vol;
  786. }
  787. if(Cou_Correction_Flag && (rt_charge_status == 6) && (ocv_rest_vol == 100)){
  788. charger->battery_info->energy_full_design = Cur_CoulombCounter;
  789. charger->battery_info->energy_full_design *= 100;
  790. charger->battery_info->energy_full_design /= (100 - (int)Pre_Cur_Cal_rest_cap);
  791. temp_value[0] = ((((charger->battery_info->energy_full_design /5) & 0xff0) | 0x800) >> 4);
  792. temp_value[1] &= 0x0f;
  793. temp_value[1] |= (((charger->battery_info->energy_full_design /5) & 0x0f) << 4) ;
  794. axp_write(charger->master,AXP19_DATA_BUFFER1,temp_value[0]);
  795. axp_write(charger->master,AXP19_DATA_BUFFER1,temp_value[1] );
  796. Cou_Correction_Flag = 0x00;
  797. Real_Cou_Flag = 0x01;
  798. }
  799. if(coulomb_flag){ //充电
  800. cou_rest_vol = (Pre_rest_cap + (100 * Cur_CoulombCounter /
  801. charger->battery_info->energy_full_design));
  802. }
  803. else{//放电
  804. if(Pre_rest_cap < (100 * Cur_CoulombCounter /
  805. charger->battery_info->energy_full_design)){
  806. cou_rest_vol = 0;
  807. }
  808. else{
  809. cou_rest_vol = ((int)Pre_rest_cap - (100 * Cur_CoulombCounter /
  810. charger->battery_info->energy_full_design));
  811. }
  812. }
  813. if(((ocv_rest_vol > Pre_ocv_rest_cap) && (rt_charge_status < 0x04))
  814. || (ocv_rest_vol < (Pre_ocv_rest_cap - 2))){//放电时电量不能增加
  815. ocv_rest_vol = (int)Pre_ocv_rest_cap;
  816. }
  817. else if(((ocv_rest_vol < Pre_ocv_rest_cap) && (rt_charge_status > 0x03))
  818. ||(ocv_rest_vol > (Pre_ocv_rest_cap + 2))){//充电时电量不能减少
  819. ocv_rest_vol = (int)Pre_ocv_rest_cap;
  820. }
  821. Pre_ocv_rest_cap = (uint8_t)ocv_rest_vol;
  822. if(cou_rest_vol > 100){
  823. if(Real_Cou_Flag){
  824. charger->rest_vol = ocv_rest_vol + (3 * 100); //如果曾经校正过电池容量,则库仑电量比例占3/4,否则1/4
  825. }
  826. else{
  827. charger->rest_vol = 2 * ocv_rest_vol + 200;
  828. }
  829. }
  830. else{
  831. if(Real_Cou_Flag)
  832. charger->rest_vol = ocv_rest_vol + (3 * cou_rest_vol);
  833. else
  834. charger->rest_vol = 2 * ocv_rest_vol + 2 * cou_rest_vol;
  835. }
  836. charger->rest_vol /= 4;
  837. /*when charging , capacity is less than 100 */
  838. if (charger->rest_vol >= 99 && charger->is_on == 1 )
  839. charger->rest_vol = 99;
  840. if(((charger->rest_vol > pre_rest_vol) && (rt_charge_status < 0x04))){//放电时电量不能增加
  841. charger->rest_vol = pre_rest_vol;
  842. }
  843. else if((charger->rest_vol < pre_rest_vol) && (rt_charge_status > 0x03)){//充电时电量不能减少
  844. charger->rest_vol = pre_rest_vol;
  845. }
  846. charger->rest_time = axp_cal_resttime(charger,rt_charge_status,Bat_Ocv_Vol,Bat_Rdc);
  847. Total_Time -= Bat_Time_Buffer[k];
  848. Bat_Time_Buffer[k] = charger->rest_time;
  849. Total_Time += Bat_Time_Buffer[k];
  850. k++;
  851. if(k == AXP19_TIME_MAX){
  852. k = 0;
  853. }
  854. charger->rest_time = Total_Time / AXP19_TIME_MAX;
  855. }
  856. else if(j < AXP19_VOL_MAX){
  857. charger->rest_vol = ocv_rest_vol;
  858. Pre_rest_cap = ocv_rest_vol;
  859. Pre_ocv_rest_cap = ocv_rest_vol;
  860. //pre_rest_vol = charger->rest_vol;
  861. cou_rest_vol = 0;
  862. if(j == AXP19_VOL_MAX - 1){
  863. axp_set_bits(charger->master,AXP19_COULOMB_CONTROL,0xA0);
  864. }
  865. }
  866. /* if battery volume changed, inform uevent */
  867. if(charger->rest_vol - pre_rest_vol){
  868. printk("battery vol change: %d, %d \n", pre_rest_vol, charger->rest_vol);
  869. pre_rest_vol = charger->rest_vol;
  870. power_supply_changed(&charger->batt);
  871. }
  872. ssleep(1);
  873. }
  874. return 0;
  875. }
  876. static ssize_t chgen_show(struct device *dev,
  877. struct device_attribute *attr, char *buf)
  878. {
  879. struct axp_charger *charger = dev_get_drvdata(dev);
  880. uint8_t val;
  881. axp_read(charger->master, AXP19_CHARGE_CONTROL1, &val);
  882. charger->chgen = val >> 7;
  883. return sprintf(buf, "%d\n",charger->chgen);
  884. }
  885. static ssize_t chgen_store(struct device *dev,
  886. struct device_attribute *attr, const char *buf, size_t count)
  887. {
  888. struct axp_charger *charger = dev_get_drvdata(dev);
  889. int var;
  890. var = simple_strtoul(buf, NULL, 10);
  891. if(var){
  892. charger->chgen = 1;
  893. axp_set_bits(charger->master,AXP19_CHARGE_CONTROL1,0x80);
  894. }
  895. else{
  896. charger->chgen = 0;
  897. axp_clr_bits(charger->master,AXP19_CHARGE_CONTROL1,0x80);
  898. }
  899. return count;
  900. }
  901. static ssize_t chgmicrovol_show(struct device *dev,
  902. struct device_attribute *attr, char *buf)
  903. {
  904. struct axp_charger *charger = dev_get_drvdata(dev);
  905. uint8_t val;
  906. axp_read(charger->master, AXP19_CHARGE_CONTROL1, &val);
  907. switch ((val >> 5) & 0x03){
  908. case 0: charger->chgvol = 4100;break;
  909. case 1: charger->chgvol = 4150;break;
  910. case 2: charger->chgvol = 4200;break;
  911. case 3: charger->chgvol = 4360;break;
  912. }
  913. return sprintf(buf, "%d\n",charger->chgvol*1000);
  914. }
  915. static ssize_t chgmicrovol_store(struct device *dev,
  916. struct device_attribute *attr, const char *buf, size_t count)
  917. {
  918. struct axp_charger *charger = dev_get_drvdata(dev);
  919. int var;
  920. uint8_t tmp, val;
  921. var = simple_strtoul(buf, NULL, 10);
  922. switch(var){
  923. case 4100000:tmp = 0;break;
  924. case 4150000:tmp = 1;break;
  925. case 4200000:tmp = 2;break;
  926. case 4360000:tmp = 3;break;
  927. default: tmp = 4;break;
  928. }
  929. if(tmp < 4){
  930. charger->chgvol = var/1000;
  931. axp_read(charger->master, AXP19_CHARGE_CONTROL1, &val);
  932. val &= 0x9F;
  933. val |= tmp << 5;
  934. axp_write(charger->master, AXP19_CHARGE_CONTROL1, val);
  935. }
  936. return count;
  937. }
  938. static ssize_t chgintmicrocur_show(struct device *dev,
  939. struct device_attribute *attr, char *buf)
  940. {
  941. struct axp_charger *charger = dev_get_drvdata(dev);
  942. uint8_t val;
  943. axp_read(charger->master, AXP19_CHARGE_CONTROL1, &val);
  944. charger->chgcur = (val & 0x0F) * 100 +100;
  945. return sprintf(buf, "%d\n",charger->chgcur*1000);
  946. }
  947. static ssize_t chgintmicrocur_store(struct device *dev,
  948. struct device_attribute *attr, const char *buf, size_t count)
  949. {
  950. struct axp_charger *charger = dev_get_drvdata(dev);
  951. int var;
  952. uint8_t val;
  953. var = simple_strtoul(buf, NULL, 10);
  954. if(var >= 100000 && var <= 1600000){
  955. val = (var -100000)/100000;
  956. charger->chgcur = val *100 + 100;
  957. axp_read(charger->master, AXP19_CHARGE_CONTROL1, &val);
  958. val &= 0xF0;
  959. val |= val;
  960. axp_write(charger->master, AXP19_CHARGE_CONTROL1, val);
  961. }
  962. return count;
  963. }
  964. static ssize_t chgendcur_show(struct device *dev,
  965. struct device_attribute *attr, char *buf)
  966. {
  967. struct axp_charger *charger = dev_get_drvdata(dev);
  968. uint8_t val;
  969. axp_read(charger->master, AXP19_CHARGE_CONTROL1, &val);
  970. charger->chgend = ((val >> 4)& 0x01)? 15 : 10;
  971. return sprintf(buf, "%d\n",charger->chgend);
  972. }
  973. static ssize_t chgendcur_store(struct device *dev,
  974. struct device_attribute *attr, const char *buf, size_t count)
  975. {
  976. struct axp_charger *charger = dev_get_drvdata(dev);
  977. int var;
  978. var = simple_strtoul(buf, NULL, 10);
  979. if(var == 10 ){
  980. charger->chgend = var;
  981. axp_clr_bits(charger->master ,AXP19_CHARGE_CONTROL1,0x10);
  982. }
  983. else if (var == 15){
  984. charger->chgend = var;
  985. axp_set_bits(charger->master ,AXP19_CHARGE_CONTROL1,0x10);
  986. }
  987. return count;
  988. }
  989. static ssize_t chgpretimemin_show(struct device *dev,
  990. struct device_attribute *attr, char *buf)
  991. {
  992. struct axp_charger *charger = dev_get_drvdata(dev);
  993. uint8_t val;
  994. axp_read(charger->master,AXP19_CHARGE_CONTROL2, &val);
  995. charger->chgpretime = (val >> 6) * 10 +30;
  996. return sprintf(buf, "%d\n",charger->chgpretime);
  997. }
  998. static ssize_t chgpretimemin_store(struct device *dev,
  999. struct device_attribute *attr, const char *buf, size_t count)
  1000. {
  1001. struct axp_charger *charger = dev_get_drvdata(dev);
  1002. int var;
  1003. uint8_t tmp,val;
  1004. var = simple_strtoul(buf, NULL, 10);
  1005. if(var >= 30 && var <= 60){
  1006. tmp = (var - 30)/10;
  1007. charger->chgpretime = tmp * 10 + 30;
  1008. axp_read(charger->master,AXP19_CHARGE_CONTROL2,&val);
  1009. val &= 0x3F;
  1010. val |= (tmp << 6);
  1011. axp_write(charger->master,AXP19_CHARGE_CONTROL2,val);
  1012. }
  1013. return count;
  1014. }
  1015. static ssize_t chgcsttimemin_show(struct device *dev,
  1016. struct device_attribute *attr, char *buf)
  1017. {
  1018. struct axp_charger *charger = dev_get_drvdata(dev);
  1019. uint8_t val;
  1020. axp_read(charger->master,AXP19_CHARGE_CONTROL2, &val);
  1021. charger->chgcsttime = (val & 0x03) *60 + 420;
  1022. return sprintf(buf, "%d\n",charger->chgcsttime);
  1023. }
  1024. static ssize_t chgcsttimemin_store(struct device *dev,
  1025. struct device_attribute *attr, const char *buf, size_t count)
  1026. {
  1027. struct axp_charger *charger = dev_get_drvdata(dev);
  1028. int var;
  1029. uint8_t tmp,val;
  1030. var = simple_strtoul(buf, NULL, 10);
  1031. if(var >= 420 && var <= 600){
  1032. tmp = (var - 420)/60;
  1033. charger->chgcsttime = tmp * 60 + 420;
  1034. axp_read(charger->master,AXP19_CHARGE_CONTROL2,&val);
  1035. val &= 0xFC;
  1036. val |= tmp;
  1037. axp_write(charger->master,AXP19_CHARGE_CONTROL2,val);
  1038. }
  1039. return count;
  1040. }
  1041. static ssize_t chgextmicrocur_show(struct device *dev,
  1042. struct device_attribute *attr, char *buf)
  1043. {
  1044. struct axp_charger *charger = dev_get_drvdata(dev);
  1045. uint8_t val;
  1046. axp_read(charger->master,AXP19_CHARGE_CONTROL2, &val);
  1047. charger->chgextcur = ((val >> 3) & 0x07) * 100000 + 300000;
  1048. return sprintf(buf, "%d\n",charger->chgextcur);
  1049. }
  1050. static ssize_t chgextmicrocur_store(struct device *dev,
  1051. struct device_attribute *attr, const char *buf, size_t count)
  1052. {
  1053. struct axp_charger *charger = dev_get_drvdata(dev);
  1054. int var;
  1055. uint8_t val;
  1056. var = simple_strtoul(buf, NULL, 10);
  1057. if(var >= 300000 && var <= 1000000){
  1058. val = (var -300000)/100000;
  1059. charger->chgcur = val *100000 + 300000;
  1060. axp_read(charger->master, AXP19_CHARGE_CONTROL2, &val);
  1061. val &= 0xC7;
  1062. val |= (val << 3);
  1063. axp_write(charger->master, AXP19_CHARGE_CONTROL2, val);
  1064. }
  1065. return count;
  1066. }
  1067. static ssize_t chgexten_show(struct device *dev,
  1068. struct device_attribute *attr, char *buf)
  1069. {
  1070. struct axp_charger *charger = dev_get_drvdata(dev);
  1071. uint8_t val;
  1072. axp_read(charger->master,AXP19_CHARGE_CONTROL2, &val);
  1073. charger->chgexten = (val >> 2) & 0x01;
  1074. return sprintf(buf, "%d\n",charger->chgexten);
  1075. }
  1076. static ssize_t chgexten_store(struct device *dev,
  1077. struct device_attribute *attr, const char *buf, size_t count)
  1078. {
  1079. struct axp_charger *charger = dev_get_drvdata(dev);
  1080. int var;
  1081. var = simple_strtoul(buf, NULL, 10);
  1082. if(var){
  1083. charger->chgexten = 1;
  1084. axp_set_bits(charger->master,AXP19_CHARGE_CONTROL2,0x04);
  1085. }
  1086. else{
  1087. charger->chgexten = 0;
  1088. axp_clr_bits(charger->master,AXP19_CHARGE_CONTROL2,0x04);
  1089. }
  1090. return count;
  1091. }
  1092. static ssize_t adcfreq_show(struct device *dev,
  1093. struct device_attribute *attr, char *buf)
  1094. {
  1095. struct axp_charger *charger = dev_get_drvdata(dev);
  1096. uint8_t val;
  1097. axp_read(charger->master, AXP19_ADC_CONTROL3, &val);
  1098. switch ((val >> 6) & 0x03){
  1099. case 0: charger->sample_time = 25;break;
  1100. case 1: charger->sample_time = 50;break;
  1101. case 2: charger->sample_time = 100;break;
  1102. case 3: charger->sample_time = 200;break;
  1103. default:break;
  1104. }
  1105. return sprintf(buf, "%d\n",charger->sample_time);
  1106. }
  1107. static ssize_t adcfreq_store(struct device *dev,
  1108. struct device_attribute *attr, const char *buf, size_t count)
  1109. {
  1110. struct axp_charger *charger = dev_get_drvdata(dev);
  1111. int var;
  1112. uint8_t val;
  1113. var = simple_strtoul(buf, NULL, 10);
  1114. axp_read(charger->master, AXP19_ADC_CONTROL3, &val);
  1115. switch (var/25){
  1116. case 1: val &= ~(3 << 6);charger->sample_time = 25;break;
  1117. case 2: val &= ~(3 << 6);val |= 1 << 6;charger->sample_time = 50;break;
  1118. case 4: val &= ~(3 << 6);val |= 2 << 6;charger->sample_time = 100;break;
  1119. case 8: val |= 3 << 6;charger->sample_time = 200;break;
  1120. default: break;
  1121. }
  1122. axp_write(charger->master, AXP19_ADC_CONTROL3, val);
  1123. return count;
  1124. }
  1125. static ssize_t vholden_show(struct device *dev,
  1126. struct device_attribute *attr, char *buf)
  1127. {
  1128. struct axp_charger *charger = dev_get_drvdata(dev);
  1129. uint8_t val;
  1130. axp_read(charger->master,AXP19_CHARGE_VBUS, &val);
  1131. val = (val>>6) & 0x01;
  1132. return sprintf(buf, "%d\n",val);
  1133. }
  1134. static ssize_t vholden_store(struct device *dev,
  1135. struct device_attribute *attr, const char *buf, size_t count)
  1136. {
  1137. struct axp_charger *charger = dev_get_drvdata(dev);
  1138. int var;
  1139. var = simple_strtoul(buf, NULL, 10);
  1140. if(var)
  1141. axp_set_bits(charger->master, AXP19_CHARGE_VBUS, 0x40);
  1142. else
  1143. axp_clr_bits(charger->master, AXP19_CHARGE_VBUS, 0x40);
  1144. return count;
  1145. }
  1146. static ssize_t vhold_show(struct device *dev,
  1147. struct device_attribute *attr, char *buf)
  1148. {
  1149. struct axp_charger *charger = dev_get_drvdata(dev);
  1150. uint8_t val;
  1151. int vhold;
  1152. axp_read(charger->master,AXP19_CHARGE_VBUS, &val);
  1153. vhold = ((val >> 3) & 0x07) * 100000 + 4000000;
  1154. return sprintf(buf, "%d\n",vhold);
  1155. }
  1156. static ssize_t vhold_store(struct device *dev,
  1157. struct device_attribute *attr, const char *buf, size_t count)
  1158. {
  1159. struct axp_charger *charger = dev_get_drvdata(dev);
  1160. int var;
  1161. uint8_t val,tmp;
  1162. var = simple_strtoul(buf, NULL, 10);
  1163. if(var >= 4000000 && var <=4700000){
  1164. tmp = (var - 4000000)/100000;
  1165. //printk("tmp = 0x%x\n",tmp);
  1166. axp_read(charger->master, AXP19_CHARGE_VBUS,&val);
  1167. val &= 0xC7;
  1168. val |= tmp << 3;
  1169. //printk("val = 0x%x\n",val);
  1170. axp_write(charger->master, AXP19_CHARGE_VBUS,val);
  1171. }
  1172. return count;
  1173. }
  1174. static ssize_t iholden_show(struct device *dev,
  1175. struct device_attribute *attr, char *buf)
  1176. {
  1177. struct axp_charger *charger = dev_get_drvdata(dev);
  1178. uint8_t val;
  1179. axp_read(charger->master,AXP19_CHARGE_VBUS, &val);
  1180. return sprintf(buf, "%d\n",(val >> 1) & 0x01);
  1181. }
  1182. static ssize_t iholden_store(struct device *dev,
  1183. struct device_attribute *attr, const char *buf, size_t count)
  1184. {
  1185. struct axp_charger *charger = dev_get_drvdata(dev);
  1186. int var;
  1187. var = simple_strtoul(buf, NULL, 10);
  1188. if(var)
  1189. axp_set_bits(charger->master, AXP19_CHARGE_VBUS, 0x02);
  1190. else
  1191. axp_clr_bits(charger->master, AXP19_CHARGE_VBUS, 0x02);
  1192. return count;
  1193. }
  1194. static ssize_t ihold_show(struct device *dev,
  1195. struct device_attribute *attr, char *buf)
  1196. {
  1197. struct axp_charger *charger = dev_get_drvdata(dev);
  1198. uint8_t val;
  1199. int vhold;
  1200. axp_read(charger->master,AXP19_CHARGE_VBUS, &val);
  1201. vhold = ((val) & 0x01)? 500000: 100000;
  1202. return sprintf(buf, "%d\n",vhold);
  1203. }
  1204. static ssize_t ihold_store(struct device *dev,
  1205. struct device_attribute *attr, const char *buf, size_t count)
  1206. {
  1207. struct axp_charger *charger = dev_get_drvdata(dev);
  1208. int var;
  1209. var = simple_strtoul(buf, NULL, 10);
  1210. if(var == 500000)
  1211. axp_set_bits(charger->master, AXP19_CHARGE_VBUS, 0x01);
  1212. else if (var == 100000)
  1213. axp_clr_bits(charger->master, AXP19_CHARGE_VBUS, 0x01);
  1214. else
  1215. ;
  1216. return count;
  1217. }
  1218. static struct device_attribute axp_charger_attrs[] = {
  1219. AXP_CHG_ATTR(chgen),
  1220. AXP_CHG_ATTR(chgmicrovol),
  1221. AXP_CHG_ATTR(chgintmicrocur),
  1222. AXP_CHG_ATTR(chgendcur),
  1223. AXP_CHG_ATTR(chgpretimemin),
  1224. AXP_CHG_ATTR(chgcsttimemin),
  1225. AXP_CHG_ATTR(chgextmicrocur),
  1226. AXP_CHG_ATTR(chgexten),
  1227. AXP_CHG_ATTR(adcfreq),
  1228. AXP_CHG_ATTR(vholden),
  1229. AXP_CHG_ATTR(vhold),
  1230. AXP_CHG_ATTR(iholden),
  1231. AXP_CHG_ATTR(ihold),
  1232. };
  1233. int axp_charger_create_attrs(struct power_supply *psy)
  1234. {
  1235. int j,ret;
  1236. for (j = 0; j < ARRAY_SIZE(axp_charger_attrs); j++) {
  1237. ret = device_create_file(psy->dev,
  1238. &axp_charger_attrs[j]);
  1239. if (ret)
  1240. goto sysfs_failed;
  1241. }
  1242. goto succeed;
  1243. sysfs_failed:
  1244. while (j--)
  1245. device_remove_file(psy->dev,
  1246. &axp_charger_attrs[j]);
  1247. succeed:
  1248. return ret;
  1249. }
  1250. /*
  1251. static void axp_charging_monitor(struct work_struct *work)
  1252. {
  1253. struct axp_charger *charger;
  1254. charger = container_of(work, struct axp_charger, work.work);
  1255. axp_charger_update_state(charger);
  1256. axp_charger_update(charger);
  1257. schedule_delayed_work(&charger->work, charger->interval);
  1258. }
  1259. */
  1260. static int axp_battery_probe(struct platform_device *pdev)
  1261. {
  1262. struct axp_charger *charger;
  1263. struct axp_supply_init_data *pdata = pdev->dev.platform_data;
  1264. int ret;
  1265. powerkeydev = input_allocate_device();
  1266. if (!powerkeydev) {
  1267. kfree(powerkeydev);
  1268. return -ENODEV;
  1269. }
  1270. powerkeydev->name = pdev->name;
  1271. powerkeydev->phys = "m1kbd/input2";
  1272. powerkeydev->id.bustype = BUS_HOST;
  1273. powerkeydev->id.vendor = 0x0001;
  1274. powerkeydev->id.product = 0x0001;
  1275. powerkeydev->id.version = 0x0100;
  1276. powerkeydev->open = NULL;
  1277. powerkeydev->close = NULL;
  1278. powerkeydev->dev.parent = &pdev->dev;
  1279. set_bit(EV_KEY, powerkeydev->evbit);
  1280. set_bit(EV_REL, powerkeydev->evbit);
  1281. //set_bit(EV_REP, powerkeydev->evbit);
  1282. set_bit(KEY_POWER, powerkeydev->keybit);
  1283. ret = input_register_device(powerkeydev);
  1284. if(ret) {
  1285. printk("Unable to Register the power key\n");
  1286. }
  1287. if (pdata == NULL)
  1288. return -EINVAL;
  1289. if (pdata->chgcur > 1600 ||
  1290. pdata->chgvol < 4100 ||
  1291. pdata->chgvol > 4360){
  1292. printk("charger milliamp is too high or target voltage is over range\n");
  1293. return -EINVAL;
  1294. }
  1295. if (pdata->chgpretime < 30 || pdata->chgpretime >60 ||
  1296. pdata->chgcsttime < 420 || pdata->chgcsttime > 600){
  1297. printk("prechaging time or constant current charging time is over range\n");
  1298. return -EINVAL;
  1299. }
  1300. charger = kzalloc(sizeof(*charger), GFP_KERNEL);
  1301. if (charger == NULL)
  1302. return -ENOMEM;
  1303. charger->master = pdev->dev.parent;
  1304. charger->chgcur = pdata->chgcur;
  1305. charger->chgvol = pdata->chgvol;
  1306. charger->chgend = pdata->chgend; //axp199
  1307. charger->sample_time = pdata->sample_time;
  1308. charger->chgen = pdata->chgen;
  1309. charger->chgpretime = pdata->chgpretime;
  1310. charger->chgcsttime = pdata->chgcsttime;
  1311. charger->battery_info = pdata->battery_info;
  1312. charger->battery_low = pdata->battery_low;
  1313. charger->battery_critical = pdata->battery_critical;
  1314. ret = axp_battery_first_init(charger);
  1315. if (ret)
  1316. goto err_charger_init;
  1317. charger->nb.notifier_call = axp_battery_event;
  1318. ret = axp_register_notifier(charger->master, &charger->nb, AXP19_NOTIFIER_ON);
  1319. if (ret)
  1320. goto err_notifier;
  1321. axp_battery_setup_psy(charger);
  1322. ret = power_supply_register(&pdev->dev, &charger->batt);
  1323. if (ret)
  1324. goto err_ps_register;
  1325. ret = power_supply_register(&pdev->dev, &charger->ac);
  1326. if (ret){
  1327. power_supply_unregister(&charger->batt);
  1328. goto err_ps_register;
  1329. }
  1330. ret = power_supply_register(&pdev->dev, &charger->usb);
  1331. if (ret){
  1332. power_supply_unregister(&charger->ac);
  1333. power_supply_unregister(&charger->batt);
  1334. goto err_ps_register;
  1335. }
  1336. ret = axp_charger_create_attrs(&charger->batt);
  1337. if(ret){
  1338. return ret;
  1339. }
  1340. platform_set_drvdata(pdev, charger);
  1341. main_task = kthread_run(axp_main_task,charger,"kaxp19");
  1342. if(IS_ERR(main_task)){
  1343. printk("Unable to start main task.\n");
  1344. ret = PTR_ERR(main_task);
  1345. main_task = NULL;
  1346. return ret;
  1347. }
  1348. /*
  1349. charger->interval = msecs_to_jiffies(1 * 1000);
  1350. INIT_DELAYED_WORK(&charger->work, axp_charging_monitor);
  1351. schedule_delayed_work(&charger->work, charger->interval);
  1352. */
  1353. return ret;
  1354. err_ps_register:
  1355. axp_unregister_notifier(charger->master, &charger->nb, AXP19_NOTIFIER_ON);
  1356. err_notifier:
  1357. cancel_delayed_work(&charger->work);
  1358. err_charger_init:
  1359. kfree(charger);
  1360. input_unregister_device(powerkeydev);
  1361. kfree(powerkeydev);
  1362. return ret;
  1363. }
  1364. static int axp_battery_remove(struct platform_device *dev)
  1365. {
  1366. struct axp_charger *charger = platform_get_drvdata(dev);
  1367. if(main_task){
  1368. kthread_stop(main_task);
  1369. main_task = NULL;
  1370. }
  1371. axp_unregister_notifier(charger->master, &charger->nb, AXP19_NOTIFIER_ON);
  1372. cancel_delayed_work(&charger->work);
  1373. power_supply_unregister(&charger->usb);
  1374. power_supply_unregister(&charger->ac);
  1375. power_supply_unregister(&charger->batt);
  1376. kfree(charger);
  1377. input_unregister_device(powerkeydev);
  1378. kfree(powerkeydev);
  1379. return 0;
  1380. }
  1381. static struct platform_driver axp_battery_driver = {
  1382. .driver = {
  1383. .name = "axp19-supplyer",
  1384. .owner = THIS_MODULE,
  1385. },
  1386. .probe = axp_battery_probe,
  1387. .remove = axp_battery_remove,
  1388. };
  1389. static int axp_battery_init(void)
  1390. {
  1391. return platform_driver_register(&axp_battery_driver);
  1392. }
  1393. static void axp_battery_exit(void)
  1394. {
  1395. platform_driver_unregister(&axp_battery_driver);
  1396. }
  1397. module_init(axp_battery_init);
  1398. module_exit(axp_battery_exit);
  1399. MODULE_DESCRIPTION("AXP19 battery charger driver");
  1400. MODULE_AUTHOR("Donglu Zhang, Krosspower");
  1401. MODULE_LICENSE("GPL");