Commit 1032fbfd792f2b384ac16a63993b8fae5eea9083
Committed by
Linus Walleij
1 parent
f0e733f32e
Exists in
master
and in
7 other branches
mach-ux500: voltage domain regulators for DB8500
The DB8500 has ePOD:s (electronic power domains) which are possible to switch on/off to deactivate silicon blocks on the DB8500 SoC by cutting their power without retention. We model these as simple regulators with one bit on/off settings. Acked-by: Liam Girdwood <lrg@slimlogic.co.uk> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Bengt Jonsson <bengt.g.jonsson@stericsson.com> Signed-off-by: Sundar Iyer <sundar.iyer@stericsson.com> Signed-off-by: Jonas Aberg <jonas.aberg@stericsson.com> Signed-off-by: Virupax Sadashivpetimath <virupax.sadashivpetimath@stericsson.com> Signed-off-by: Martin Persson <martin.persson@stericsson.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Showing 6 changed files with 791 additions and 0 deletions Side-by-side Diff
arch/arm/mach-ux500/Kconfig
drivers/mfd/db8500-prcmu.c
... | ... | @@ -28,6 +28,8 @@ |
28 | 28 | #include <linux/uaccess.h> |
29 | 29 | #include <linux/mfd/core.h> |
30 | 30 | #include <linux/mfd/db8500-prcmu.h> |
31 | +#include <linux/regulator/db8500-prcmu.h> | |
32 | +#include <linux/regulator/machine.h> | |
31 | 33 | #include <mach/hardware.h> |
32 | 34 | #include <mach/irqs.h> |
33 | 35 | #include <mach/db8500-regs.h> |
34 | 36 | |
... | ... | @@ -1824,9 +1826,186 @@ |
1824 | 1826 | } |
1825 | 1827 | } |
1826 | 1828 | |
1829 | +/* | |
1830 | + * Power domain switches (ePODs) modeled as regulators for the DB8500 SoC | |
1831 | + */ | |
1832 | +static struct regulator_consumer_supply db8500_vape_consumers[] = { | |
1833 | + REGULATOR_SUPPLY("v-ape", NULL), | |
1834 | + REGULATOR_SUPPLY("v-i2c", "nmk-i2c.0"), | |
1835 | + REGULATOR_SUPPLY("v-i2c", "nmk-i2c.1"), | |
1836 | + REGULATOR_SUPPLY("v-i2c", "nmk-i2c.2"), | |
1837 | + REGULATOR_SUPPLY("v-i2c", "nmk-i2c.3"), | |
1838 | + /* "v-mmc" changed to "vcore" in the mainline kernel */ | |
1839 | + REGULATOR_SUPPLY("vcore", "sdi0"), | |
1840 | + REGULATOR_SUPPLY("vcore", "sdi1"), | |
1841 | + REGULATOR_SUPPLY("vcore", "sdi2"), | |
1842 | + REGULATOR_SUPPLY("vcore", "sdi3"), | |
1843 | + REGULATOR_SUPPLY("vcore", "sdi4"), | |
1844 | + REGULATOR_SUPPLY("v-dma", "dma40.0"), | |
1845 | + REGULATOR_SUPPLY("v-ape", "ab8500-usb.0"), | |
1846 | + /* "v-uart" changed to "vcore" in the mainline kernel */ | |
1847 | + REGULATOR_SUPPLY("vcore", "uart0"), | |
1848 | + REGULATOR_SUPPLY("vcore", "uart1"), | |
1849 | + REGULATOR_SUPPLY("vcore", "uart2"), | |
1850 | + REGULATOR_SUPPLY("v-ape", "nmk-ske-keypad.0"), | |
1851 | +}; | |
1852 | + | |
1853 | +static struct regulator_consumer_supply db8500_vsmps2_consumers[] = { | |
1854 | + /* CG2900 and CW1200 power to off-chip peripherals */ | |
1855 | + REGULATOR_SUPPLY("gbf_1v8", "cg2900-uart.0"), | |
1856 | + REGULATOR_SUPPLY("wlan_1v8", "cw1200.0"), | |
1857 | + REGULATOR_SUPPLY("musb_1v8", "ab8500-usb.0"), | |
1858 | + /* AV8100 regulator */ | |
1859 | + REGULATOR_SUPPLY("hdmi_1v8", "0-0070"), | |
1860 | +}; | |
1861 | + | |
1862 | +static struct regulator_consumer_supply db8500_b2r2_mcde_consumers[] = { | |
1863 | + REGULATOR_SUPPLY("vsupply", "b2r2.0"), | |
1864 | + REGULATOR_SUPPLY("vsupply", "mcde.0"), | |
1865 | +}; | |
1866 | + | |
1867 | +static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = { | |
1868 | + [DB8500_REGULATOR_VAPE] = { | |
1869 | + .constraints = { | |
1870 | + .name = "db8500-vape", | |
1871 | + .valid_ops_mask = REGULATOR_CHANGE_STATUS, | |
1872 | + }, | |
1873 | + .consumer_supplies = db8500_vape_consumers, | |
1874 | + .num_consumer_supplies = ARRAY_SIZE(db8500_vape_consumers), | |
1875 | + }, | |
1876 | + [DB8500_REGULATOR_VARM] = { | |
1877 | + .constraints = { | |
1878 | + .name = "db8500-varm", | |
1879 | + .valid_ops_mask = REGULATOR_CHANGE_STATUS, | |
1880 | + }, | |
1881 | + }, | |
1882 | + [DB8500_REGULATOR_VMODEM] = { | |
1883 | + .constraints = { | |
1884 | + .name = "db8500-vmodem", | |
1885 | + .valid_ops_mask = REGULATOR_CHANGE_STATUS, | |
1886 | + }, | |
1887 | + }, | |
1888 | + [DB8500_REGULATOR_VPLL] = { | |
1889 | + .constraints = { | |
1890 | + .name = "db8500-vpll", | |
1891 | + .valid_ops_mask = REGULATOR_CHANGE_STATUS, | |
1892 | + }, | |
1893 | + }, | |
1894 | + [DB8500_REGULATOR_VSMPS1] = { | |
1895 | + .constraints = { | |
1896 | + .name = "db8500-vsmps1", | |
1897 | + .valid_ops_mask = REGULATOR_CHANGE_STATUS, | |
1898 | + }, | |
1899 | + }, | |
1900 | + [DB8500_REGULATOR_VSMPS2] = { | |
1901 | + .constraints = { | |
1902 | + .name = "db8500-vsmps2", | |
1903 | + .valid_ops_mask = REGULATOR_CHANGE_STATUS, | |
1904 | + }, | |
1905 | + .consumer_supplies = db8500_vsmps2_consumers, | |
1906 | + .num_consumer_supplies = ARRAY_SIZE(db8500_vsmps2_consumers), | |
1907 | + }, | |
1908 | + [DB8500_REGULATOR_VSMPS3] = { | |
1909 | + .constraints = { | |
1910 | + .name = "db8500-vsmps3", | |
1911 | + .valid_ops_mask = REGULATOR_CHANGE_STATUS, | |
1912 | + }, | |
1913 | + }, | |
1914 | + [DB8500_REGULATOR_VRF1] = { | |
1915 | + .constraints = { | |
1916 | + .name = "db8500-vrf1", | |
1917 | + .valid_ops_mask = REGULATOR_CHANGE_STATUS, | |
1918 | + }, | |
1919 | + }, | |
1920 | + [DB8500_REGULATOR_SWITCH_SVAMMDSP] = { | |
1921 | + .supply_regulator = "db8500-vape", | |
1922 | + .constraints = { | |
1923 | + .name = "db8500-sva-mmdsp", | |
1924 | + .valid_ops_mask = REGULATOR_CHANGE_STATUS, | |
1925 | + }, | |
1926 | + }, | |
1927 | + [DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = { | |
1928 | + .constraints = { | |
1929 | + /* "ret" means "retention" */ | |
1930 | + .name = "db8500-sva-mmdsp-ret", | |
1931 | + .valid_ops_mask = REGULATOR_CHANGE_STATUS, | |
1932 | + }, | |
1933 | + }, | |
1934 | + [DB8500_REGULATOR_SWITCH_SVAPIPE] = { | |
1935 | + .supply_regulator = "db8500-vape", | |
1936 | + .constraints = { | |
1937 | + .name = "db8500-sva-pipe", | |
1938 | + .valid_ops_mask = REGULATOR_CHANGE_STATUS, | |
1939 | + }, | |
1940 | + }, | |
1941 | + [DB8500_REGULATOR_SWITCH_SIAMMDSP] = { | |
1942 | + .supply_regulator = "db8500-vape", | |
1943 | + .constraints = { | |
1944 | + .name = "db8500-sia-mmdsp", | |
1945 | + .valid_ops_mask = REGULATOR_CHANGE_STATUS, | |
1946 | + }, | |
1947 | + }, | |
1948 | + [DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = { | |
1949 | + .constraints = { | |
1950 | + .name = "db8500-sia-mmdsp-ret", | |
1951 | + .valid_ops_mask = REGULATOR_CHANGE_STATUS, | |
1952 | + }, | |
1953 | + }, | |
1954 | + [DB8500_REGULATOR_SWITCH_SIAPIPE] = { | |
1955 | + .supply_regulator = "db8500-vape", | |
1956 | + .constraints = { | |
1957 | + .name = "db8500-sia-pipe", | |
1958 | + .valid_ops_mask = REGULATOR_CHANGE_STATUS, | |
1959 | + }, | |
1960 | + }, | |
1961 | + [DB8500_REGULATOR_SWITCH_SGA] = { | |
1962 | + .supply_regulator = "db8500-vape", | |
1963 | + .constraints = { | |
1964 | + .name = "db8500-sga", | |
1965 | + .valid_ops_mask = REGULATOR_CHANGE_STATUS, | |
1966 | + }, | |
1967 | + }, | |
1968 | + [DB8500_REGULATOR_SWITCH_B2R2_MCDE] = { | |
1969 | + .supply_regulator = "db8500-vape", | |
1970 | + .constraints = { | |
1971 | + .name = "db8500-b2r2-mcde", | |
1972 | + .valid_ops_mask = REGULATOR_CHANGE_STATUS, | |
1973 | + }, | |
1974 | + .consumer_supplies = db8500_b2r2_mcde_consumers, | |
1975 | + .num_consumer_supplies = ARRAY_SIZE(db8500_b2r2_mcde_consumers), | |
1976 | + }, | |
1977 | + [DB8500_REGULATOR_SWITCH_ESRAM12] = { | |
1978 | + .supply_regulator = "db8500-vape", | |
1979 | + .constraints = { | |
1980 | + .name = "db8500-esram12", | |
1981 | + .valid_ops_mask = REGULATOR_CHANGE_STATUS, | |
1982 | + }, | |
1983 | + }, | |
1984 | + [DB8500_REGULATOR_SWITCH_ESRAM12RET] = { | |
1985 | + .constraints = { | |
1986 | + .name = "db8500-esram12-ret", | |
1987 | + .valid_ops_mask = REGULATOR_CHANGE_STATUS, | |
1988 | + }, | |
1989 | + }, | |
1990 | + [DB8500_REGULATOR_SWITCH_ESRAM34] = { | |
1991 | + .supply_regulator = "db8500-vape", | |
1992 | + .constraints = { | |
1993 | + .name = "db8500-esram34", | |
1994 | + .valid_ops_mask = REGULATOR_CHANGE_STATUS, | |
1995 | + }, | |
1996 | + }, | |
1997 | + [DB8500_REGULATOR_SWITCH_ESRAM34RET] = { | |
1998 | + .constraints = { | |
1999 | + .name = "db8500-esram34-ret", | |
2000 | + .valid_ops_mask = REGULATOR_CHANGE_STATUS, | |
2001 | + }, | |
2002 | + }, | |
2003 | +}; | |
2004 | + | |
1827 | 2005 | static struct mfd_cell db8500_prcmu_devs[] = { |
1828 | 2006 | { |
1829 | 2007 | .name = "db8500-prcmu-regulators", |
2008 | + .mfd_data = &db8500_regulators, | |
1830 | 2009 | }, |
1831 | 2010 | { |
1832 | 2011 | .name = "cpufreq-u8500", |
drivers/regulator/Kconfig
... | ... | @@ -274,6 +274,13 @@ |
274 | 274 | This driver supports the regulators found on the ST-Ericsson mixed |
275 | 275 | signal AB8500 PMIC |
276 | 276 | |
277 | +config REGULATOR_DB8500_PRCMU | |
278 | + bool "ST-Ericsson DB8500 Voltage Domain Regulators" | |
279 | + depends on MFD_DB8500_PRCMU | |
280 | + help | |
281 | + This driver supports the voltage domain regulators controlled by the | |
282 | + DB8500 PRCMU | |
283 | + | |
277 | 284 | config REGULATOR_TPS6586X |
278 | 285 | tristate "TI TPS6586X Power regulators" |
279 | 286 | depends on MFD_TPS6586X |
drivers/regulator/Makefile
... | ... | @@ -41,6 +41,7 @@ |
41 | 41 | obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o |
42 | 42 | obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o |
43 | 43 | obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o |
44 | +obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o | |
44 | 45 | |
45 | 46 | ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG |
drivers/regulator/db8500-prcmu.c
1 | +/* | |
2 | + * Copyright (C) ST-Ericsson SA 2010 | |
3 | + * | |
4 | + * License Terms: GNU General Public License v2 | |
5 | + * Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson | |
6 | + * Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson | |
7 | + * | |
8 | + * Power domain regulators on DB8500 | |
9 | + */ | |
10 | + | |
11 | +#include <linux/kernel.h> | |
12 | +#include <linux/init.h> | |
13 | +#include <linux/err.h> | |
14 | +#include <linux/spinlock.h> | |
15 | +#include <linux/platform_device.h> | |
16 | +#include <linux/mfd/core.h> | |
17 | +#include <linux/mfd/db8500-prcmu.h> | |
18 | +#include <linux/regulator/driver.h> | |
19 | +#include <linux/regulator/machine.h> | |
20 | +#include <linux/regulator/db8500-prcmu.h> | |
21 | + | |
22 | +/* | |
23 | + * power state reference count | |
24 | + */ | |
25 | +static int power_state_active_cnt; /* will initialize to zero */ | |
26 | +static DEFINE_SPINLOCK(power_state_active_lock); | |
27 | + | |
28 | +static void power_state_active_enable(void) | |
29 | +{ | |
30 | + unsigned long flags; | |
31 | + | |
32 | + spin_lock_irqsave(&power_state_active_lock, flags); | |
33 | + power_state_active_cnt++; | |
34 | + spin_unlock_irqrestore(&power_state_active_lock, flags); | |
35 | +} | |
36 | + | |
37 | +static int power_state_active_disable(void) | |
38 | +{ | |
39 | + int ret = 0; | |
40 | + unsigned long flags; | |
41 | + | |
42 | + spin_lock_irqsave(&power_state_active_lock, flags); | |
43 | + if (power_state_active_cnt <= 0) { | |
44 | + pr_err("power state: unbalanced enable/disable calls\n"); | |
45 | + ret = -EINVAL; | |
46 | + goto out; | |
47 | + } | |
48 | + | |
49 | + power_state_active_cnt--; | |
50 | +out: | |
51 | + spin_unlock_irqrestore(&power_state_active_lock, flags); | |
52 | + return ret; | |
53 | +} | |
54 | + | |
55 | +/* | |
56 | + * Exported interface for CPUIdle only. This function is called when interrupts | |
57 | + * are turned off. Hence, no locking. | |
58 | + */ | |
59 | +int power_state_active_is_enabled(void) | |
60 | +{ | |
61 | + return (power_state_active_cnt > 0); | |
62 | +} | |
63 | + | |
64 | +/** | |
65 | + * struct db8500_regulator_info - db8500 regulator information | |
66 | + * @dev: device pointer | |
67 | + * @desc: regulator description | |
68 | + * @rdev: regulator device pointer | |
69 | + * @is_enabled: status of the regulator | |
70 | + * @epod_id: id for EPOD (power domain) | |
71 | + * @is_ramret: RAM retention switch for EPOD (power domain) | |
72 | + * @operating_point: operating point (only for vape, to be removed) | |
73 | + * | |
74 | + */ | |
75 | +struct db8500_regulator_info { | |
76 | + struct device *dev; | |
77 | + struct regulator_desc desc; | |
78 | + struct regulator_dev *rdev; | |
79 | + bool is_enabled; | |
80 | + u16 epod_id; | |
81 | + bool is_ramret; | |
82 | + bool exclude_from_power_state; | |
83 | + unsigned int operating_point; | |
84 | +}; | |
85 | + | |
86 | +static int db8500_regulator_enable(struct regulator_dev *rdev) | |
87 | +{ | |
88 | + struct db8500_regulator_info *info = rdev_get_drvdata(rdev); | |
89 | + | |
90 | + if (info == NULL) | |
91 | + return -EINVAL; | |
92 | + | |
93 | + dev_vdbg(rdev_get_dev(rdev), "regulator-%s-enable\n", | |
94 | + info->desc.name); | |
95 | + | |
96 | + info->is_enabled = true; | |
97 | + if (!info->exclude_from_power_state) | |
98 | + power_state_active_enable(); | |
99 | + | |
100 | + return 0; | |
101 | +} | |
102 | + | |
103 | +static int db8500_regulator_disable(struct regulator_dev *rdev) | |
104 | +{ | |
105 | + struct db8500_regulator_info *info = rdev_get_drvdata(rdev); | |
106 | + int ret = 0; | |
107 | + | |
108 | + if (info == NULL) | |
109 | + return -EINVAL; | |
110 | + | |
111 | + dev_vdbg(rdev_get_dev(rdev), "regulator-%s-disable\n", | |
112 | + info->desc.name); | |
113 | + | |
114 | + info->is_enabled = false; | |
115 | + if (!info->exclude_from_power_state) | |
116 | + ret = power_state_active_disable(); | |
117 | + | |
118 | + return ret; | |
119 | +} | |
120 | + | |
121 | +static int db8500_regulator_is_enabled(struct regulator_dev *rdev) | |
122 | +{ | |
123 | + struct db8500_regulator_info *info = rdev_get_drvdata(rdev); | |
124 | + | |
125 | + if (info == NULL) | |
126 | + return -EINVAL; | |
127 | + | |
128 | + dev_vdbg(rdev_get_dev(rdev), "regulator-%s-is_enabled (is_enabled):" | |
129 | + " %i\n", info->desc.name, info->is_enabled); | |
130 | + | |
131 | + return info->is_enabled; | |
132 | +} | |
133 | + | |
134 | +/* db8500 regulator operations */ | |
135 | +static struct regulator_ops db8500_regulator_ops = { | |
136 | + .enable = db8500_regulator_enable, | |
137 | + .disable = db8500_regulator_disable, | |
138 | + .is_enabled = db8500_regulator_is_enabled, | |
139 | +}; | |
140 | + | |
141 | +/* | |
142 | + * EPOD control | |
143 | + */ | |
144 | +static bool epod_on[NUM_EPOD_ID]; | |
145 | +static bool epod_ramret[NUM_EPOD_ID]; | |
146 | + | |
147 | +static int enable_epod(u16 epod_id, bool ramret) | |
148 | +{ | |
149 | + int ret; | |
150 | + | |
151 | + if (ramret) { | |
152 | + if (!epod_on[epod_id]) { | |
153 | + ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET); | |
154 | + if (ret < 0) | |
155 | + return ret; | |
156 | + } | |
157 | + epod_ramret[epod_id] = true; | |
158 | + } else { | |
159 | + ret = prcmu_set_epod(epod_id, EPOD_STATE_ON); | |
160 | + if (ret < 0) | |
161 | + return ret; | |
162 | + epod_on[epod_id] = true; | |
163 | + } | |
164 | + | |
165 | + return 0; | |
166 | +} | |
167 | + | |
168 | +static int disable_epod(u16 epod_id, bool ramret) | |
169 | +{ | |
170 | + int ret; | |
171 | + | |
172 | + if (ramret) { | |
173 | + if (!epod_on[epod_id]) { | |
174 | + ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF); | |
175 | + if (ret < 0) | |
176 | + return ret; | |
177 | + } | |
178 | + epod_ramret[epod_id] = false; | |
179 | + } else { | |
180 | + if (epod_ramret[epod_id]) { | |
181 | + ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET); | |
182 | + if (ret < 0) | |
183 | + return ret; | |
184 | + } else { | |
185 | + ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF); | |
186 | + if (ret < 0) | |
187 | + return ret; | |
188 | + } | |
189 | + epod_on[epod_id] = false; | |
190 | + } | |
191 | + | |
192 | + return 0; | |
193 | +} | |
194 | + | |
195 | +/* | |
196 | + * Regulator switch | |
197 | + */ | |
198 | +static int db8500_regulator_switch_enable(struct regulator_dev *rdev) | |
199 | +{ | |
200 | + struct db8500_regulator_info *info = rdev_get_drvdata(rdev); | |
201 | + int ret; | |
202 | + | |
203 | + if (info == NULL) | |
204 | + return -EINVAL; | |
205 | + | |
206 | + dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-enable\n", | |
207 | + info->desc.name); | |
208 | + | |
209 | + ret = enable_epod(info->epod_id, info->is_ramret); | |
210 | + if (ret < 0) { | |
211 | + dev_err(rdev_get_dev(rdev), | |
212 | + "regulator-switch-%s-enable: prcmu call failed\n", | |
213 | + info->desc.name); | |
214 | + goto out; | |
215 | + } | |
216 | + | |
217 | + info->is_enabled = true; | |
218 | +out: | |
219 | + return ret; | |
220 | +} | |
221 | + | |
222 | +static int db8500_regulator_switch_disable(struct regulator_dev *rdev) | |
223 | +{ | |
224 | + struct db8500_regulator_info *info = rdev_get_drvdata(rdev); | |
225 | + int ret; | |
226 | + | |
227 | + if (info == NULL) | |
228 | + return -EINVAL; | |
229 | + | |
230 | + dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-disable\n", | |
231 | + info->desc.name); | |
232 | + | |
233 | + ret = disable_epod(info->epod_id, info->is_ramret); | |
234 | + if (ret < 0) { | |
235 | + dev_err(rdev_get_dev(rdev), | |
236 | + "regulator_switch-%s-disable: prcmu call failed\n", | |
237 | + info->desc.name); | |
238 | + goto out; | |
239 | + } | |
240 | + | |
241 | + info->is_enabled = 0; | |
242 | +out: | |
243 | + return ret; | |
244 | +} | |
245 | + | |
246 | +static int db8500_regulator_switch_is_enabled(struct regulator_dev *rdev) | |
247 | +{ | |
248 | + struct db8500_regulator_info *info = rdev_get_drvdata(rdev); | |
249 | + | |
250 | + if (info == NULL) | |
251 | + return -EINVAL; | |
252 | + | |
253 | + dev_vdbg(rdev_get_dev(rdev), | |
254 | + "regulator-switch-%s-is_enabled (is_enabled): %i\n", | |
255 | + info->desc.name, info->is_enabled); | |
256 | + | |
257 | + return info->is_enabled; | |
258 | +} | |
259 | + | |
260 | +static struct regulator_ops db8500_regulator_switch_ops = { | |
261 | + .enable = db8500_regulator_switch_enable, | |
262 | + .disable = db8500_regulator_switch_disable, | |
263 | + .is_enabled = db8500_regulator_switch_is_enabled, | |
264 | +}; | |
265 | + | |
266 | +/* | |
267 | + * Regulator information | |
268 | + */ | |
269 | +static struct db8500_regulator_info | |
270 | + db8500_regulator_info[DB8500_NUM_REGULATORS] = { | |
271 | + [DB8500_REGULATOR_VAPE] = { | |
272 | + .desc = { | |
273 | + .name = "db8500-vape", | |
274 | + .id = DB8500_REGULATOR_VAPE, | |
275 | + .ops = &db8500_regulator_ops, | |
276 | + .type = REGULATOR_VOLTAGE, | |
277 | + .owner = THIS_MODULE, | |
278 | + }, | |
279 | + }, | |
280 | + [DB8500_REGULATOR_VARM] = { | |
281 | + .desc = { | |
282 | + .name = "db8500-varm", | |
283 | + .id = DB8500_REGULATOR_VARM, | |
284 | + .ops = &db8500_regulator_ops, | |
285 | + .type = REGULATOR_VOLTAGE, | |
286 | + .owner = THIS_MODULE, | |
287 | + }, | |
288 | + }, | |
289 | + [DB8500_REGULATOR_VMODEM] = { | |
290 | + .desc = { | |
291 | + .name = "db8500-vmodem", | |
292 | + .id = DB8500_REGULATOR_VMODEM, | |
293 | + .ops = &db8500_regulator_ops, | |
294 | + .type = REGULATOR_VOLTAGE, | |
295 | + .owner = THIS_MODULE, | |
296 | + }, | |
297 | + }, | |
298 | + [DB8500_REGULATOR_VPLL] = { | |
299 | + .desc = { | |
300 | + .name = "db8500-vpll", | |
301 | + .id = DB8500_REGULATOR_VPLL, | |
302 | + .ops = &db8500_regulator_ops, | |
303 | + .type = REGULATOR_VOLTAGE, | |
304 | + .owner = THIS_MODULE, | |
305 | + }, | |
306 | + }, | |
307 | + [DB8500_REGULATOR_VSMPS1] = { | |
308 | + .desc = { | |
309 | + .name = "db8500-vsmps1", | |
310 | + .id = DB8500_REGULATOR_VSMPS1, | |
311 | + .ops = &db8500_regulator_ops, | |
312 | + .type = REGULATOR_VOLTAGE, | |
313 | + .owner = THIS_MODULE, | |
314 | + }, | |
315 | + }, | |
316 | + [DB8500_REGULATOR_VSMPS2] = { | |
317 | + .desc = { | |
318 | + .name = "db8500-vsmps2", | |
319 | + .id = DB8500_REGULATOR_VSMPS2, | |
320 | + .ops = &db8500_regulator_ops, | |
321 | + .type = REGULATOR_VOLTAGE, | |
322 | + .owner = THIS_MODULE, | |
323 | + }, | |
324 | + .exclude_from_power_state = true, | |
325 | + }, | |
326 | + [DB8500_REGULATOR_VSMPS3] = { | |
327 | + .desc = { | |
328 | + .name = "db8500-vsmps3", | |
329 | + .id = DB8500_REGULATOR_VSMPS3, | |
330 | + .ops = &db8500_regulator_ops, | |
331 | + .type = REGULATOR_VOLTAGE, | |
332 | + .owner = THIS_MODULE, | |
333 | + }, | |
334 | + }, | |
335 | + [DB8500_REGULATOR_VRF1] = { | |
336 | + .desc = { | |
337 | + .name = "db8500-vrf1", | |
338 | + .id = DB8500_REGULATOR_VRF1, | |
339 | + .ops = &db8500_regulator_ops, | |
340 | + .type = REGULATOR_VOLTAGE, | |
341 | + .owner = THIS_MODULE, | |
342 | + }, | |
343 | + }, | |
344 | + [DB8500_REGULATOR_SWITCH_SVAMMDSP] = { | |
345 | + .desc = { | |
346 | + .name = "db8500-sva-mmdsp", | |
347 | + .id = DB8500_REGULATOR_SWITCH_SVAMMDSP, | |
348 | + .ops = &db8500_regulator_switch_ops, | |
349 | + .type = REGULATOR_VOLTAGE, | |
350 | + .owner = THIS_MODULE, | |
351 | + }, | |
352 | + .epod_id = EPOD_ID_SVAMMDSP, | |
353 | + }, | |
354 | + [DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = { | |
355 | + .desc = { | |
356 | + .name = "db8500-sva-mmdsp-ret", | |
357 | + .id = DB8500_REGULATOR_SWITCH_SVAMMDSPRET, | |
358 | + .ops = &db8500_regulator_switch_ops, | |
359 | + .type = REGULATOR_VOLTAGE, | |
360 | + .owner = THIS_MODULE, | |
361 | + }, | |
362 | + .epod_id = EPOD_ID_SVAMMDSP, | |
363 | + .is_ramret = true, | |
364 | + }, | |
365 | + [DB8500_REGULATOR_SWITCH_SVAPIPE] = { | |
366 | + .desc = { | |
367 | + .name = "db8500-sva-pipe", | |
368 | + .id = DB8500_REGULATOR_SWITCH_SVAPIPE, | |
369 | + .ops = &db8500_regulator_switch_ops, | |
370 | + .type = REGULATOR_VOLTAGE, | |
371 | + .owner = THIS_MODULE, | |
372 | + }, | |
373 | + .epod_id = EPOD_ID_SVAPIPE, | |
374 | + }, | |
375 | + [DB8500_REGULATOR_SWITCH_SIAMMDSP] = { | |
376 | + .desc = { | |
377 | + .name = "db8500-sia-mmdsp", | |
378 | + .id = DB8500_REGULATOR_SWITCH_SIAMMDSP, | |
379 | + .ops = &db8500_regulator_switch_ops, | |
380 | + .type = REGULATOR_VOLTAGE, | |
381 | + .owner = THIS_MODULE, | |
382 | + }, | |
383 | + .epod_id = EPOD_ID_SIAMMDSP, | |
384 | + }, | |
385 | + [DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = { | |
386 | + .desc = { | |
387 | + .name = "db8500-sia-mmdsp-ret", | |
388 | + .id = DB8500_REGULATOR_SWITCH_SIAMMDSPRET, | |
389 | + .ops = &db8500_regulator_switch_ops, | |
390 | + .type = REGULATOR_VOLTAGE, | |
391 | + .owner = THIS_MODULE, | |
392 | + }, | |
393 | + .epod_id = EPOD_ID_SIAMMDSP, | |
394 | + .is_ramret = true, | |
395 | + }, | |
396 | + [DB8500_REGULATOR_SWITCH_SIAPIPE] = { | |
397 | + .desc = { | |
398 | + .name = "db8500-sia-pipe", | |
399 | + .id = DB8500_REGULATOR_SWITCH_SIAPIPE, | |
400 | + .ops = &db8500_regulator_switch_ops, | |
401 | + .type = REGULATOR_VOLTAGE, | |
402 | + .owner = THIS_MODULE, | |
403 | + }, | |
404 | + .epod_id = EPOD_ID_SIAPIPE, | |
405 | + }, | |
406 | + [DB8500_REGULATOR_SWITCH_SGA] = { | |
407 | + .desc = { | |
408 | + .name = "db8500-sga", | |
409 | + .id = DB8500_REGULATOR_SWITCH_SGA, | |
410 | + .ops = &db8500_regulator_switch_ops, | |
411 | + .type = REGULATOR_VOLTAGE, | |
412 | + .owner = THIS_MODULE, | |
413 | + }, | |
414 | + .epod_id = EPOD_ID_SGA, | |
415 | + }, | |
416 | + [DB8500_REGULATOR_SWITCH_B2R2_MCDE] = { | |
417 | + .desc = { | |
418 | + .name = "db8500-b2r2-mcde", | |
419 | + .id = DB8500_REGULATOR_SWITCH_B2R2_MCDE, | |
420 | + .ops = &db8500_regulator_switch_ops, | |
421 | + .type = REGULATOR_VOLTAGE, | |
422 | + .owner = THIS_MODULE, | |
423 | + }, | |
424 | + .epod_id = EPOD_ID_B2R2_MCDE, | |
425 | + }, | |
426 | + [DB8500_REGULATOR_SWITCH_ESRAM12] = { | |
427 | + .desc = { | |
428 | + .name = "db8500-esram12", | |
429 | + .id = DB8500_REGULATOR_SWITCH_ESRAM12, | |
430 | + .ops = &db8500_regulator_switch_ops, | |
431 | + .type = REGULATOR_VOLTAGE, | |
432 | + .owner = THIS_MODULE, | |
433 | + }, | |
434 | + .epod_id = EPOD_ID_ESRAM12, | |
435 | + .is_enabled = true, | |
436 | + }, | |
437 | + [DB8500_REGULATOR_SWITCH_ESRAM12RET] = { | |
438 | + .desc = { | |
439 | + .name = "db8500-esram12-ret", | |
440 | + .id = DB8500_REGULATOR_SWITCH_ESRAM12RET, | |
441 | + .ops = &db8500_regulator_switch_ops, | |
442 | + .type = REGULATOR_VOLTAGE, | |
443 | + .owner = THIS_MODULE, | |
444 | + }, | |
445 | + .epod_id = EPOD_ID_ESRAM12, | |
446 | + .is_ramret = true, | |
447 | + }, | |
448 | + [DB8500_REGULATOR_SWITCH_ESRAM34] = { | |
449 | + .desc = { | |
450 | + .name = "db8500-esram34", | |
451 | + .id = DB8500_REGULATOR_SWITCH_ESRAM34, | |
452 | + .ops = &db8500_regulator_switch_ops, | |
453 | + .type = REGULATOR_VOLTAGE, | |
454 | + .owner = THIS_MODULE, | |
455 | + }, | |
456 | + .epod_id = EPOD_ID_ESRAM34, | |
457 | + .is_enabled = true, | |
458 | + }, | |
459 | + [DB8500_REGULATOR_SWITCH_ESRAM34RET] = { | |
460 | + .desc = { | |
461 | + .name = "db8500-esram34-ret", | |
462 | + .id = DB8500_REGULATOR_SWITCH_ESRAM34RET, | |
463 | + .ops = &db8500_regulator_switch_ops, | |
464 | + .type = REGULATOR_VOLTAGE, | |
465 | + .owner = THIS_MODULE, | |
466 | + }, | |
467 | + .epod_id = EPOD_ID_ESRAM34, | |
468 | + .is_ramret = true, | |
469 | + }, | |
470 | +}; | |
471 | + | |
472 | +static int __devinit db8500_regulator_probe(struct platform_device *pdev) | |
473 | +{ | |
474 | + struct regulator_init_data *db8500_init_data = mfd_get_data(pdev); | |
475 | + int i, err; | |
476 | + | |
477 | + /* register all regulators */ | |
478 | + for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) { | |
479 | + struct db8500_regulator_info *info; | |
480 | + struct regulator_init_data *init_data = &db8500_init_data[i]; | |
481 | + | |
482 | + /* assign per-regulator data */ | |
483 | + info = &db8500_regulator_info[i]; | |
484 | + info->dev = &pdev->dev; | |
485 | + | |
486 | + /* register with the regulator framework */ | |
487 | + info->rdev = regulator_register(&info->desc, &pdev->dev, | |
488 | + init_data, info); | |
489 | + if (IS_ERR(info->rdev)) { | |
490 | + err = PTR_ERR(info->rdev); | |
491 | + dev_err(&pdev->dev, "failed to register %s: err %i\n", | |
492 | + info->desc.name, err); | |
493 | + | |
494 | + /* if failing, unregister all earlier regulators */ | |
495 | + i--; | |
496 | + while (i >= 0) { | |
497 | + info = &db8500_regulator_info[i]; | |
498 | + regulator_unregister(info->rdev); | |
499 | + i--; | |
500 | + } | |
501 | + return err; | |
502 | + } | |
503 | + | |
504 | + dev_dbg(rdev_get_dev(info->rdev), | |
505 | + "regulator-%s-probed\n", info->desc.name); | |
506 | + } | |
507 | + | |
508 | + return 0; | |
509 | +} | |
510 | + | |
511 | +static int __exit db8500_regulator_remove(struct platform_device *pdev) | |
512 | +{ | |
513 | + int i; | |
514 | + | |
515 | + for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) { | |
516 | + struct db8500_regulator_info *info; | |
517 | + info = &db8500_regulator_info[i]; | |
518 | + | |
519 | + dev_vdbg(rdev_get_dev(info->rdev), | |
520 | + "regulator-%s-remove\n", info->desc.name); | |
521 | + | |
522 | + regulator_unregister(info->rdev); | |
523 | + } | |
524 | + | |
525 | + return 0; | |
526 | +} | |
527 | + | |
528 | +static struct platform_driver db8500_regulator_driver = { | |
529 | + .driver = { | |
530 | + .name = "db8500-prcmu-regulators", | |
531 | + .owner = THIS_MODULE, | |
532 | + }, | |
533 | + .probe = db8500_regulator_probe, | |
534 | + .remove = __exit_p(db8500_regulator_remove), | |
535 | +}; | |
536 | + | |
537 | +static int __init db8500_regulator_init(void) | |
538 | +{ | |
539 | + int ret; | |
540 | + | |
541 | + ret = platform_driver_register(&db8500_regulator_driver); | |
542 | + if (ret < 0) | |
543 | + return -ENODEV; | |
544 | + | |
545 | + return 0; | |
546 | +} | |
547 | + | |
548 | +static void __exit db8500_regulator_exit(void) | |
549 | +{ | |
550 | + platform_driver_unregister(&db8500_regulator_driver); | |
551 | +} | |
552 | + | |
553 | +arch_initcall(db8500_regulator_init); | |
554 | +module_exit(db8500_regulator_exit); | |
555 | + | |
556 | +MODULE_AUTHOR("STMicroelectronics/ST-Ericsson"); | |
557 | +MODULE_DESCRIPTION("DB8500 regulator driver"); | |
558 | +MODULE_LICENSE("GPL v2"); |
include/linux/regulator/db8500-prcmu.h
1 | +/* | |
2 | + * Copyright (C) ST-Ericsson SA 2010 | |
3 | + * | |
4 | + * License Terms: GNU General Public License v2 | |
5 | + * | |
6 | + * Author: Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson | |
7 | + * | |
8 | + * Interface to power domain regulators on DB8500 | |
9 | + */ | |
10 | + | |
11 | +#ifndef __REGULATOR_H__ | |
12 | +#define __REGULATOR_H__ | |
13 | + | |
14 | +/* Number of DB8500 regulators and regulator enumeration */ | |
15 | +enum db8500_regulator_id { | |
16 | + DB8500_REGULATOR_VAPE, | |
17 | + DB8500_REGULATOR_VARM, | |
18 | + DB8500_REGULATOR_VMODEM, | |
19 | + DB8500_REGULATOR_VPLL, | |
20 | + DB8500_REGULATOR_VSMPS1, | |
21 | + DB8500_REGULATOR_VSMPS2, | |
22 | + DB8500_REGULATOR_VSMPS3, | |
23 | + DB8500_REGULATOR_VRF1, | |
24 | + DB8500_REGULATOR_SWITCH_SVAMMDSP, | |
25 | + DB8500_REGULATOR_SWITCH_SVAMMDSPRET, | |
26 | + DB8500_REGULATOR_SWITCH_SVAPIPE, | |
27 | + DB8500_REGULATOR_SWITCH_SIAMMDSP, | |
28 | + DB8500_REGULATOR_SWITCH_SIAMMDSPRET, | |
29 | + DB8500_REGULATOR_SWITCH_SIAPIPE, | |
30 | + DB8500_REGULATOR_SWITCH_SGA, | |
31 | + DB8500_REGULATOR_SWITCH_B2R2_MCDE, | |
32 | + DB8500_REGULATOR_SWITCH_ESRAM12, | |
33 | + DB8500_REGULATOR_SWITCH_ESRAM12RET, | |
34 | + DB8500_REGULATOR_SWITCH_ESRAM34, | |
35 | + DB8500_REGULATOR_SWITCH_ESRAM34RET, | |
36 | + DB8500_NUM_REGULATORS | |
37 | +}; | |
38 | + | |
39 | +/* | |
40 | + * Exported interface for CPUIdle only. This function is called with all | |
41 | + * interrupts turned off. | |
42 | + */ | |
43 | +int power_state_active_is_enabled(void); | |
44 | + | |
45 | +#endif |