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

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.27-rc9 167 lines 4.3 kB view raw
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 21static 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 35static 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 43static 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 54static 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 65static 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 73static 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 81static struct regulator_desc bq24022_desc = { 82 .name = "bq24022", 83 .ops = &bq24022_ops, 84 .type = REGULATOR_CURRENT, 85}; 86 87static 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; 121err_reg: 122 gpio_free(pdata->gpio_iset2); 123err_iset2: 124 gpio_free(pdata->gpio_nce); 125err_ce: 126 return ret; 127} 128 129static 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 141static struct platform_driver bq24022_driver = { 142 .driver = { 143 .name = "bq24022", 144 }, 145 .remove = __devexit_p(bq24022_remove), 146}; 147 148static int __init bq24022_init(void) 149{ 150 return platform_driver_probe(&bq24022_driver, bq24022_probe); 151} 152 153static 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 */ 162subsys_initcall(bq24022_init); 163module_exit(bq24022_exit); 164 165MODULE_AUTHOR("Philipp Zabel"); 166MODULE_DESCRIPTION("TI bq24022 Li-Ion Charger driver"); 167MODULE_LICENSE("GPL");