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

Merge remote-tracking branch 'regulator/topic/tps51632' into regulator-next

+130 -49
+27
Documentation/devicetree/bindings/regulator/tps51632-regulator.txt
··· 1 + TPS51632 Voltage regulators 2 + 3 + Required properties: 4 + - compatible: Must be "ti,tps51632" 5 + - reg: I2C slave address 6 + 7 + Optional properties: 8 + - ti,enable-pwm-dvfs: Enable the DVFS voltage control through the PWM interface. 9 + - ti,dvfs-step-20mV: The 20mV step voltage when PWM DVFS enabled. Missing this 10 + will set 10mV step voltage in PWM DVFS mode. In normal mode, the voltage 11 + step is 10mV as per datasheet. 12 + 13 + Any property defined as part of the core regulator binding, defined in 14 + regulator.txt, can also be used. 15 + 16 + Example: 17 + 18 + tps51632 { 19 + compatible = "ti,tps51632"; 20 + reg = <0x43>; 21 + regulator-name = "tps51632-vout"; 22 + regulator-min-microvolt = <500000>; 23 + regulator-max-microvolt = <1500000>; 24 + regulator-boot-on; 25 + ti,enable-pwm-dvfs; 26 + ti,dvfs-step-20mV; 27 + };
+103 -49
drivers/regulator/tps51632-regulator.c
··· 28 28 #include <linux/init.h> 29 29 #include <linux/kernel.h> 30 30 #include <linux/module.h> 31 + #include <linux/of.h> 32 + #include <linux/of_device.h> 31 33 #include <linux/platform_device.h> 32 34 #include <linux/regmap.h> 33 35 #include <linux/regulator/driver.h> 34 36 #include <linux/regulator/machine.h> 37 + #include <linux/regulator/of_regulator.h> 35 38 #include <linux/regulator/tps51632-regulator.h> 36 39 #include <linux/slab.h> 37 40 ··· 88 85 struct regulator_desc desc; 89 86 struct regulator_dev *rdev; 90 87 struct regmap *regmap; 91 - bool enable_pwm_dvfs; 92 88 }; 93 - 94 - static int tps51632_dcdc_get_voltage_sel(struct regulator_dev *rdev) 95 - { 96 - struct tps51632_chip *tps = rdev_get_drvdata(rdev); 97 - unsigned int data; 98 - int ret; 99 - unsigned int reg = TPS51632_VOLTAGE_SELECT_REG; 100 - int vsel; 101 - 102 - if (tps->enable_pwm_dvfs) 103 - reg = TPS51632_VOLTAGE_BASE_REG; 104 - 105 - ret = regmap_read(tps->regmap, reg, &data); 106 - if (ret < 0) { 107 - dev_err(tps->dev, "reg read failed, err %d\n", ret); 108 - return ret; 109 - } 110 - 111 - vsel = data & TPS51632_VOUT_MASK; 112 - return vsel; 113 - } 114 - 115 - static int tps51632_dcdc_set_voltage_sel(struct regulator_dev *rdev, 116 - unsigned selector) 117 - { 118 - struct tps51632_chip *tps = rdev_get_drvdata(rdev); 119 - int ret; 120 - unsigned int reg = TPS51632_VOLTAGE_SELECT_REG; 121 - 122 - if (tps->enable_pwm_dvfs) 123 - reg = TPS51632_VOLTAGE_BASE_REG; 124 - 125 - if (selector > TPS51632_MAX_VSEL) 126 - return -EINVAL; 127 - 128 - ret = regmap_write(tps->regmap, reg, selector); 129 - if (ret < 0) 130 - dev_err(tps->dev, "reg write failed, err %d\n", ret); 131 - return ret; 132 - } 133 89 134 90 static int tps51632_dcdc_set_ramp_delay(struct regulator_dev *rdev, 135 91 int ramp_delay) ··· 106 144 } 107 145 108 146 static struct regulator_ops tps51632_dcdc_ops = { 109 - .get_voltage_sel = tps51632_dcdc_get_voltage_sel, 110 - .set_voltage_sel = tps51632_dcdc_set_voltage_sel, 147 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 148 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 111 149 .list_voltage = regulator_list_voltage_linear, 112 150 .set_voltage_time_sel = regulator_set_voltage_time_sel, 113 151 .set_ramp_delay = tps51632_dcdc_set_ramp_delay, ··· 124 162 goto skip_pwm_config; 125 163 126 164 control |= TPS51632_DVFS_PWMEN; 127 - tps->enable_pwm_dvfs = pdata->enable_pwm_dvfs; 128 165 vsel = TPS51632_VOLT_VSEL(pdata->base_voltage_uV); 129 166 ret = regmap_write(tps->regmap, TPS51632_VOLTAGE_BASE_REG, vsel); 130 167 if (ret < 0) { ··· 166 205 return ret; 167 206 } 168 207 169 - static bool rd_wr_reg(struct device *dev, unsigned int reg) 208 + static bool is_volatile_reg(struct device *dev, unsigned int reg) 170 209 { 171 - if ((reg >= 0x8) && (reg <= 0x10)) 210 + switch (reg) { 211 + case TPS51632_OFFSET_REG: 212 + case TPS51632_FAULT_REG: 213 + case TPS51632_IMON_REG: 214 + return true; 215 + default: 172 216 return false; 173 - return true; 217 + } 218 + } 219 + 220 + static bool is_read_reg(struct device *dev, unsigned int reg) 221 + { 222 + switch (reg) { 223 + case 0x08 ... 0x0F: 224 + return false; 225 + default: 226 + return true; 227 + } 228 + } 229 + 230 + static bool is_write_reg(struct device *dev, unsigned int reg) 231 + { 232 + switch (reg) { 233 + case TPS51632_VOLTAGE_SELECT_REG: 234 + case TPS51632_VOLTAGE_BASE_REG: 235 + case TPS51632_VMAX_REG: 236 + case TPS51632_DVFS_CONTROL_REG: 237 + case TPS51632_POWER_STATE_REG: 238 + case TPS51632_SLEW_REGS: 239 + return true; 240 + default: 241 + return false; 242 + } 174 243 } 175 244 176 245 static const struct regmap_config tps51632_regmap_config = { 177 246 .reg_bits = 8, 178 247 .val_bits = 8, 179 - .writeable_reg = rd_wr_reg, 180 - .readable_reg = rd_wr_reg, 248 + .writeable_reg = is_write_reg, 249 + .readable_reg = is_read_reg, 250 + .volatile_reg = is_volatile_reg, 181 251 .max_register = TPS51632_MAX_REG - 1, 182 252 .cache_type = REGCACHE_RBTREE, 183 253 }; 254 + 255 + #if defined(CONFIG_OF) 256 + static const struct of_device_id tps51632_of_match[] = { 257 + { .compatible = "ti,tps51632",}, 258 + {}, 259 + }; 260 + MODULE_DEVICE_TABLE(of, tps51632_of_match); 261 + 262 + static struct tps51632_regulator_platform_data * 263 + of_get_tps51632_platform_data(struct device *dev) 264 + { 265 + struct tps51632_regulator_platform_data *pdata; 266 + struct device_node *np = dev->of_node; 267 + 268 + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 269 + if (!pdata) { 270 + dev_err(dev, "Memory alloc failed for platform data\n"); 271 + return NULL; 272 + } 273 + 274 + pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node); 275 + if (!pdata->reg_init_data) { 276 + dev_err(dev, "Not able to get OF regulator init data\n"); 277 + return NULL; 278 + } 279 + 280 + pdata->enable_pwm_dvfs = 281 + of_property_read_bool(np, "ti,enable-pwm-dvfs"); 282 + pdata->dvfs_step_20mV = of_property_read_bool(np, "ti,dvfs-step-20mV"); 283 + 284 + pdata->base_voltage_uV = pdata->reg_init_data->constraints.min_uV ? : 285 + TPS51632_MIN_VOLATGE; 286 + pdata->max_voltage_uV = pdata->reg_init_data->constraints.max_uV ? : 287 + TPS51632_MAX_VOLATGE; 288 + return pdata; 289 + } 290 + #else 291 + static struct tps51632_regulator_platform_data * 292 + of_get_tps51632_platform_data(struct device *dev) 293 + { 294 + return NULL; 295 + } 296 + #endif 184 297 185 298 static int tps51632_probe(struct i2c_client *client, 186 299 const struct i2c_device_id *id) ··· 265 230 int ret; 266 231 struct regulator_config config = { }; 267 232 233 + if (client->dev.of_node) { 234 + const struct of_device_id *match; 235 + match = of_match_device(of_match_ptr(tps51632_of_match), 236 + &client->dev); 237 + if (!match) { 238 + dev_err(&client->dev, "Error: No device match found\n"); 239 + return -ENODEV; 240 + } 241 + } 242 + 268 243 pdata = client->dev.platform_data; 244 + if (!pdata && client->dev.of_node) 245 + pdata = of_get_tps51632_platform_data(&client->dev); 269 246 if (!pdata) { 270 247 dev_err(&client->dev, "No Platform data\n"); 271 248 return -EINVAL; ··· 315 268 tps->desc.ops = &tps51632_dcdc_ops; 316 269 tps->desc.type = REGULATOR_VOLTAGE; 317 270 tps->desc.owner = THIS_MODULE; 271 + 272 + if (pdata->enable_pwm_dvfs) 273 + tps->desc.vsel_reg = TPS51632_VOLTAGE_BASE_REG; 274 + else 275 + tps->desc.vsel_reg = TPS51632_VOLTAGE_SELECT_REG; 276 + tps->desc.vsel_mask = TPS51632_VOUT_MASK; 318 277 319 278 tps->regmap = devm_regmap_init_i2c(client, &tps51632_regmap_config); 320 279 if (IS_ERR(tps->regmap)) { ··· 372 319 .driver = { 373 320 .name = "tps51632", 374 321 .owner = THIS_MODULE, 322 + .of_match_table = of_match_ptr(tps51632_of_match), 375 323 }, 376 324 .probe = tps51632_probe, 377 325 .remove = tps51632_remove,