Blame view
drivers/power/gpio-charger.c
4.88 KB
5070437cd power_supply: Add... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
/* * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de> * Driver for chargers which report their online status through a GPIO pin * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include <linux/device.h> #include <linux/gpio.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/power_supply.h> #include <linux/slab.h> #include <linux/power/gpio-charger.h> struct gpio_charger { const struct gpio_charger_platform_data *pdata; unsigned int irq; struct power_supply charger; }; static irqreturn_t gpio_charger_irq(int irq, void *devid) { struct power_supply *charger = devid; power_supply_changed(charger); return IRQ_HANDLED; } static inline struct gpio_charger *psy_to_gpio_charger(struct power_supply *psy) { return container_of(psy, struct gpio_charger, charger); } static int gpio_charger_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) { struct gpio_charger *gpio_charger = psy_to_gpio_charger(psy); const struct gpio_charger_platform_data *pdata = gpio_charger->pdata; switch (psp) { case POWER_SUPPLY_PROP_ONLINE: |
ecb7a8ebd gpio-charger: Use... |
57 |
val->intval = gpio_get_value_cansleep(pdata->gpio); |
5070437cd power_supply: Add... |
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
val->intval ^= pdata->gpio_active_low; break; default: return -EINVAL; } return 0; } static enum power_supply_property gpio_charger_properties[] = { POWER_SUPPLY_PROP_ONLINE, }; static int __devinit gpio_charger_probe(struct platform_device *pdev) { const struct gpio_charger_platform_data *pdata = pdev->dev.platform_data; struct gpio_charger *gpio_charger; struct power_supply *charger; int ret; int irq; if (!pdata) { dev_err(&pdev->dev, "No platform data "); return -EINVAL; } if (!gpio_is_valid(pdata->gpio)) { dev_err(&pdev->dev, "Invalid gpio pin "); return -EINVAL; } gpio_charger = kzalloc(sizeof(*gpio_charger), GFP_KERNEL); |
2e9ff5f5e gpio-charger: Che... |
92 93 94 95 96 |
if (!gpio_charger) { dev_err(&pdev->dev, "Failed to alloc driver structure "); return -ENOMEM; } |
5070437cd power_supply: Add... |
97 98 |
charger = &gpio_charger->charger; |
80577b8a4 gpio-charger: Pro... |
99 |
charger->name = pdata->name ? pdata->name : "gpio-charger"; |
5070437cd power_supply: Add... |
100 101 102 |
charger->type = pdata->type; charger->properties = gpio_charger_properties; charger->num_properties = ARRAY_SIZE(gpio_charger_properties); |
26eb38726 gpio-charger: Fix... |
103 |
charger->get_property = gpio_charger_get_property; |
5070437cd power_supply: Add... |
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
charger->supplied_to = pdata->supplied_to; charger->num_supplicants = pdata->num_supplicants; ret = gpio_request(pdata->gpio, dev_name(&pdev->dev)); if (ret) { dev_err(&pdev->dev, "Failed to request gpio pin: %d ", ret); goto err_free; } ret = gpio_direction_input(pdata->gpio); if (ret) { dev_err(&pdev->dev, "Failed to set gpio to input: %d ", ret); goto err_gpio_free; } |
26eb38726 gpio-charger: Fix... |
119 120 121 122 123 124 125 126 127 |
gpio_charger->pdata = pdata; ret = power_supply_register(&pdev->dev, charger); if (ret < 0) { dev_err(&pdev->dev, "Failed to register power supply: %d ", ret); goto err_gpio_free; } |
5070437cd power_supply: Add... |
128 129 |
irq = gpio_to_irq(pdata->gpio); if (irq > 0) { |
26eb38726 gpio-charger: Fix... |
130 |
ret = request_any_context_irq(irq, gpio_charger_irq, |
5070437cd power_supply: Add... |
131 132 |
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, dev_name(&pdev->dev), charger); |
f8c63918c gpio-charger: Fix... |
133 |
if (ret < 0) |
5070437cd power_supply: Add... |
134 135 136 137 138 |
dev_warn(&pdev->dev, "Failed to request irq: %d ", ret); else gpio_charger->irq = irq; } |
5070437cd power_supply: Add... |
139 140 141 |
platform_set_drvdata(pdev, gpio_charger); return 0; |
5070437cd power_supply: Add... |
142 143 144 145 146 147 148 149 150 151 |
err_gpio_free: gpio_free(pdata->gpio); err_free: kfree(gpio_charger); return ret; } static int __devexit gpio_charger_remove(struct platform_device *pdev) { struct gpio_charger *gpio_charger = platform_get_drvdata(pdev); |
5070437cd power_supply: Add... |
152 153 |
if (gpio_charger->irq) free_irq(gpio_charger->irq, &gpio_charger->charger); |
26eb38726 gpio-charger: Fix... |
154 155 |
power_supply_unregister(&gpio_charger->charger); |
5070437cd power_supply: Add... |
156 157 158 159 160 161 162 |
gpio_free(gpio_charger->pdata->gpio); platform_set_drvdata(pdev, NULL); kfree(gpio_charger); return 0; } |
f10513de2 gpio-charger: Add... |
163 164 165 166 167 168 169 170 171 172 173 174 175 |
#ifdef CONFIG_PM_SLEEP static int gpio_charger_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct gpio_charger *gpio_charger = platform_get_drvdata(pdev); power_supply_changed(&gpio_charger->charger); return 0; } #endif static SIMPLE_DEV_PM_OPS(gpio_charger_pm_ops, NULL, gpio_charger_resume); |
5070437cd power_supply: Add... |
176 177 178 179 180 181 |
static struct platform_driver gpio_charger_driver = { .probe = gpio_charger_probe, .remove = __devexit_p(gpio_charger_remove), .driver = { .name = "gpio-charger", .owner = THIS_MODULE, |
f10513de2 gpio-charger: Add... |
182 |
.pm = &gpio_charger_pm_ops, |
5070437cd power_supply: Add... |
183 184 |
}, }; |
300bac7fb power_supply: Con... |
185 |
module_platform_driver(gpio_charger_driver); |
5070437cd power_supply: Add... |
186 187 188 189 190 |
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); MODULE_DESCRIPTION("Driver for chargers which report their online status through a GPIO"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:gpio-charger"); |