1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Regulators driver for Maxim max8649 4 * 5 * Copyright (C) 2009-2010 Marvell International Ltd. 6 * Haojian Zhuang <haojian.zhuang@marvell.com> 7 */ 8 #include <linux/kernel.h> 9 #include <linux/module.h> 10 #include <linux/err.h> 11 #include <linux/i2c.h> 12 #include <linux/platform_device.h> 13 #include <linux/regulator/driver.h> 14 #include <linux/slab.h> 15 #include <linux/regulator/max8649.h> 16 #include <linux/regmap.h> 17 18 #define MAX8649_DCDC_VMIN 750000 /* uV */ 19 #define MAX8649_DCDC_VMAX 1380000 /* uV */ 20 #define MAX8649_DCDC_STEP 10000 /* uV */ 21 #define MAX8649_VOL_MASK 0x3f 22 23 /* Registers */ 24 #define MAX8649_MODE0 0x00 25 #define MAX8649_MODE1 0x01 26 #define MAX8649_MODE2 0x02 27 #define MAX8649_MODE3 0x03 28 #define MAX8649_CONTROL 0x04 29 #define MAX8649_SYNC 0x05 30 #define MAX8649_RAMP 0x06 31 #define MAX8649_CHIP_ID1 0x08 32 #define MAX8649_CHIP_ID2 0x09 33 34 /* Bits */ 35 #define MAX8649_EN_PD (1 << 7) 36 #define MAX8649_VID0_PD (1 << 6) 37 #define MAX8649_VID1_PD (1 << 5) 38 #define MAX8649_VID_MASK (3 << 5) 39 40 #define MAX8649_FORCE_PWM (1 << 7) 41 #define MAX8649_SYNC_EXTCLK (1 << 6) 42 43 #define MAX8649_EXT_MASK (3 << 6) 44 45 #define MAX8649_RAMP_MASK (7 << 5) 46 #define MAX8649_RAMP_DOWN (1 << 1) 47 48 struct max8649_regulator_info { 49 struct device *dev; 50 struct regmap *regmap; 51 52 unsigned mode:2; /* bit[1:0] = VID1, VID0 */ 53 unsigned extclk_freq:2; 54 unsigned extclk:1; 55 unsigned ramp_timing:3; 56 unsigned ramp_down:1; 57 }; 58 59 static int max8649_enable_time(struct regulator_dev *rdev) 60 { 61 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 62 int voltage, rate, ret; 63 unsigned int val; 64 65 /* get voltage */ 66 ret = regmap_read(info->regmap, rdev->desc->vsel_reg, &val); 67 if (ret != 0) 68 return ret; 69 val &= MAX8649_VOL_MASK; 70 voltage = regulator_list_voltage_linear(rdev, (unsigned char)val); 71 72 /* get rate */ 73 ret = regmap_read(info->regmap, MAX8649_RAMP, &val); 74 if (ret != 0) 75 return ret; 76 ret = (val & MAX8649_RAMP_MASK) >> 5; 77 rate = (32 * 1000) >> ret; /* uV/uS */ 78 79 return DIV_ROUND_UP(voltage, rate); 80 } 81 82 static int max8649_set_mode(struct regulator_dev *rdev, unsigned int mode) 83 { 84 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 85 86 switch (mode) { 87 case REGULATOR_MODE_FAST: 88 regmap_update_bits(info->regmap, rdev->desc->vsel_reg, 89 MAX8649_FORCE_PWM, MAX8649_FORCE_PWM); 90 break; 91 case REGULATOR_MODE_NORMAL: 92 regmap_update_bits(info->regmap, rdev->desc->vsel_reg, 93 MAX8649_FORCE_PWM, 0); 94 break; 95 default: 96 return -EINVAL; 97 } 98 return 0; 99 } 100 101 static unsigned int max8649_get_mode(struct regulator_dev *rdev) 102 { 103 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 104 unsigned int val; 105 int ret; 106 107 ret = regmap_read(info->regmap, rdev->desc->vsel_reg, &val); 108 if (ret != 0) 109 return ret; 110 if (val & MAX8649_FORCE_PWM) 111 return REGULATOR_MODE_FAST; 112 return REGULATOR_MODE_NORMAL; 113 } 114 115 static const struct regulator_ops max8649_dcdc_ops = { 116 .set_voltage_sel = regulator_set_voltage_sel_regmap, 117 .get_voltage_sel = regulator_get_voltage_sel_regmap, 118 .list_voltage = regulator_list_voltage_linear, 119 .map_voltage = regulator_map_voltage_linear, 120 .enable = regulator_enable_regmap, 121 .disable = regulator_disable_regmap, 122 .is_enabled = regulator_is_enabled_regmap, 123 .enable_time = max8649_enable_time, 124 .set_mode = max8649_set_mode, 125 .get_mode = max8649_get_mode, 126 127 }; 128 129 static struct regulator_desc dcdc_desc = { 130 .name = "max8649", 131 .ops = &max8649_dcdc_ops, 132 .type = REGULATOR_VOLTAGE, 133 .n_voltages = 1 << 6, 134 .owner = THIS_MODULE, 135 .vsel_mask = MAX8649_VOL_MASK, 136 .min_uV = MAX8649_DCDC_VMIN, 137 .uV_step = MAX8649_DCDC_STEP, 138 .enable_reg = MAX8649_CONTROL, 139 .enable_mask = MAX8649_EN_PD, 140 .enable_is_inverted = true, 141 }; 142 143 static const struct regmap_config max8649_regmap_config = { 144 .reg_bits = 8, 145 .val_bits = 8, 146 }; 147 148 static int max8649_regulator_probe(struct i2c_client *client) 149 { 150 struct max8649_platform_data *pdata = dev_get_platdata(&client->dev); 151 struct max8649_regulator_info *info = NULL; 152 struct regulator_dev *regulator; 153 struct regulator_config config = { }; 154 unsigned int val; 155 unsigned char data; 156 int ret; 157 158 info = devm_kzalloc(&client->dev, sizeof(struct max8649_regulator_info), 159 GFP_KERNEL); 160 if (!info) 161 return -ENOMEM; 162 163 info->regmap = devm_regmap_init_i2c(client, &max8649_regmap_config); 164 if (IS_ERR(info->regmap)) { 165 ret = PTR_ERR(info->regmap); 166 dev_err(&client->dev, "Failed to allocate register map: %d\n", ret); 167 return ret; 168 } 169 170 info->dev = &client->dev; 171 i2c_set_clientdata(client, info); 172 173 info->mode = pdata->mode; 174 switch (info->mode) { 175 case 0: 176 dcdc_desc.vsel_reg = MAX8649_MODE0; 177 break; 178 case 1: 179 dcdc_desc.vsel_reg = MAX8649_MODE1; 180 break; 181 case 2: 182 dcdc_desc.vsel_reg = MAX8649_MODE2; 183 break; 184 case 3: 185 dcdc_desc.vsel_reg = MAX8649_MODE3; 186 break; 187 default: 188 break; 189 } 190 191 ret = regmap_read(info->regmap, MAX8649_CHIP_ID1, &val); 192 if (ret != 0) { 193 dev_err(info->dev, "Failed to detect ID of MAX8649:%d\n", 194 ret); 195 return ret; 196 } 197 dev_info(info->dev, "Detected MAX8649 (ID:%x)\n", val); 198 199 /* enable VID0 & VID1 */ 200 regmap_update_bits(info->regmap, MAX8649_CONTROL, MAX8649_VID_MASK, 0); 201 202 /* enable/disable external clock synchronization */ 203 info->extclk = pdata->extclk; 204 data = (info->extclk) ? MAX8649_SYNC_EXTCLK : 0; 205 regmap_update_bits(info->regmap, dcdc_desc.vsel_reg, 206 MAX8649_SYNC_EXTCLK, data); 207 if (info->extclk) { 208 /* set external clock frequency */ 209 info->extclk_freq = pdata->extclk_freq; 210 regmap_update_bits(info->regmap, MAX8649_SYNC, MAX8649_EXT_MASK, 211 info->extclk_freq << 6); 212 } 213 214 if (pdata->ramp_timing) { 215 info->ramp_timing = pdata->ramp_timing; 216 regmap_update_bits(info->regmap, MAX8649_RAMP, MAX8649_RAMP_MASK, 217 info->ramp_timing << 5); 218 } 219 220 info->ramp_down = pdata->ramp_down; 221 if (info->ramp_down) { 222 regmap_update_bits(info->regmap, MAX8649_RAMP, MAX8649_RAMP_DOWN, 223 MAX8649_RAMP_DOWN); 224 } 225 226 config.dev = &client->dev; 227 config.init_data = pdata->regulator; 228 config.driver_data = info; 229 config.regmap = info->regmap; 230 231 regulator = devm_regulator_register(&client->dev, &dcdc_desc, 232 &config); 233 if (IS_ERR(regulator)) { 234 dev_err(info->dev, "failed to register regulator %s\n", 235 dcdc_desc.name); 236 return PTR_ERR(regulator); 237 } 238 239 return 0; 240 } 241 242 static const struct i2c_device_id max8649_id[] = { 243 { "max8649", 0 }, 244 { } 245 }; 246 MODULE_DEVICE_TABLE(i2c, max8649_id); 247 248 static struct i2c_driver max8649_driver = { 249 .probe = max8649_regulator_probe, 250 .driver = { 251 .name = "max8649", 252 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 253 }, 254 .id_table = max8649_id, 255 }; 256 257 static int __init max8649_init(void) 258 { 259 return i2c_add_driver(&max8649_driver); 260 } 261 subsys_initcall(max8649_init); 262 263 static void __exit max8649_exit(void) 264 { 265 i2c_del_driver(&max8649_driver); 266 } 267 module_exit(max8649_exit); 268 269 /* Module information */ 270 MODULE_DESCRIPTION("MAXIM 8649 voltage regulator driver"); 271 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); 272 MODULE_LICENSE("GPL"); 273