aat2870-regulator.c revision 4506c6d5ea5dddab562fd06398fd9b8d1681bbd0
1f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park/*
2f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * linux/drivers/regulator/aat2870-regulator.c
3f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park *
4f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * Copyright (c) 2011, NVIDIA Corporation.
5f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * Author: Jin Park <jinyoungp@nvidia.com>
6f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park *
7f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * This program is free software; you can redistribute it and/or
8f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * modify it under the terms of the GNU General Public License
9f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * version 2 as published by the Free Software Foundation.
10f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park *
11f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * This program is distributed in the hope that it will be useful, but
12f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * WITHOUT ANY WARRANTY; without even the implied warranty of
13f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * General Public License for more details.
15f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park *
16f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * You should have received a copy of the GNU General Public License
17f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * along with this program; if not, write to the Free Software
18f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park * 02110-1301 USA
20f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park */
21f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
22f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park#include <linux/kernel.h>
23f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park#include <linux/init.h>
24f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park#include <linux/err.h>
253a7d021b5e1de205c964c30d0ceda660501dc107Randy Dunlap#include <linux/module.h>
26f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park#include <linux/slab.h>
27f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park#include <linux/platform_device.h>
28f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park#include <linux/regulator/driver.h>
29f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park#include <linux/regulator/machine.h>
30f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park#include <linux/mfd/aat2870.h>
31f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
32f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstruct aat2870_regulator {
33b21bcd1ada026cd90243311e89dd8d999fe0a227Axel Lin	struct aat2870_data *aat2870;
34f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	struct regulator_desc desc;
35f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
36f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	int min_uV;
37f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	int max_uV;
38f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
39f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	u8 enable_addr;
40f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	u8 enable_shift;
41f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	u8 enable_mask;
42f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
43f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	u8 voltage_addr;
44f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	u8 voltage_shift;
45f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	u8 voltage_mask;
46f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park};
47f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
48f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int aat2870_ldo_set_voltage_sel(struct regulator_dev *rdev,
49f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park				       unsigned selector)
50f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{
51f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	struct aat2870_regulator *ri = rdev_get_drvdata(rdev);
52b21bcd1ada026cd90243311e89dd8d999fe0a227Axel Lin	struct aat2870_data *aat2870 = ri->aat2870;
53f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
54f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	return aat2870->update(aat2870, ri->voltage_addr, ri->voltage_mask,
55a5228d2e5ea02c90581d5957cb6c4c73c191298fAxel Lin			       selector << ri->voltage_shift);
56f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}
57f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
58f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int aat2870_ldo_get_voltage_sel(struct regulator_dev *rdev)
59f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{
60f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	struct aat2870_regulator *ri = rdev_get_drvdata(rdev);
61b21bcd1ada026cd90243311e89dd8d999fe0a227Axel Lin	struct aat2870_data *aat2870 = ri->aat2870;
62f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	u8 val;
63f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	int ret;
64f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
65f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	ret = aat2870->read(aat2870, ri->voltage_addr, &val);
66f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	if (ret)
67f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		return ret;
68f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
69f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	return (val & ri->voltage_mask) >> ri->voltage_shift;
70f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}
71f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
72f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int aat2870_ldo_enable(struct regulator_dev *rdev)
73f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{
74f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	struct aat2870_regulator *ri = rdev_get_drvdata(rdev);
75b21bcd1ada026cd90243311e89dd8d999fe0a227Axel Lin	struct aat2870_data *aat2870 = ri->aat2870;
76f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
77f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	return aat2870->update(aat2870, ri->enable_addr, ri->enable_mask,
78f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park			       ri->enable_mask);
79f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}
80f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
81f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int aat2870_ldo_disable(struct regulator_dev *rdev)
82f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{
83f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	struct aat2870_regulator *ri = rdev_get_drvdata(rdev);
84b21bcd1ada026cd90243311e89dd8d999fe0a227Axel Lin	struct aat2870_data *aat2870 = ri->aat2870;
85f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
86f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	return aat2870->update(aat2870, ri->enable_addr, ri->enable_mask, 0);
87f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}
88f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
89f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int aat2870_ldo_is_enabled(struct regulator_dev *rdev)
90f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{
91f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	struct aat2870_regulator *ri = rdev_get_drvdata(rdev);
92b21bcd1ada026cd90243311e89dd8d999fe0a227Axel Lin	struct aat2870_data *aat2870 = ri->aat2870;
93f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	u8 val;
94f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	int ret;
95f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
96f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	ret = aat2870->read(aat2870, ri->enable_addr, &val);
97f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	if (ret)
98f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		return ret;
99f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
100f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	return val & ri->enable_mask ? 1 : 0;
101f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}
102f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
103f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic struct regulator_ops aat2870_ldo_ops = {
1044506c6d5ea5dddab562fd06398fd9b8d1681bbd0Axel Lin	.list_voltage = regulator_list_voltage_table,
105f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	.set_voltage_sel = aat2870_ldo_set_voltage_sel,
106f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	.get_voltage_sel = aat2870_ldo_get_voltage_sel,
107f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	.enable = aat2870_ldo_enable,
108f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	.disable = aat2870_ldo_disable,
109f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	.is_enabled = aat2870_ldo_is_enabled,
110f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park};
111f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
1124506c6d5ea5dddab562fd06398fd9b8d1681bbd0Axel Linstatic const unsigned int aat2870_ldo_voltages[] = {
113f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	1200000, 1300000, 1500000, 1600000,
114f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	1800000, 2000000, 2200000, 2500000,
115f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	2600000, 2700000, 2800000, 2900000,
116f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	3000000, 3100000, 3200000, 3300000,
117f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park};
118f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
119f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park#define AAT2870_LDO(ids)				\
120f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	{						\
121f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		.desc = {				\
122f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park			.name = #ids,			\
123f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park			.id = AAT2870_ID_##ids,		\
124f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park			.n_voltages = ARRAY_SIZE(aat2870_ldo_voltages),	\
1254506c6d5ea5dddab562fd06398fd9b8d1681bbd0Axel Lin			.volt_table = aat2870_ldo_voltages, \
126f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park			.ops = &aat2870_ldo_ops,	\
127f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park			.type = REGULATOR_VOLTAGE,	\
128f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park			.owner = THIS_MODULE,		\
129f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		},					\
130f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		.min_uV = 1200000,			\
131f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		.max_uV = 3300000,			\
132f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	}
133f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
134f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic struct aat2870_regulator aat2870_regulators[] = {
135f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	AAT2870_LDO(LDOA),
136f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	AAT2870_LDO(LDOB),
137f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	AAT2870_LDO(LDOC),
138f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	AAT2870_LDO(LDOD),
139f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park};
140f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
141f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic struct aat2870_regulator *aat2870_get_regulator(int id)
142f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{
143f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	struct aat2870_regulator *ri = NULL;
144f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	int i;
145f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
146f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	for (i = 0; i < ARRAY_SIZE(aat2870_regulators); i++) {
147f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		ri = &aat2870_regulators[i];
148f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		if (ri->desc.id == id)
149f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park			break;
150f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	}
151f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
152d4d6373c1109b11c8118340be97ae31b8f94d66aAxel Lin	if (i == ARRAY_SIZE(aat2870_regulators))
153f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		return NULL;
154f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
155f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	ri->enable_addr = AAT2870_LDO_EN;
156f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	ri->enable_shift = id - AAT2870_ID_LDOA;
157f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	ri->enable_mask = 0x1 << ri->enable_shift;
158f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
159f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	ri->voltage_addr = (id - AAT2870_ID_LDOA) / 2 ?
160f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park			   AAT2870_LDO_CD : AAT2870_LDO_AB;
161f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	ri->voltage_shift = (id - AAT2870_ID_LDOA) % 2 ? 0 : 4;
162f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	ri->voltage_mask = 0xF << ri->voltage_shift;
163f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
164f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	return ri;
165f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}
166f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
167f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int aat2870_regulator_probe(struct platform_device *pdev)
168f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{
169f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	struct aat2870_regulator *ri;
170c172708d38a401b2f3f841dfcd862b469fa0b670Mark Brown	struct regulator_config config = { 0 };
171f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	struct regulator_dev *rdev;
172f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
173f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	ri = aat2870_get_regulator(pdev->id);
174f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	if (!ri) {
175f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		dev_err(&pdev->dev, "Invalid device ID, %d\n", pdev->id);
176f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		return -EINVAL;
177f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	}
178b21bcd1ada026cd90243311e89dd8d999fe0a227Axel Lin	ri->aat2870 = dev_get_drvdata(pdev->dev.parent);
179f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
180c172708d38a401b2f3f841dfcd862b469fa0b670Mark Brown	config.dev = &pdev->dev;
181c172708d38a401b2f3f841dfcd862b469fa0b670Mark Brown	config.driver_data = ri;
182c172708d38a401b2f3f841dfcd862b469fa0b670Mark Brown	config.init_data = pdev->dev.platform_data;
183c172708d38a401b2f3f841dfcd862b469fa0b670Mark Brown
184c172708d38a401b2f3f841dfcd862b469fa0b670Mark Brown	rdev = regulator_register(&ri->desc, &config);
185f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	if (IS_ERR(rdev)) {
186f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		dev_err(&pdev->dev, "Failed to register regulator %s\n",
187f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park			ri->desc.name);
188f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		return PTR_ERR(rdev);
189f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	}
190f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	platform_set_drvdata(pdev, rdev);
191f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
192f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	return 0;
193f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}
194f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
195f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int __devexit aat2870_regulator_remove(struct platform_device *pdev)
196f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{
197f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	struct regulator_dev *rdev = platform_get_drvdata(pdev);
198f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
199f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	regulator_unregister(rdev);
200f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	return 0;
201f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}
202f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
203f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic struct platform_driver aat2870_regulator_driver = {
204f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	.driver = {
205f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		.name	= "aat2870-regulator",
206f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		.owner	= THIS_MODULE,
207f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	},
208f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	.probe	= aat2870_regulator_probe,
209f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	.remove	= __devexit_p(aat2870_regulator_remove),
210f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park};
211f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
212f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int __init aat2870_regulator_init(void)
213f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{
214f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	return platform_driver_register(&aat2870_regulator_driver);
215f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}
216f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parksubsys_initcall(aat2870_regulator_init);
217f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
218f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic void __exit aat2870_regulator_exit(void)
219f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{
220f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	platform_driver_unregister(&aat2870_regulator_driver);
221f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}
222f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkmodule_exit(aat2870_regulator_exit);
223f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
224f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin ParkMODULE_DESCRIPTION("AnalogicTech AAT2870 Regulator");
225f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin ParkMODULE_LICENSE("GPL");
226f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin ParkMODULE_AUTHOR("Jin Park <jinyoungp@nvidia.com>");
227ad9c5ffea8de1d989e205650bb46111b37498cf3Mark BrownMODULE_ALIAS("platform:aat2870-regulator");
228