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 unsigned mode:2; /* bit[1:0] = VID1, VID0 */ 57 unsigned extclk_freq:2; 58 unsigned extclk:1; 59 unsigned ramp_timing:3; 60 unsigned ramp_down:1; 61 }; 62 63 /* EN_PD means pulldown on EN input */ 64 static int max8649_enable(struct regulator_dev *rdev) 65 { 66 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 67 return regmap_update_bits(info->regmap, MAX8649_CONTROL, MAX8649_EN_PD, 0); 68 } 69 70 /* 71 * Applied internal pulldown resistor on EN input pin. 72 * If pulldown EN pin outside, it would be better. 73 */ 74 static int max8649_disable(struct regulator_dev *rdev) 75 { 76 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 77 return regmap_update_bits(info->regmap, MAX8649_CONTROL, MAX8649_EN_PD, 78 MAX8649_EN_PD); 79 } 80 81 static int max8649_is_enabled(struct regulator_dev *rdev) 82 { 83 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 84 unsigned int val; 85 int ret; 86 87 ret = regmap_read(info->regmap, MAX8649_CONTROL, &val); 88 if (ret != 0) 89 return ret; 90 return !((unsigned char)val & MAX8649_EN_PD); 91 } 92 93 static int max8649_enable_time(struct regulator_dev *rdev) 94 { 95 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 96 int voltage, rate, ret; 97 unsigned int val; 98 99 /* get voltage */ 100 ret = regmap_read(info->regmap, rdev->desc->vsel_reg, &val); 101 if (ret != 0) 102 return ret; 103 val &= MAX8649_VOL_MASK; 104 voltage = regulator_list_voltage_linear(rdev, (unsigned char)val); 105 106 /* get rate */ 107 ret = regmap_read(info->regmap, MAX8649_RAMP, &val); 108 if (ret != 0) 109 return ret; 110 ret = (val & MAX8649_RAMP_MASK) >> 5; 111 rate = (32 * 1000) >> ret; /* uV/uS */ 112 113 return DIV_ROUND_UP(voltage, rate); 114 } 115 116 static int max8649_set_mode(struct regulator_dev *rdev, unsigned int mode) 117 { 118 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 119 120 switch (mode) { 121 case REGULATOR_MODE_FAST: 122 regmap_update_bits(info->regmap, rdev->desc->vsel_reg, 123 MAX8649_FORCE_PWM, MAX8649_FORCE_PWM); 124 break; 125 case REGULATOR_MODE_NORMAL: 126 regmap_update_bits(info->regmap, rdev->desc->vsel_reg, 127 MAX8649_FORCE_PWM, 0); 128 break; 129 default: 130 return -EINVAL; 131 } 132 return 0; 133 } 134 135 static unsigned int max8649_get_mode(struct regulator_dev *rdev) 136 { 137 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 138 unsigned int val; 139 int ret; 140 141 ret = regmap_read(info->regmap, rdev->desc->vsel_reg, &val); 142 if (ret != 0) 143 return ret; 144 if (val & MAX8649_FORCE_PWM) 145 return REGULATOR_MODE_FAST; 146 return REGULATOR_MODE_NORMAL; 147 } 148 149 static struct regulator_ops max8649_dcdc_ops = { 150 .set_voltage_sel = regulator_set_voltage_sel_regmap, 151 .get_voltage_sel = regulator_get_voltage_sel_regmap, 152 .list_voltage = regulator_list_voltage_linear, 153 .map_voltage = regulator_map_voltage_linear, 154 .enable = max8649_enable, 155 .disable = max8649_disable, 156 .is_enabled = max8649_is_enabled, 157 .enable_time = max8649_enable_time, 158 .set_mode = max8649_set_mode, 159 .get_mode = max8649_get_mode, 160 161 }; 162 163 static struct regulator_desc dcdc_desc = { 164 .name = "max8649", 165 .ops = &max8649_dcdc_ops, 166 .type = REGULATOR_VOLTAGE, 167 .n_voltages = 1 << 6, 168 .owner = THIS_MODULE, 169 .vsel_mask = MAX8649_VOL_MASK, 170 .min_uV = MAX8649_DCDC_VMIN, 171 .uV_step = MAX8649_DCDC_STEP, 172 }; 173 174 static struct regmap_config max8649_regmap_config = { 175 .reg_bits = 8, 176 .val_bits = 8, 177 }; 178 179 static int __devinit max8649_regulator_probe(struct i2c_client *client, 180 const struct i2c_device_id *id) 181 { 182 struct max8649_platform_data *pdata = client->dev.platform_data; 183 struct max8649_regulator_info *info = NULL; 184 struct regulator_config config = { }; 185 unsigned int val; 186 unsigned char data; 187 int ret; 188 189 info = devm_kzalloc(&client->dev, sizeof(struct max8649_regulator_info), 190 GFP_KERNEL); 191 if (!info) { 192 dev_err(&client->dev, "No enough memory\n"); 193 return -ENOMEM; 194 } 195 196 info->regmap = devm_regmap_init_i2c(client, &max8649_regmap_config); 197 if (IS_ERR(info->regmap)) { 198 ret = PTR_ERR(info->regmap); 199 dev_err(&client->dev, "Failed to allocate register map: %d\n", ret); 200 return ret; 201 } 202 203 info->dev = &client->dev; 204 i2c_set_clientdata(client, info); 205 206 info->mode = pdata->mode; 207 switch (info->mode) { 208 case 0: 209 dcdc_desc.vsel_reg = MAX8649_MODE0; 210 break; 211 case 1: 212 dcdc_desc.vsel_reg = MAX8649_MODE1; 213 break; 214 case 2: 215 dcdc_desc.vsel_reg = MAX8649_MODE2; 216 break; 217 case 3: 218 dcdc_desc.vsel_reg = MAX8649_MODE3; 219 break; 220 default: 221 break; 222 } 223 224 ret = regmap_read(info->regmap, MAX8649_CHIP_ID1, &val); 225 if (ret != 0) { 226 dev_err(info->dev, "Failed to detect ID of MAX8649:%d\n", 227 ret); 228 return ret; 229 } 230 dev_info(info->dev, "Detected MAX8649 (ID:%x)\n", val); 231 232 /* enable VID0 & VID1 */ 233 regmap_update_bits(info->regmap, MAX8649_CONTROL, MAX8649_VID_MASK, 0); 234 235 /* enable/disable external clock synchronization */ 236 info->extclk = pdata->extclk; 237 data = (info->extclk) ? MAX8649_SYNC_EXTCLK : 0; 238 regmap_update_bits(info->regmap, dcdc_desc.vsel_reg, 239 MAX8649_SYNC_EXTCLK, data); 240 if (info->extclk) { 241 /* set external clock frequency */ 242 info->extclk_freq = pdata->extclk_freq; 243 regmap_update_bits(info->regmap, MAX8649_SYNC, MAX8649_EXT_MASK, 244 info->extclk_freq << 6); 245 } 246 247 if (pdata->ramp_timing) { 248 info->ramp_timing = pdata->ramp_timing; 249 regmap_update_bits(info->regmap, MAX8649_RAMP, MAX8649_RAMP_MASK, 250 info->ramp_timing << 5); 251 } 252 253 info->ramp_down = pdata->ramp_down; 254 if (info->ramp_down) { 255 regmap_update_bits(info->regmap, MAX8649_RAMP, MAX8649_RAMP_DOWN, 256 MAX8649_RAMP_DOWN); 257 } 258 259 config.dev = &client->dev; 260 config.init_data = pdata->regulator; 261 config.driver_data = info; 262 config.regmap = info->regmap; 263 264 info->regulator = regulator_register(&dcdc_desc, &config); 265 if (IS_ERR(info->regulator)) { 266 dev_err(info->dev, "failed to register regulator %s\n", 267 dcdc_desc.name); 268 return PTR_ERR(info->regulator); 269 } 270 271 return 0; 272 } 273 274 static int __devexit max8649_regulator_remove(struct i2c_client *client) 275 { 276 struct max8649_regulator_info *info = i2c_get_clientdata(client); 277 278 if (info) { 279 if (info->regulator) 280 regulator_unregister(info->regulator); 281 } 282 283 return 0; 284 } 285 286 static const struct i2c_device_id max8649_id[] = { 287 { "max8649", 0 }, 288 { } 289 }; 290 MODULE_DEVICE_TABLE(i2c, max8649_id); 291 292 static struct i2c_driver max8649_driver = { 293 .probe = max8649_regulator_probe, 294 .remove = __devexit_p(max8649_regulator_remove), 295 .driver = { 296 .name = "max8649", 297 }, 298 .id_table = max8649_id, 299 }; 300 301 static int __init max8649_init(void) 302 { 303 return i2c_add_driver(&max8649_driver); 304 } 305 subsys_initcall(max8649_init); 306 307 static void __exit max8649_exit(void) 308 { 309 i2c_del_driver(&max8649_driver); 310 } 311 module_exit(max8649_exit); 312 313 /* Module information */ 314 MODULE_DESCRIPTION("MAXIM 8649 voltage regulator driver"); 315 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); 316 MODULE_LICENSE("GPL"); 317