Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

regulator: TI bq24022 Li-Ion Charger driver

This adds a regulator driver for the TI bq24022 Single-Chip
Li-Ion Charger with its nCE and ISET2 pins connected to GPIOs.

Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
Signed-off-by: Liam Girdwood <lg@opensource.wolfsonmicro.com>

authored by

Philipp Zabel and committed by
Liam Girdwood
0eb5d5ab e53e86c7

+200
+10
drivers/regulator/Kconfig
··· 46 46 47 47 If unsure, say no. 48 48 49 + config REGULATOR_BQ24022 50 + tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC" 51 + default n 52 + select REGULATOR 53 + help 54 + This driver controls a TI bq24022 Charger attached via 55 + GPIOs. The provided current regulator can enable/disable 56 + charging select between 100 mA and 500 mA charging current 57 + limit. 58 + 49 59 endmenu
+2
drivers/regulator/Makefile
··· 7 7 obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o 8 8 obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o 9 9 10 + obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o 11 + 10 12 ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
+167
drivers/regulator/bq24022.c
··· 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 + static int bq24022_set_current_limit(struct regulator_dev *rdev, 22 + int min_uA, int max_uA) 23 + { 24 + struct platform_device *pdev = rdev_get_drvdata(rdev); 25 + struct bq24022_mach_info *pdata = pdev->dev.platform_data; 26 + 27 + dev_dbg(&pdev->dev, "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 + 35 + static int bq24022_get_current_limit(struct regulator_dev *rdev) 36 + { 37 + struct platform_device *pdev = rdev_get_drvdata(rdev); 38 + struct bq24022_mach_info *pdata = pdev->dev.platform_data; 39 + 40 + return gpio_get_value(pdata->gpio_iset2) ? 500000 : 100000; 41 + } 42 + 43 + static int bq24022_enable(struct regulator_dev *rdev) 44 + { 45 + struct platform_device *pdev = rdev_get_drvdata(rdev); 46 + struct bq24022_mach_info *pdata = pdev->dev.platform_data; 47 + 48 + dev_dbg(&pdev->dev, "enabling charger\n"); 49 + 50 + gpio_set_value(pdata->gpio_nce, 0); 51 + return 0; 52 + } 53 + 54 + static int bq24022_disable(struct regulator_dev *rdev) 55 + { 56 + struct platform_device *pdev = rdev_get_drvdata(rdev); 57 + struct bq24022_mach_info *pdata = pdev->dev.platform_data; 58 + 59 + dev_dbg(&pdev->dev, "disabling charger\n"); 60 + 61 + gpio_set_value(pdata->gpio_nce, 1); 62 + return 0; 63 + } 64 + 65 + static int bq24022_is_enabled(struct regulator_dev *rdev) 66 + { 67 + struct platform_device *pdev = rdev_get_drvdata(rdev); 68 + struct bq24022_mach_info *pdata = pdev->dev.platform_data; 69 + 70 + return !gpio_get_value(pdata->gpio_nce); 71 + } 72 + 73 + static struct regulator_ops bq24022_ops = { 74 + .set_current_limit = bq24022_set_current_limit, 75 + .get_current_limit = bq24022_get_current_limit, 76 + .enable = bq24022_enable, 77 + .disable = bq24022_disable, 78 + .is_enabled = bq24022_is_enabled, 79 + }; 80 + 81 + static struct regulator_desc bq24022_desc = { 82 + .name = "bq24022", 83 + .ops = &bq24022_ops, 84 + .type = REGULATOR_CURRENT, 85 + }; 86 + 87 + static int __init bq24022_probe(struct platform_device *pdev) 88 + { 89 + struct bq24022_mach_info *pdata = pdev->dev.platform_data; 90 + struct regulator_dev *bq24022; 91 + int ret; 92 + 93 + if (!pdata || !pdata->gpio_nce || !pdata->gpio_iset2) 94 + return -EINVAL; 95 + 96 + ret = gpio_request(pdata->gpio_nce, "ncharge_en"); 97 + if (ret) { 98 + dev_dbg(&pdev->dev, "couldn't request nCE GPIO: %d\n", 99 + pdata->gpio_nce); 100 + goto err_ce; 101 + } 102 + ret = gpio_request(pdata->gpio_iset2, "charge_mode"); 103 + if (ret) { 104 + dev_dbg(&pdev->dev, "couldn't request ISET2 GPIO: %d\n", 105 + pdata->gpio_iset2); 106 + goto err_iset2; 107 + } 108 + ret = gpio_direction_output(pdata->gpio_iset2, 0); 109 + ret = gpio_direction_output(pdata->gpio_nce, 1); 110 + 111 + bq24022 = regulator_register(&bq24022_desc, pdev); 112 + if (IS_ERR(bq24022)) { 113 + dev_dbg(&pdev->dev, "couldn't register regulator\n"); 114 + ret = PTR_ERR(bq24022); 115 + goto err_reg; 116 + } 117 + platform_set_drvdata(pdev, bq24022); 118 + dev_dbg(&pdev->dev, "registered regulator\n"); 119 + 120 + return 0; 121 + err_reg: 122 + gpio_free(pdata->gpio_iset2); 123 + err_iset2: 124 + gpio_free(pdata->gpio_nce); 125 + err_ce: 126 + return ret; 127 + } 128 + 129 + static int __devexit bq24022_remove(struct platform_device *pdev) 130 + { 131 + struct bq24022_mach_info *pdata = pdev->dev.platform_data; 132 + struct regulator_dev *bq24022 = platform_get_drvdata(pdev); 133 + 134 + regulator_unregister(bq24022); 135 + gpio_free(pdata->gpio_iset2); 136 + gpio_free(pdata->gpio_nce); 137 + 138 + return 0; 139 + } 140 + 141 + static struct platform_driver bq24022_driver = { 142 + .driver = { 143 + .name = "bq24022", 144 + }, 145 + .remove = __devexit_p(bq24022_remove), 146 + }; 147 + 148 + static int __init bq24022_init(void) 149 + { 150 + return platform_driver_probe(&bq24022_driver, bq24022_probe); 151 + } 152 + 153 + static void __exit bq24022_exit(void) 154 + { 155 + platform_driver_unregister(&bq24022_driver); 156 + } 157 + 158 + /* 159 + * make sure this is probed before gpio_vbus and pda_power, 160 + * but after asic3 or other GPIO expander drivers. 161 + */ 162 + subsys_initcall(bq24022_init); 163 + module_exit(bq24022_exit); 164 + 165 + MODULE_AUTHOR("Philipp Zabel"); 166 + MODULE_DESCRIPTION("TI bq24022 Li-Ion Charger driver"); 167 + MODULE_LICENSE("GPL");
+21
include/linux/regulator/bq24022.h
··· 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 + /** 14 + * bq24022_mach_info - platform data for bq24022 15 + * @gpio_nce: GPIO line connected to the nCE pin, used to enable / disable charging 16 + * @gpio_iset2: GPIO line connected to the ISET2 pin, used to limit charging current to 100 mA / 500 mA 17 + */ 18 + struct bq24022_mach_info { 19 + int gpio_nce; 20 + int gpio_iset2; 21 + };