cps4038_cmfet.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. /*
  2. * mfc_cmfet.c
  3. * Samsung Mobile MFC CMFET Module
  4. *
  5. * Copyright (C) 2023 Samsung Electronics
  6. *
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. */
  12. #include <linux/of.h>
  13. #include <linux/slab.h>
  14. #include <linux/mutex.h>
  15. #include <linux/device.h>
  16. #include <linux/module.h>
  17. #include "cps4038_charger.h"
  18. #define cmfet_log(str, ...) pr_info("[MFC-CMFET]:%s: "str, __func__, ##__VA_ARGS__)
  19. struct mfc_cmfet {
  20. struct device *parent;
  21. mfc_set_cmfet cb_func;
  22. struct mutex lock;
  23. union mfc_cmfet_state state;
  24. /* threshold */
  25. bool unknown_cmb_ctrl;
  26. unsigned int high_swell_cc_cv_thr;
  27. };
  28. static int mfc_cmfet_parse_dt(struct device_node *np, struct mfc_cmfet *cmfet)
  29. {
  30. int ret = 0;
  31. cmfet->unknown_cmb_ctrl = of_property_read_bool(np, "battery,unknown_cmb_ctrl");
  32. ret = of_property_read_u32(np, "high_swell_cc_cv_thr", &cmfet->high_swell_cc_cv_thr);
  33. if (ret < 0)
  34. cmfet->high_swell_cc_cv_thr = 70;
  35. cmfet_log("unknown_cmb_ctrl = %d, high_swell_cc_cv_thr = %d\n",
  36. cmfet->unknown_cmb_ctrl, cmfet->high_swell_cc_cv_thr);
  37. return 0;
  38. }
  39. struct mfc_cmfet *mfc_cmfet_init(struct device *dev, mfc_set_cmfet cb_func)
  40. {
  41. struct mfc_cmfet *cmfet;
  42. int ret = 0;
  43. if (IS_ERR_OR_NULL(dev) ||
  44. (cb_func == NULL))
  45. return ERR_PTR(-EINVAL);
  46. cmfet = kzalloc(sizeof(struct mfc_cmfet), GFP_KERNEL);
  47. if (!cmfet)
  48. return ERR_PTR(-ENOMEM);
  49. ret = mfc_cmfet_parse_dt(dev->of_node, cmfet);
  50. if (ret < 0) {
  51. kfree(cmfet);
  52. return ERR_PTR(ret);
  53. }
  54. mutex_init(&cmfet->lock);
  55. cmfet->parent = dev;
  56. cmfet->cb_func = cb_func;
  57. cmfet->state.value = 0;
  58. cmfet_log("DONE!!\n");
  59. return cmfet;
  60. }
  61. EXPORT_SYMBOL(mfc_cmfet_init);
  62. int mfc_cmfet_init_state(struct mfc_cmfet *cmfet)
  63. {
  64. if (IS_ERR(cmfet))
  65. return -EINVAL;
  66. mutex_lock(&cmfet->lock);
  67. if (cmfet->state.value != 0) {
  68. cmfet->state.value = 0;
  69. cmfet->cb_func(cmfet->parent, &cmfet->state, false, false);
  70. }
  71. mutex_unlock(&cmfet->lock);
  72. return 0;
  73. }
  74. EXPORT_SYMBOL(mfc_cmfet_init_state);
  75. int mfc_cmfet_refresh(struct mfc_cmfet *cmfet)
  76. {
  77. if (IS_ERR(cmfet))
  78. return -EINVAL;
  79. mutex_lock(&cmfet->lock);
  80. if (cmfet->state.value != 0)
  81. cmfet->cb_func(cmfet->parent, &cmfet->state, cmfet->state.cma, cmfet->state.cmb);
  82. mutex_unlock(&cmfet->lock);
  83. return 0;
  84. }
  85. EXPORT_SYMBOL(mfc_cmfet_refresh);
  86. static void set_init_state(union mfc_cmfet_state *state, bool cma, bool cmb)
  87. {
  88. state->cma = cma;
  89. state->cmb = cmb;
  90. }
  91. static unsigned long long check_tx_default(struct mfc_cmfet *cmfet, union mfc_cmfet_state *state)
  92. {
  93. if (state->high_swell)
  94. state->cmb = (state->bat_cap > cmfet->high_swell_cc_cv_thr);
  95. if (state->full)
  96. state->cmb = true;
  97. if (state->chg_done)
  98. state->cmb = false;
  99. return state->value;
  100. }
  101. static unsigned long long check_tx_unknown(struct mfc_cmfet *cmfet, union mfc_cmfet_state *state)
  102. {
  103. set_init_state(state, true, (cmfet->unknown_cmb_ctrl));
  104. return state->value;
  105. }
  106. static unsigned long long check_tx_p1100(struct mfc_cmfet *cmfet, union mfc_cmfet_state *state)
  107. {
  108. set_init_state(state, true, true);
  109. if (state->vout <= 5500)
  110. state->cmb = false;
  111. if (state->chg_done)
  112. state->cmb = false;
  113. return state->value;
  114. }
  115. static unsigned long long check_tx_n5200(struct mfc_cmfet *cmfet, union mfc_cmfet_state *state)
  116. {
  117. set_init_state(state, true, false);
  118. return check_tx_default(cmfet, state);
  119. }
  120. static unsigned long long check_tx_p5200(struct mfc_cmfet *cmfet, union mfc_cmfet_state *state)
  121. {
  122. set_init_state(state, true, true);
  123. if (state->auth)
  124. state->cmb = false;
  125. return check_tx_default(cmfet, state);
  126. }
  127. static unsigned long long check_cmfet_state(struct mfc_cmfet *cmfet, union mfc_cmfet_state *state)
  128. {
  129. switch (state->tx_id) {
  130. case TX_ID_UNKNOWN:
  131. return check_tx_unknown(cmfet, state);
  132. case TX_ID_P1100_PAD:
  133. return check_tx_p1100(cmfet, state);
  134. case TX_ID_N5200_V_PAD:
  135. case TX_ID_N5200_H_PAD:
  136. return check_tx_n5200(cmfet, state);
  137. case TX_ID_P5200_PAD:
  138. return check_tx_p5200(cmfet, state);
  139. default:
  140. break;
  141. }
  142. set_init_state(state, true, true);
  143. return check_tx_default(cmfet, state);
  144. }
  145. static bool is_changed_state(union mfc_cmfet_state *state1, union mfc_cmfet_state *state2)
  146. {
  147. return (state1->cma != state2->cma) || (state1->cmb != state2->cmb);
  148. }
  149. static int update_cmfet_state(struct mfc_cmfet *cmfet, union mfc_cmfet_state *state)
  150. {
  151. state->value = check_cmfet_state(cmfet, state);
  152. if (is_changed_state(state, &cmfet->state))
  153. cmfet->cb_func(cmfet->parent, state, state->cma, state->cmb);
  154. cmfet->state.value = state->value;
  155. return 0;
  156. }
  157. int mfc_cmfet_set_tx_id(struct mfc_cmfet *cmfet, int tx_id)
  158. {
  159. if (IS_ERR(cmfet) ||
  160. (tx_id < 0) || (tx_id >= 256))
  161. return -EINVAL;
  162. mutex_lock(&cmfet->lock);
  163. if (cmfet->state.tx_id != tx_id) {
  164. union mfc_cmfet_state temp = { cmfet->state.value, };
  165. temp.tx_id = tx_id;
  166. update_cmfet_state(cmfet, &temp);
  167. }
  168. mutex_unlock(&cmfet->lock);
  169. return 0;
  170. }
  171. EXPORT_SYMBOL(mfc_cmfet_set_tx_id);
  172. int mfc_cmfet_set_bat_cap(struct mfc_cmfet *cmfet, int bat_cap)
  173. {
  174. if (IS_ERR(cmfet) ||
  175. (bat_cap < 0) || (bat_cap > 100))
  176. return -EINVAL;
  177. mutex_lock(&cmfet->lock);
  178. if (cmfet->state.bat_cap != bat_cap) {
  179. union mfc_cmfet_state temp = { cmfet->state.value, };
  180. temp.bat_cap = bat_cap;
  181. update_cmfet_state(cmfet, &temp);
  182. }
  183. mutex_unlock(&cmfet->lock);
  184. return 0;
  185. }
  186. EXPORT_SYMBOL(mfc_cmfet_set_bat_cap);
  187. int mfc_cmfet_set_vout(struct mfc_cmfet *cmfet, int vout)
  188. {
  189. if (IS_ERR(cmfet) ||
  190. (vout <= 0))
  191. return -EINVAL;
  192. mutex_lock(&cmfet->lock);
  193. if (cmfet->state.vout != vout) {
  194. union mfc_cmfet_state temp = { cmfet->state.value, };
  195. temp.vout = vout;
  196. update_cmfet_state(cmfet, &temp);
  197. }
  198. mutex_unlock(&cmfet->lock);
  199. return 0;
  200. }
  201. EXPORT_SYMBOL(mfc_cmfet_set_vout);
  202. int mfc_cmfet_set_high_swell(struct mfc_cmfet *cmfet, bool state)
  203. {
  204. if (IS_ERR(cmfet))
  205. return -EINVAL;
  206. mutex_lock(&cmfet->lock);
  207. if (cmfet->state.high_swell != state) {
  208. union mfc_cmfet_state temp = { cmfet->state.value, };
  209. temp.high_swell = state;
  210. update_cmfet_state(cmfet, &temp);
  211. }
  212. mutex_unlock(&cmfet->lock);
  213. return 0;
  214. }
  215. EXPORT_SYMBOL(mfc_cmfet_set_high_swell);
  216. int mfc_cmfet_set_full(struct mfc_cmfet *cmfet, bool full)
  217. {
  218. if (IS_ERR(cmfet))
  219. return -EINVAL;
  220. mutex_lock(&cmfet->lock);
  221. if (cmfet->state.full != full) {
  222. union mfc_cmfet_state temp = { cmfet->state.value, };
  223. temp.full = full;
  224. update_cmfet_state(cmfet, &temp);
  225. }
  226. mutex_unlock(&cmfet->lock);
  227. return 0;
  228. }
  229. EXPORT_SYMBOL(mfc_cmfet_set_full);
  230. int mfc_cmfet_set_chg_done(struct mfc_cmfet *cmfet, bool chg_done)
  231. {
  232. if (IS_ERR(cmfet))
  233. return -EINVAL;
  234. mutex_lock(&cmfet->lock);
  235. if (cmfet->state.chg_done != chg_done) {
  236. union mfc_cmfet_state temp = { cmfet->state.value, };
  237. temp.chg_done = chg_done;
  238. update_cmfet_state(cmfet, &temp);
  239. }
  240. mutex_unlock(&cmfet->lock);
  241. return 0;
  242. }
  243. EXPORT_SYMBOL(mfc_cmfet_set_chg_done);
  244. int mfc_cmfet_set_auth(struct mfc_cmfet *cmfet, bool auth)
  245. {
  246. if (IS_ERR(cmfet))
  247. return -EINVAL;
  248. mutex_lock(&cmfet->lock);
  249. if (cmfet->state.auth != auth) {
  250. union mfc_cmfet_state temp = { cmfet->state.value, };
  251. temp.auth = auth;
  252. update_cmfet_state(cmfet, &temp);
  253. }
  254. mutex_unlock(&cmfet->lock);
  255. return 0;
  256. }
  257. EXPORT_SYMBOL(mfc_cmfet_set_auth);
  258. int mfc_cmfet_get_state(struct mfc_cmfet *cmfet, union mfc_cmfet_state *state)
  259. {
  260. if (IS_ERR(cmfet) ||
  261. (state == NULL))
  262. return -EINVAL;
  263. mutex_lock(&cmfet->lock);
  264. state->value = cmfet->state.value;
  265. mutex_unlock(&cmfet->lock);
  266. return 0;
  267. }
  268. EXPORT_SYMBOL(mfc_cmfet_get_state);