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	u8 enable_addr;
37f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	u8 enable_shift;
38f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	u8 enable_mask;
39f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
40f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	u8 voltage_addr;
41f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	u8 voltage_shift;
42f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	u8 voltage_mask;
43f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park};
44f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
45f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int aat2870_ldo_set_voltage_sel(struct regulator_dev *rdev,
46f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park				       unsigned selector)
47f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{
48f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	struct aat2870_regulator *ri = rdev_get_drvdata(rdev);
49b21bcd1ada026cd90243311e89dd8d999fe0a227Axel Lin	struct aat2870_data *aat2870 = ri->aat2870;
50f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
51f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	return aat2870->update(aat2870, ri->voltage_addr, ri->voltage_mask,
52a5228d2e5ea02c90581d5957cb6c4c73c191298fAxel Lin			       selector << ri->voltage_shift);
53f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}
54f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
55f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int aat2870_ldo_get_voltage_sel(struct regulator_dev *rdev)
56f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{
57f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	struct aat2870_regulator *ri = rdev_get_drvdata(rdev);
58b21bcd1ada026cd90243311e89dd8d999fe0a227Axel Lin	struct aat2870_data *aat2870 = ri->aat2870;
59f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	u8 val;
60f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	int ret;
61f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
62f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	ret = aat2870->read(aat2870, ri->voltage_addr, &val);
63f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	if (ret)
64f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		return ret;
65f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
66f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	return (val & ri->voltage_mask) >> ri->voltage_shift;
67f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}
68f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
69f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int aat2870_ldo_enable(struct regulator_dev *rdev)
70f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{
71f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	struct aat2870_regulator *ri = rdev_get_drvdata(rdev);
72b21bcd1ada026cd90243311e89dd8d999fe0a227Axel Lin	struct aat2870_data *aat2870 = ri->aat2870;
73f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
74f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	return aat2870->update(aat2870, ri->enable_addr, ri->enable_mask,
75f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park			       ri->enable_mask);
76f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}
77f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
78f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int aat2870_ldo_disable(struct regulator_dev *rdev)
79f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{
80f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	struct aat2870_regulator *ri = rdev_get_drvdata(rdev);
81b21bcd1ada026cd90243311e89dd8d999fe0a227Axel Lin	struct aat2870_data *aat2870 = ri->aat2870;
82f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
83f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	return aat2870->update(aat2870, ri->enable_addr, ri->enable_mask, 0);
84f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}
85f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
86f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int aat2870_ldo_is_enabled(struct regulator_dev *rdev)
87f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{
88f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	struct aat2870_regulator *ri = rdev_get_drvdata(rdev);
89b21bcd1ada026cd90243311e89dd8d999fe0a227Axel Lin	struct aat2870_data *aat2870 = ri->aat2870;
90f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	u8 val;
91f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	int ret;
92f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
93f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	ret = aat2870->read(aat2870, ri->enable_addr, &val);
94f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	if (ret)
95f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		return ret;
96f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
97f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	return val & ri->enable_mask ? 1 : 0;
98f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}
99f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
100f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic struct regulator_ops aat2870_ldo_ops = {
1014506c6d5ea5dddab562fd06398fd9b8d1681bbd0Axel Lin	.list_voltage = regulator_list_voltage_table,
10208d6da291435f5de0f0fa283994a74f67d9ab23aAxel Lin	.map_voltage = regulator_map_voltage_ascend,
103f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	.set_voltage_sel = aat2870_ldo_set_voltage_sel,
104f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	.get_voltage_sel = aat2870_ldo_get_voltage_sel,
105f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	.enable = aat2870_ldo_enable,
106f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	.disable = aat2870_ldo_disable,
107f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	.is_enabled = aat2870_ldo_is_enabled,
108f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park};
109f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
1104506c6d5ea5dddab562fd06398fd9b8d1681bbd0Axel Linstatic const unsigned int aat2870_ldo_voltages[] = {
111f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	1200000, 1300000, 1500000, 1600000,
112f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	1800000, 2000000, 2200000, 2500000,
113f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	2600000, 2700000, 2800000, 2900000,
114f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	3000000, 3100000, 3200000, 3300000,
115f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park};
116f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
117f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park#define AAT2870_LDO(ids)				\
118f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	{						\
119f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		.desc = {				\
120f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park			.name = #ids,			\
121f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park			.id = AAT2870_ID_##ids,		\
122f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park			.n_voltages = ARRAY_SIZE(aat2870_ldo_voltages),	\
1234506c6d5ea5dddab562fd06398fd9b8d1681bbd0Axel Lin			.volt_table = aat2870_ldo_voltages, \
124f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park			.ops = &aat2870_ldo_ops,	\
125f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park			.type = REGULATOR_VOLTAGE,	\
126f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park			.owner = THIS_MODULE,		\
127f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		},					\
128f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	}
129f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
130f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic struct aat2870_regulator aat2870_regulators[] = {
131f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	AAT2870_LDO(LDOA),
132f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	AAT2870_LDO(LDOB),
133f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	AAT2870_LDO(LDOC),
134f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	AAT2870_LDO(LDOD),
135f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park};
136f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
137f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic struct aat2870_regulator *aat2870_get_regulator(int id)
138f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{
139f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	struct aat2870_regulator *ri = NULL;
140f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	int i;
141f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
142f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	for (i = 0; i < ARRAY_SIZE(aat2870_regulators); i++) {
143f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		ri = &aat2870_regulators[i];
144f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		if (ri->desc.id == id)
145f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park			break;
146f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	}
147f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
148d4d6373c1109b11c8118340be97ae31b8f94d66aAxel Lin	if (i == ARRAY_SIZE(aat2870_regulators))
149f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		return NULL;
150f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
151f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	ri->enable_addr = AAT2870_LDO_EN;
152f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	ri->enable_shift = id - AAT2870_ID_LDOA;
153f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	ri->enable_mask = 0x1 << ri->enable_shift;
154f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
155f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	ri->voltage_addr = (id - AAT2870_ID_LDOA) / 2 ?
156f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park			   AAT2870_LDO_CD : AAT2870_LDO_AB;
157f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	ri->voltage_shift = (id - AAT2870_ID_LDOA) % 2 ? 0 : 4;
158f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	ri->voltage_mask = 0xF << ri->voltage_shift;
159f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
160f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	return ri;
161f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}
162f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
163f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int aat2870_regulator_probe(struct platform_device *pdev)
164f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{
165f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	struct aat2870_regulator *ri;
166e4c5288e410440abcc3e2e1887111b09a98304d5Mark Brown	struct regulator_config config = { };
167f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	struct regulator_dev *rdev;
168f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
169f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	ri = aat2870_get_regulator(pdev->id);
170f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	if (!ri) {
171f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		dev_err(&pdev->dev, "Invalid device ID, %d\n", pdev->id);
172f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		return -EINVAL;
173f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	}
174b21bcd1ada026cd90243311e89dd8d999fe0a227Axel Lin	ri->aat2870 = dev_get_drvdata(pdev->dev.parent);
175f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
176c172708d38a401b2f3f841dfcd862b469fa0b670Mark Brown	config.dev = &pdev->dev;
177c172708d38a401b2f3f841dfcd862b469fa0b670Mark Brown	config.driver_data = ri;
178dff91d0b721bf8f036c1071a8f16a7effaa87514Jingoo Han	config.init_data = dev_get_platdata(&pdev->dev);
179c172708d38a401b2f3f841dfcd862b469fa0b670Mark Brown
180b1a613d505c53ad4f4af4cf228841a1784a50011Axel Lin	rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config);
181f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	if (IS_ERR(rdev)) {
182f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		dev_err(&pdev->dev, "Failed to register regulator %s\n",
183f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park			ri->desc.name);
184f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		return PTR_ERR(rdev);
185f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	}
186f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	platform_set_drvdata(pdev, rdev);
187f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
188f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	return 0;
189f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}
190f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
191f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic struct platform_driver aat2870_regulator_driver = {
192f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	.driver = {
193f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		.name	= "aat2870-regulator",
194f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park		.owner	= THIS_MODULE,
195f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	},
196f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	.probe	= aat2870_regulator_probe,
197f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park};
198f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
199f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic int __init aat2870_regulator_init(void)
200f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{
201f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	return platform_driver_register(&aat2870_regulator_driver);
202f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}
203f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parksubsys_initcall(aat2870_regulator_init);
204f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
205f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkstatic void __exit aat2870_regulator_exit(void)
206f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park{
207f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park	platform_driver_unregister(&aat2870_regulator_driver);
208f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park}
209f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Parkmodule_exit(aat2870_regulator_exit);
210f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin Park
211f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin ParkMODULE_DESCRIPTION("AnalogicTech AAT2870 Regulator");
212f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin ParkMODULE_LICENSE("GPL");
213f7eb6c5e8e5e1e96c36763778e9a78b9da6fcd31Jin ParkMODULE_AUTHOR("Jin Park <jinyoungp@nvidia.com>");
214ad9c5ffea8de1d989e205650bb46111b37498cf3Mark BrownMODULE_ALIAS("platform:aat2870-regulator");
215