aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/board-whistler-power.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/board-whistler-power.c')
-rw-r--r--arch/arm/mach-tegra/board-whistler-power.c291
1 files changed, 291 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/board-whistler-power.c b/arch/arm/mach-tegra/board-whistler-power.c
new file mode 100644
index 00000000000..72389f18177
--- /dev/null
+++ b/arch/arm/mach-tegra/board-whistler-power.c
@@ -0,0 +1,291 @@
1/*
2 * Copyright (C) 2010-2011 NVIDIA, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
16 * 02111-1307, USA
17 */
18#include <linux/i2c.h>
19#include <linux/pda_power.h>
20#include <linux/platform_device.h>
21#include <linux/resource.h>
22#include <linux/regulator/machine.h>
23#include <linux/mfd/max8907c.h>
24#include <linux/regulator/max8907c-regulator.h>
25#include <linux/gpio.h>
26#include <linux/io.h>
27
28#include <mach/iomap.h>
29#include <mach/irqs.h>
30
31#include "gpio-names.h"
32#include "fuse.h"
33#include "pm.h"
34#include "wakeups-t2.h"
35#include "board.h"
36
37#define PMC_CTRL 0x0
38#define PMC_CTRL_INTR_LOW (1 << 17)
39
40static struct regulator_consumer_supply max8907c_SD1_supply[] = {
41 REGULATOR_SUPPLY("vdd_cpu", NULL),
42};
43
44static struct regulator_consumer_supply max8907c_SD2_supply[] = {
45 REGULATOR_SUPPLY("vdd_core", NULL),
46 REGULATOR_SUPPLY("vdd_aon", NULL),
47};
48
49static struct regulator_consumer_supply max8907c_SD3_supply[] = {
50 REGULATOR_SUPPLY("vddio_sys", NULL),
51};
52
53static struct regulator_consumer_supply max8907c_LDO1_supply[] = {
54 REGULATOR_SUPPLY("vddio_rx_ddr", NULL),
55};
56
57static struct regulator_consumer_supply max8907c_LDO2_supply[] = {
58 REGULATOR_SUPPLY("avdd_plla", NULL),
59};
60
61static struct regulator_consumer_supply max8907c_LDO3_supply[] = {
62 REGULATOR_SUPPLY("vdd_vcom_1v8b", NULL),
63};
64
65static struct regulator_consumer_supply max8907c_LDO4_supply[] = {
66 REGULATOR_SUPPLY("avdd_usb", NULL),
67 REGULATOR_SUPPLY("avdd_usb_pll", NULL),
68};
69
70static struct regulator_consumer_supply max8907c_LDO5_supply[] = {
71};
72
73static struct regulator_consumer_supply max8907c_LDO6_supply[] = {
74 REGULATOR_SUPPLY("avdd_hdmi_pll", NULL),
75};
76
77static struct regulator_consumer_supply max8907c_LDO7_supply[] = {
78 REGULATOR_SUPPLY("avddio_audio", NULL),
79};
80
81static struct regulator_consumer_supply max8907c_LDO8_supply[] = {
82 REGULATOR_SUPPLY("vdd_vcom_3v0", NULL),
83};
84
85static struct regulator_consumer_supply max8907c_LDO9_supply[] = {
86 REGULATOR_SUPPLY("vdd_cam1", NULL),
87};
88
89static struct regulator_consumer_supply max8907c_LDO10_supply[] = {
90 REGULATOR_SUPPLY("avdd_usb_ic", NULL),
91};
92
93static struct regulator_consumer_supply max8907c_LDO11_supply[] = {
94 REGULATOR_SUPPLY("vddio_pex_clk", NULL),
95 REGULATOR_SUPPLY("avdd_hdmi", NULL),
96};
97
98static struct regulator_consumer_supply max8907c_LDO12_supply[] = {
99 REGULATOR_SUPPLY("vddio_sdio", NULL),
100};
101
102static struct regulator_consumer_supply max8907c_LDO13_supply[] = {
103 REGULATOR_SUPPLY("vdd_vcore_phtn", NULL),
104 REGULATOR_SUPPLY("vdd_vcore_af", NULL),
105};
106
107static struct regulator_consumer_supply max8907c_LDO14_supply[] = {
108 REGULATOR_SUPPLY("avdd_vdac", NULL),
109};
110
111static struct regulator_consumer_supply max8907c_LDO15_supply[] = {
112 REGULATOR_SUPPLY("vdd_vcore_temp", NULL),
113 REGULATOR_SUPPLY("vdd_vcore_hdcp", NULL),
114};
115
116static struct regulator_consumer_supply max8907c_LDO16_supply[] = {
117 REGULATOR_SUPPLY("vdd_vbrtr", NULL),
118};
119
120static struct regulator_consumer_supply max8907c_LDO17_supply[] = {
121 REGULATOR_SUPPLY("vddio_mipi", NULL),
122};
123
124static struct regulator_consumer_supply max8907c_LDO18_supply[] = {
125 REGULATOR_SUPPLY("vddio_vi", NULL),
126 REGULATOR_SUPPLY("vcsi", "tegra_camera"),
127};
128
129static struct regulator_consumer_supply max8907c_LDO19_supply[] = {
130 REGULATOR_SUPPLY("vddio_lx", NULL),
131};
132
133static struct regulator_consumer_supply max8907c_LDO20_supply[] = {
134 REGULATOR_SUPPLY("vddio_ddr_1v2", NULL),
135 REGULATOR_SUPPLY("vddio_hsic", NULL),
136};
137
138#define MAX8907C_REGULATOR_DEVICE(_id, _minmv, _maxmv) \
139static struct regulator_init_data max8907c_##_id##_data = { \
140 .constraints = { \
141 .min_uV = (_minmv), \
142 .max_uV = (_maxmv), \
143 .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
144 REGULATOR_MODE_STANDBY), \
145 .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
146 REGULATOR_CHANGE_STATUS | \
147 REGULATOR_CHANGE_VOLTAGE), \
148 }, \
149 .num_consumer_supplies = ARRAY_SIZE(max8907c_##_id##_supply), \
150 .consumer_supplies = max8907c_##_id##_supply, \
151}; \
152static struct platform_device max8907c_##_id##_device = { \
153 .name = "max8907c-regulator", \
154 .id = MAX8907C_##_id, \
155 .dev = { \
156 .platform_data = &max8907c_##_id##_data, \
157 }, \
158}
159
160MAX8907C_REGULATOR_DEVICE(SD1, 637500, 1425000);
161MAX8907C_REGULATOR_DEVICE(SD2, 637500, 1425000);
162MAX8907C_REGULATOR_DEVICE(SD3, 750000, 3900000);
163MAX8907C_REGULATOR_DEVICE(LDO1, 750000, 3900000);
164MAX8907C_REGULATOR_DEVICE(LDO2, 650000, 2225000);
165MAX8907C_REGULATOR_DEVICE(LDO3, 650000, 2225000);
166MAX8907C_REGULATOR_DEVICE(LDO4, 750000, 3900000);
167MAX8907C_REGULATOR_DEVICE(LDO5, 750000, 3900000);
168MAX8907C_REGULATOR_DEVICE(LDO6, 750000, 3900000);
169MAX8907C_REGULATOR_DEVICE(LDO7, 750000, 3900000);
170MAX8907C_REGULATOR_DEVICE(LDO8, 750000, 3900000);
171MAX8907C_REGULATOR_DEVICE(LDO9, 750000, 3900000);
172MAX8907C_REGULATOR_DEVICE(LDO10, 750000, 3900000);
173MAX8907C_REGULATOR_DEVICE(LDO11, 750000, 3900000);
174MAX8907C_REGULATOR_DEVICE(LDO12, 750000, 3900000);
175MAX8907C_REGULATOR_DEVICE(LDO13, 750000, 3900000);
176MAX8907C_REGULATOR_DEVICE(LDO14, 750000, 3900000);
177MAX8907C_REGULATOR_DEVICE(LDO15, 750000, 3900000);
178MAX8907C_REGULATOR_DEVICE(LDO16, 750000, 3900000);
179MAX8907C_REGULATOR_DEVICE(LDO17, 650000, 2225000);
180MAX8907C_REGULATOR_DEVICE(LDO18, 650000, 2225000);
181MAX8907C_REGULATOR_DEVICE(LDO19, 750000, 3900000);
182MAX8907C_REGULATOR_DEVICE(LDO20, 750000, 3900000);
183
184static struct platform_device *whistler_max8907c_power_devices[] = {
185 &max8907c_SD1_device,
186 &max8907c_SD2_device,
187 &max8907c_SD3_device,
188 &max8907c_LDO1_device,
189 &max8907c_LDO2_device,
190 &max8907c_LDO3_device,
191 &max8907c_LDO4_device,
192 &max8907c_LDO5_device,
193 &max8907c_LDO6_device,
194 &max8907c_LDO7_device,
195 &max8907c_LDO8_device,
196 &max8907c_LDO9_device,
197 &max8907c_LDO10_device,
198 &max8907c_LDO11_device,
199 &max8907c_LDO12_device,
200 &max8907c_LDO13_device,
201 &max8907c_LDO14_device,
202 &max8907c_LDO15_device,
203 &max8907c_LDO16_device,
204 &max8907c_LDO17_device,
205 &max8907c_LDO18_device,
206 &max8907c_LDO19_device,
207 &max8907c_LDO20_device,
208};
209
210static int whistler_max8907c_setup(void)
211{
212 int ret;
213
214 /*
215 * Configure PWREN, and attach CPU V1 rail to it.
216 * TODO: h/w events (power cycle, reset, battery low) auto-disables PWREN.
217 * Only soft reset (not supported) requires s/w to disable PWREN explicitly
218 */
219 ret = max8907c_pwr_en_config();
220 if (ret != 0)
221 return ret;
222
223 return max8907c_pwr_en_attach();
224}
225
226static struct max8907c_platform_data max8907c_pdata = {
227 .num_subdevs = ARRAY_SIZE(whistler_max8907c_power_devices),
228 .subdevs = whistler_max8907c_power_devices,
229 .irq_base = TEGRA_NR_IRQS,
230 .max8907c_setup = whistler_max8907c_setup,
231 .use_power_off = true,
232};
233
234static struct i2c_board_info __initdata whistler_regulators[] = {
235 {
236 I2C_BOARD_INFO("max8907c", 0x3C),
237 .irq = INT_EXTERNAL_PMU,
238 .platform_data = &max8907c_pdata,
239 },
240};
241
242static void whistler_board_suspend(int lp_state, enum suspend_stage stg)
243{
244 if ((lp_state == TEGRA_SUSPEND_LP1) && (stg == TEGRA_SUSPEND_BEFORE_CPU))
245 tegra_console_uart_suspend();
246}
247
248static void whistler_board_resume(int lp_state, enum resume_stage stg)
249{
250 if ((lp_state == TEGRA_SUSPEND_LP1) && (stg == TEGRA_RESUME_AFTER_CPU))
251 tegra_console_uart_resume();
252}
253
254static struct tegra_suspend_platform_data whistler_suspend_data = {
255 .cpu_timer = 2000,
256 .cpu_off_timer = 1000,
257 .suspend_mode = TEGRA_SUSPEND_LP0,
258 .core_timer = 0x7e,
259 .core_off_timer = 0xc00,
260 .corereq_high = true,
261 .sysclkreq_high = true,
262 .combined_req = true,
263 .board_suspend = whistler_board_suspend,
264 .board_resume = whistler_board_resume,
265};
266
267int __init whistler_regulator_init(void)
268{
269 void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
270 void __iomem *chip_id = IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804;
271 u32 pmc_ctrl;
272 u32 minor;
273
274 minor = (readl(chip_id) >> 16) & 0xf;
275 /* A03 (but not A03p) chips do not support LP0 */
276 if (minor == 3 && !(tegra_spare_fuse(18) || tegra_spare_fuse(19)))
277 whistler_suspend_data.suspend_mode = TEGRA_SUSPEND_LP1;
278
279 /* configure the power management controller to trigger PMU
280 * interrupts when low */
281 pmc_ctrl = readl(pmc + PMC_CTRL);
282 writel(pmc_ctrl | PMC_CTRL_INTR_LOW, pmc + PMC_CTRL);
283
284 i2c_register_board_info(4, whistler_regulators, 1);
285
286 tegra_deep_sleep = max8907c_deep_sleep;
287
288 tegra_init_suspend(&whistler_suspend_data);
289
290 return 0;
291}