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