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 .owner = THIS_MODULE, 82}; 83 84static int __init bq24022_probe(struct platform_device *pdev) 85{ 86 struct bq24022_mach_info *pdata = pdev->dev.platform_data; 87 struct regulator_dev *bq24022; 88 int ret; 89 90 if (!pdata || !pdata->gpio_nce || !pdata->gpio_iset2) 91 return -EINVAL; 92 93 ret = gpio_request(pdata->gpio_nce, "ncharge_en"); 94 if (ret) { 95 dev_dbg(&pdev->dev, "couldn't request nCE GPIO: %d\n", 96 pdata->gpio_nce); 97 goto err_ce; 98 } 99 ret = gpio_request(pdata->gpio_iset2, "charge_mode"); 100 if (ret) { 101 dev_dbg(&pdev->dev, "couldn't request ISET2 GPIO: %d\n", 102 pdata->gpio_iset2); 103 goto err_iset2; 104 } 105 ret = gpio_direction_output(pdata->gpio_iset2, 0); 106 ret = gpio_direction_output(pdata->gpio_nce, 1); 107 108 bq24022 = regulator_register(&bq24022_desc, &pdev->dev, 109 pdata->init_data, pdata); 110 if (IS_ERR(bq24022)) { 111 dev_dbg(&pdev->dev, "couldn't register regulator\n"); 112 ret = PTR_ERR(bq24022); 113 goto err_reg; 114 } 115 platform_set_drvdata(pdev, bq24022); 116 dev_dbg(&pdev->dev, "registered regulator\n"); 117 118 return 0; 119err_reg: 120 gpio_free(pdata->gpio_iset2); 121err_iset2: 122 gpio_free(pdata->gpio_nce); 123err_ce: 124 return ret; 125} 126 127static int __devexit bq24022_remove(struct platform_device *pdev) 128{ 129 struct bq24022_mach_info *pdata = pdev->dev.platform_data; 130 struct regulator_dev *bq24022 = platform_get_drvdata(pdev); 131 132 regulator_unregister(bq24022); 133 gpio_free(pdata->gpio_iset2); 134 gpio_free(pdata->gpio_nce); 135 136 return 0; 137} 138 139static struct platform_driver bq24022_driver = { 140 .driver = { 141 .name = "bq24022", 142 }, 143 .remove = __devexit_p(bq24022_remove), 144}; 145 146static int __init bq24022_init(void) 147{ 148 return platform_driver_probe(&bq24022_driver, bq24022_probe); 149} 150 151static void __exit bq24022_exit(void) 152{ 153 platform_driver_unregister(&bq24022_driver); 154} 155 156module_init(bq24022_init); 157module_exit(bq24022_exit); 158 159MODULE_AUTHOR("Philipp Zabel"); 160MODULE_DESCRIPTION("TI bq24022 Li-Ion Charger driver"); 161MODULE_LICENSE("GPL"); 162