fg_max17042.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /*
  2. * Copyright (C) 2012 Samsung Electronics
  3. * Lukasz Majewski <l.majewski@samsung.com>
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. #include <common.h>
  8. #include <power/pmic.h>
  9. #include <power/max17042_fg.h>
  10. #include <i2c.h>
  11. #include <power/max8997_pmic.h>
  12. #include <power/power_chrg.h>
  13. #include <power/battery.h>
  14. #include <power/fg_battery_cell_params.h>
  15. #include <errno.h>
  16. static int fg_write_regs(struct pmic *p, u8 addr, u16 *data, int num)
  17. {
  18. int ret = 0;
  19. int i;
  20. for (i = 0; i < num; i++, addr++) {
  21. ret = pmic_reg_write(p, addr, *(data + i));
  22. if (ret)
  23. return ret;
  24. }
  25. return 0;
  26. }
  27. static int fg_read_regs(struct pmic *p, u8 addr, u16 *data, int num)
  28. {
  29. unsigned int dat;
  30. int ret = 0;
  31. int i;
  32. for (i = 0; i < num; i++, addr++) {
  33. ret = pmic_reg_read(p, addr, &dat);
  34. if (ret)
  35. return ret;
  36. *(data + i) = (u16)dat;
  37. }
  38. return 0;
  39. }
  40. static int fg_write_and_verify(struct pmic *p, u8 addr, u16 data)
  41. {
  42. unsigned int val = data;
  43. int ret = 0;
  44. ret |= pmic_reg_write(p, addr, val);
  45. ret |= pmic_reg_read(p, addr, &val);
  46. if (ret)
  47. return ret;
  48. if (((u16) val) == data)
  49. return 0;
  50. return -1;
  51. }
  52. static void por_fuelgauge_init(struct pmic *p)
  53. {
  54. u16 r_data0[16], r_data1[16], r_data2[16];
  55. u32 rewrite_count = 5;
  56. u32 check_count;
  57. u32 lock_count;
  58. u32 i = 0;
  59. u32 val;
  60. s32 ret = 0;
  61. char *status_msg;
  62. /* Delay 500 ms */
  63. mdelay(500);
  64. /* Initilize Configuration */
  65. pmic_reg_write(p, MAX17042_CONFIG, 0x2310);
  66. rewrite_model:
  67. check_count = 5;
  68. lock_count = 5;
  69. if (!rewrite_count--) {
  70. status_msg = "init failed!";
  71. goto error;
  72. }
  73. /* Unlock Model Access */
  74. pmic_reg_write(p, MAX17042_MLOCKReg1, MODEL_UNLOCK1);
  75. pmic_reg_write(p, MAX17042_MLOCKReg2, MODEL_UNLOCK2);
  76. /* Write/Read/Verify the Custom Model */
  77. ret = fg_write_regs(p, MAX17042_MODEL1, cell_character0,
  78. ARRAY_SIZE(cell_character0));
  79. if (ret)
  80. goto rewrite_model;
  81. ret = fg_write_regs(p, MAX17042_MODEL2, cell_character1,
  82. ARRAY_SIZE(cell_character1));
  83. if (ret)
  84. goto rewrite_model;
  85. ret = fg_write_regs(p, MAX17042_MODEL3, cell_character2,
  86. ARRAY_SIZE(cell_character2));
  87. if (ret)
  88. goto rewrite_model;
  89. check_model:
  90. if (!check_count--) {
  91. if (rewrite_count)
  92. goto rewrite_model;
  93. else
  94. status_msg = "check failed!";
  95. goto error;
  96. }
  97. ret = fg_read_regs(p, MAX17042_MODEL1, r_data0, ARRAY_SIZE(r_data0));
  98. if (ret)
  99. goto check_model;
  100. ret = fg_read_regs(p, MAX17042_MODEL2, r_data1, ARRAY_SIZE(r_data1));
  101. if (ret)
  102. goto check_model;
  103. ret = fg_read_regs(p, MAX17042_MODEL3, r_data2, ARRAY_SIZE(r_data2));
  104. if (ret)
  105. goto check_model;
  106. for (i = 0; i < 16; i++) {
  107. if ((cell_character0[i] != r_data0[i])
  108. || (cell_character1[i] != r_data1[i])
  109. || (cell_character2[i] != r_data2[i]))
  110. goto rewrite_model;
  111. }
  112. lock_model:
  113. if (!lock_count--) {
  114. if (rewrite_count)
  115. goto rewrite_model;
  116. else
  117. status_msg = "lock failed!";
  118. goto error;
  119. }
  120. /* Lock model access */
  121. pmic_reg_write(p, MAX17042_MLOCKReg1, MODEL_LOCK1);
  122. pmic_reg_write(p, MAX17042_MLOCKReg2, MODEL_LOCK2);
  123. /* Verify the model access is locked */
  124. ret = fg_read_regs(p, MAX17042_MODEL1, r_data0, ARRAY_SIZE(r_data0));
  125. if (ret)
  126. goto lock_model;
  127. ret = fg_read_regs(p, MAX17042_MODEL2, r_data1, ARRAY_SIZE(r_data1));
  128. if (ret)
  129. goto lock_model;
  130. ret = fg_read_regs(p, MAX17042_MODEL3, r_data2, ARRAY_SIZE(r_data2));
  131. if (ret)
  132. goto lock_model;
  133. for (i = 0; i < ARRAY_SIZE(r_data0); i++) {
  134. /* Check if model locked */
  135. if (r_data0[i] || r_data1[i] || r_data2[i])
  136. goto lock_model;
  137. }
  138. /* Write Custom Parameters */
  139. fg_write_and_verify(p, MAX17042_RCOMP0, RCOMP0);
  140. fg_write_and_verify(p, MAX17042_TEMPCO, TempCo);
  141. /* Delay at least 350mS */
  142. mdelay(350);
  143. /* Initialization Complete */
  144. pmic_reg_read(p, MAX17042_STATUS, &val);
  145. /* Write and Verify Status with POR bit Cleared */
  146. fg_write_and_verify(p, MAX17042_STATUS, val & ~MAX17042_POR);
  147. /* Delay at least 350 ms */
  148. mdelay(350);
  149. status_msg = "OK!";
  150. error:
  151. debug("%s: model init status: %s\n", p->name, status_msg);
  152. return;
  153. }
  154. static int power_update_battery(struct pmic *p, struct pmic *bat)
  155. {
  156. struct power_battery *pb = bat->pbat;
  157. unsigned int val;
  158. int ret = 0;
  159. if (pmic_probe(p)) {
  160. puts("Can't find max17042 fuel gauge\n");
  161. return -1;
  162. }
  163. ret |= pmic_reg_read(p, MAX17042_VFSOC, &val);
  164. pb->bat->state_of_chrg = (val >> 8);
  165. pmic_reg_read(p, MAX17042_VCELL, &val);
  166. debug("vfsoc: 0x%x\n", val);
  167. pb->bat->voltage_uV = ((val & 0xFFUL) >> 3) + ((val & 0xFF00) >> 3);
  168. pb->bat->voltage_uV = (pb->bat->voltage_uV * 625);
  169. pmic_reg_read(p, 0x05, &val);
  170. pb->bat->capacity = val >> 2;
  171. return ret;
  172. }
  173. static int power_check_battery(struct pmic *p, struct pmic *bat)
  174. {
  175. struct power_battery *pb = bat->pbat;
  176. unsigned int val;
  177. int ret = 0;
  178. if (pmic_probe(p)) {
  179. puts("Can't find max17042 fuel gauge\n");
  180. return -1;
  181. }
  182. ret |= pmic_reg_read(p, MAX17042_STATUS, &val);
  183. debug("fg status: 0x%x\n", val);
  184. if (val & MAX17042_POR)
  185. por_fuelgauge_init(p);
  186. ret |= pmic_reg_read(p, MAX17042_VERSION, &val);
  187. pb->bat->version = val;
  188. power_update_battery(p, bat);
  189. debug("fg ver: 0x%x\n", pb->bat->version);
  190. printf("BAT: state_of_charge(SOC):%d%%\n",
  191. pb->bat->state_of_chrg);
  192. printf(" voltage: %d.%6.6d [V] (expected to be %d [mAh])\n",
  193. pb->bat->voltage_uV / 1000000,
  194. pb->bat->voltage_uV % 1000000,
  195. pb->bat->capacity);
  196. if (pb->bat->voltage_uV > 3850000)
  197. pb->bat->state = EXT_SOURCE;
  198. else if (pb->bat->voltage_uV < 3600000 || pb->bat->state_of_chrg < 5)
  199. pb->bat->state = CHARGE;
  200. else
  201. pb->bat->state = NORMAL;
  202. return ret;
  203. }
  204. static struct power_fg power_fg_ops = {
  205. .fg_battery_check = power_check_battery,
  206. .fg_battery_update = power_update_battery,
  207. };
  208. int power_fg_init(unsigned char bus)
  209. {
  210. static const char name[] = "MAX17042_FG";
  211. struct pmic *p = pmic_alloc();
  212. if (!p) {
  213. printf("%s: POWER allocation error!\n", __func__);
  214. return -ENOMEM;
  215. }
  216. debug("Board Fuel Gauge init\n");
  217. p->name = name;
  218. p->interface = PMIC_I2C;
  219. p->number_of_regs = FG_NUM_OF_REGS;
  220. p->hw.i2c.addr = MAX17042_I2C_ADDR;
  221. p->hw.i2c.tx_num = 2;
  222. p->sensor_byte_order = PMIC_SENSOR_BYTE_ORDER_BIG;
  223. p->bus = bus;
  224. p->fg = &power_fg_ops;
  225. return 0;
  226. }