]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
cd782635 TR |
2 | /* |
3 | * Copyright (c) 2009 Wind River Systems, Inc. | |
4 | * Tom Rix <Tom.Rix at windriver.com> | |
5 | * | |
2c155130 TR |
6 | * twl4030_power_reset_init is derived from code on omapzoom, |
7 | * git://git.omapzoom.com/repo/u-boot.git | |
cd782635 TR |
8 | * |
9 | * Copyright (C) 2007-2009 Texas Instruments, Inc. | |
2c155130 TR |
10 | * |
11 | * twl4030_power_init is from cpu/omap3/common.c, power_init_r | |
12 | * | |
13 | * (C) Copyright 2004-2008 | |
14 | * Texas Instruments, <www.ti.com> | |
15 | * | |
16 | * Author : | |
17 | * Sunil Kumar <sunilsaini05 at gmail.com> | |
18 | * Shashi Ranjan <shashiranjanmca05 at gmail.com> | |
19 | * | |
20 | * Derived from Beagle Board and 3430 SDP code by | |
21 | * Richard Woodruff <r-woodruff2 at ti.com> | |
22 | * Syed Mohammed Khasim <khasim at ti.com> | |
cd782635 TR |
23 | */ |
24 | ||
09140113 | 25 | #include <command.h> |
cd782635 | 26 | #include <twl4030.h> |
c05ed00a | 27 | #include <linux/delay.h> |
cd782635 TR |
28 | |
29 | /* | |
30 | * Power Reset | |
31 | */ | |
32 | void twl4030_power_reset_init(void) | |
33 | { | |
34 | u8 val = 0; | |
b29c2f0c NM |
35 | if (twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER, |
36 | TWL4030_PM_MASTER_P1_SW_EVENTS, &val)) { | |
cd782635 TR |
37 | printf("Error:TWL4030: failed to read the power register\n"); |
38 | printf("Could not initialize hardware reset\n"); | |
39 | } else { | |
40 | val |= TWL4030_PM_MASTER_SW_EVENTS_STOPON_PWRON; | |
0208aaf6 NM |
41 | if (twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, |
42 | TWL4030_PM_MASTER_P1_SW_EVENTS, val)) { | |
cd782635 TR |
43 | printf("Error:TWL4030: failed to write the power register\n"); |
44 | printf("Could not initialize hardware reset\n"); | |
45 | } | |
46 | } | |
47 | } | |
48 | ||
6dc443e6 PK |
49 | /* |
50 | * Power off | |
51 | */ | |
52 | void twl4030_power_off(void) | |
53 | { | |
54 | u8 data; | |
55 | ||
56 | /* PM master unlock (CFG and TST keys) */ | |
57 | ||
58 | data = 0xCE; | |
59 | twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, | |
60 | TWL4030_PM_MASTER_PROTECT_KEY, data); | |
61 | data = 0xEC; | |
62 | twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, | |
63 | TWL4030_PM_MASTER_PROTECT_KEY, data); | |
64 | ||
65 | /* VBAT start disable */ | |
66 | ||
67 | twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER, | |
68 | TWL4030_PM_MASTER_CFG_P1_TRANSITION, &data); | |
69 | data &= ~TWL4030_PM_MASTER_CFG_TRANSITION_STARTON_VBAT; | |
70 | twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, | |
71 | TWL4030_PM_MASTER_CFG_P1_TRANSITION, data); | |
72 | ||
73 | twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER, | |
74 | TWL4030_PM_MASTER_CFG_P2_TRANSITION, &data); | |
75 | data &= ~TWL4030_PM_MASTER_CFG_TRANSITION_STARTON_VBAT; | |
76 | twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, | |
77 | TWL4030_PM_MASTER_CFG_P2_TRANSITION, data); | |
78 | ||
79 | twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER, | |
80 | TWL4030_PM_MASTER_CFG_P3_TRANSITION, &data); | |
81 | data &= ~TWL4030_PM_MASTER_CFG_TRANSITION_STARTON_VBAT; | |
82 | twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, | |
83 | TWL4030_PM_MASTER_CFG_P3_TRANSITION, data); | |
84 | ||
85 | /* High jitter for PWRANA2 */ | |
86 | ||
87 | twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER, | |
88 | TWL4030_PM_MASTER_CFG_PWRANA2, &data); | |
89 | data &= ~(TWL4030_PM_MASTER_CFG_PWRANA2_LOJIT0_LOWV | | |
90 | TWL4030_PM_MASTER_CFG_PWRANA2_LOJIT1_LOWV); | |
91 | twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, | |
92 | TWL4030_PM_MASTER_CFG_PWRANA2, data); | |
93 | ||
94 | /* PM master lock */ | |
95 | ||
96 | data = 0xFF; | |
97 | twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, | |
98 | TWL4030_PM_MASTER_PROTECT_KEY, data); | |
99 | ||
100 | /* Power off */ | |
101 | ||
102 | twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER, | |
103 | TWL4030_PM_MASTER_P1_SW_EVENTS, &data); | |
104 | data |= TWL4030_PM_MASTER_SW_EVENTS_DEVOFF; | |
105 | twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, | |
106 | TWL4030_PM_MASTER_P1_SW_EVENTS, data); | |
107 | } | |
108 | ||
2c155130 | 109 | /* |
5a0a82f4 | 110 | * Set Device Group and Voltage |
2c155130 | 111 | */ |
5a0a82f4 SS |
112 | void twl4030_pmrecv_vsel_cfg(u8 vsel_reg, u8 vsel_val, |
113 | u8 dev_grp, u8 dev_grp_sel) | |
114 | { | |
61712bca | 115 | int ret; |
5a0a82f4 SS |
116 | |
117 | /* Select the Voltage */ | |
0208aaf6 NM |
118 | ret = twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, vsel_reg, |
119 | vsel_val); | |
61712bca | 120 | if (ret != 0) { |
dfe36109 | 121 | printf("Could not write vsel to reg %02x (%d)\n", |
61712bca GI |
122 | vsel_reg, ret); |
123 | return; | |
124 | } | |
125 | ||
126 | /* Select the Device Group (enable the supply if dev_grp_sel != 0) */ | |
0208aaf6 NM |
127 | ret = twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, dev_grp, |
128 | dev_grp_sel); | |
61712bca | 129 | if (ret != 0) |
dfe36109 | 130 | printf("Could not write grp_sel to reg %02x (%d)\n", |
61712bca | 131 | dev_grp, ret); |
5a0a82f4 | 132 | } |
2c155130 TR |
133 | |
134 | void twl4030_power_init(void) | |
135 | { | |
2c155130 | 136 | /* set VAUX3 to 2.8V */ |
5a0a82f4 SS |
137 | twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VAUX3_DEDICATED, |
138 | TWL4030_PM_RECEIVER_VAUX3_VSEL_28, | |
139 | TWL4030_PM_RECEIVER_VAUX3_DEV_GRP, | |
140 | TWL4030_PM_RECEIVER_DEV_GRP_P1); | |
2c155130 TR |
141 | |
142 | /* set VPLL2 to 1.8V */ | |
5a0a82f4 SS |
143 | twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VPLL2_DEDICATED, |
144 | TWL4030_PM_RECEIVER_VPLL2_VSEL_18, | |
145 | TWL4030_PM_RECEIVER_VPLL2_DEV_GRP, | |
146 | TWL4030_PM_RECEIVER_DEV_GRP_ALL); | |
2c155130 TR |
147 | |
148 | /* set VDAC to 1.8V */ | |
5a0a82f4 SS |
149 | twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VDAC_DEDICATED, |
150 | TWL4030_PM_RECEIVER_VDAC_VSEL_18, | |
151 | TWL4030_PM_RECEIVER_VDAC_DEV_GRP, | |
152 | TWL4030_PM_RECEIVER_DEV_GRP_P1); | |
2c155130 TR |
153 | } |
154 | ||
f3e85e48 | 155 | void twl4030_power_mmc_init(int dev_index) |
fccc0fca | 156 | { |
f3e85e48 PK |
157 | if (dev_index == 0) { |
158 | /* Set VMMC1 to 3.15 Volts */ | |
159 | twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VMMC1_DEDICATED, | |
160 | TWL4030_PM_RECEIVER_VMMC1_VSEL_32, | |
161 | TWL4030_PM_RECEIVER_VMMC1_DEV_GRP, | |
162 | TWL4030_PM_RECEIVER_DEV_GRP_P1); | |
2ed8c878 | 163 | |
f3e85e48 PK |
164 | mdelay(100); /* ramp-up delay from Linux code */ |
165 | } else if (dev_index == 1) { | |
166 | /* Set VMMC2 to 3.15 Volts */ | |
167 | twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VMMC2_DEDICATED, | |
168 | TWL4030_PM_RECEIVER_VMMC2_VSEL_32, | |
169 | TWL4030_PM_RECEIVER_VMMC2_DEV_GRP, | |
170 | TWL4030_PM_RECEIVER_DEV_GRP_P1); | |
171 | ||
172 | mdelay(100); /* ramp-up delay from Linux code */ | |
173 | } | |
fccc0fca | 174 | } |
4c2fb5fc AF |
175 | |
176 | #ifdef CONFIG_CMD_POWEROFF | |
09140113 | 177 | int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) |
4c2fb5fc AF |
178 | { |
179 | twl4030_power_off(); | |
180 | ||
181 | return 0; | |
182 | } | |
183 | #endif | |
fb1b7712 JJH |
184 | |
185 | #ifdef CONFIG_DM_I2C | |
186 | int twl4030_i2c_write_u8(u8 chip_no, u8 reg, u8 val) | |
187 | { | |
188 | struct udevice *dev; | |
189 | int ret; | |
190 | ||
191 | ret = i2c_get_chip_for_busnum(0, chip_no, 1, &dev); | |
192 | if (ret) { | |
193 | pr_err("unable to get I2C bus. ret %d\n", ret); | |
194 | return ret; | |
195 | } | |
196 | ret = dm_i2c_reg_write(dev, reg, val); | |
197 | if (ret) { | |
198 | pr_err("writing to twl4030 failed. ret %d\n", ret); | |
199 | return ret; | |
200 | } | |
201 | return 0; | |
202 | } | |
203 | ||
4fcc084e | 204 | int twl4030_i2c_read(u8 chip_no, u8 reg, u8 *valp, int len) |
fb1b7712 JJH |
205 | { |
206 | struct udevice *dev; | |
207 | int ret; | |
208 | ||
209 | ret = i2c_get_chip_for_busnum(0, chip_no, 1, &dev); | |
210 | if (ret) { | |
211 | pr_err("unable to get I2C bus. ret %d\n", ret); | |
212 | return ret; | |
213 | } | |
4fcc084e T |
214 | ret = dm_i2c_read(dev, reg, valp, len); |
215 | if (ret) { | |
fb1b7712 JJH |
216 | pr_err("reading from twl4030 failed. ret %d\n", ret); |
217 | return ret; | |
218 | } | |
fb1b7712 JJH |
219 | return 0; |
220 | } | |
221 | #endif |