1b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham/* 2b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham * max8903_charger.c - Maxim 8903 USB/Adapter Charger Driver 3b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham * 4b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham * Copyright (C) 2011 Samsung Electronics 5b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham * MyungJoo Ham <myungjoo.ham@samsung.com> 6b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham * 7b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham * This program is free software; you can redistribute it and/or modify 8b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham * it under the terms of the GNU General Public License as published by 9b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham * the Free Software Foundation; either version 2 of the License, or 10b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham * (at your option) any later version. 11b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham * 12b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham * This program is distributed in the hope that it will be useful, 13b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham * but WITHOUT ANY WARRANTY; without even the implied warranty of 14b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham * GNU General Public License for more details. 16b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham * 17b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham * You should have received a copy of the GNU General Public License 18b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham * along with this program; if not, write to the Free Software 19b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham * 21b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham */ 22b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 23b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham#include <linux/gpio.h> 24b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham#include <linux/interrupt.h> 257e6d62db5efecded2dd4606ff2ff3726b9c52505Paul Gortmaker#include <linux/module.h> 26b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham#include <linux/slab.h> 27b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham#include <linux/power_supply.h> 28b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham#include <linux/platform_device.h> 29b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham#include <linux/power/max8903_charger.h> 30b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 31b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Hamstruct max8903_data { 32464f29a21792e0e506d936d147beea72a5f8e904MyungJoo Ham struct max8903_pdata pdata; 33b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham struct device *dev; 34b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham struct power_supply psy; 35b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham bool fault; 36b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham bool usb_in; 37b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham bool ta_in; 38b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham}; 39b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 40b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Hamstatic enum power_supply_property max8903_charger_props[] = { 41b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham POWER_SUPPLY_PROP_STATUS, /* Charger status output */ 42b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham POWER_SUPPLY_PROP_ONLINE, /* External power source */ 43b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham POWER_SUPPLY_PROP_HEALTH, /* Fault or OK */ 44b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham}; 45b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 46b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Hamstatic int max8903_get_property(struct power_supply *psy, 47b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham enum power_supply_property psp, 48b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham union power_supply_propval *val) 49b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham{ 50b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham struct max8903_data *data = container_of(psy, 51b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham struct max8903_data, psy); 52b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 53b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham switch (psp) { 54b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham case POWER_SUPPLY_PROP_STATUS: 55b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham val->intval = POWER_SUPPLY_STATUS_UNKNOWN; 56464f29a21792e0e506d936d147beea72a5f8e904MyungJoo Ham if (data->pdata.chg) { 57464f29a21792e0e506d936d147beea72a5f8e904MyungJoo Ham if (gpio_get_value(data->pdata.chg) == 0) 58b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham val->intval = POWER_SUPPLY_STATUS_CHARGING; 59b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham else if (data->usb_in || data->ta_in) 60b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 61b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham else 62b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 63b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 64b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham break; 65b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham case POWER_SUPPLY_PROP_ONLINE: 66b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham val->intval = 0; 67b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (data->usb_in || data->ta_in) 68b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham val->intval = 1; 69b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham break; 70b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham case POWER_SUPPLY_PROP_HEALTH: 71b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham val->intval = POWER_SUPPLY_HEALTH_GOOD; 72b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (data->fault) 73b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; 74b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham break; 75b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham default: 76b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham return -EINVAL; 77b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 78b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham return 0; 79b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham} 80b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 81b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Hamstatic irqreturn_t max8903_dcin(int irq, void *_data) 82b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham{ 83b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham struct max8903_data *data = _data; 84464f29a21792e0e506d936d147beea72a5f8e904MyungJoo Ham struct max8903_pdata *pdata = &data->pdata; 85b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham bool ta_in; 86b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham enum power_supply_type old_type; 87b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 88b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham ta_in = gpio_get_value(pdata->dok) ? false : true; 89b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 90b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (ta_in == data->ta_in) 91b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham return IRQ_HANDLED; 92b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 93b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham data->ta_in = ta_in; 94b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 95b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham /* Set Current-Limit-Mode 1:DC 0:USB */ 96b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (pdata->dcm) 97b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham gpio_set_value(pdata->dcm, ta_in ? 1 : 0); 98b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 99b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham /* Charger Enable / Disable (cen is negated) */ 100b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (pdata->cen) 101b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham gpio_set_value(pdata->cen, ta_in ? 0 : 102b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham (data->usb_in ? 0 : 1)); 103b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 104b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham dev_dbg(data->dev, "TA(DC-IN) Charger %s.\n", ta_in ? 105b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham "Connected" : "Disconnected"); 106b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 107b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham old_type = data->psy.type; 108b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 109b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (data->ta_in) 110b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham data->psy.type = POWER_SUPPLY_TYPE_MAINS; 111b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham else if (data->usb_in) 112b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham data->psy.type = POWER_SUPPLY_TYPE_USB; 113b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham else 114b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham data->psy.type = POWER_SUPPLY_TYPE_BATTERY; 115b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 116b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (old_type != data->psy.type) 117b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham power_supply_changed(&data->psy); 118b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 119b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham return IRQ_HANDLED; 120b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham} 121b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 122b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Hamstatic irqreturn_t max8903_usbin(int irq, void *_data) 123b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham{ 124b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham struct max8903_data *data = _data; 125464f29a21792e0e506d936d147beea72a5f8e904MyungJoo Ham struct max8903_pdata *pdata = &data->pdata; 126b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham bool usb_in; 127b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham enum power_supply_type old_type; 128b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 129b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham usb_in = gpio_get_value(pdata->uok) ? false : true; 130b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 131b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (usb_in == data->usb_in) 132b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham return IRQ_HANDLED; 133b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 134b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham data->usb_in = usb_in; 135b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 136b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham /* Do not touch Current-Limit-Mode */ 137b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 138b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham /* Charger Enable / Disable (cen is negated) */ 139b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (pdata->cen) 140b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham gpio_set_value(pdata->cen, usb_in ? 0 : 141b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham (data->ta_in ? 0 : 1)); 142b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 143b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham dev_dbg(data->dev, "USB Charger %s.\n", usb_in ? 144b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham "Connected" : "Disconnected"); 145b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 146b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham old_type = data->psy.type; 147b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 148b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (data->ta_in) 149b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham data->psy.type = POWER_SUPPLY_TYPE_MAINS; 150b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham else if (data->usb_in) 151b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham data->psy.type = POWER_SUPPLY_TYPE_USB; 152b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham else 153b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham data->psy.type = POWER_SUPPLY_TYPE_BATTERY; 154b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 155b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (old_type != data->psy.type) 156b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham power_supply_changed(&data->psy); 157b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 158b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham return IRQ_HANDLED; 159b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham} 160b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 161b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Hamstatic irqreturn_t max8903_fault(int irq, void *_data) 162b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham{ 163b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham struct max8903_data *data = _data; 164464f29a21792e0e506d936d147beea72a5f8e904MyungJoo Ham struct max8903_pdata *pdata = &data->pdata; 165b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham bool fault; 166b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 167b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham fault = gpio_get_value(pdata->flt) ? false : true; 168b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 169b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (fault == data->fault) 170b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham return IRQ_HANDLED; 171b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 172b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham data->fault = fault; 173b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 174b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (fault) 175b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham dev_err(data->dev, "Charger suffers a fault and stops.\n"); 176b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham else 177b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham dev_err(data->dev, "Charger recovered from a fault.\n"); 178b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 179b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham return IRQ_HANDLED; 180b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham} 181b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 182b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Hamstatic __devinit int max8903_probe(struct platform_device *pdev) 183b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham{ 184b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham struct max8903_data *data; 185b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham struct device *dev = &pdev->dev; 186b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham struct max8903_pdata *pdata = pdev->dev.platform_data; 187b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham int ret = 0; 188b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham int gpio; 189b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham int ta_in = 0; 190b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham int usb_in = 0; 191b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 192b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham data = kzalloc(sizeof(struct max8903_data), GFP_KERNEL); 193b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (data == NULL) { 194b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham dev_err(dev, "Cannot allocate memory.\n"); 195b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham return -ENOMEM; 196b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 197464f29a21792e0e506d936d147beea72a5f8e904MyungJoo Ham memcpy(&data->pdata, pdata, sizeof(struct max8903_pdata)); 198b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham data->dev = dev; 199b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham platform_set_drvdata(pdev, data); 200b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 201b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (pdata->dc_valid == false && pdata->usb_valid == false) { 202b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham dev_err(dev, "No valid power sources.\n"); 203b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham ret = -EINVAL; 204b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham goto err; 205b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 206b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 207b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (pdata->dc_valid) { 208b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (pdata->dok && gpio_is_valid(pdata->dok) && 209b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham pdata->dcm && gpio_is_valid(pdata->dcm)) { 210b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham gpio = pdata->dok; /* PULL_UPed Interrupt */ 211b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham ta_in = gpio_get_value(gpio) ? 0 : 1; 212b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 213b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham gpio = pdata->dcm; /* Output */ 214b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham gpio_set_value(gpio, ta_in); 215b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } else { 216b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham dev_err(dev, "When DC is wired, DOK and DCM should" 217b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham " be wired as well.\n"); 218b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham ret = -EINVAL; 219b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham goto err; 220b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 221b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } else { 222b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (pdata->dcm) { 223b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (gpio_is_valid(pdata->dcm)) 224b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham gpio_set_value(pdata->dcm, 0); 225b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham else { 226b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham dev_err(dev, "Invalid pin: dcm.\n"); 227b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham ret = -EINVAL; 228b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham goto err; 229b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 230b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 231b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 232b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 233b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (pdata->usb_valid) { 234b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (pdata->uok && gpio_is_valid(pdata->uok)) { 235b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham gpio = pdata->uok; 236b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham usb_in = gpio_get_value(gpio) ? 0 : 1; 237b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } else { 238b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham dev_err(dev, "When USB is wired, UOK should be wired." 239b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham "as well.\n"); 240b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham ret = -EINVAL; 241b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham goto err; 242b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 243b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 244b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 245b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (pdata->cen) { 246b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (gpio_is_valid(pdata->cen)) { 247b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham gpio_set_value(pdata->cen, (ta_in || usb_in) ? 0 : 1); 248b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } else { 249b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham dev_err(dev, "Invalid pin: cen.\n"); 250b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham ret = -EINVAL; 251b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham goto err; 252b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 253b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 254b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 255b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (pdata->chg) { 256b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (!gpio_is_valid(pdata->chg)) { 257b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham dev_err(dev, "Invalid pin: chg.\n"); 258b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham ret = -EINVAL; 259b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham goto err; 260b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 261b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 262b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 263b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (pdata->flt) { 264b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (!gpio_is_valid(pdata->flt)) { 265b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham dev_err(dev, "Invalid pin: flt.\n"); 266b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham ret = -EINVAL; 267b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham goto err; 268b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 269b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 270b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 271b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (pdata->usus) { 272b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (!gpio_is_valid(pdata->usus)) { 273b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham dev_err(dev, "Invalid pin: usus.\n"); 274b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham ret = -EINVAL; 275b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham goto err; 276b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 277b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 278b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 279b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham data->fault = false; 280b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham data->ta_in = ta_in; 281b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham data->usb_in = usb_in; 282b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 283b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham data->psy.name = "max8903_charger"; 284b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham data->psy.type = (ta_in) ? POWER_SUPPLY_TYPE_MAINS : 285b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham ((usb_in) ? POWER_SUPPLY_TYPE_USB : 286b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham POWER_SUPPLY_TYPE_BATTERY); 287b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham data->psy.get_property = max8903_get_property; 288b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham data->psy.properties = max8903_charger_props; 289b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham data->psy.num_properties = ARRAY_SIZE(max8903_charger_props); 290b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 291b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham ret = power_supply_register(dev, &data->psy); 292b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (ret) { 293b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham dev_err(dev, "failed: power supply register.\n"); 294b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham goto err; 295b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 296b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 297b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (pdata->dc_valid) { 298b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham ret = request_threaded_irq(gpio_to_irq(pdata->dok), 299b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham NULL, max8903_dcin, 300b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, 301b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham "MAX8903 DC IN", data); 302b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (ret) { 303b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham dev_err(dev, "Cannot request irq %d for DC (%d)\n", 304b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham gpio_to_irq(pdata->dok), ret); 305b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham goto err_psy; 306b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 307b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 308b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 309b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (pdata->usb_valid) { 310b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham ret = request_threaded_irq(gpio_to_irq(pdata->uok), 311b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham NULL, max8903_usbin, 312b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, 313b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham "MAX8903 USB IN", data); 314b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (ret) { 315b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham dev_err(dev, "Cannot request irq %d for USB (%d)\n", 316b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham gpio_to_irq(pdata->uok), ret); 317b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham goto err_dc_irq; 318b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 319b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 320b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 321b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (pdata->flt) { 322b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham ret = request_threaded_irq(gpio_to_irq(pdata->flt), 323b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham NULL, max8903_fault, 324b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, 325b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham "MAX8903 Fault", data); 326b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (ret) { 327b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham dev_err(dev, "Cannot request irq %d for Fault (%d)\n", 328b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham gpio_to_irq(pdata->flt), ret); 329b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham goto err_usb_irq; 330b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 331b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 332b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 333b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham return 0; 334b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 335b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Hamerr_usb_irq: 336b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (pdata->usb_valid) 337b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham free_irq(gpio_to_irq(pdata->uok), data); 338b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Hamerr_dc_irq: 339b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (pdata->dc_valid) 340b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham free_irq(gpio_to_irq(pdata->dok), data); 341b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Hamerr_psy: 342b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham power_supply_unregister(&data->psy); 343b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Hamerr: 344b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham kfree(data); 345b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham return ret; 346b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham} 347b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 348b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Hamstatic __devexit int max8903_remove(struct platform_device *pdev) 349b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham{ 350b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham struct max8903_data *data = platform_get_drvdata(pdev); 351b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 352b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (data) { 353464f29a21792e0e506d936d147beea72a5f8e904MyungJoo Ham struct max8903_pdata *pdata = &data->pdata; 354b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 355b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (pdata->flt) 356b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham free_irq(gpio_to_irq(pdata->flt), data); 357b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (pdata->usb_valid) 358b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham free_irq(gpio_to_irq(pdata->uok), data); 359b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham if (pdata->dc_valid) 360b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham free_irq(gpio_to_irq(pdata->dok), data); 361b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham power_supply_unregister(&data->psy); 362b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham kfree(data); 363b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham } 364b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 365b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham return 0; 366b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham} 367b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 368b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Hamstatic struct platform_driver max8903_driver = { 369b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham .probe = max8903_probe, 370b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham .remove = __devexit_p(max8903_remove), 371b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham .driver = { 372b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham .name = "max8903-charger", 373b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham .owner = THIS_MODULE, 374b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham }, 375b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham}; 376b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 377300bac7fb85a20b2704dc3645419057992f78565Axel Linmodule_platform_driver(max8903_driver); 378b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo Ham 379b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo HamMODULE_LICENSE("GPL"); 380b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo HamMODULE_DESCRIPTION("MAX8903 Charger Driver"); 381b14a9ccc1ddddfbc76b7cae06d02db4adf0ae1dbMyungJoo HamMODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>"); 382bd19c756b1a69ec2c8f5f81624d66a1a0daad7c0Axel LinMODULE_ALIAS("platform:max8903-charger"); 383