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