Advertisement
Guest User

Untitled

a guest
Jun 29th, 2017
491
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 31.51 KB | None | 0 0
  1. /* drivers/power/ds2784_battery.c
  2. *
  3. * Copyright (C) 2009 HTC Corporation
  4. * Copyright (C) 2009 Google, Inc.
  5. *
  6. * This software is licensed under the terms of the GNU General Public
  7. * License version 2, as published by the Free Software Foundation, and
  8. * may be copied, distributed, and modified under those terms.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. */
  16. #include <linux/module.h>
  17. #include <linux/param.h>
  18. #include <linux/jiffies.h>
  19. #include <linux/workqueue.h>
  20. #include <linux/pm.h>
  21. #include <linux/platform_device.h>
  22. #include <linux/power_supply.h>
  23. #include <linux/slab.h>
  24. #include <linux/spinlock.h>
  25.  
  26. #include <linux/android_alarm.h>
  27. #include <linux/delay.h>
  28. #include <linux/init.h>
  29. #include <linux/kernel.h>
  30. #include <linux/err.h>
  31. #include <linux/wakelock.h>
  32.  
  33. #include <linux/debugfs.h>
  34. #include <linux/seq_file.h>
  35. #include <linux/mutex.h>
  36. #include <linux/ds2784_battery.h>
  37.  
  38. #include "../w1/w1.h"
  39. #include "w1_ds2784.h"
  40.  
  41. extern int is_ac_power_supplied(void);
  42.  
  43. struct battery_status {
  44. int timestamp;
  45.  
  46. int voltage_uV; /* units of uV */
  47. int current_uA; /* units of uA */
  48. int current_avg_uA;
  49. int charge_uAh;
  50.  
  51. u16 temp_C; /* units of 0.1 C */
  52.  
  53. u8 percentage; /* battery percentage */
  54. u8 charge_source;
  55. u8 status_reg;
  56. u8 battery_full; /* battery full (don't charge) */
  57.  
  58. u8 cooldown; /* was overtemp */
  59. u8 charge_mode;
  60. } __attribute__((packed));
  61.  
  62.  
  63. #define SOURCE_NONE 0
  64. #define SOURCE_USB 1
  65. #define SOURCE_AC 2
  66.  
  67. #define CHARGE_OFF 0
  68. #define CHARGE_SLOW 1
  69. #define CHARGE_FAST 2
  70. #define CHARGE_BATT_DISABLE 3 /* disable charging at battery */
  71.  
  72. #define TEMP_CRITICAL 600 /* no charging at all */
  73. #define TEMP_HOT 500 /* no fast charge, no charge > 4.1v */
  74. #define TEMP_WARM 450 /* no fast charge above this */
  75.  
  76. #define TEMP_HOT_MAX_MV 4100 /* stop charging here when hot */
  77. #define TEMP_HOT_MIN_MV 3800 /* resume charging here when hot */
  78. #define CE_DISABLE_MIN_MV 4100
  79.  
  80. #define BATTERY_LOG_MAX 1024
  81. #define BATTERY_LOG_MASK (BATTERY_LOG_MAX - 1)
  82.  
  83. /* When we're awake or running on wall power, sample the battery
  84. * gauge every FAST_POLL seconds. If we're asleep and on battery
  85. * power, sample every SLOW_POLL seconds
  86. */
  87. #define FAST_POLL (1 * 60)
  88. #define SLOW_POLL (10 * 60)
  89.  
  90. static DEFINE_MUTEX(battery_log_lock);
  91. static struct battery_status battery_log[BATTERY_LOG_MAX];
  92. static unsigned battery_log_head;
  93. static unsigned battery_log_tail;
  94.  
  95. void battery_log_status(struct battery_status *s)
  96. {
  97. unsigned n;
  98. mutex_lock(&battery_log_lock);
  99. n = battery_log_head;
  100. memcpy(battery_log + n, s, sizeof(struct battery_status));
  101. n = (n + 1) & BATTERY_LOG_MASK;
  102. if (n == battery_log_tail)
  103. battery_log_tail = (battery_log_tail + 1) & BATTERY_LOG_MASK;
  104. battery_log_head = n;
  105. mutex_unlock(&battery_log_lock);
  106. }
  107.  
  108. static const char *battery_source[3] = { "none", " usb", " ac" };
  109. static const char *battery_mode[4] = { " off", "slow", "fast", "full" };
  110.  
  111. static int battery_log_print(struct seq_file *sf, void *private)
  112. {
  113. unsigned n;
  114. mutex_lock(&battery_log_lock);
  115. seq_printf(sf, "timestamp mV mA avg mA uAh dC %% src mode reg full\n");
  116. for (n = battery_log_tail; n != battery_log_head; n = (n + 1) & BATTERY_LOG_MASK) {
  117. struct battery_status *s = battery_log + n;
  118. seq_printf(sf, "%9d %5d %6d %6d %8d %4d %3d %s %s 0x%02x %d\n",
  119. s->timestamp, s->voltage_uV / 1000,
  120. s->current_uA / 1000, s->current_avg_uA / 1000,
  121. s->charge_uAh, s->temp_C,
  122. s->percentage,
  123. battery_source[s->charge_source],
  124. battery_mode[s->charge_mode],
  125. s->status_reg, s->battery_full);
  126. }
  127. mutex_unlock(&battery_log_lock);
  128. return 0;
  129. }
  130.  
  131.  
  132. struct ds2784_device_info {
  133. struct device *dev;
  134.  
  135. /* DS2784 data, valid after calling ds2784_battery_read_status() */
  136. char raw[DS2784_DATA_SIZE]; /* raw DS2784 data */
  137.  
  138. struct battery_status status;
  139.  
  140. struct power_supply bat;
  141. struct workqueue_struct *monitor_wqueue;
  142. struct work_struct monitor_work;
  143. struct alarm alarm;
  144. struct wake_lock work_wake_lock;
  145.  
  146. int (*charge)(int on, int fast);
  147. struct w1_slave *w1_slave;
  148.  
  149. u8 dummy; /* dummy battery flag */
  150. u8 last_charge_mode; /* previous charger state */
  151. u8 slow_poll;
  152.  
  153. ktime_t last_poll;
  154. ktime_t last_charge_seen;
  155. };
  156.  
  157. #define psy_to_dev_info(x) container_of((x), struct ds2784_device_info, bat)
  158.  
  159. static struct wake_lock vbus_wake_lock;
  160.  
  161. #define BATT_RSNSP (67) /*Passion battery source 1*/
  162.  
  163. static enum power_supply_property battery_properties[] = {
  164. POWER_SUPPLY_PROP_STATUS,
  165. POWER_SUPPLY_PROP_HEALTH,
  166. POWER_SUPPLY_PROP_PRESENT,
  167. POWER_SUPPLY_PROP_TECHNOLOGY,
  168. POWER_SUPPLY_PROP_CAPACITY,
  169. POWER_SUPPLY_PROP_VOLTAGE_NOW,
  170. POWER_SUPPLY_PROP_TEMP,
  171. POWER_SUPPLY_PROP_CURRENT_NOW,
  172. POWER_SUPPLY_PROP_CURRENT_AVG,
  173. POWER_SUPPLY_PROP_CHARGE_COUNTER,
  174. };
  175.  
  176. static int battery_initial;
  177.  
  178. static int battery_get_property(struct power_supply *psy,
  179. enum power_supply_property psp,
  180. union power_supply_propval *val);
  181.  
  182. static void battery_ext_power_changed(struct power_supply *psy);
  183.  
  184. #define to_ds2784_device_info(x) container_of((x), struct ds2784_device_info, \
  185. bat);
  186.  
  187. static void ds2784_parse_data(u8 *raw, struct battery_status *s)
  188. {
  189. short n;
  190.  
  191. /* Get status reg */
  192. s->status_reg = raw[DS2784_REG_STS];
  193.  
  194. /* Get Level */
  195. s->percentage = raw[DS2784_REG_RARC];
  196.  
  197. /* Get Voltage: Unit=4.886mV, range is 0V to 4.99V */
  198. n = (((raw[DS2784_REG_VOLT_MSB] << 8) |
  199. (raw[DS2784_REG_VOLT_LSB])) >> 5);
  200.  
  201. s->voltage_uV = n * 4886;
  202.  
  203. /* Get Current: Unit= 1.5625uV x Rsnsp(67)=104.68 */
  204. n = ((raw[DS2784_REG_CURR_MSB]) << 8) |
  205. raw[DS2784_REG_CURR_LSB];
  206. s->current_uA = ((n * 15625) / 10000) * 67;
  207.  
  208. n = ((raw[DS2784_REG_AVG_CURR_MSB]) << 8) |
  209. raw[DS2784_REG_AVG_CURR_LSB];
  210. s->current_avg_uA = ((n * 15625) / 10000) * 67;
  211.  
  212. /* Get Temperature:
  213. * 11 bit signed result in Unit=0.125 degree C.
  214. * Convert to integer tenths of degree C.
  215. */
  216. n = ((raw[DS2784_REG_TEMP_MSB] << 8) |
  217. (raw[DS2784_REG_TEMP_LSB])) >> 5;
  218.  
  219. s->temp_C = (n * 10) / 8;
  220.  
  221. /* RAAC is in units of 1.6mAh */
  222. s->charge_uAh = ((raw[DS2784_REG_RAAC_MSB] << 8) |
  223. raw[DS2784_REG_RAAC_LSB]) * 1600;
  224. }
  225.  
  226. static int w1_ds2784_io(struct w1_slave *sl, char *buf, int addr, size_t count, int io)
  227. {
  228. if (!sl)
  229. return 0;
  230.  
  231. mutex_lock(&sl->master->mutex);
  232.  
  233. if (addr > DS2784_DATA_SIZE || addr < 0) {
  234. count = 0;
  235. goto out;
  236. }
  237. if (addr + count > DS2784_DATA_SIZE)
  238. count = DS2784_DATA_SIZE - addr;
  239.  
  240. if (!w1_reset_select_slave(sl)) {
  241. if (!io) {
  242. w1_write_8(sl->master, W1_DS2784_READ_DATA);
  243. w1_write_8(sl->master, addr);
  244. count = w1_read_block(sl->master, buf, count);
  245. } else {
  246. w1_write_8(sl->master, W1_DS2784_WRITE_DATA);
  247. w1_write_8(sl->master, addr);
  248. w1_write_block(sl->master, buf, count);
  249. /* XXX w1_write_block returns void, not n_written */
  250. }
  251. }
  252.  
  253. out:
  254. mutex_unlock(&sl->master->mutex);
  255.  
  256. return count;
  257. }
  258.  
  259. static int w1_ds2784_read(struct w1_slave *sl, char *buf, int addr, size_t count)
  260. {
  261. return w1_ds2784_io(sl, buf, addr, count, 0);
  262. }
  263.  
  264. static int w1_ds2784_write(struct w1_slave *sl, char *buf, int addr, size_t count)
  265. {
  266. return w1_ds2784_io(sl, buf, addr, count, 1);
  267. }
  268.  
  269. static int ds2784_set_cc(struct ds2784_device_info *di, bool enable)
  270. {
  271. int ret;
  272.  
  273. if (enable)
  274. di->raw[DS2784_REG_PORT] |= 0x02;
  275. else
  276. di->raw[DS2784_REG_PORT] &= ~0x02;
  277. ret = w1_ds2784_write(di->w1_slave, di->raw + DS2784_REG_PORT,
  278. DS2784_REG_PORT, 1);
  279. if (ret != 1) {
  280. dev_warn(di->dev, "call to w1_ds2784_write failed (0x%p)\n",
  281. di->w1_slave);
  282. return 1;
  283. }
  284. return 0;
  285. }
  286.  
  287. static int ds2784_battery_read_status(struct ds2784_device_info *di)
  288. {
  289. int ret, start, count;
  290.  
  291. /* The first time we read the entire contents of SRAM/EEPROM,
  292. * but after that we just read the interesting bits that change. */
  293. if (di->raw[DS2784_REG_RSNSP] == 0x00) {
  294. start = 0;
  295. count = DS2784_DATA_SIZE;
  296. } else {
  297. start = DS2784_REG_PORT;
  298. count = DS2784_REG_CURR_LSB - start + 1;
  299. }
  300.  
  301. ret = w1_ds2784_read(di->w1_slave, di->raw + start, start, count);
  302. if (ret != count) {
  303. dev_warn(di->dev, "call to w1_ds2784_read failed (0x%p)\n",
  304. di->w1_slave);
  305. return 1;
  306. }
  307.  
  308. if (battery_initial == 0) {
  309. if (!memcmp(di->raw + 0x20, "DUMMY!", 6)) {
  310. unsigned char acr[2];
  311.  
  312. di->dummy = 1;
  313. pr_info("batt: dummy battery detected\n");
  314.  
  315. /* reset ACC register to ~500mAh, since it may have zeroed out */
  316. acr[0] = 0x05;
  317. acr[1] = 0x06;
  318. w1_ds2784_write(di->w1_slave, acr, DS2784_REG_ACCUMULATE_CURR_MSB, 2);
  319. }
  320. battery_initial = 1;
  321. }
  322.  
  323. ds2784_parse_data(di->raw, &di->status);
  324.  
  325. pr_info("batt: %3d%%, %d mV, %d mA (%d avg), %d.%d C, %d mAh\n",
  326. di->status.percentage,
  327. di->status.voltage_uV / 1000, di->status.current_uA / 1000,
  328. di->status.current_avg_uA / 1000,
  329. di->status.temp_C / 10, di->status.temp_C % 10,
  330. di->status.charge_uAh / 1000);
  331.  
  332. return 0;
  333. }
  334.  
  335. static int battery_get_property(struct power_supply *psy,
  336. enum power_supply_property psp,
  337. union power_supply_propval *val)
  338. {
  339. struct ds2784_device_info *di = psy_to_dev_info(psy);
  340.  
  341. switch (psp) {
  342. case POWER_SUPPLY_PROP_STATUS:
  343. switch (di->status.charge_source) {
  344. case CHARGE_OFF:
  345. val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
  346. break;
  347. case CHARGE_FAST:
  348. case CHARGE_SLOW:
  349. if (di->status.battery_full)
  350. val->intval = POWER_SUPPLY_STATUS_FULL;
  351. else if (di->status.charge_mode == CHARGE_OFF ||
  352. di->status.charge_mode == CHARGE_BATT_DISABLE)
  353. val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
  354. else
  355. val->intval = POWER_SUPPLY_STATUS_CHARGING;
  356. break;
  357. default:
  358. val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
  359. break;
  360. }
  361. break;
  362. case POWER_SUPPLY_PROP_HEALTH:
  363. if (di->status.temp_C >= TEMP_HOT)
  364. val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
  365. else
  366. val->intval = POWER_SUPPLY_HEALTH_GOOD;
  367. break;
  368. case POWER_SUPPLY_PROP_PRESENT:
  369. /* XXX todo */
  370. val->intval = 1;
  371. break;
  372. case POWER_SUPPLY_PROP_TECHNOLOGY:
  373. if (di->dummy)
  374. val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
  375. else
  376. val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
  377. break;
  378. case POWER_SUPPLY_PROP_CAPACITY:
  379. if (di->dummy)
  380. val->intval = 75;
  381. else
  382. val->intval = di->status.percentage;
  383. break;
  384. case POWER_SUPPLY_PROP_VOLTAGE_NOW:
  385. val->intval = di->status.voltage_uV;
  386. break;
  387. case POWER_SUPPLY_PROP_TEMP:
  388. val->intval = di->status.temp_C;
  389. break;
  390. case POWER_SUPPLY_PROP_CURRENT_NOW:
  391. val->intval = di->status.current_uA;
  392. break;
  393. case POWER_SUPPLY_PROP_CURRENT_AVG:
  394. val->intval = di->status.current_avg_uA;
  395. break;
  396. case POWER_SUPPLY_PROP_CHARGE_COUNTER:
  397. val->intval = di->status.charge_uAh;
  398. break;
  399. default:
  400. return -EINVAL;
  401. }
  402.  
  403. return 0;
  404. }
  405.  
  406. /* Here we begin to add the functions for our device attribute
  407. * files which act as our link from kernel space to user space.
  408. *
  409. * --RogerPodacter, theloginwithnoname
  410. */
  411.  
  412. static ssize_t store_set_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
  413. {
  414. struct ds2784_device_info *di = dev_get_drvdata(dev);
  415. int reg;
  416. int val;
  417. int check;
  418.  
  419. sscanf(buf, "%x %x", &reg, &val);
  420.  
  421. if (reg < 0 || reg > 255)
  422. return -EINVAL;
  423. if (val < 0 || val > 255)
  424. return -EINVAL;
  425.  
  426. di->raw[reg] = val;
  427. check = w1_ds2784_write(di->w1_slave, di->raw + reg, reg, 1);
  428.  
  429. if (check != 1) {
  430. dev_warn(di->dev, "w1_ds2784_write register failed (ox%p)\n", di->w1_slave);
  431. }
  432.  
  433. pr_info("batt: register 0x%02x changed to 0x%02x by user\n", reg, val);
  434.  
  435. return count;
  436. }
  437. /*This is the actual device attr macro call-out for "setreg" file*/
  438. static DEVICE_ATTR(setreg, 0644, NULL, store_set_reg);
  439.  
  440. static ssize_t show_dump_reg(struct device *dev, struct device_attribute *attr, char *buf)
  441. {
  442. struct ds2784_device_info *di = dev_get_drvdata(dev);
  443.  
  444. int addr;
  445. int ret = 0;
  446. int val;
  447. int printbytes = 0;
  448.  
  449. for (addr = 0; addr <= 0xb1; addr++, printbytes++) {
  450. if (addr == 0 || addr == 0x30 || addr == 0x80) {
  451. if (addr == 0x30) {
  452. addr = 0x60;
  453. }
  454. if (addr == 0x80) {
  455. addr = 0xb0;
  456. }
  457.  
  458. if (PAGE_SIZE-ret > 2) {
  459. ret+= snprintf(&buf[ret], PAGE_SIZE-ret, "\n%02x:", addr);
  460. }
  461.  
  462. w1_ds2784_read(di->w1_slave, di->raw + addr, addr, 1);
  463. val = di->raw[addr];
  464. printbytes = 0;
  465. }
  466.  
  467. if (printbytes >= 16) {
  468. if (PAGE_SIZE-ret > 2) {
  469. ret+= snprintf(&buf[ret], PAGE_SIZE-ret, "\n%02x:", addr);
  470. }
  471. printbytes = 0;
  472. }
  473.  
  474. if (PAGE_SIZE-ret > 2) {
  475. val = di->raw[addr];
  476. ret+= snprintf(&buf[ret], PAGE_SIZE-ret, " %02x", val);
  477. }
  478. else
  479. {
  480. break;
  481. }
  482. }
  483. if (PAGE_SIZE-ret > 2) {
  484. ret+= snprintf(&buf[ret], PAGE_SIZE-ret, "\n");
  485. }
  486.  
  487. return ret;
  488. }
  489.  
  490. static DEVICE_ATTR(dumpreg, 0644, show_dump_reg, NULL);
  491.  
  492. static ssize_t show_status_reg(struct device *dev, struct device_attribute *attr, char *buf)
  493. {
  494. struct ds2784_device_info *di = dev_get_drvdata(dev);
  495. int ret;
  496. int statusreg;
  497. int check;
  498.  
  499. check = w1_ds2784_read(di->w1_slave, di->raw + DS2784_REG_STS, DS2784_REG_STS, 1);
  500.  
  501. if (check != 1) {
  502. dev_warn(di->dev, "w1_ds2784_read Status Register failed (ox%p)\n", di->w1_slave);
  503. }
  504.  
  505. statusreg = di->raw[DS2784_REG_STS];
  506.  
  507. ret = sprintf(buf, "0x%02x\n", statusreg);
  508. return ret;
  509. }
  510.  
  511. static ssize_t store_status_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
  512. {
  513. struct ds2784_device_info *di = dev_get_drvdata(dev);
  514. int val;
  515. int check;
  516.  
  517. sscanf(buf, "%x", &val);
  518.  
  519. if (val < 0 || val > 255)
  520. return -EINVAL;
  521.  
  522. di->raw[DS2784_REG_STS] = val;
  523. check = w1_ds2784_write(di->w1_slave, di->raw + DS2784_REG_STS, DS2784_REG_STS, 1);
  524.  
  525. if (check != 1) {
  526. dev_warn(di->dev, "w1_ds2784_write Status Register failed (ox%p)\n", di->w1_slave);
  527. }
  528.  
  529. pr_info("batt: Status Register set to: 0x%02x \n", val);
  530.  
  531. return count;
  532. }
  533.  
  534. static DEVICE_ATTR(statusreg, 0644, show_status_reg, store_status_reg);
  535.  
  536. static ssize_t show_getvoltage(struct device *dev, struct device_attribute *attr, char *buf)
  537. {
  538. struct ds2784_device_info *di = dev_get_drvdata(dev);
  539. int ret;
  540. int getvoltage;
  541. int check;
  542.  
  543. check = w1_ds2784_read(di->w1_slave, di->raw + DS2784_REG_VOLT_MSB, DS2784_REG_VOLT_MSB, 2);
  544.  
  545. getvoltage = (((di->raw[DS2784_REG_VOLT_MSB]<<8) | (di->raw[DS2784_REG_VOLT_LSB]))>>5)*4886;
  546.  
  547. if (check != 2) {
  548. dev_warn(di->dev, "w1_ds2784_read Voltage failed (ox%p)\n", di->w1_slave);
  549. }
  550.  
  551. ret = sprintf(buf, "%d\n", getvoltage);
  552. return ret;
  553. }
  554.  
  555. static DEVICE_ATTR(getvoltage, 0644, show_getvoltage, NULL);
  556.  
  557. static ssize_t show_getcurrent(struct device *dev, struct device_attribute *attr, char *buf)
  558. {
  559. struct ds2784_device_info *di = dev_get_drvdata(dev);
  560. short n;
  561. int ret;
  562. int getcurrent;
  563. int check;
  564.  
  565. check = w1_ds2784_read(di->w1_slave, di->raw + DS2784_REG_CURR_MSB, DS2784_REG_CURR_MSB, 2);
  566.  
  567. if (check != 2) {
  568. dev_warn(di->dev, "w1_ds2784_read Current failed (ox%p)\n", di->w1_slave);
  569. }
  570.  
  571. n = ((di->raw[DS2784_REG_CURR_MSB]) << 8) | di->raw[DS2784_REG_CURR_LSB];
  572. getcurrent = ((n * 15625) / 10000) * 67;
  573.  
  574. ret = sprintf(buf, "%d\n", getcurrent);
  575. return ret;
  576. }
  577.  
  578. static DEVICE_ATTR(getcurrent, 0644, show_getcurrent, NULL);
  579.  
  580. static ssize_t show_getavgcurrent(struct device *dev, struct device_attribute *attr, char *buf)
  581. {
  582. struct ds2784_device_info *di = dev_get_drvdata(dev);
  583. short n;
  584. int ret;
  585. int getavgcurrent;
  586. int check;
  587.  
  588. check = w1_ds2784_read(di->w1_slave, di->raw + DS2784_REG_AVG_CURR_MSB, DS2784_REG_AVG_CURR_MSB, 2);
  589.  
  590. if (check != 2) {
  591. dev_warn(di->dev, "w1_ds2784_read Avg Current failed (ox%p)\n", di->w1_slave);
  592. }
  593.  
  594. n = ((di->raw[DS2784_REG_AVG_CURR_MSB]) << 8) | di->raw[DS2784_REG_AVG_CURR_LSB];
  595. getavgcurrent = ((n * 15625) / 10000) * 67;
  596.  
  597. ret = sprintf(buf, "%d\n", getavgcurrent);
  598. return ret;
  599. }
  600. static DEVICE_ATTR(getavgcurrent, 0644, show_getavgcurrent, NULL);
  601.  
  602. static ssize_t show_set_age(struct device *dev, struct device_attribute *attr, char *buf)
  603. {
  604. struct ds2784_device_info *di = dev_get_drvdata(dev);
  605. int ret;
  606. int check;
  607. int age;
  608. int ageraw;
  609.  
  610. check = w1_ds2784_read(di->w1_slave, di->raw + DS2784_REG_AGE_SCALAR, DS2784_REG_AGE_SCALAR, 1);
  611.  
  612. if (check != 1) {
  613. dev_warn(di->dev, "w1_ds2784_read age_scalar failed (ox%p)\n", di->w1_slave);
  614. }
  615.  
  616. ageraw = di->raw[DS2784_REG_AGE_SCALAR];
  617. age = (ageraw * 100) / 128;
  618.  
  619. pr_info("batt: age_scalar life left is: %d\n", age);
  620.  
  621. ret = sprintf(buf, "Battery's age: %d", age);
  622. return ret;
  623.  
  624. }
  625.  
  626. static ssize_t store_set_age(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
  627. {
  628. struct ds2784_device_info *di = dev_get_drvdata(dev);
  629. int age;
  630. int check;
  631.  
  632. sscanf(buf, "%d", &age);
  633.  
  634. di->raw[DS2784_REG_AGE_SCALAR] = ((age * 128) / 100);
  635.  
  636. check = w1_ds2784_write(di->w1_slave, di->raw + DS2784_REG_AGE_SCALAR, DS2784_REG_AGE_SCALAR, 1);
  637.  
  638. if (check != 1) {
  639. dev_warn(di->dev, "w1_ds2784_write age_scalar failed (ox%p)\n", di->w1_slave);
  640. }
  641.  
  642. pr_info("batt: age_scalar set to: %d percent\n", age);
  643.  
  644. return count;
  645. }
  646.  
  647. static DEVICE_ATTR(setage, 0644, show_set_age, store_set_age);
  648.  
  649. static ssize_t show_set_AEvolt(struct device *dev, struct device_attribute *attr, char *buf)
  650. {
  651. struct ds2784_device_info *di = dev_get_drvdata(dev);
  652. int ret;
  653. int check;
  654. int rawaevolt;
  655. int aevolt;
  656.  
  657. check = w1_ds2784_read(di->w1_slave, di->raw + DS2784_REG_ACTIVE_EMPTY_VOLT, DS2784_REG_ACTIVE_EMPTY_VOLT, 1);
  658.  
  659. if (check != 1) {
  660. dev_warn(di->dev, "w1_ds2784_read Active Empty Voltage failed (ox%p)\n", di->w1_slave);
  661. }
  662. rawaevolt = di->raw[DS2784_REG_ACTIVE_EMPTY_VOLT];
  663. aevolt = (rawaevolt * 1952) / 100;
  664.  
  665. pr_info("batt: Active Empty Voltage is: %d volts\n", aevolt);
  666.  
  667. ret = sprintf(buf, "AEvolt: %d\n", aevolt);
  668.  
  669. return ret;
  670. }
  671.  
  672. static ssize_t store_set_AEvolt (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
  673. {
  674. struct ds2784_device_info *di = dev_get_drvdata(dev);
  675. int val;
  676. int check;
  677. int temp;
  678.  
  679. sscanf(buf, "%d", &val);
  680.  
  681. di->raw[DS2784_REG_ACTIVE_EMPTY_VOLT] = ( ( val * 100 ) / 1952 ) ;
  682.  
  683. check = w1_ds2784_write(di->w1_slave, di->raw + DS2784_REG_ACTIVE_EMPTY_VOLT, DS2784_REG_ACTIVE_EMPTY_VOLT, 1);
  684.  
  685. if (check != 1) {
  686. dev_warn(di->dev, "w1_ds2784_write Active Empty Voltage failed (ox%p)\n", di->w1_slave);
  687. }
  688.  
  689. temp = ( ( val * 100 ) / 1952 ) ;
  690.  
  691. pr_info("batt: Active Empty Voltage set to: %d percent\n", temp);
  692.  
  693. return count;
  694. }
  695.  
  696. static DEVICE_ATTR(setAEvolt, 0644, show_set_AEvolt, store_set_AEvolt);
  697.  
  698. static ssize_t show_get_full40(struct device *dev, struct device_attribute *attr, char *buf)
  699. {
  700. struct ds2784_device_info *di = dev_get_drvdata(dev);
  701. int ret;
  702. int check;
  703. int full40mAh, full40raw;
  704.  
  705. check = w1_ds2784_read(di->w1_slave, di->raw + DS2784_REG_FULL_40_MSB, DS2784_REG_FULL_40_MSB, 2);
  706.  
  707. if (check != 2) {
  708. dev_warn(di->dev, "w1_ds2784_read Full40 mAh failed (ox%p)\n", di->w1_slave);
  709. }
  710.  
  711. full40raw = ((di->raw[DS2784_REG_FULL_40_MSB]) << 8) | di->raw[DS2784_REG_FULL_40_LSB];
  712.  
  713. full40mAh = ((full40raw * 625) / 100) / 15;
  714.  
  715. pr_info("batt: Full40 mAh capacity is: %d mAh\n", full40mAh);
  716.  
  717. ret = sprintf(buf, "Full40: %d mAh\n", full40mAh);
  718.  
  719. return ret;
  720. }
  721.  
  722. static DEVICE_ATTR(getFull40, 0644, show_get_full40, NULL);
  723.  
  724. static ssize_t show_get_mAh(struct device *dev, struct device_attribute *attr, char *buf)
  725. {
  726. struct ds2784_device_info *di = dev_get_drvdata(dev);
  727. int ret;
  728. int check;
  729. int mAh;
  730.  
  731. check = w1_ds2784_read(di->w1_slave, di->raw + DS2784_REG_RAAC_MSB, DS2784_REG_RAAC_MSB, 2);
  732.  
  733. if (check != 2) {
  734. dev_warn(di->dev, "w1_ds2784_read mAh failed (ox%p)\n", di->w1_slave);
  735. }
  736.  
  737. mAh = ((di->raw[DS2784_REG_RAAC_MSB] << 8) | di->raw[DS2784_REG_RAAC_LSB]) * 1600;
  738.  
  739. ret = sprintf(buf, "%d\n", mAh);
  740.  
  741. return ret;
  742. }
  743.  
  744. static DEVICE_ATTR(getmAh, 0644, show_get_mAh, NULL);
  745.  
  746. /*End of file functions edits
  747. *--RP
  748. */
  749.  
  750. static void ds2784_battery_update_status(struct ds2784_device_info *di)
  751. {
  752. u8 last_level;
  753. last_level = di->status.percentage;
  754.  
  755. ds2784_battery_read_status(di);
  756.  
  757. if ((last_level != di->status.percentage) || (di->status.temp_C > 450))
  758. power_supply_changed(&di->bat);
  759. }
  760.  
  761. static DEFINE_MUTEX(charge_state_lock);
  762.  
  763. static bool check_timeout(ktime_t now, ktime_t last, int seconds)
  764. {
  765. ktime_t timeout = ktime_add(last, ktime_set(seconds, 0));
  766. return ktime_sub(timeout, now).tv64 < 0;
  767. }
  768.  
  769. static int battery_adjust_charge_state(struct ds2784_device_info *di)
  770. {
  771. unsigned source;
  772. int rc = 0;
  773. int temp, volt;
  774. u8 charge_mode;
  775. bool charge_timeout = false;
  776.  
  777. mutex_lock(&charge_state_lock);
  778.  
  779. temp = di->status.temp_C;
  780. volt = di->status.voltage_uV / 1000;
  781.  
  782. source = di->status.charge_source;
  783.  
  784. /* initially our charge mode matches our source:
  785. * NONE:OFF, USB:SLOW, AC:FAST
  786. */
  787. charge_mode = source;
  788.  
  789. /* shut off charger when full:
  790. * - CHGTF flag is set
  791. */
  792.  
  793. /* Changed this code if-statement back to stock because this
  794. * parameter is now user settable by changing the actual
  795. * register value inside the battery chip EEPROM.
  796. * --RP
  797. */
  798.  
  799. if ((di->status.status_reg & 0x80) &&
  800. (di->status.percentage == 100)) {
  801. di->status.battery_full = 1;
  802. charge_mode = CHARGE_BATT_DISABLE;
  803. }
  804.  
  805. /* We don't move from full to not-full until
  806. * we drop below 95%, to avoid confusing the
  807. * user while we're maintaining a full charge
  808. * (slowly draining to 95 and charging back
  809.  
  810. * to 100)
  811. * Oddly, only Passion is for 99% cycles, HTC
  812. * set the Bravo to 95%.
  813. * -od of xbravoteam
  814. *
  815. * Set 99 for Passion - pershoot
  816. */
  817.  
  818. if (di->status.percentage < 99) {
  819. di->status.battery_full = 0;
  820. }
  821.  
  822. if (temp >= TEMP_HOT) {
  823. if (temp >= TEMP_CRITICAL)
  824. charge_mode = CHARGE_BATT_DISABLE;
  825.  
  826. /* once we charge to max voltage when hot, disable
  827. * charging until the temp drops or the voltage drops
  828. */
  829. if (volt >= TEMP_HOT_MAX_MV)
  830. di->status.cooldown = 1;
  831. }
  832.  
  833. /* when the battery is warm, only charge in slow charge mode */
  834. if ((temp >= TEMP_WARM) && (charge_mode == CHARGE_FAST))
  835. charge_mode = CHARGE_SLOW;
  836.  
  837. if (di->status.cooldown) {
  838. if ((temp < TEMP_WARM) || (volt <= TEMP_HOT_MIN_MV))
  839. di->status.cooldown = 0;
  840. else
  841. charge_mode = CHARGE_BATT_DISABLE;
  842. }
  843.  
  844. if (di->status.battery_full == 1)
  845. di->last_charge_seen = di->last_poll;
  846. else if (di->last_charge_mode != CHARGE_OFF &&
  847. check_timeout(di->last_poll, di->last_charge_seen, 60 * 60)) {
  848. if (di->last_charge_mode == CHARGE_BATT_DISABLE) {
  849. /* The charger is only powering the phone. Toggle the
  850. * enable line periodically to prevent auto shutdown.
  851. */
  852. di->last_charge_seen = di->last_poll;
  853. pr_info("batt: charging POKE CHARGER\n");
  854. di->charge(0, 0);
  855. udelay(10);
  856. di->charge(1, source == CHARGE_FAST);
  857. } else {
  858. /* The charger has probably stopped charging. Turn it
  859. * off until the next sample period.
  860. */
  861. charge_timeout = true;
  862. charge_mode = CHARGE_OFF;
  863. }
  864. }
  865.  
  866. if (source == CHARGE_OFF)
  867. charge_mode = CHARGE_OFF;
  868.  
  869. /* Don't use CHARGE_BATT_DISABLE unless the voltage is high since the
  870. * voltage drop over the discharge-path diode can cause a shutdown.
  871. */
  872. if (charge_mode == CHARGE_BATT_DISABLE && volt < CE_DISABLE_MIN_MV)
  873. charge_mode = CHARGE_OFF;
  874.  
  875. if (di->last_charge_mode == charge_mode)
  876. goto done;
  877.  
  878. di->last_charge_mode = charge_mode;
  879. di->status.charge_mode = charge_mode;
  880.  
  881. switch (charge_mode) {
  882. case CHARGE_OFF:
  883. di->charge(0, 0);
  884. ds2784_set_cc(di, true);
  885. if (temp >= TEMP_CRITICAL)
  886. pr_info("batt: charging OFF [OVERTEMP]\n");
  887. else if (di->status.cooldown)
  888. pr_info("batt: charging OFF [COOLDOWN]\n");
  889. else if (di->status.battery_full)
  890. pr_info("batt: charging OFF [FULL]\n");
  891. else if (charge_timeout)
  892. pr_info("batt: charging OFF [TIMEOUT]\n");
  893. else
  894. pr_info("batt: charging OFF\n");
  895. break;
  896. case CHARGE_BATT_DISABLE:
  897. di->last_charge_seen = di->last_poll;
  898. ds2784_set_cc(di, false);
  899. di->charge(1, source == CHARGE_FAST);
  900. if (temp >= TEMP_CRITICAL)
  901. pr_info("batt: charging BATTOFF [OVERTEMP]\n");
  902. else if (di->status.cooldown)
  903. pr_info("batt: charging BATTOFF [COOLDOWN]\n");
  904. else if (di->status.battery_full)
  905. pr_info("batt: charging BATTOFF [FULL]\n");
  906. else
  907. pr_info("batt: charging BATTOFF [UNKNOWN]\n");
  908. break;
  909. case CHARGE_SLOW:
  910. di->last_charge_seen = di->last_poll;
  911. ds2784_set_cc(di, true);
  912. di->charge(1, 0);
  913. pr_info("batt: charging SLOW\n");
  914. break;
  915. case CHARGE_FAST:
  916. di->last_charge_seen = di->last_poll;
  917. ds2784_set_cc(di, true);
  918. di->charge(1, 1);
  919. pr_info("batt: charging FAST\n");
  920. break;
  921. }
  922. rc = 1;
  923. done:
  924. mutex_unlock(&charge_state_lock);
  925. return rc;
  926. }
  927.  
  928. static void ds2784_program_alarm(struct ds2784_device_info *di, int seconds)
  929. {
  930. ktime_t low_interval = ktime_set(seconds - 10, 0);
  931. ktime_t slack = ktime_set(20, 0);
  932. ktime_t next;
  933.  
  934. next = ktime_add(di->last_poll, low_interval);
  935.  
  936. alarm_start_range(&di->alarm, next, ktime_add(next, slack));
  937. }
  938.  
  939. static void ds2784_battery_work(struct work_struct *work)
  940. {
  941. struct ds2784_device_info *di =
  942. container_of(work, struct ds2784_device_info, monitor_work);
  943. struct timespec ts;
  944. unsigned long flags;
  945.  
  946. ds2784_battery_update_status(di);
  947.  
  948. di->last_poll = alarm_get_elapsed_realtime();
  949.  
  950. if (battery_adjust_charge_state(di))
  951. power_supply_changed(&di->bat);
  952.  
  953. ts = ktime_to_timespec(di->last_poll);
  954. di->status.timestamp = ts.tv_sec;
  955. battery_log_status(&di->status);
  956.  
  957. /* prevent suspend before starting the alarm */
  958. local_irq_save(flags);
  959. wake_unlock(&di->work_wake_lock);
  960. ds2784_program_alarm(di, FAST_POLL);
  961. local_irq_restore(flags);
  962. }
  963.  
  964. static void ds2784_battery_alarm(struct alarm *alarm)
  965. {
  966. struct ds2784_device_info *di =
  967. container_of(alarm, struct ds2784_device_info, alarm);
  968. wake_lock(&di->work_wake_lock);
  969. queue_work(di->monitor_wqueue, &di->monitor_work);
  970. }
  971.  
  972. static void battery_ext_power_changed(struct power_supply *psy)
  973. {
  974. struct ds2784_device_info *di;
  975. int got_power;
  976.  
  977. di = psy_to_dev_info(psy);
  978. got_power = power_supply_am_i_supplied(psy);
  979.  
  980. if (got_power) {
  981. if (is_ac_power_supplied())
  982. di->status.charge_source = SOURCE_AC;
  983. else
  984. di->status.charge_source = SOURCE_USB;
  985. wake_lock(&vbus_wake_lock);
  986. } else {
  987. di->status.charge_source = SOURCE_NONE;
  988. /* give userspace some time to see the uevent and update
  989. * LED state or whatnot...
  990. */
  991. wake_lock_timeout(&vbus_wake_lock, HZ / 2);
  992. }
  993. battery_adjust_charge_state(di);
  994. power_supply_changed(psy);
  995. }
  996.  
  997. static int ds2784_battery_probe(struct platform_device *pdev)
  998. {
  999. int rc, ret; /*Added "ret" as a check for creating the sysfs files*/
  1000. struct ds2784_device_info *di;
  1001. struct ds2784_platform_data *pdata;
  1002.  
  1003. di = kzalloc(sizeof(*di), GFP_KERNEL);
  1004. if (!di)
  1005. return -ENOMEM;
  1006.  
  1007. platform_set_drvdata(pdev, di);
  1008.  
  1009. pdata = pdev->dev.platform_data;
  1010. if (!pdata || !pdata->charge || !pdata->w1_slave) {
  1011. pr_err("%s: pdata missing or invalid\n", __func__);
  1012. rc = -EINVAL;
  1013. goto fail_register;
  1014. }
  1015.  
  1016. di->charge = pdata->charge;
  1017. di->w1_slave = pdata->w1_slave;
  1018.  
  1019. di->dev = &pdev->dev;
  1020.  
  1021. di->bat.name = "battery";
  1022. di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
  1023. di->bat.properties = battery_properties;
  1024. di->bat.num_properties = ARRAY_SIZE(battery_properties);
  1025. di->bat.external_power_changed = battery_ext_power_changed;
  1026. di->bat.get_property = battery_get_property;
  1027. di->last_charge_mode = 0xff;
  1028.  
  1029. rc = power_supply_register(&pdev->dev, &di->bat);
  1030. if (rc)
  1031. goto fail_register;
  1032.  
  1033. /* Here we call out all of the new file creations in the
  1034. * probe function.
  1035. * --RP
  1036. */
  1037. ret = device_create_file(&pdev->dev, &dev_attr_setreg);
  1038. if(ret < 0)
  1039. pr_err("%s: Failed to create sysfs entry for setreg\n", __func__);
  1040.  
  1041. ret = device_create_file(&pdev->dev, &dev_attr_dumpreg);
  1042. if(ret < 0)
  1043. pr_err("%s: Failed to create sysfs entry for dumpreg\n", __func__);
  1044.  
  1045. ret = device_create_file(&pdev->dev, &dev_attr_statusreg);
  1046. if(ret < 0)
  1047. pr_err("%s: Failed to create sysfs entry for statusreg\n", __func__);
  1048.  
  1049. ret = device_create_file(&pdev->dev, &dev_attr_getvoltage);
  1050. if(ret < 0)
  1051. pr_err("%s: Failed to create sysfs entry for voltage\n", __func__);
  1052.  
  1053. ret = device_create_file(&pdev->dev, &dev_attr_getcurrent);
  1054. if(ret < 0)
  1055. pr_err("%s: Failed to create sysfs entry for current\n", __func__);
  1056.  
  1057. ret = device_create_file(&pdev->dev, &dev_attr_getavgcurrent);
  1058. if(ret < 0)
  1059. pr_err("%s: Failed to create sysfs entry for avg current\n", __func__);
  1060.  
  1061. ret = device_create_file(&pdev->dev, &dev_attr_setage);
  1062. if(ret < 0)
  1063. pr_err("%s: Failed to create sysfs entry for setage\n", __func__);
  1064.  
  1065. ret = device_create_file(&pdev->dev, &dev_attr_setAEvolt);
  1066. if(ret < 0)
  1067. pr_err("%s: Failed to create sysfs entry for setAEvolt\n", __func__);
  1068.  
  1069. ret = device_create_file(&pdev->dev, &dev_attr_getFull40);
  1070. if(ret < 0)
  1071. pr_err("%s: Failed to create sysfs entry for getFull40\n", __func__);
  1072.  
  1073. ret = device_create_file(&pdev->dev, &dev_attr_getmAh);
  1074. if(ret < 0)
  1075. pr_err("%s: Failed to create sysfs entry for mAh\n", __func__);
  1076.  
  1077. /* End of file call-outs --RP*/
  1078.  
  1079. INIT_WORK(&di->monitor_work, ds2784_battery_work);
  1080. di->monitor_wqueue = create_freezeable_workqueue(dev_name(&pdev->dev));
  1081.  
  1082. /* init to something sane */
  1083. di->last_poll = alarm_get_elapsed_realtime();
  1084.  
  1085. if (!di->monitor_wqueue) {
  1086. rc = -ESRCH;
  1087. goto fail_workqueue;
  1088. }
  1089. wake_lock_init(&di->work_wake_lock, WAKE_LOCK_SUSPEND,
  1090. "ds2784-battery");
  1091. alarm_init(&di->alarm, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
  1092. ds2784_battery_alarm);
  1093. wake_lock(&di->work_wake_lock);
  1094. queue_work(di->monitor_wqueue, &di->monitor_work);
  1095. return 0;
  1096.  
  1097. fail_workqueue:
  1098. power_supply_unregister(&di->bat);
  1099. fail_register:
  1100. kfree(di);
  1101. return rc;
  1102. }
  1103.  
  1104. static int ds2784_suspend(struct device *dev)
  1105. {
  1106. struct ds2784_device_info *di = dev_get_drvdata(dev);
  1107.  
  1108. /* If we are on battery, reduce our update rate until
  1109. * we next resume.
  1110. */
  1111. if (di->status.charge_source == SOURCE_NONE) {
  1112. ds2784_program_alarm(di, SLOW_POLL);
  1113. di->slow_poll = 1;
  1114. }
  1115. return 0;
  1116. }
  1117.  
  1118. static int ds2784_resume(struct device *dev)
  1119. {
  1120. struct ds2784_device_info *di = dev_get_drvdata(dev);
  1121.  
  1122. /* We might be on a slow sample cycle. If we're
  1123. * resuming we should resample the battery state
  1124. * if it's been over a minute since we last did
  1125. * so, and move back to sampling every minute until
  1126. * we suspend again.
  1127. */
  1128. if (di->slow_poll) {
  1129. ds2784_program_alarm(di, FAST_POLL);
  1130. di->slow_poll = 0;
  1131. }
  1132. return 0;
  1133. }
  1134.  
  1135. static struct dev_pm_ops ds2784_pm_ops = {
  1136. .suspend = ds2784_suspend,
  1137. .resume = ds2784_resume,
  1138. };
  1139.  
  1140. static struct platform_driver ds2784_battery_driver = {
  1141. .driver = {
  1142. .name = "ds2784-battery",
  1143. .pm = &ds2784_pm_ops,
  1144. },
  1145. .probe = ds2784_battery_probe,
  1146. };
  1147.  
  1148. static int battery_log_open(struct inode *inode, struct file *file)
  1149. {
  1150. return single_open(file, battery_log_print, NULL);
  1151. }
  1152.  
  1153. static struct file_operations battery_log_fops = {
  1154. .open = battery_log_open,
  1155. .read = seq_read,
  1156. .llseek = seq_lseek,
  1157. .release = single_release,
  1158. };
  1159.  
  1160. static int __init ds2784_battery_init(void)
  1161. {
  1162. debugfs_create_file("battery_log", 0444, NULL, NULL, &battery_log_fops);
  1163. wake_lock_init(&vbus_wake_lock, WAKE_LOCK_SUSPEND, "vbus_present");
  1164. return platform_driver_register(&ds2784_battery_driver);
  1165. }
  1166.  
  1167. module_init(ds2784_battery_init);
  1168.  
  1169. MODULE_LICENSE("GPL");
  1170. MODULE_AUTHOR("Justin Lin <Justin_lin@htc.com>");
  1171. MODULE_DESCRIPTION("ds2784 battery driver");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement