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

MAX8952 PMIC Driver Initial Release

MAX8952 PMIC is used to provide voltage output between 770mV - 1400mV
with DVS support. In this initial release, users can set voltages for
four DVS modes, RAMP delay values, and SYNC frequency.
Controlling FPWM/SYNC_MODE/Pull-Down/Ramp Modes and reading CHIP_ID
is not supported in this release.

If GPIO of EN is not valid in platform data, the driver assumes that it
is always-on. If GPIO of VID0 or VID1 is invalid, the driver pulls down
VID0 and VID1 to fix DVS mode as 0 and disables DVS support.

We assume that V_OUT is capable to provide every voltage from 770mV to
1.40V in 10mV steps although the data sheet has some ambiguity on it.

Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
--
v2:
- Style correction
- Can accept platform_data with invalid GPIOs
- Removed unnecessary features
- Improved error handling
Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>

authored by

MyungJoo Ham and committed by
Liam Girdwood
202f4f53 2d3b07c0

+504
+8
drivers/regulator/Kconfig
··· 100 100 help 101 101 Say y here to support the voltage regulaltor of Maxim MAX8925 PMIC. 102 102 103 + config REGULATOR_MAX8952 104 + tristate "Maxim MAX8952 Power Management IC" 105 + depends on I2C 106 + help 107 + This driver controls a Maxim 8952 voltage output regulator 108 + via I2C bus. Maxim 8952 has one voltage output and supports 4 DVS 109 + modes ranging from 0.77V to 1.40V by 0.01V steps. 110 + 103 111 config REGULATOR_MAX8998 104 112 tristate "Maxim 8998 voltage regulator" 105 113 depends on MFD_MAX8998
+1
drivers/regulator/Makefile
··· 17 17 obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o 18 18 obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o 19 19 obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o 20 + obj-$(CONFIG_REGULATOR_MAX8952) += max8952.o 20 21 obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o 21 22 obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o 22 23 obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
+360
drivers/regulator/max8952.c
··· 1 + /* 2 + * max8952.c - Voltage and current regulation for the Maxim 8952 3 + * 4 + * Copyright (C) 2010 Samsung Electronics 5 + * MyungJoo Ham <myungjoo.ham@samsung.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 as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 + */ 21 + 22 + #include <linux/module.h> 23 + #include <linux/init.h> 24 + #include <linux/i2c.h> 25 + #include <linux/err.h> 26 + #include <linux/platform_device.h> 27 + #include <linux/regulator/driver.h> 28 + #include <linux/regulator/max8952.h> 29 + #include <linux/mutex.h> 30 + #include <linux/gpio.h> 31 + #include <linux/io.h> 32 + #include <linux/slab.h> 33 + 34 + /* Registers */ 35 + enum { 36 + MAX8952_REG_MODE0, 37 + MAX8952_REG_MODE1, 38 + MAX8952_REG_MODE2, 39 + MAX8952_REG_MODE3, 40 + MAX8952_REG_CONTROL, 41 + MAX8952_REG_SYNC, 42 + MAX8952_REG_RAMP, 43 + MAX8952_REG_CHIP_ID1, 44 + MAX8952_REG_CHIP_ID2, 45 + }; 46 + 47 + struct max8952_data { 48 + struct i2c_client *client; 49 + struct device *dev; 50 + struct mutex mutex; 51 + struct max8952_platform_data *pdata; 52 + struct regulator_dev *rdev; 53 + 54 + bool vid0; 55 + bool vid1; 56 + bool en; 57 + }; 58 + 59 + static int max8952_read_reg(struct max8952_data *max8952, u8 reg) 60 + { 61 + int ret = i2c_smbus_read_byte_data(max8952->client, reg); 62 + if (ret > 0) 63 + ret &= 0xff; 64 + 65 + return ret; 66 + } 67 + 68 + static int max8952_write_reg(struct max8952_data *max8952, 69 + u8 reg, u8 value) 70 + { 71 + return i2c_smbus_write_byte_data(max8952->client, reg, value); 72 + } 73 + 74 + static int max8952_voltage(struct max8952_data *max8952, u8 mode) 75 + { 76 + return (max8952->pdata->dvs_mode[mode] * 10 + 770) * 1000; 77 + } 78 + 79 + static int max8952_list_voltage(struct regulator_dev *rdev, 80 + unsigned int selector) 81 + { 82 + struct max8952_data *max8952 = rdev_get_drvdata(rdev); 83 + 84 + if (rdev_get_id(rdev) != 0) 85 + return -EINVAL; 86 + 87 + return max8952_voltage(max8952, selector); 88 + } 89 + 90 + static int max8952_is_enabled(struct regulator_dev *rdev) 91 + { 92 + struct max8952_data *max8952 = rdev_get_drvdata(rdev); 93 + return max8952->en; 94 + } 95 + 96 + static int max8952_enable(struct regulator_dev *rdev) 97 + { 98 + struct max8952_data *max8952 = rdev_get_drvdata(rdev); 99 + 100 + /* If not valid, assume "ALWAYS_HIGH" */ 101 + if (gpio_is_valid(max8952->pdata->gpio_en)) 102 + gpio_set_value(max8952->pdata->gpio_en, 1); 103 + 104 + max8952->en = true; 105 + return 0; 106 + } 107 + 108 + static int max8952_disable(struct regulator_dev *rdev) 109 + { 110 + struct max8952_data *max8952 = rdev_get_drvdata(rdev); 111 + 112 + /* If not valid, assume "ALWAYS_HIGH" -> not permitted */ 113 + if (gpio_is_valid(max8952->pdata->gpio_en)) 114 + gpio_set_value(max8952->pdata->gpio_en, 0); 115 + else 116 + return -EPERM; 117 + 118 + max8952->en = false; 119 + return 0; 120 + } 121 + 122 + static int max8952_get_voltage(struct regulator_dev *rdev) 123 + { 124 + struct max8952_data *max8952 = rdev_get_drvdata(rdev); 125 + u8 vid = 0; 126 + 127 + if (max8952->vid0) 128 + vid += 1; 129 + if (max8952->vid1) 130 + vid += 2; 131 + 132 + return max8952_voltage(max8952, vid); 133 + } 134 + 135 + static int max8952_set_voltage(struct regulator_dev *rdev, 136 + int min_uV, int max_uV) 137 + { 138 + struct max8952_data *max8952 = rdev_get_drvdata(rdev); 139 + u8 vid = -1, i; 140 + 141 + if (!gpio_is_valid(max8952->pdata->gpio_vid0) || 142 + !gpio_is_valid(max8952->pdata->gpio_vid0)) { 143 + /* DVS not supported */ 144 + return -EPERM; 145 + } 146 + 147 + for (i = 0; i < MAX8952_NUM_DVS_MODE; i++) { 148 + int volt = max8952_voltage(max8952, i); 149 + 150 + /* Set the voltage as low as possible within the range */ 151 + if (volt <= max_uV && volt >= min_uV) 152 + if (vid == -1 || max8952_voltage(max8952, vid) > volt) 153 + vid = i; 154 + } 155 + 156 + if (vid >= 0 && vid < MAX8952_NUM_DVS_MODE) { 157 + max8952->vid0 = (vid % 2 == 1); 158 + max8952->vid1 = (((vid >> 1) % 2) == 1); 159 + gpio_set_value(max8952->pdata->gpio_vid0, max8952->vid0); 160 + gpio_set_value(max8952->pdata->gpio_vid1, max8952->vid1); 161 + } else 162 + return -EINVAL; 163 + 164 + return 0; 165 + } 166 + 167 + static struct regulator_ops max8952_ops = { 168 + .list_voltage = max8952_list_voltage, 169 + .is_enabled = max8952_is_enabled, 170 + .enable = max8952_enable, 171 + .disable = max8952_disable, 172 + .get_voltage = max8952_get_voltage, 173 + .set_voltage = max8952_set_voltage, 174 + .set_suspend_disable = max8952_disable, 175 + }; 176 + 177 + static struct regulator_desc regulator = { 178 + .name = "MAX8952_VOUT", 179 + .id = 0, 180 + .n_voltages = MAX8952_NUM_DVS_MODE, 181 + .ops = &max8952_ops, 182 + .type = REGULATOR_VOLTAGE, 183 + .owner = THIS_MODULE, 184 + }; 185 + 186 + static int __devinit max8952_pmic_probe(struct i2c_client *client, 187 + const struct i2c_device_id *i2c_id) 188 + { 189 + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 190 + struct max8952_platform_data *pdata = client->dev.platform_data; 191 + struct max8952_data *max8952; 192 + 193 + int ret = 0, err = 0; 194 + 195 + if (!pdata) { 196 + dev_err(&client->dev, "Require the platform data\n"); 197 + return -EINVAL; 198 + } 199 + 200 + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) 201 + return -EIO; 202 + 203 + max8952 = kzalloc(sizeof(struct max8952_data), GFP_KERNEL); 204 + if (!max8952) 205 + return -ENOMEM; 206 + 207 + max8952->client = client; 208 + max8952->dev = &client->dev; 209 + max8952->pdata = pdata; 210 + mutex_init(&max8952->mutex); 211 + 212 + max8952->rdev = regulator_register(&regulator, max8952->dev, 213 + &pdata->reg_data, max8952); 214 + 215 + ret = IS_ERR(max8952->rdev); 216 + if (ret) 217 + dev_err(max8952->dev, "regulator init failed (%d)\n", ret); 218 + 219 + max8952->en = !!(pdata->reg_data.constraints.boot_on); 220 + max8952->vid0 = (pdata->default_mode % 2) == 1; 221 + max8952->vid1 = ((pdata->default_mode >> 1) % 2) == 1; 222 + 223 + if (gpio_is_valid(pdata->gpio_en)) { 224 + if (!gpio_request(pdata->gpio_en, "MAX8952 EN")) 225 + gpio_direction_output(pdata->gpio_en, max8952->en); 226 + else 227 + err = 1; 228 + } else 229 + err = 2; 230 + 231 + if (err) { 232 + dev_info(max8952->dev, "EN gpio invalid: assume that EN" 233 + "is always High\n"); 234 + max8952->en = 1; 235 + pdata->gpio_en = -1; /* Mark invalid */ 236 + } 237 + 238 + err = 0; 239 + 240 + if (gpio_is_valid(pdata->gpio_vid0) && 241 + gpio_is_valid(pdata->gpio_vid1)) { 242 + if (!gpio_request(pdata->gpio_vid0, "MAX8952 VID0")) 243 + gpio_direction_output(pdata->gpio_vid0, 244 + (pdata->default_mode) % 2); 245 + else 246 + err = 1; 247 + 248 + if (!gpio_request(pdata->gpio_vid1, "MAX8952 VID1")) 249 + gpio_direction_output(pdata->gpio_vid1, 250 + (pdata->default_mode >> 1) % 2); 251 + else { 252 + if (!err) 253 + gpio_free(pdata->gpio_vid0); 254 + err = 2; 255 + } 256 + 257 + } else 258 + err = 3; 259 + 260 + if (err) { 261 + dev_warn(max8952->dev, "VID0/1 gpio invalid: " 262 + "DVS not avilable.\n"); 263 + max8952->vid0 = 0; 264 + max8952->vid1 = 0; 265 + /* Mark invalid */ 266 + pdata->gpio_vid0 = -1; 267 + pdata->gpio_vid1 = -1; 268 + 269 + /* Disable Pulldown of EN only */ 270 + max8952_write_reg(max8952, MAX8952_REG_CONTROL, 0x60); 271 + 272 + dev_err(max8952->dev, "DVS modes disabled because VID0 and VID1" 273 + " do not have proper controls.\n"); 274 + } else { 275 + /* 276 + * Disable Pulldown on EN, VID0, VID1 to reduce 277 + * leakage current of MAX8952 assuming that MAX8952 278 + * is turned on (EN==1). Note that without having VID0/1 279 + * properly connected, turning pulldown off can be 280 + * problematic. Thus, turn this off only when they are 281 + * controllable by GPIO. 282 + */ 283 + max8952_write_reg(max8952, MAX8952_REG_CONTROL, 0x0); 284 + } 285 + 286 + max8952_write_reg(max8952, MAX8952_REG_MODE0, 287 + (max8952_read_reg(max8952, 288 + MAX8952_REG_MODE0) & 0xC0) | 289 + (pdata->dvs_mode[0] & 0x3F)); 290 + max8952_write_reg(max8952, MAX8952_REG_MODE1, 291 + (max8952_read_reg(max8952, 292 + MAX8952_REG_MODE1) & 0xC0) | 293 + (pdata->dvs_mode[1] & 0x3F)); 294 + max8952_write_reg(max8952, MAX8952_REG_MODE2, 295 + (max8952_read_reg(max8952, 296 + MAX8952_REG_MODE2) & 0xC0) | 297 + (pdata->dvs_mode[2] & 0x3F)); 298 + max8952_write_reg(max8952, MAX8952_REG_MODE3, 299 + (max8952_read_reg(max8952, 300 + MAX8952_REG_MODE3) & 0xC0) | 301 + (pdata->dvs_mode[3] & 0x3F)); 302 + 303 + max8952_write_reg(max8952, MAX8952_REG_SYNC, 304 + (max8952_read_reg(max8952, MAX8952_REG_SYNC) & 0x3F) | 305 + ((pdata->sync_freq & 0x3) << 6)); 306 + max8952_write_reg(max8952, MAX8952_REG_RAMP, 307 + (max8952_read_reg(max8952, MAX8952_REG_RAMP) & 0x1F) | 308 + ((pdata->ramp_speed & 0x7) << 5)); 309 + 310 + i2c_set_clientdata(client, max8952); 311 + 312 + return ret; 313 + } 314 + 315 + static int __devexit max8952_pmic_remove(struct i2c_client *client) 316 + { 317 + struct max8952_data *max8952 = i2c_get_clientdata(client); 318 + struct max8952_platform_data *pdata = max8952->pdata; 319 + struct regulator_dev *rdev = max8952->rdev; 320 + 321 + regulator_unregister(rdev); 322 + 323 + gpio_free(pdata->gpio_vid0); 324 + gpio_free(pdata->gpio_vid1); 325 + gpio_free(pdata->gpio_en); 326 + 327 + kfree(max8952); 328 + return 0; 329 + } 330 + 331 + static const struct i2c_device_id max8952_ids[] = { 332 + { "max8952", 0 }, 333 + { }, 334 + }; 335 + MODULE_DEVICE_TABLE(i2c, max8952_ids); 336 + 337 + static struct i2c_driver max8952_pmic_driver = { 338 + .probe = max8952_pmic_probe, 339 + .remove = __devexit_p(max8952_pmic_remove), 340 + .driver = { 341 + .name = "max8952", 342 + }, 343 + .id_table = max8952_ids, 344 + }; 345 + 346 + static int __init max8952_pmic_init(void) 347 + { 348 + return i2c_add_driver(&max8952_pmic_driver); 349 + } 350 + subsys_initcall(max8952_pmic_init); 351 + 352 + static void __exit max8952_pmic_exit(void) 353 + { 354 + i2c_del_driver(&max8952_pmic_driver); 355 + } 356 + module_exit(max8952_pmic_exit); 357 + 358 + MODULE_DESCRIPTION("MAXIM 8952 voltage regulator driver"); 359 + MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>"); 360 + MODULE_LICENSE("GPL");
+135
include/linux/regulator/max8952.h
··· 1 + /* 2 + * max8952.h - Voltage regulation for the Maxim 8952 3 + * 4 + * Copyright (C) 2010 Samsung Electrnoics 5 + * MyungJoo Ham <myungjoo.ham@samsung.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 as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 + */ 21 + 22 + #ifndef REGULATOR_MAX8952 23 + #define REGULATOR_MAX8952 24 + 25 + #include <linux/regulator/machine.h> 26 + 27 + enum { 28 + MAX8952_DVS_MODE0, 29 + MAX8952_DVS_MODE1, 30 + MAX8952_DVS_MODE2, 31 + MAX8952_DVS_MODE3, 32 + }; 33 + 34 + enum { 35 + MAX8952_DVS_770mV = 0, 36 + MAX8952_DVS_780mV, 37 + MAX8952_DVS_790mV, 38 + MAX8952_DVS_800mV, 39 + MAX8952_DVS_810mV, 40 + MAX8952_DVS_820mV, 41 + MAX8952_DVS_830mV, 42 + MAX8952_DVS_840mV, 43 + MAX8952_DVS_850mV, 44 + MAX8952_DVS_860mV, 45 + MAX8952_DVS_870mV, 46 + MAX8952_DVS_880mV, 47 + MAX8952_DVS_890mV, 48 + MAX8952_DVS_900mV, 49 + MAX8952_DVS_910mV, 50 + MAX8952_DVS_920mV, 51 + MAX8952_DVS_930mV, 52 + MAX8952_DVS_940mV, 53 + MAX8952_DVS_950mV, 54 + MAX8952_DVS_960mV, 55 + MAX8952_DVS_970mV, 56 + MAX8952_DVS_980mV, 57 + MAX8952_DVS_990mV, 58 + MAX8952_DVS_1000mV, 59 + MAX8952_DVS_1010mV, 60 + MAX8952_DVS_1020mV, 61 + MAX8952_DVS_1030mV, 62 + MAX8952_DVS_1040mV, 63 + MAX8952_DVS_1050mV, 64 + MAX8952_DVS_1060mV, 65 + MAX8952_DVS_1070mV, 66 + MAX8952_DVS_1080mV, 67 + MAX8952_DVS_1090mV, 68 + MAX8952_DVS_1100mV, 69 + MAX8952_DVS_1110mV, 70 + MAX8952_DVS_1120mV, 71 + MAX8952_DVS_1130mV, 72 + MAX8952_DVS_1140mV, 73 + MAX8952_DVS_1150mV, 74 + MAX8952_DVS_1160mV, 75 + MAX8952_DVS_1170mV, 76 + MAX8952_DVS_1180mV, 77 + MAX8952_DVS_1190mV, 78 + MAX8952_DVS_1200mV, 79 + MAX8952_DVS_1210mV, 80 + MAX8952_DVS_1220mV, 81 + MAX8952_DVS_1230mV, 82 + MAX8952_DVS_1240mV, 83 + MAX8952_DVS_1250mV, 84 + MAX8952_DVS_1260mV, 85 + MAX8952_DVS_1270mV, 86 + MAX8952_DVS_1280mV, 87 + MAX8952_DVS_1290mV, 88 + MAX8952_DVS_1300mV, 89 + MAX8952_DVS_1310mV, 90 + MAX8952_DVS_1320mV, 91 + MAX8952_DVS_1330mV, 92 + MAX8952_DVS_1340mV, 93 + MAX8952_DVS_1350mV, 94 + MAX8952_DVS_1360mV, 95 + MAX8952_DVS_1370mV, 96 + MAX8952_DVS_1380mV, 97 + MAX8952_DVS_1390mV, 98 + MAX8952_DVS_1400mV, 99 + }; 100 + 101 + enum { 102 + MAX8952_SYNC_FREQ_26MHZ, /* Default */ 103 + MAX8952_SYNC_FREQ_13MHZ, 104 + MAX8952_SYNC_FREQ_19_2MHZ, 105 + }; 106 + 107 + enum { 108 + MAX8952_RAMP_32mV_us = 0, /* Default */ 109 + MAX8952_RAMP_16mV_us, 110 + MAX8952_RAMP_8mV_us, 111 + MAX8952_RAMP_4mV_us, 112 + MAX8952_RAMP_2mV_us, 113 + MAX8952_RAMP_1mV_us, 114 + MAX8952_RAMP_0_5mV_us, 115 + MAX8952_RAMP_0_25mV_us, 116 + }; 117 + 118 + #define MAX8952_NUM_DVS_MODE 4 119 + 120 + struct max8952_platform_data { 121 + int gpio_vid0; 122 + int gpio_vid1; 123 + int gpio_en; 124 + 125 + u8 default_mode; 126 + u8 dvs_mode[MAX8952_NUM_DVS_MODE]; /* MAX8952_DVS_MODEx_XXXXmV */ 127 + 128 + u8 sync_freq; 129 + u8 ramp_speed; 130 + 131 + struct regulator_init_data reg_data; 132 + }; 133 + 134 + 135 + #endif /* REGULATOR_MAX8952 */