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