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

regulator: Add LTC3676 support

This patch adds support for the Linear Technology LTC3676
8-output I2C voltage regulator IC.

Cc: Jaffer Kapasi <jkapasi@linear.com>
Signed-off-by: Tim Harvey <tharvey@gateworks.com>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Tim Harvey and committed by
Mark Brown
37b918a0 29b4817d

+523
+94
Documentation/devicetree/bindings/regulator/ltc3676.txt
··· 1 + Linear Technology LTC3676 8-output regulators 2 + 3 + Required properties: 4 + - compatible: "lltc,ltc3676" 5 + - reg: I2C slave address 6 + 7 + Required child node: 8 + - regulators: Contains eight regulator child nodes sw1, sw2, sw3, sw4, 9 + ldo1, ldo2, ldo3, and ldo4, specifying the initialization data as 10 + documented in Documentation/devicetree/bindings/regulator/regulator.txt. 11 + 12 + Each regulator is defined using the standard binding for regulators. The 13 + nodes for sw1, sw2, sw3, sw4, ldo1, ldo2 and ldo4 additionally need to specify 14 + the resistor values of their external feedback voltage dividers: 15 + 16 + Required properties (not on ldo3): 17 + - lltc,fb-voltage-divider: An array of two integers containing the resistor 18 + values R1 and R2 of the feedback voltage divider in ohms. 19 + 20 + Regulators sw1, sw2, sw3, sw4 can regulate the feedback reference from: 21 + 412.5mV to 800mV in 12.5 mV steps. The output voltage thus ranges between 22 + 0.4125 * (1 + R1/R2) V and 0.8 * (1 + R1/R2) V. 23 + 24 + Regulators ldo1, ldo2, and ldo4 have a fixed 0.725 V reference and thus output 25 + 0.725 * (1 + R1/R2) V. The ldo3 regulator is fixed to 1.8 V. The ldo1 standby 26 + regulator can not be disabled and thus should have the regulator-always-on 27 + property set. 28 + 29 + Example: 30 + 31 + ltc3676: pmic@3c { 32 + compatible = "lltc,ltc3676"; 33 + reg = <0x3c>; 34 + 35 + regulators { 36 + sw1_reg: sw1 { 37 + regulator-min-microvolt = <674400>; 38 + regulator-max-microvolt = <1308000>; 39 + lltc,fb-voltage-divider = <127000 200000>; 40 + regulator-ramp-delay = <7000>; 41 + regulator-boot-on; 42 + regulator-always-on; 43 + }; 44 + 45 + sw2_reg: sw2 { 46 + regulator-min-microvolt = <1033310>; 47 + regulator-max-microvolt = <200400>; 48 + lltc,fb-voltage-divider = <301000 200000>; 49 + regulator-ramp-delay = <7000>; 50 + regulator-boot-on; 51 + regulator-always-on; 52 + }; 53 + 54 + sw3_reg: sw3 { 55 + regulator-min-microvolt = <674400>; 56 + regulator-max-microvolt = <130800>; 57 + lltc,fb-voltage-divider = <127000 200000>; 58 + regulator-ramp-delay = <7000>; 59 + regulator-boot-on; 60 + regulator-always-on; 61 + }; 62 + 63 + sw4_reg: sw4 { 64 + regulator-min-microvolt = <868310>; 65 + regulator-max-microvolt = <168400>; 66 + lltc,fb-voltage-divider = <221000 200000>; 67 + regulator-ramp-delay = <7000>; 68 + regulator-boot-on; 69 + regulator-always-on; 70 + }; 71 + 72 + ldo2_reg: ldo2 { 73 + regulator-min-microvolt = <2490375>; 74 + regulator-max-microvolt = <2490375>; 75 + lltc,fb-voltage-divider = <487000 200000>; 76 + regulator-boot-on; 77 + regulator-always-on; 78 + }; 79 + 80 + ldo3_reg: ldo3 { 81 + regulator-min-microvolt = <1800000>; 82 + regulator-max-microvolt = <1800000>; 83 + regulator-boot-on; 84 + }; 85 + 86 + ldo4_reg: ldo4 { 87 + regulator-min-microvolt = <3023250>; 88 + regulator-max-microvolt = <3023250>; 89 + lltc,fb-voltage-divider = <634000 200000>; 90 + regulator-boot-on; 91 + regulator-always-on; 92 + }; 93 + }; 94 + };
+8
drivers/regulator/Kconfig
··· 353 353 This enables support for the LTC3589, LTC3589-1, and LTC3589-2 354 354 8-output regulators controlled via I2C. 355 355 356 + config REGULATOR_LTC3676 357 + tristate "LTC3676 8-output voltage regulator" 358 + depends on I2C 359 + select REGMAP_I2C 360 + help 361 + This enables support for the LTC3676 362 + 8-output regulators controlled via I2C. 363 + 356 364 config REGULATOR_MAX14577 357 365 tristate "Maxim 14577/77836 regulator" 358 366 depends on MFD_MAX14577
+1
drivers/regulator/Makefile
··· 47 47 obj-$(CONFIG_REGULATOR_LP8788) += lp8788-ldo.o 48 48 obj-$(CONFIG_REGULATOR_LP8755) += lp8755.o 49 49 obj-$(CONFIG_REGULATOR_LTC3589) += ltc3589.o 50 + obj-$(CONFIG_REGULATOR_LTC3676) += ltc3676.o 50 51 obj-$(CONFIG_REGULATOR_MAX14577) += max14577-regulator.o 51 52 obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o 52 53 obj-$(CONFIG_REGULATOR_MAX77620) += max77620-regulator.o
+420
drivers/regulator/ltc3676.c
··· 1 + /* 2 + * Copyright (C) 2016 Gateworks Corporation, Inc. All Rights Reserved. 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 6 + * as published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + * 13 + */ 14 + #include <linux/i2c.h> 15 + #include <linux/init.h> 16 + #include <linux/interrupt.h> 17 + #include <linux/module.h> 18 + #include <linux/kernel.h> 19 + #include <linux/of.h> 20 + #include <linux/regmap.h> 21 + #include <linux/regulator/driver.h> 22 + #include <linux/regulator/machine.h> 23 + #include <linux/regulator/of_regulator.h> 24 + 25 + #define DRIVER_NAME "ltc3676" 26 + 27 + /* LTC3676 Registers */ 28 + #define LTC3676_BUCK1 0x01 29 + #define LTC3676_BUCK2 0x02 30 + #define LTC3676_BUCK3 0x03 31 + #define LTC3676_BUCK4 0x04 32 + #define LTC3676_LDOA 0x05 33 + #define LTC3676_LDOB 0x06 34 + #define LTC3676_SQD1 0x07 35 + #define LTC3676_SQD2 0x08 36 + #define LTC3676_CNTRL 0x09 37 + #define LTC3676_DVB1A 0x0A 38 + #define LTC3676_DVB1B 0x0B 39 + #define LTC3676_DVB2A 0x0C 40 + #define LTC3676_DVB2B 0x0D 41 + #define LTC3676_DVB3A 0x0E 42 + #define LTC3676_DVB3B 0x0F 43 + #define LTC3676_DVB4A 0x10 44 + #define LTC3676_DVB4B 0x11 45 + #define LTC3676_MSKIRQ 0x12 46 + #define LTC3676_MSKPG 0x13 47 + #define LTC3676_USER 0x14 48 + #define LTC3676_IRQSTAT 0x15 49 + #define LTC3676_PGSTATL 0x16 50 + #define LTC3676_PGSTATRT 0x17 51 + #define LTC3676_HRST 0x1E 52 + #define LTC3676_CLIRQ 0x1F 53 + 54 + #define LTC3676_DVBxA_REF_SELECT BIT(5) 55 + 56 + #define LTC3676_IRQSTAT_PGOOD_TIMEOUT BIT(3) 57 + #define LTC3676_IRQSTAT_UNDERVOLT_WARN BIT(4) 58 + #define LTC3676_IRQSTAT_UNDERVOLT_FAULT BIT(5) 59 + #define LTC3676_IRQSTAT_THERMAL_WARN BIT(6) 60 + #define LTC3676_IRQSTAT_THERMAL_FAULT BIT(7) 61 + 62 + enum ltc3676_reg { 63 + LTC3676_SW1, 64 + LTC3676_SW2, 65 + LTC3676_SW3, 66 + LTC3676_SW4, 67 + LTC3676_LDO1, 68 + LTC3676_LDO2, 69 + LTC3676_LDO3, 70 + LTC3676_LDO4, 71 + LTC3676_NUM_REGULATORS, 72 + }; 73 + 74 + struct ltc3676 { 75 + struct regmap *regmap; 76 + struct device *dev; 77 + struct regulator_desc regulator_descs[LTC3676_NUM_REGULATORS]; 78 + struct regulator_dev *regulators[LTC3676_NUM_REGULATORS]; 79 + }; 80 + 81 + static int ltc3676_set_suspend_voltage(struct regulator_dev *rdev, int uV) 82 + { 83 + struct ltc3676 *ltc3676 = rdev_get_drvdata(rdev); 84 + struct device *dev = ltc3676->dev; 85 + int dcdc = rdev_get_id(rdev); 86 + int sel; 87 + 88 + dev_dbg(dev, "%s id=%d uV=%d\n", __func__, dcdc, uV); 89 + sel = regulator_map_voltage_linear(rdev, uV, uV); 90 + if (sel < 0) 91 + return sel; 92 + 93 + /* DVBB register follows right after the corresponding DVBA register */ 94 + return regmap_update_bits(ltc3676->regmap, rdev->desc->vsel_reg + 1, 95 + rdev->desc->vsel_mask, sel); 96 + } 97 + 98 + static int ltc3676_set_suspend_mode(struct regulator_dev *rdev, 99 + unsigned int mode) 100 + { 101 + struct ltc3676 *ltc3676= rdev_get_drvdata(rdev); 102 + struct device *dev = ltc3676->dev; 103 + int mask, val; 104 + int dcdc = rdev_get_id(rdev); 105 + 106 + dev_dbg(dev, "%s id=%d mode=%d\n", __func__, dcdc, mode); 107 + 108 + mask = LTC3676_DVBxA_REF_SELECT; 109 + switch (mode) { 110 + case REGULATOR_MODE_STANDBY: 111 + val = 0; /* select DVBxA */ 112 + break; 113 + case REGULATOR_MODE_NORMAL: 114 + val = LTC3676_DVBxA_REF_SELECT; /* select DVBxB */ 115 + break; 116 + default: 117 + dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n", 118 + rdev->desc->name, mode); 119 + return -EINVAL; 120 + } 121 + 122 + return regmap_update_bits(ltc3676->regmap, rdev->desc->vsel_reg, 123 + mask, val); 124 + } 125 + 126 + static inline unsigned int ltc3676_scale(unsigned int uV, u32 r1, u32 r2) 127 + { 128 + uint64_t tmp; 129 + if (uV == 0) 130 + return 0; 131 + tmp = (uint64_t)uV * r1; 132 + do_div(tmp, r2); 133 + return uV + (unsigned int)tmp; 134 + } 135 + 136 + static int ltc3676_of_parse_cb(struct device_node *np, 137 + const struct regulator_desc *desc, 138 + struct regulator_config *config) 139 + { 140 + struct ltc3676 *ltc3676 = config->driver_data; 141 + struct regulator_desc *rdesc = &ltc3676->regulator_descs[desc->id]; 142 + u32 r[2]; 143 + int ret; 144 + 145 + /* LDO3 has a fixed output */ 146 + if (desc->id == LTC3676_LDO3) 147 + return 0; 148 + 149 + ret = of_property_read_u32_array(np, "lltc,fb-voltage-divider", r, 2); 150 + if (ret) { 151 + dev_err(ltc3676->dev, "Failed to parse voltage divider: %d\n", 152 + ret); 153 + return ret; 154 + } 155 + 156 + rdesc->min_uV = ltc3676_scale(desc->min_uV, r[0], r[1]); 157 + rdesc->uV_step = ltc3676_scale(desc->uV_step, r[0], r[1]); 158 + rdesc->fixed_uV = ltc3676_scale(desc->fixed_uV, r[0], r[1]); 159 + 160 + return 0; 161 + } 162 + 163 + /* SW1, SW2, SW3, SW4 linear 0.8V-3.3V with scalar via R1/R2 feeback res */ 164 + static struct regulator_ops ltc3676_linear_regulator_ops = { 165 + .enable = regulator_enable_regmap, 166 + .disable = regulator_disable_regmap, 167 + .is_enabled = regulator_is_enabled_regmap, 168 + .list_voltage = regulator_list_voltage_linear, 169 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 170 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 171 + .set_suspend_voltage = ltc3676_set_suspend_voltage, 172 + .set_suspend_mode = ltc3676_set_suspend_mode, 173 + }; 174 + 175 + /* LDO1 always on fixed 0.8V-3.3V via scalar via R1/R2 feeback res */ 176 + static struct regulator_ops ltc3676_fixed_standby_regulator_ops = { 177 + }; 178 + 179 + /* LDO2, LDO3 fixed (LDO2 has external scalar via R1/R2 feedback res) */ 180 + static struct regulator_ops ltc3676_fixed_regulator_ops = { 181 + .enable = regulator_enable_regmap, 182 + .disable = regulator_disable_regmap, 183 + .is_enabled = regulator_is_enabled_regmap, 184 + }; 185 + 186 + #define LTC3676_REG(_id, _name, _ops, en_reg, en_bit, dvba_reg, dvb_mask) \ 187 + [LTC3676_ ## _id] = { \ 188 + .name = #_name, \ 189 + .of_match = of_match_ptr(#_name), \ 190 + .regulators_node = of_match_ptr("regulators"), \ 191 + .of_parse_cb = ltc3676_of_parse_cb, \ 192 + .n_voltages = (dvb_mask) + 1, \ 193 + .min_uV = (dvba_reg) ? 412500 : 0, \ 194 + .uV_step = (dvba_reg) ? 12500 : 0, \ 195 + .ramp_delay = (dvba_reg) ? 800 : 0, \ 196 + .fixed_uV = (dvb_mask) ? 0 : 725000, \ 197 + .ops = &ltc3676_ ## _ops ## _regulator_ops, \ 198 + .type = REGULATOR_VOLTAGE, \ 199 + .id = LTC3676_ ## _id, \ 200 + .owner = THIS_MODULE, \ 201 + .vsel_reg = (dvba_reg), \ 202 + .vsel_mask = (dvb_mask), \ 203 + .enable_reg = (en_reg), \ 204 + .enable_mask = (1 << en_bit), \ 205 + } 206 + 207 + #define LTC3676_LINEAR_REG(_id, _name, _en, _dvba) \ 208 + LTC3676_REG(_id, _name, linear, \ 209 + LTC3676_ ## _en, 7, \ 210 + LTC3676_ ## _dvba, 0x1f) 211 + 212 + #define LTC3676_FIXED_REG(_id, _name, _en_reg, _en_bit) \ 213 + LTC3676_REG(_id, _name, fixed, LTC3676_ ## _en_reg, _en_bit, 0, 0) 214 + 215 + static struct regulator_desc ltc3676_regulators[LTC3676_NUM_REGULATORS] = { 216 + LTC3676_LINEAR_REG(SW1, sw1, BUCK1, DVB1A), 217 + LTC3676_LINEAR_REG(SW2, sw2, BUCK2, DVB2A), 218 + LTC3676_LINEAR_REG(SW3, sw3, BUCK3, DVB3A), 219 + LTC3676_LINEAR_REG(SW4, sw4, BUCK4, DVB4A), 220 + LTC3676_REG(LDO1, ldo1, fixed_standby, 0, 0, 0, 0), 221 + LTC3676_FIXED_REG(LDO2, ldo2, LDOA, 2), 222 + LTC3676_FIXED_REG(LDO3, ldo3, LDOA, 5), 223 + LTC3676_FIXED_REG(LDO4, ldo4, LDOB, 2), 224 + }; 225 + 226 + static bool ltc3676_writeable_reg(struct device *dev, unsigned int reg) 227 + { 228 + switch (reg) { 229 + case LTC3676_IRQSTAT: 230 + case LTC3676_BUCK1: 231 + case LTC3676_BUCK2: 232 + case LTC3676_BUCK3: 233 + case LTC3676_BUCK4: 234 + case LTC3676_LDOA: 235 + case LTC3676_LDOB: 236 + case LTC3676_SQD1: 237 + case LTC3676_SQD2: 238 + case LTC3676_CNTRL: 239 + case LTC3676_DVB1A: 240 + case LTC3676_DVB1B: 241 + case LTC3676_DVB2A: 242 + case LTC3676_DVB2B: 243 + case LTC3676_DVB3A: 244 + case LTC3676_DVB3B: 245 + case LTC3676_DVB4A: 246 + case LTC3676_DVB4B: 247 + case LTC3676_MSKIRQ: 248 + case LTC3676_MSKPG: 249 + case LTC3676_USER: 250 + case LTC3676_HRST: 251 + case LTC3676_CLIRQ: 252 + return true; 253 + } 254 + return false; 255 + } 256 + 257 + static bool ltc3676_readable_reg(struct device *dev, unsigned int reg) 258 + { 259 + switch (reg) { 260 + case LTC3676_IRQSTAT: 261 + case LTC3676_BUCK1: 262 + case LTC3676_BUCK2: 263 + case LTC3676_BUCK3: 264 + case LTC3676_BUCK4: 265 + case LTC3676_LDOA: 266 + case LTC3676_LDOB: 267 + case LTC3676_SQD1: 268 + case LTC3676_SQD2: 269 + case LTC3676_CNTRL: 270 + case LTC3676_DVB1A: 271 + case LTC3676_DVB1B: 272 + case LTC3676_DVB2A: 273 + case LTC3676_DVB2B: 274 + case LTC3676_DVB3A: 275 + case LTC3676_DVB3B: 276 + case LTC3676_DVB4A: 277 + case LTC3676_DVB4B: 278 + case LTC3676_MSKIRQ: 279 + case LTC3676_MSKPG: 280 + case LTC3676_USER: 281 + case LTC3676_HRST: 282 + case LTC3676_CLIRQ: 283 + return true; 284 + } 285 + return false; 286 + } 287 + 288 + static bool ltc3676_volatile_reg(struct device *dev, unsigned int reg) 289 + { 290 + switch (reg) { 291 + case LTC3676_IRQSTAT: 292 + case LTC3676_PGSTATL: 293 + case LTC3676_PGSTATRT: 294 + return true; 295 + } 296 + return false; 297 + } 298 + 299 + static const struct regmap_config ltc3676_regmap_config = { 300 + .reg_bits = 8, 301 + .val_bits = 8, 302 + .writeable_reg = ltc3676_writeable_reg, 303 + .readable_reg = ltc3676_readable_reg, 304 + .volatile_reg = ltc3676_volatile_reg, 305 + .max_register = LTC3676_CLIRQ, 306 + .use_single_rw = true, 307 + .cache_type = REGCACHE_RBTREE, 308 + }; 309 + 310 + static irqreturn_t ltc3676_isr(int irq, void *dev_id) 311 + { 312 + struct ltc3676 *ltc3676 = dev_id; 313 + struct device *dev = ltc3676->dev; 314 + unsigned int i, irqstat, event; 315 + 316 + regmap_read(ltc3676->regmap, LTC3676_IRQSTAT, &irqstat); 317 + 318 + dev_dbg(dev, "irq%d irqstat=0x%02x\n", irq, irqstat); 319 + if (irqstat & LTC3676_IRQSTAT_THERMAL_WARN) { 320 + dev_warn(dev, "Over-temperature Warning\n"); 321 + event = REGULATOR_EVENT_OVER_TEMP; 322 + for (i = 0; i < LTC3676_NUM_REGULATORS; i++) 323 + regulator_notifier_call_chain(ltc3676->regulators[i], 324 + event, NULL); 325 + } 326 + 327 + if (irqstat & LTC3676_IRQSTAT_UNDERVOLT_WARN) { 328 + dev_info(dev, "Undervoltage Warning\n"); 329 + event = REGULATOR_EVENT_UNDER_VOLTAGE; 330 + for (i = 0; i < LTC3676_NUM_REGULATORS; i++) 331 + regulator_notifier_call_chain(ltc3676->regulators[i], 332 + event, NULL); 333 + } 334 + 335 + /* Clear warning condition */ 336 + regmap_write(ltc3676->regmap, LTC3676_CLIRQ, 0); 337 + 338 + return IRQ_HANDLED; 339 + } 340 + 341 + static int ltc3676_regulator_probe(struct i2c_client *client, 342 + const struct i2c_device_id *id) 343 + { 344 + struct device *dev = &client->dev; 345 + struct regulator_init_data *init_data = dev_get_platdata(dev); 346 + struct regulator_desc *descs; 347 + struct ltc3676 *ltc3676; 348 + int i, ret; 349 + 350 + ltc3676 = devm_kzalloc(dev, sizeof(*ltc3676), GFP_KERNEL); 351 + if (!ltc3676) 352 + return -ENOMEM; 353 + 354 + i2c_set_clientdata(client, ltc3676); 355 + ltc3676->dev = dev; 356 + 357 + descs = ltc3676->regulator_descs; 358 + memcpy(descs, ltc3676_regulators, sizeof(ltc3676_regulators)); 359 + descs[LTC3676_LDO3].fixed_uV = 1800000; /* LDO3 is fixed 1.8V */ 360 + 361 + ltc3676->regmap = devm_regmap_init_i2c(client, &ltc3676_regmap_config); 362 + if (IS_ERR(ltc3676->regmap)) { 363 + ret = PTR_ERR(ltc3676->regmap); 364 + dev_err(dev, "failed to initialize regmap: %d\n", ret); 365 + return ret; 366 + } 367 + 368 + for (i = 0; i < LTC3676_NUM_REGULATORS; i++) { 369 + struct regulator_desc *desc = &ltc3676->regulator_descs[i]; 370 + struct regulator_config config = { }; 371 + 372 + if (init_data) 373 + config.init_data = &init_data[i]; 374 + 375 + config.dev = dev; 376 + config.driver_data = ltc3676; 377 + 378 + ltc3676->regulators[i] = devm_regulator_register(dev, desc, 379 + &config); 380 + if (IS_ERR(ltc3676->regulators[i])) { 381 + ret = PTR_ERR(ltc3676->regulators[i]); 382 + dev_err(dev, "failed to register regulator %s: %d\n", 383 + desc->name, ret); 384 + return ret; 385 + } 386 + } 387 + 388 + regmap_write(ltc3676->regmap, LTC3676_CLIRQ, 0); 389 + if (client->irq) { 390 + ret = devm_request_threaded_irq(dev, client->irq, NULL, 391 + ltc3676_isr, 392 + IRQF_TRIGGER_LOW | IRQF_ONESHOT, 393 + client->name, ltc3676); 394 + if (ret) { 395 + dev_err(dev, "Failed to request IRQ: %d\n", ret); 396 + return ret; 397 + } 398 + } 399 + 400 + return 0; 401 + } 402 + 403 + static const struct i2c_device_id ltc3676_i2c_id[] = { 404 + { "ltc3676" }, 405 + { } 406 + }; 407 + MODULE_DEVICE_TABLE(i2c, ltc3676_i2c_id); 408 + 409 + static struct i2c_driver ltc3676_driver = { 410 + .driver = { 411 + .name = DRIVER_NAME, 412 + }, 413 + .probe = ltc3676_regulator_probe, 414 + .id_table = ltc3676_i2c_id, 415 + }; 416 + module_i2c_driver(ltc3676_driver); 417 + 418 + MODULE_AUTHOR("Tim Harvey <tharvey@gateworks.com>"); 419 + MODULE_DESCRIPTION("Regulator driver for Linear Technology LTC1376"); 420 + MODULE_LICENSE("GPL v2");