Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Bengt Jonsson and committed by
Linus Walleij
1032fbfd f0e733f3

+791
+1
arch/arm/mach-ux500/Kconfig
··· 17 17 config UX500_SOC_DB8500 18 18 bool "DB8500" 19 19 select MFD_DB8500_PRCMU 20 + select REGULATOR_DB8500_PRCMU 20 21 21 22 endmenu 22 23
+179
drivers/mfd/db8500-prcmu.c
··· 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> ··· 1826 1824 } 1827 1825 } 1828 1826 1827 + /* 1828 + * Power domain switches (ePODs) modeled as regulators for the DB8500 SoC 1829 + */ 1830 + static struct regulator_consumer_supply db8500_vape_consumers[] = { 1831 + REGULATOR_SUPPLY("v-ape", NULL), 1832 + REGULATOR_SUPPLY("v-i2c", "nmk-i2c.0"), 1833 + REGULATOR_SUPPLY("v-i2c", "nmk-i2c.1"), 1834 + REGULATOR_SUPPLY("v-i2c", "nmk-i2c.2"), 1835 + REGULATOR_SUPPLY("v-i2c", "nmk-i2c.3"), 1836 + /* "v-mmc" changed to "vcore" in the mainline kernel */ 1837 + REGULATOR_SUPPLY("vcore", "sdi0"), 1838 + REGULATOR_SUPPLY("vcore", "sdi1"), 1839 + REGULATOR_SUPPLY("vcore", "sdi2"), 1840 + REGULATOR_SUPPLY("vcore", "sdi3"), 1841 + REGULATOR_SUPPLY("vcore", "sdi4"), 1842 + REGULATOR_SUPPLY("v-dma", "dma40.0"), 1843 + REGULATOR_SUPPLY("v-ape", "ab8500-usb.0"), 1844 + /* "v-uart" changed to "vcore" in the mainline kernel */ 1845 + REGULATOR_SUPPLY("vcore", "uart0"), 1846 + REGULATOR_SUPPLY("vcore", "uart1"), 1847 + REGULATOR_SUPPLY("vcore", "uart2"), 1848 + REGULATOR_SUPPLY("v-ape", "nmk-ske-keypad.0"), 1849 + }; 1850 + 1851 + static struct regulator_consumer_supply db8500_vsmps2_consumers[] = { 1852 + /* CG2900 and CW1200 power to off-chip peripherals */ 1853 + REGULATOR_SUPPLY("gbf_1v8", "cg2900-uart.0"), 1854 + REGULATOR_SUPPLY("wlan_1v8", "cw1200.0"), 1855 + REGULATOR_SUPPLY("musb_1v8", "ab8500-usb.0"), 1856 + /* AV8100 regulator */ 1857 + REGULATOR_SUPPLY("hdmi_1v8", "0-0070"), 1858 + }; 1859 + 1860 + static struct regulator_consumer_supply db8500_b2r2_mcde_consumers[] = { 1861 + REGULATOR_SUPPLY("vsupply", "b2r2.0"), 1862 + REGULATOR_SUPPLY("vsupply", "mcde.0"), 1863 + }; 1864 + 1865 + static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = { 1866 + [DB8500_REGULATOR_VAPE] = { 1867 + .constraints = { 1868 + .name = "db8500-vape", 1869 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1870 + }, 1871 + .consumer_supplies = db8500_vape_consumers, 1872 + .num_consumer_supplies = ARRAY_SIZE(db8500_vape_consumers), 1873 + }, 1874 + [DB8500_REGULATOR_VARM] = { 1875 + .constraints = { 1876 + .name = "db8500-varm", 1877 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1878 + }, 1879 + }, 1880 + [DB8500_REGULATOR_VMODEM] = { 1881 + .constraints = { 1882 + .name = "db8500-vmodem", 1883 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1884 + }, 1885 + }, 1886 + [DB8500_REGULATOR_VPLL] = { 1887 + .constraints = { 1888 + .name = "db8500-vpll", 1889 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1890 + }, 1891 + }, 1892 + [DB8500_REGULATOR_VSMPS1] = { 1893 + .constraints = { 1894 + .name = "db8500-vsmps1", 1895 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1896 + }, 1897 + }, 1898 + [DB8500_REGULATOR_VSMPS2] = { 1899 + .constraints = { 1900 + .name = "db8500-vsmps2", 1901 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1902 + }, 1903 + .consumer_supplies = db8500_vsmps2_consumers, 1904 + .num_consumer_supplies = ARRAY_SIZE(db8500_vsmps2_consumers), 1905 + }, 1906 + [DB8500_REGULATOR_VSMPS3] = { 1907 + .constraints = { 1908 + .name = "db8500-vsmps3", 1909 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1910 + }, 1911 + }, 1912 + [DB8500_REGULATOR_VRF1] = { 1913 + .constraints = { 1914 + .name = "db8500-vrf1", 1915 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1916 + }, 1917 + }, 1918 + [DB8500_REGULATOR_SWITCH_SVAMMDSP] = { 1919 + .supply_regulator = "db8500-vape", 1920 + .constraints = { 1921 + .name = "db8500-sva-mmdsp", 1922 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1923 + }, 1924 + }, 1925 + [DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = { 1926 + .constraints = { 1927 + /* "ret" means "retention" */ 1928 + .name = "db8500-sva-mmdsp-ret", 1929 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1930 + }, 1931 + }, 1932 + [DB8500_REGULATOR_SWITCH_SVAPIPE] = { 1933 + .supply_regulator = "db8500-vape", 1934 + .constraints = { 1935 + .name = "db8500-sva-pipe", 1936 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1937 + }, 1938 + }, 1939 + [DB8500_REGULATOR_SWITCH_SIAMMDSP] = { 1940 + .supply_regulator = "db8500-vape", 1941 + .constraints = { 1942 + .name = "db8500-sia-mmdsp", 1943 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1944 + }, 1945 + }, 1946 + [DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = { 1947 + .constraints = { 1948 + .name = "db8500-sia-mmdsp-ret", 1949 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1950 + }, 1951 + }, 1952 + [DB8500_REGULATOR_SWITCH_SIAPIPE] = { 1953 + .supply_regulator = "db8500-vape", 1954 + .constraints = { 1955 + .name = "db8500-sia-pipe", 1956 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1957 + }, 1958 + }, 1959 + [DB8500_REGULATOR_SWITCH_SGA] = { 1960 + .supply_regulator = "db8500-vape", 1961 + .constraints = { 1962 + .name = "db8500-sga", 1963 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1964 + }, 1965 + }, 1966 + [DB8500_REGULATOR_SWITCH_B2R2_MCDE] = { 1967 + .supply_regulator = "db8500-vape", 1968 + .constraints = { 1969 + .name = "db8500-b2r2-mcde", 1970 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1971 + }, 1972 + .consumer_supplies = db8500_b2r2_mcde_consumers, 1973 + .num_consumer_supplies = ARRAY_SIZE(db8500_b2r2_mcde_consumers), 1974 + }, 1975 + [DB8500_REGULATOR_SWITCH_ESRAM12] = { 1976 + .supply_regulator = "db8500-vape", 1977 + .constraints = { 1978 + .name = "db8500-esram12", 1979 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1980 + }, 1981 + }, 1982 + [DB8500_REGULATOR_SWITCH_ESRAM12RET] = { 1983 + .constraints = { 1984 + .name = "db8500-esram12-ret", 1985 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1986 + }, 1987 + }, 1988 + [DB8500_REGULATOR_SWITCH_ESRAM34] = { 1989 + .supply_regulator = "db8500-vape", 1990 + .constraints = { 1991 + .name = "db8500-esram34", 1992 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1993 + }, 1994 + }, 1995 + [DB8500_REGULATOR_SWITCH_ESRAM34RET] = { 1996 + .constraints = { 1997 + .name = "db8500-esram34-ret", 1998 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1999 + }, 2000 + }, 2001 + }; 2002 + 1829 2003 static struct mfd_cell db8500_prcmu_devs[] = { 1830 2004 { 1831 2005 .name = "db8500-prcmu-regulators", 2006 + .mfd_data = &db8500_regulators, 1832 2007 }, 1833 2008 { 1834 2009 .name = "cpufreq-u8500",
+7
drivers/regulator/Kconfig
··· 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
+1
drivers/regulator/Makefile
··· 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
+558
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");
+45
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