1 /* 2 * Regulators driver for Maxim max8649 3 * 4 * Copyright (C) 2009-2010 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/module.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/slab.h> 18 #include <linux/regulator/max8649.h> 19 #include <linux/regmap.h> 20 21 #define MAX8649_DCDC_VMIN 750000 /* uV */ 22 #define MAX8649_DCDC_VMAX 1380000 /* uV */ 23 #define MAX8649_DCDC_STEP 10000 /* uV */ 24 #define MAX8649_VOL_MASK 0x3f 25 26 /* Registers */ 27 #define MAX8649_MODE0 0x00 28 #define MAX8649_MODE1 0x01 29 #define MAX8649_MODE2 0x02 30 #define MAX8649_MODE3 0x03 31 #define MAX8649_CONTROL 0x04 32 #define MAX8649_SYNC 0x05 33 #define MAX8649_RAMP 0x06 34 #define MAX8649_CHIP_ID1 0x08 35 #define MAX8649_CHIP_ID2 0x09 36 37 /* Bits */ 38 #define MAX8649_EN_PD (1 << 7) 39 #define MAX8649_VID0_PD (1 << 6) 40 #define MAX8649_VID1_PD (1 << 5) 41 #define MAX8649_VID_MASK (3 << 5) 42 43 #define MAX8649_FORCE_PWM (1 << 7) 44 #define MAX8649_SYNC_EXTCLK (1 << 6) 45 46 #define MAX8649_EXT_MASK (3 << 6) 47 48 #define MAX8649_RAMP_MASK (7 << 5) 49 #define MAX8649_RAMP_DOWN (1 << 1) 50 51 struct max8649_regulator_info { 52 struct regulator_dev *regulator; 53 struct device *dev; 54 struct regmap *regmap; 55 56 int vol_reg; 57 unsigned mode:2; /* bit[1:0] = VID1, VID0 */ 58 unsigned extclk_freq:2; 59 unsigned extclk:1; 60 unsigned ramp_timing:3; 61 unsigned ramp_down:1; 62 }; 63 64 /* I2C operations */ 65 66 static inline int check_range(int min_uV, int max_uV) 67 { 68 if ((min_uV < MAX8649_DCDC_VMIN) || (max_uV > MAX8649_DCDC_VMAX) 69 || (min_uV > max_uV)) 70 return -EINVAL; 71 return 0; 72 } 73 74 static int max8649_list_voltage(struct regulator_dev *rdev, unsigned index) 75 { 76 return (MAX8649_DCDC_VMIN + index * MAX8649_DCDC_STEP); 77 } 78 79 static int max8649_get_voltage(struct regulator_dev *rdev) 80 { 81 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 82 unsigned int val; 83 unsigned char data; 84 int ret; 85 86 ret = regmap_read(info->regmap, info->vol_reg, &val); 87 if (ret != 0) 88 return ret; 89 data = (unsigned char)val & MAX8649_VOL_MASK; 90 return max8649_list_voltage(rdev, data); 91 } 92 93 static int max8649_set_voltage(struct regulator_dev *rdev, 94 int min_uV, int max_uV, unsigned *selector) 95 { 96 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 97 unsigned char data, mask; 98 99 if (check_range(min_uV, max_uV)) { 100 dev_err(info->dev, "invalid voltage range (%d, %d) uV\n", 101 min_uV, max_uV); 102 return -EINVAL; 103 } 104 data = (min_uV - MAX8649_DCDC_VMIN + MAX8649_DCDC_STEP - 1) 105 / MAX8649_DCDC_STEP; 106 mask = MAX8649_VOL_MASK; 107 *selector = data & mask; 108 109 return regmap_update_bits(info->regmap, info->vol_reg, mask, data); 110 } 111 112 /* EN_PD means pulldown on EN input */ 113 static int max8649_enable(struct regulator_dev *rdev) 114 { 115 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 116 return regmap_update_bits(info->regmap, MAX8649_CONTROL, MAX8649_EN_PD, 0); 117 } 118 119 /* 120 * Applied internal pulldown resistor on EN input pin. 121 * If pulldown EN pin outside, it would be better. 122 */ 123 static int max8649_disable(struct regulator_dev *rdev) 124 { 125 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 126 return regmap_update_bits(info->regmap, MAX8649_CONTROL, MAX8649_EN_PD, 127 MAX8649_EN_PD); 128 } 129 130 static int max8649_is_enabled(struct regulator_dev *rdev) 131 { 132 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 133 unsigned int val; 134 int ret; 135 136 ret = regmap_read(info->regmap, MAX8649_CONTROL, &val); 137 if (ret != 0) 138 return ret; 139 return !((unsigned char)val & MAX8649_EN_PD); 140 } 141 142 static int max8649_enable_time(struct regulator_dev *rdev) 143 { 144 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 145 int voltage, rate, ret; 146 unsigned int val; 147 148 /* get voltage */ 149 ret = regmap_read(info->regmap, info->vol_reg, &val); 150 if (ret != 0) 151 return ret; 152 val &= MAX8649_VOL_MASK; 153 voltage = max8649_list_voltage(rdev, (unsigned char)val); /* uV */ 154 155 /* get rate */ 156 ret = regmap_read(info->regmap, MAX8649_RAMP, &val); 157 if (ret != 0) 158 return ret; 159 ret = (val & MAX8649_RAMP_MASK) >> 5; 160 rate = (32 * 1000) >> ret; /* uV/uS */ 161 162 return DIV_ROUND_UP(voltage, rate); 163 } 164 165 static int max8649_set_mode(struct regulator_dev *rdev, unsigned int mode) 166 { 167 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 168 169 switch (mode) { 170 case REGULATOR_MODE_FAST: 171 regmap_update_bits(info->regmap, info->vol_reg, MAX8649_FORCE_PWM, 172 MAX8649_FORCE_PWM); 173 break; 174 case REGULATOR_MODE_NORMAL: 175 regmap_update_bits(info->regmap, info->vol_reg, 176 MAX8649_FORCE_PWM, 0); 177 break; 178 default: 179 return -EINVAL; 180 } 181 return 0; 182 } 183 184 static unsigned int max8649_get_mode(struct regulator_dev *rdev) 185 { 186 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 187 unsigned int val; 188 int ret; 189 190 ret = regmap_read(info->regmap, info->vol_reg, &val); 191 if (ret != 0) 192 return ret; 193 if (val & MAX8649_FORCE_PWM) 194 return REGULATOR_MODE_FAST; 195 return REGULATOR_MODE_NORMAL; 196 } 197 198 static struct regulator_ops max8649_dcdc_ops = { 199 .set_voltage = max8649_set_voltage, 200 .get_voltage = max8649_get_voltage, 201 .list_voltage = max8649_list_voltage, 202 .enable = max8649_enable, 203 .disable = max8649_disable, 204 .is_enabled = max8649_is_enabled, 205 .enable_time = max8649_enable_time, 206 .set_mode = max8649_set_mode, 207 .get_mode = max8649_get_mode, 208 209 }; 210 211 static struct regulator_desc dcdc_desc = { 212 .name = "max8649", 213 .ops = &max8649_dcdc_ops, 214 .type = REGULATOR_VOLTAGE, 215 .n_voltages = 1 << 6, 216 .owner = THIS_MODULE, 217 }; 218 219 static struct regmap_config max8649_regmap_config = { 220 .reg_bits = 8, 221 .val_bits = 8, 222 }; 223 224 static int __devinit max8649_regulator_probe(struct i2c_client *client, 225 const struct i2c_device_id *id) 226 { 227 struct max8649_platform_data *pdata = client->dev.platform_data; 228 struct max8649_regulator_info *info = NULL; 229 unsigned int val; 230 unsigned char data; 231 int ret; 232 233 info = kzalloc(sizeof(struct max8649_regulator_info), GFP_KERNEL); 234 if (!info) { 235 dev_err(&client->dev, "No enough memory\n"); 236 return -ENOMEM; 237 } 238 239 info->regmap = regmap_init_i2c(client, &max8649_regmap_config); 240 if (IS_ERR(info->regmap)) { 241 ret = PTR_ERR(info->regmap); 242 dev_err(&client->dev, "Failed to allocate register map: %d\n", ret); 243 goto fail; 244 } 245 246 info->dev = &client->dev; 247 i2c_set_clientdata(client, info); 248 249 info->mode = pdata->mode; 250 switch (info->mode) { 251 case 0: 252 info->vol_reg = MAX8649_MODE0; 253 break; 254 case 1: 255 info->vol_reg = MAX8649_MODE1; 256 break; 257 case 2: 258 info->vol_reg = MAX8649_MODE2; 259 break; 260 case 3: 261 info->vol_reg = MAX8649_MODE3; 262 break; 263 default: 264 break; 265 } 266 267 ret = regmap_read(info->regmap, MAX8649_CHIP_ID1, &val); 268 if (ret != 0) { 269 dev_err(info->dev, "Failed to detect ID of MAX8649:%d\n", 270 ret); 271 goto out; 272 } 273 dev_info(info->dev, "Detected MAX8649 (ID:%x)\n", ret); 274 275 /* enable VID0 & VID1 */ 276 regmap_update_bits(info->regmap, MAX8649_CONTROL, MAX8649_VID_MASK, 0); 277 278 /* enable/disable external clock synchronization */ 279 info->extclk = pdata->extclk; 280 data = (info->extclk) ? MAX8649_SYNC_EXTCLK : 0; 281 regmap_update_bits(info->regmap, info->vol_reg, MAX8649_SYNC_EXTCLK, data); 282 if (info->extclk) { 283 /* set external clock frequency */ 284 info->extclk_freq = pdata->extclk_freq; 285 regmap_update_bits(info->regmap, MAX8649_SYNC, MAX8649_EXT_MASK, 286 info->extclk_freq << 6); 287 } 288 289 if (pdata->ramp_timing) { 290 info->ramp_timing = pdata->ramp_timing; 291 regmap_update_bits(info->regmap, MAX8649_RAMP, MAX8649_RAMP_MASK, 292 info->ramp_timing << 5); 293 } 294 295 info->ramp_down = pdata->ramp_down; 296 if (info->ramp_down) { 297 regmap_update_bits(info->regmap, MAX8649_RAMP, MAX8649_RAMP_DOWN, 298 MAX8649_RAMP_DOWN); 299 } 300 301 info->regulator = regulator_register(&dcdc_desc, &client->dev, 302 pdata->regulator, info, NULL); 303 if (IS_ERR(info->regulator)) { 304 dev_err(info->dev, "failed to register regulator %s\n", 305 dcdc_desc.name); 306 ret = PTR_ERR(info->regulator); 307 goto out; 308 } 309 310 dev_info(info->dev, "Max8649 regulator device is detected.\n"); 311 return 0; 312 out: 313 regmap_exit(info->regmap); 314 fail: 315 kfree(info); 316 return ret; 317 } 318 319 static int __devexit max8649_regulator_remove(struct i2c_client *client) 320 { 321 struct max8649_regulator_info *info = i2c_get_clientdata(client); 322 323 if (info) { 324 if (info->regulator) 325 regulator_unregister(info->regulator); 326 regmap_exit(info->regmap); 327 kfree(info); 328 } 329 330 return 0; 331 } 332 333 static const struct i2c_device_id max8649_id[] = { 334 { "max8649", 0 }, 335 { } 336 }; 337 MODULE_DEVICE_TABLE(i2c, max8649_id); 338 339 static struct i2c_driver max8649_driver = { 340 .probe = max8649_regulator_probe, 341 .remove = __devexit_p(max8649_regulator_remove), 342 .driver = { 343 .name = "max8649", 344 }, 345 .id_table = max8649_id, 346 }; 347 348 static int __init max8649_init(void) 349 { 350 return i2c_add_driver(&max8649_driver); 351 } 352 subsys_initcall(max8649_init); 353 354 static void __exit max8649_exit(void) 355 { 356 i2c_del_driver(&max8649_driver); 357 } 358 module_exit(max8649_exit); 359 360 /* Module information */ 361 MODULE_DESCRIPTION("MAXIM 8649 voltage regulator driver"); 362 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); 363 MODULE_LICENSE("GPL"); 364 365