bq24022.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. * Support for TI bq24022 (bqTINY-II) Dual Input (USB/AC Adpater)
  3. * 1-Cell Li-Ion Charger connected via GPIOs.
  4. *
  5. * Copyright (c) 2008 Philipp Zabel
  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. */
  12. #include <linux/kernel.h>
  13. #include <linux/init.h>
  14. #include <linux/platform_device.h>
  15. #include <linux/err.h>
  16. #include <linux/module.h>
  17. #include <linux/gpio.h>
  18. #include <linux/regulator/bq24022.h>
  19. #include <linux/regulator/driver.h>
  20. static int bq24022_set_current_limit(struct regulator_dev *rdev,
  21. int min_uA, int max_uA)
  22. {
  23. struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev);
  24. dev_dbg(rdev_get_dev(rdev), "setting current limit to %s mA\n",
  25. max_uA >= 500000 ? "500" : "100");
  26. /* REVISIT: maybe return error if min_uA != 0 ? */
  27. gpio_set_value(pdata->gpio_iset2, max_uA >= 500000);
  28. return 0;
  29. }
  30. static int bq24022_get_current_limit(struct regulator_dev *rdev)
  31. {
  32. struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev);
  33. return gpio_get_value(pdata->gpio_iset2) ? 500000 : 100000;
  34. }
  35. static int bq24022_enable(struct regulator_dev *rdev)
  36. {
  37. struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev);
  38. dev_dbg(rdev_get_dev(rdev), "enabling charger\n");
  39. gpio_set_value(pdata->gpio_nce, 0);
  40. return 0;
  41. }
  42. static int bq24022_disable(struct regulator_dev *rdev)
  43. {
  44. struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev);
  45. dev_dbg(rdev_get_dev(rdev), "disabling charger\n");
  46. gpio_set_value(pdata->gpio_nce, 1);
  47. return 0;
  48. }
  49. static int bq24022_is_enabled(struct regulator_dev *rdev)
  50. {
  51. struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev);
  52. return !gpio_get_value(pdata->gpio_nce);
  53. }
  54. static struct regulator_ops bq24022_ops = {
  55. .set_current_limit = bq24022_set_current_limit,
  56. .get_current_limit = bq24022_get_current_limit,
  57. .enable = bq24022_enable,
  58. .disable = bq24022_disable,
  59. .is_enabled = bq24022_is_enabled,
  60. };
  61. static struct regulator_desc bq24022_desc = {
  62. .name = "bq24022",
  63. .ops = &bq24022_ops,
  64. .type = REGULATOR_CURRENT,
  65. .owner = THIS_MODULE,
  66. };
  67. static int __init bq24022_probe(struct platform_device *pdev)
  68. {
  69. struct bq24022_mach_info *pdata = pdev->dev.platform_data;
  70. struct regulator_dev *bq24022;
  71. int ret;
  72. if (!pdata || !pdata->gpio_nce || !pdata->gpio_iset2)
  73. return -EINVAL;
  74. ret = gpio_request(pdata->gpio_nce, "ncharge_en");
  75. if (ret) {
  76. dev_dbg(&pdev->dev, "couldn't request nCE GPIO: %d\n",
  77. pdata->gpio_nce);
  78. goto err_ce;
  79. }
  80. ret = gpio_request(pdata->gpio_iset2, "charge_mode");
  81. if (ret) {
  82. dev_dbg(&pdev->dev, "couldn't request ISET2 GPIO: %d\n",
  83. pdata->gpio_iset2);
  84. goto err_iset2;
  85. }
  86. ret = gpio_direction_output(pdata->gpio_iset2, 0);
  87. ret = gpio_direction_output(pdata->gpio_nce, 1);
  88. bq24022 = regulator_register(&bq24022_desc, &pdev->dev,
  89. pdata->init_data, pdata);
  90. if (IS_ERR(bq24022)) {
  91. dev_dbg(&pdev->dev, "couldn't register regulator\n");
  92. ret = PTR_ERR(bq24022);
  93. goto err_reg;
  94. }
  95. platform_set_drvdata(pdev, bq24022);
  96. dev_dbg(&pdev->dev, "registered regulator\n");
  97. return 0;
  98. err_reg:
  99. gpio_free(pdata->gpio_iset2);
  100. err_iset2:
  101. gpio_free(pdata->gpio_nce);
  102. err_ce:
  103. return ret;
  104. }
  105. static int __devexit bq24022_remove(struct platform_device *pdev)
  106. {
  107. struct bq24022_mach_info *pdata = pdev->dev.platform_data;
  108. struct regulator_dev *bq24022 = platform_get_drvdata(pdev);
  109. regulator_unregister(bq24022);
  110. gpio_free(pdata->gpio_iset2);
  111. gpio_free(pdata->gpio_nce);
  112. return 0;
  113. }
  114. static struct platform_driver bq24022_driver = {
  115. .driver = {
  116. .name = "bq24022",
  117. },
  118. .remove = __devexit_p(bq24022_remove),
  119. };
  120. static int __init bq24022_init(void)
  121. {
  122. return platform_driver_probe(&bq24022_driver, bq24022_probe);
  123. }
  124. static void __exit bq24022_exit(void)
  125. {
  126. platform_driver_unregister(&bq24022_driver);
  127. }
  128. module_init(bq24022_init);
  129. module_exit(bq24022_exit);
  130. MODULE_AUTHOR("Philipp Zabel");
  131. MODULE_DESCRIPTION("TI bq24022 Li-Ion Charger driver");
  132. MODULE_LICENSE("GPL");