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->enable_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 struct max8925_regulator_info * __devinit 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; 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 platform_set_drvdata(pdev, NULL); 278 regulator_unregister(rdev); 279 280 return 0; 281 } 282 283 static struct platform_driver max8925_regulator_driver = { 284 .driver = { 285 .name = "max8925-regulator", 286 .owner = THIS_MODULE, 287 }, 288 .probe = max8925_regulator_probe, 289 .remove = __devexit_p(max8925_regulator_remove), 290 }; 291 292 static int __init max8925_regulator_init(void) 293 { 294 return platform_driver_register(&max8925_regulator_driver); 295 } 296 subsys_initcall(max8925_regulator_init); 297 298 static void __exit max8925_regulator_exit(void) 299 { 300 platform_driver_unregister(&max8925_regulator_driver); 301 } 302 module_exit(max8925_regulator_exit); 303 304 MODULE_LICENSE("GPL"); 305 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); 306 MODULE_DESCRIPTION("Regulator Driver for Maxim 8925 PMIC"); 307 MODULE_ALIAS("platform:max8925-regulator"); 308 309