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

regulator: Add max8925 support

MAX8925 contains 3 Buck and 20 LDO regulator.

Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

authored by

Haojian Zhuang and committed by
Samuel Ortiz
08ff6f2a 4f811ef0

+313
+6
drivers/regulator/Kconfig
··· 94 94 This driver controls a Maxim 8660/8661 voltage output 95 95 regulator via I2C bus. 96 96 97 + config REGULATOR_MAX8925 98 + tristate "Maxim MAX8925 Power Management IC" 99 + depends on MFD_MAX8925 100 + help 101 + Say y here to support the voltage regulaltor of Maxim MAX8925 PMIC. 102 + 97 103 config REGULATOR_TWL4030 98 104 bool "TI TWL4030/TWL5030/TWL6030/TPS695x0 PMIC" 99 105 depends on TWL4030_CORE
+1
drivers/regulator/Makefile
··· 15 15 obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o 16 16 obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o 17 17 obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o 18 + obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o 18 19 obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o 19 20 obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o 20 21 obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
+306
drivers/regulator/max8925-regulator.c
··· 1 + /* 2 + * Regulators driver for Maxim max8925 3 + * 4 + * Copyright (C) 2009 Marvell International Ltd. 5 + * Haojian Zhuang <haojian.zhuang@marvell.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + */ 11 + #include <linux/kernel.h> 12 + #include <linux/init.h> 13 + #include <linux/err.h> 14 + #include <linux/i2c.h> 15 + #include <linux/platform_device.h> 16 + #include <linux/regulator/driver.h> 17 + #include <linux/regulator/machine.h> 18 + #include <linux/mfd/max8925.h> 19 + 20 + #define SD1_DVM_VMIN 850000 21 + #define SD1_DVM_VMAX 1000000 22 + #define SD1_DVM_STEP 50000 23 + #define SD1_DVM_SHIFT 5 /* SDCTL1 bit5 */ 24 + #define SD1_DVM_EN 6 /* SDV1 bit 6 */ 25 + 26 + struct max8925_regulator_info { 27 + struct regulator_desc desc; 28 + struct regulator_dev *regulator; 29 + struct i2c_client *i2c; 30 + struct max8925_chip *chip; 31 + 32 + int min_uV; 33 + int max_uV; 34 + int step_uV; 35 + int vol_reg; 36 + int vol_shift; 37 + int vol_nbits; 38 + int enable_bit; 39 + int enable_reg; 40 + }; 41 + 42 + static inline int check_range(struct max8925_regulator_info *info, 43 + int min_uV, int max_uV) 44 + { 45 + if (min_uV < info->min_uV || min_uV > info->max_uV) 46 + return -EINVAL; 47 + 48 + return 0; 49 + } 50 + 51 + static int max8925_list_voltage(struct regulator_dev *rdev, unsigned index) 52 + { 53 + struct max8925_regulator_info *info = rdev_get_drvdata(rdev); 54 + return info->min_uV + index * info->step_uV; 55 + } 56 + 57 + static int max8925_set_voltage(struct regulator_dev *rdev, 58 + int min_uV, int max_uV) 59 + { 60 + struct max8925_regulator_info *info = rdev_get_drvdata(rdev); 61 + unsigned char data, mask; 62 + 63 + if (check_range(info, min_uV, max_uV)) { 64 + dev_err(info->chip->dev, "invalid voltage range (%d, %d) uV\n", 65 + min_uV, max_uV); 66 + return -EINVAL; 67 + } 68 + data = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; 69 + data <<= info->vol_shift; 70 + mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; 71 + 72 + return max8925_set_bits(info->i2c, info->vol_reg, mask, data); 73 + } 74 + 75 + static int max8925_get_voltage(struct regulator_dev *rdev) 76 + { 77 + struct max8925_regulator_info *info = rdev_get_drvdata(rdev); 78 + unsigned char data, mask; 79 + int ret; 80 + 81 + ret = max8925_reg_read(info->i2c, info->vol_reg); 82 + if (ret < 0) 83 + return ret; 84 + mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; 85 + data = (ret & mask) >> info->vol_shift; 86 + 87 + return max8925_list_voltage(rdev, data); 88 + } 89 + 90 + static int max8925_enable(struct regulator_dev *rdev) 91 + { 92 + struct max8925_regulator_info *info = rdev_get_drvdata(rdev); 93 + 94 + return max8925_set_bits(info->i2c, info->enable_reg, 95 + 1 << info->enable_bit, 96 + 1 << info->enable_bit); 97 + } 98 + 99 + static int max8925_disable(struct regulator_dev *rdev) 100 + { 101 + struct max8925_regulator_info *info = rdev_get_drvdata(rdev); 102 + 103 + return max8925_set_bits(info->i2c, info->enable_reg, 104 + 1 << info->enable_bit, 0); 105 + } 106 + 107 + static int max8925_is_enabled(struct regulator_dev *rdev) 108 + { 109 + struct max8925_regulator_info *info = rdev_get_drvdata(rdev); 110 + int ret; 111 + 112 + ret = max8925_reg_read(info->i2c, info->vol_reg); 113 + if (ret < 0) 114 + return ret; 115 + 116 + return ret & (1 << info->enable_bit); 117 + } 118 + 119 + static int max8925_set_dvm_voltage(struct regulator_dev *rdev, int uV) 120 + { 121 + struct max8925_regulator_info *info = rdev_get_drvdata(rdev); 122 + unsigned char data, mask; 123 + 124 + if (uV < SD1_DVM_VMIN || uV > SD1_DVM_VMAX) 125 + return -EINVAL; 126 + 127 + data = (uV - SD1_DVM_VMIN + SD1_DVM_STEP - 1) / SD1_DVM_STEP; 128 + data <<= SD1_DVM_SHIFT; 129 + mask = 3 << SD1_DVM_SHIFT; 130 + 131 + return max8925_set_bits(info->i2c, info->enable_reg, mask, data); 132 + } 133 + 134 + static int max8925_set_dvm_enable(struct regulator_dev *rdev) 135 + { 136 + struct max8925_regulator_info *info = rdev_get_drvdata(rdev); 137 + 138 + return max8925_set_bits(info->i2c, info->vol_reg, 1 << SD1_DVM_EN, 139 + 1 << SD1_DVM_EN); 140 + } 141 + 142 + static int max8925_set_dvm_disable(struct regulator_dev *rdev) 143 + { 144 + struct max8925_regulator_info *info = rdev_get_drvdata(rdev); 145 + 146 + return max8925_set_bits(info->i2c, info->vol_reg, 1 << SD1_DVM_EN, 0); 147 + } 148 + 149 + static struct regulator_ops max8925_regulator_sdv_ops = { 150 + .set_voltage = max8925_set_voltage, 151 + .get_voltage = max8925_get_voltage, 152 + .enable = max8925_enable, 153 + .disable = max8925_disable, 154 + .is_enabled = max8925_is_enabled, 155 + .set_suspend_voltage = max8925_set_dvm_voltage, 156 + .set_suspend_enable = max8925_set_dvm_enable, 157 + .set_suspend_disable = max8925_set_dvm_disable, 158 + }; 159 + 160 + static struct regulator_ops max8925_regulator_ldo_ops = { 161 + .set_voltage = max8925_set_voltage, 162 + .get_voltage = max8925_get_voltage, 163 + .enable = max8925_enable, 164 + .disable = max8925_disable, 165 + .is_enabled = max8925_is_enabled, 166 + }; 167 + 168 + #define MAX8925_SDV(_id, min, max, step) \ 169 + { \ 170 + .desc = { \ 171 + .name = "SDV" #_id, \ 172 + .ops = &max8925_regulator_sdv_ops, \ 173 + .type = REGULATOR_VOLTAGE, \ 174 + .id = MAX8925_ID_SD##_id, \ 175 + .owner = THIS_MODULE, \ 176 + }, \ 177 + .min_uV = min * 1000, \ 178 + .max_uV = max * 1000, \ 179 + .step_uV = step * 1000, \ 180 + .vol_reg = MAX8925_SDV##_id, \ 181 + .vol_shift = 0, \ 182 + .vol_nbits = 6, \ 183 + .enable_reg = MAX8925_SDCTL##_id, \ 184 + .enable_bit = 0, \ 185 + } 186 + 187 + #define MAX8925_LDO(_id, min, max, step) \ 188 + { \ 189 + .desc = { \ 190 + .name = "LDO" #_id, \ 191 + .ops = &max8925_regulator_ldo_ops, \ 192 + .type = REGULATOR_VOLTAGE, \ 193 + .id = MAX8925_ID_LDO##_id, \ 194 + .owner = THIS_MODULE, \ 195 + }, \ 196 + .min_uV = min * 1000, \ 197 + .max_uV = max * 1000, \ 198 + .step_uV = step * 1000, \ 199 + .vol_reg = MAX8925_LDOVOUT##_id, \ 200 + .vol_shift = 0, \ 201 + .vol_nbits = 6, \ 202 + .enable_reg = MAX8925_LDOCTL##_id, \ 203 + .enable_bit = 0, \ 204 + } 205 + 206 + static struct max8925_regulator_info max8925_regulator_info[] = { 207 + MAX8925_SDV(1, 637.5, 1425, 12.5), 208 + MAX8925_SDV(2, 650, 2225, 25), 209 + MAX8925_SDV(3, 750, 3900, 50), 210 + 211 + MAX8925_LDO(1, 750, 3900, 50), 212 + MAX8925_LDO(2, 650, 2250, 25), 213 + MAX8925_LDO(3, 650, 2250, 25), 214 + MAX8925_LDO(4, 750, 3900, 50), 215 + MAX8925_LDO(5, 750, 3900, 50), 216 + MAX8925_LDO(6, 750, 3900, 50), 217 + MAX8925_LDO(7, 750, 3900, 50), 218 + MAX8925_LDO(8, 750, 3900, 50), 219 + MAX8925_LDO(9, 750, 3900, 50), 220 + MAX8925_LDO(10, 750, 3900, 50), 221 + MAX8925_LDO(11, 750, 3900, 50), 222 + MAX8925_LDO(12, 750, 3900, 50), 223 + MAX8925_LDO(13, 750, 3900, 50), 224 + MAX8925_LDO(14, 750, 3900, 50), 225 + MAX8925_LDO(15, 750, 3900, 50), 226 + MAX8925_LDO(16, 750, 3900, 50), 227 + MAX8925_LDO(17, 650, 2250, 25), 228 + MAX8925_LDO(18, 650, 2250, 25), 229 + MAX8925_LDO(19, 750, 3900, 50), 230 + MAX8925_LDO(20, 750, 3900, 50), 231 + }; 232 + 233 + static inline struct max8925_regulator_info *find_regulator_info(int id) 234 + { 235 + struct max8925_regulator_info *ri; 236 + int i; 237 + 238 + for (i = 0; i < ARRAY_SIZE(max8925_regulator_info); i++) { 239 + ri = &max8925_regulator_info[i]; 240 + if (ri->desc.id == id) 241 + return ri; 242 + } 243 + return NULL; 244 + } 245 + 246 + static int __devinit max8925_regulator_probe(struct platform_device *pdev) 247 + { 248 + struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); 249 + struct max8925_platform_data *pdata = chip->dev->platform_data; 250 + struct max8925_regulator_info *ri = NULL; 251 + struct regulator_dev *rdev; 252 + 253 + ri = find_regulator_info(pdev->id); 254 + if (ri == NULL) { 255 + dev_err(&pdev->dev, "invalid regulator ID specified\n"); 256 + return -EINVAL; 257 + } 258 + ri->i2c = chip->i2c; 259 + ri->chip = chip; 260 + 261 + rdev = regulator_register(&ri->desc, &pdev->dev, 262 + pdata->regulator[pdev->id], ri); 263 + if (IS_ERR(rdev)) { 264 + dev_err(&pdev->dev, "failed to register regulator %s\n", 265 + ri->desc.name); 266 + return PTR_ERR(rdev); 267 + } 268 + 269 + platform_set_drvdata(pdev, rdev); 270 + return 0; 271 + } 272 + 273 + static int __devexit max8925_regulator_remove(struct platform_device *pdev) 274 + { 275 + struct regulator_dev *rdev = platform_get_drvdata(pdev); 276 + 277 + regulator_unregister(rdev); 278 + return 0; 279 + } 280 + 281 + static struct platform_driver max8925_regulator_driver = { 282 + .driver = { 283 + .name = "max8925-regulator", 284 + .owner = THIS_MODULE, 285 + }, 286 + .probe = max8925_regulator_probe, 287 + .remove = __devexit_p(max8925_regulator_remove), 288 + }; 289 + 290 + static int __init max8925_regulator_init(void) 291 + { 292 + return platform_driver_register(&max8925_regulator_driver); 293 + } 294 + subsys_initcall(max8925_regulator_init); 295 + 296 + static void __exit max8925_regulator_exit(void) 297 + { 298 + platform_driver_unregister(&max8925_regulator_driver); 299 + } 300 + module_exit(max8925_regulator_exit); 301 + 302 + MODULE_LICENSE("GPL"); 303 + MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); 304 + MODULE_DESCRIPTION("Regulator Driver for Maxim 8925 PMIC"); 305 + MODULE_ALIAS("platform:max8925-regulator"); 306 +