ltc4088-charger.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. /*
  2. * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 and
  6. * only version 2 as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #define pr_fmt(fmt) "%s: " fmt, __func__
  14. #include <linux/kernel.h>
  15. #include <linux/module.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/errno.h>
  18. #include <linux/power_supply.h>
  19. #include <linux/slab.h>
  20. #include <linux/gpio.h>
  21. #include <linux/power/ltc4088-charger.h>
  22. #define MAX_CURRENT_UA(n) (n)
  23. #define MAX_CURRENT_MA(n) (n * MAX_CURRENT_UA(1000))
  24. /**
  25. * ltc4088_max_current - A typical current values supported by the charger
  26. * @LTC4088_MAX_CURRENT_100mA: 100mA current
  27. * @LTC4088_MAX_CURRENT_500mA: 500mA current
  28. * @LTC4088_MAX_CURRENT_1A: 1A current
  29. */
  30. enum ltc4088_max_current {
  31. LTC4088_MAX_CURRENT_100mA = 100,
  32. LTC4088_MAX_CURRENT_500mA = 500,
  33. LTC4088_MAX_CURRENT_1A = 1000,
  34. };
  35. /**
  36. * struct ltc4088_chg_chip - Device information
  37. * @dev: Device pointer to access the parent
  38. * @lock: Enable mutual exclusion
  39. * @usb_psy: USB device information
  40. * @gpio_mode_select_d0: GPIO #pin for D0 charger line
  41. * @gpio_mode_select_d1: GPIO #pin for D1 charger line
  42. * @gpio_mode_select_d2: GPIO #pin for D2 charger line
  43. * @max_current: Maximum current that is supplied at this time
  44. */
  45. struct ltc4088_chg_chip {
  46. struct device *dev;
  47. struct mutex lock;
  48. struct power_supply usb_psy;
  49. unsigned int gpio_mode_select_d0;
  50. unsigned int gpio_mode_select_d1;
  51. unsigned int gpio_mode_select_d2;
  52. unsigned int max_current;
  53. };
  54. static enum power_supply_property pm_power_props[] = {
  55. POWER_SUPPLY_PROP_CURRENT_MAX,
  56. POWER_SUPPLY_PROP_ONLINE,
  57. };
  58. static char *pm_power_supplied_to[] = {
  59. "battery",
  60. };
  61. static int ltc4088_set_charging(struct ltc4088_chg_chip *chip, bool enable)
  62. {
  63. mutex_lock(&chip->lock);
  64. if (enable) {
  65. gpio_set_value_cansleep(chip->gpio_mode_select_d2, 0);
  66. } else {
  67. /* When disabling charger, set the max current to 0 also */
  68. chip->max_current = 0;
  69. gpio_set_value_cansleep(chip->gpio_mode_select_d0, 1);
  70. gpio_set_value_cansleep(chip->gpio_mode_select_d1, 1);
  71. gpio_set_value_cansleep(chip->gpio_mode_select_d2, 1);
  72. }
  73. mutex_unlock(&chip->lock);
  74. return 0;
  75. }
  76. static void ltc4088_set_max_current(struct ltc4088_chg_chip *chip, int value)
  77. {
  78. mutex_lock(&chip->lock);
  79. /* If current is less than 100mA, we can not support that granularity */
  80. if (value < MAX_CURRENT_MA(LTC4088_MAX_CURRENT_100mA)) {
  81. chip->max_current = 0;
  82. gpio_set_value_cansleep(chip->gpio_mode_select_d0, 1);
  83. gpio_set_value_cansleep(chip->gpio_mode_select_d1, 1);
  84. } else if (value < MAX_CURRENT_MA(LTC4088_MAX_CURRENT_500mA)) {
  85. chip->max_current = MAX_CURRENT_MA(LTC4088_MAX_CURRENT_100mA);
  86. gpio_set_value_cansleep(chip->gpio_mode_select_d0, 0);
  87. gpio_set_value_cansleep(chip->gpio_mode_select_d1, 0);
  88. } else if (value < MAX_CURRENT_MA(LTC4088_MAX_CURRENT_1A)) {
  89. chip->max_current = MAX_CURRENT_MA(LTC4088_MAX_CURRENT_500mA);
  90. gpio_set_value_cansleep(chip->gpio_mode_select_d0, 0);
  91. gpio_set_value_cansleep(chip->gpio_mode_select_d1, 1);
  92. } else {
  93. chip->max_current = MAX_CURRENT_MA(LTC4088_MAX_CURRENT_1A);
  94. gpio_set_value_cansleep(chip->gpio_mode_select_d0, 1);
  95. gpio_set_value_cansleep(chip->gpio_mode_select_d1, 0);
  96. }
  97. mutex_unlock(&chip->lock);
  98. }
  99. static void ltc4088_set_charging_off(struct ltc4088_chg_chip *chip)
  100. {
  101. gpio_set_value_cansleep(chip->gpio_mode_select_d0, 1);
  102. gpio_set_value_cansleep(chip->gpio_mode_select_d1, 1);
  103. }
  104. static int ltc4088_set_initial_state(struct ltc4088_chg_chip *chip)
  105. {
  106. int rc;
  107. rc = gpio_request(chip->gpio_mode_select_d0, "ltc4088_D0");
  108. if (rc) {
  109. pr_err("gpio request failed for GPIO %d\n",
  110. chip->gpio_mode_select_d0);
  111. return rc;
  112. }
  113. rc = gpio_request(chip->gpio_mode_select_d1, "ltc4088_D1");
  114. if (rc) {
  115. pr_err("gpio request failed for GPIO %d\n",
  116. chip->gpio_mode_select_d1);
  117. goto gpio_err_d0;
  118. }
  119. rc = gpio_request(chip->gpio_mode_select_d2, "ltc4088_D2");
  120. if (rc) {
  121. pr_err("gpio request failed for GPIO %d\n",
  122. chip->gpio_mode_select_d2);
  123. goto gpio_err_d1;
  124. }
  125. rc = gpio_direction_output(chip->gpio_mode_select_d0, 0);
  126. if (rc) {
  127. pr_err("failed to set direction for GPIO %d\n",
  128. chip->gpio_mode_select_d0);
  129. goto gpio_err_d2;
  130. }
  131. rc = gpio_direction_output(chip->gpio_mode_select_d1, 0);
  132. if (rc) {
  133. pr_err("failed to set direction for GPIO %d\n",
  134. chip->gpio_mode_select_d1);
  135. goto gpio_err_d2;
  136. }
  137. rc = gpio_direction_output(chip->gpio_mode_select_d2, 1);
  138. if (rc) {
  139. pr_err("failed to set direction for GPIO %d\n",
  140. chip->gpio_mode_select_d2);
  141. goto gpio_err_d2;
  142. }
  143. return 0;
  144. gpio_err_d2:
  145. gpio_free(chip->gpio_mode_select_d2);
  146. gpio_err_d1:
  147. gpio_free(chip->gpio_mode_select_d1);
  148. gpio_err_d0:
  149. gpio_free(chip->gpio_mode_select_d0);
  150. return rc;
  151. }
  152. static int pm_power_get_property(struct power_supply *psy,
  153. enum power_supply_property psp,
  154. union power_supply_propval *val)
  155. {
  156. struct ltc4088_chg_chip *chip;
  157. if (psy->type == POWER_SUPPLY_TYPE_USB) {
  158. chip = container_of(psy, struct ltc4088_chg_chip,
  159. usb_psy);
  160. switch (psp) {
  161. case POWER_SUPPLY_PROP_ONLINE:
  162. if (chip->max_current)
  163. val->intval = 1;
  164. else
  165. val->intval = 0;
  166. break;
  167. case POWER_SUPPLY_PROP_CURRENT_MAX:
  168. val->intval = chip->max_current;
  169. break;
  170. default:
  171. return -EINVAL;
  172. }
  173. }
  174. return 0;
  175. }
  176. static int pm_power_set_property(struct power_supply *psy,
  177. enum power_supply_property psp,
  178. const union power_supply_propval *val)
  179. {
  180. struct ltc4088_chg_chip *chip;
  181. if (psy->type == POWER_SUPPLY_TYPE_USB) {
  182. chip = container_of(psy, struct ltc4088_chg_chip, usb_psy);
  183. switch (psp) {
  184. case POWER_SUPPLY_PROP_TYPE:
  185. psy.type = val->intval;
  186. break;
  187. case POWER_SUPPLY_PROP_ONLINE:
  188. ltc4088_set_charging(chip, val->intval);
  189. break;
  190. case POWER_SUPPLY_PROP_CURRENT_MAX:
  191. ltc4088_set_max_current(chip, val->intval);
  192. break;
  193. default:
  194. return -EINVAL;
  195. }
  196. }
  197. return 0;
  198. }
  199. static int __devinit ltc4088_charger_probe(struct platform_device *pdev)
  200. {
  201. int rc;
  202. struct ltc4088_chg_chip *chip;
  203. const struct ltc4088_charger_platform_data *pdata
  204. = pdev->dev.platform_data;
  205. if (!pdata) {
  206. pr_err("missing platform data\n");
  207. return -EINVAL;
  208. }
  209. chip = kzalloc(sizeof(struct ltc4088_chg_chip),
  210. GFP_KERNEL);
  211. if (!chip) {
  212. pr_err("Cannot allocate pm_chg_chip\n");
  213. return -ENOMEM;
  214. }
  215. chip->dev = &pdev->dev;
  216. if (pdata->gpio_mode_select_d0 < 0 ||
  217. pdata->gpio_mode_select_d1 < 0 ||
  218. pdata->gpio_mode_select_d2 < 0) {
  219. pr_err("Invalid platform data supplied\n");
  220. rc = -EINVAL;
  221. goto free_chip;
  222. }
  223. mutex_init(&chip->lock);
  224. chip->gpio_mode_select_d0 = pdata->gpio_mode_select_d0;
  225. chip->gpio_mode_select_d1 = pdata->gpio_mode_select_d1;
  226. chip->gpio_mode_select_d2 = pdata->gpio_mode_select_d2;
  227. chip->usb_psy.name = "usb",
  228. chip->usb_psy.type = POWER_SUPPLY_TYPE_USB,
  229. chip->usb_psy.supplied_to = pm_power_supplied_to,
  230. chip->usb_psy.num_supplicants = ARRAY_SIZE(pm_power_supplied_to),
  231. chip->usb_psy.properties = pm_power_props,
  232. chip->usb_psy.num_properties = ARRAY_SIZE(pm_power_props),
  233. chip->usb_psy.get_property = pm_power_get_property,
  234. chip->usb_psy.set_property = pm_power_set_property,
  235. rc = power_supply_register(chip->dev, &chip->usb_psy);
  236. if (rc < 0) {
  237. pr_err("power_supply_register usb failed rc = %d\n", rc);
  238. goto free_chip;
  239. }
  240. platform_set_drvdata(pdev, chip);
  241. rc = ltc4088_set_initial_state(chip);
  242. if (rc < 0) {
  243. pr_err("setting initial state failed rc = %d\n", rc);
  244. goto unregister_usb;
  245. }
  246. return 0;
  247. unregister_usb:
  248. platform_set_drvdata(pdev, NULL);
  249. power_supply_unregister(&chip->usb_psy);
  250. free_chip:
  251. kfree(chip);
  252. return rc;
  253. }
  254. static int __devexit ltc4088_charger_remove(struct platform_device *pdev)
  255. {
  256. struct ltc4088_chg_chip *chip = platform_get_drvdata(pdev);
  257. ltc4088_set_charging_off(chip);
  258. gpio_free(chip->gpio_mode_select_d2);
  259. gpio_free(chip->gpio_mode_select_d1);
  260. gpio_free(chip->gpio_mode_select_d0);
  261. power_supply_unregister(&chip->usb_psy);
  262. platform_set_drvdata(pdev, NULL);
  263. mutex_destroy(&chip->lock);
  264. kfree(chip);
  265. return 0;
  266. }
  267. static struct platform_driver ltc4088_charger_driver = {
  268. .probe = ltc4088_charger_probe,
  269. .remove = __devexit_p(ltc4088_charger_remove),
  270. .driver = {
  271. .name = LTC4088_CHARGER_DEV_NAME,
  272. .owner = THIS_MODULE,
  273. },
  274. };
  275. static int __init ltc4088_charger_init(void)
  276. {
  277. return platform_driver_register(&ltc4088_charger_driver);
  278. }
  279. static void __exit ltc4088_charger_exit(void)
  280. {
  281. platform_driver_unregister(&ltc4088_charger_driver);
  282. }
  283. subsys_initcall(ltc4088_charger_init);
  284. module_exit(ltc4088_charger_exit);
  285. MODULE_LICENSE("GPL v2");
  286. MODULE_DESCRIPTION("LTC4088 charger/battery driver");
  287. MODULE_VERSION("1.0");
  288. MODULE_ALIAS("platform:" LTC4088_CHARGER_DEV_NAME);