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

Merge remote-tracking branches 'regulator/topic/lp8788', 'regulator/topic/mt6311', 'regulator/topic/optional', 'regulator/topic/palmas' and 'regulator/topic/pv88060' into regulator-next

+702 -17
+124
Documentation/devicetree/bindings/regulator/pv88060.txt
··· 1 + * Powerventure Semiconductor PV88060 Voltage Regulator 2 + 3 + Required properties: 4 + - compatible: "pvs,pv88060". 5 + - reg: I2C slave address, usually 0x49. 6 + - interrupts: the interrupt outputs of the controller 7 + - regulators: A node that houses a sub-node for each regulator within the 8 + device. Each sub-node is identified using the node's name, with valid 9 + values listed below. The content of each sub-node is defined by the 10 + standard binding for regulators; see regulator.txt. 11 + BUCK1, LDO1, LDO2, LDO3, LDO4, LDO5, LDO6, LDO7, SW1, SW2, SW3, SW4, 12 + SW5, and SW6. 13 + 14 + Optional properties: 15 + - Any optional property defined in regulator.txt 16 + 17 + Example 18 + 19 + pmic: pv88060@49 { 20 + compatible = "pvs,pv88060"; 21 + reg = <0x49>; 22 + interrupt-parent = <&gpio>; 23 + interrupts = <24 24>; 24 + 25 + regulators { 26 + BUCK1 { 27 + regulator-name = "buck1"; 28 + regulator-min-microvolt = <2800000>; 29 + regulator-max-microvolt = <4387500>; 30 + regulator-min-microamp = <1496000>; 31 + regulator-max-microamp = <4189000>; 32 + regulator-boot-on; 33 + }; 34 + 35 + LDO1 { 36 + regulator-name = "ldo1"; 37 + regulator-min-microvolt = <1200000>; 38 + regulator-max-microvolt = <3350000>; 39 + regulator-boot-on; 40 + }; 41 + 42 + LDO2 { 43 + regulator-name = "ldo2"; 44 + regulator-min-microvolt = <1200000>; 45 + regulator-max-microvolt = <3350000>; 46 + regulator-boot-on; 47 + }; 48 + 49 + LDO3 { 50 + regulator-name = "ldo3"; 51 + regulator-min-microvolt = <1200000>; 52 + regulator-max-microvolt = <3350000>; 53 + regulator-boot-on; 54 + }; 55 + 56 + LDO4 { 57 + regulator-name = "ldo4"; 58 + regulator-min-microvolt = <1200000>; 59 + regulator-max-microvolt = <3350000>; 60 + regulator-boot-on; 61 + }; 62 + 63 + LDO5 { 64 + regulator-name = "ldo5"; 65 + regulator-min-microvolt = <1200000>; 66 + regulator-max-microvolt = <3350000>; 67 + regulator-boot-on; 68 + }; 69 + 70 + LDO6 { 71 + regulator-name = "ldo6"; 72 + regulator-min-microvolt = <1200000>; 73 + regulator-max-microvolt = <3350000>; 74 + regulator-boot-on; 75 + }; 76 + 77 + LDO7 { 78 + regulator-name = "ldo7"; 79 + regulator-min-microvolt = <1200000>; 80 + regulator-max-microvolt = <3350000>; 81 + regulator-boot-on; 82 + }; 83 + 84 + SW1 { 85 + regulator-name = "sw1"; 86 + regulator-min-microvolt = <5000000>; 87 + regulator-max-microvolt = <5000000>; 88 + }; 89 + 90 + SW2 { 91 + regulator-name = "sw2"; 92 + regulator-min-microvolt = <5000000>; 93 + regulator-max-microvolt = <5000000>; 94 + regulator-boot-on; 95 + }; 96 + 97 + SW3 { 98 + regulator-name = "sw3"; 99 + regulator-min-microvolt = <5000000>; 100 + regulator-max-microvolt = <5000000>; 101 + regulator-boot-on; 102 + }; 103 + 104 + SW4 { 105 + regulator-name = "sw4"; 106 + regulator-min-microvolt = <5000000>; 107 + regulator-max-microvolt = <5000000>; 108 + regulator-boot-on; 109 + }; 110 + 111 + SW5 { 112 + regulator-name = "sw5"; 113 + regulator-min-microvolt = <5000000>; 114 + regulator-max-microvolt = <5000000>; 115 + regulator-boot-on; 116 + }; 117 + 118 + SW6 { 119 + regulator-name = "sw6"; 120 + regulator-min-microvolt = <5000000>; 121 + regulator-max-microvolt = <5000000>; 122 + }; 123 + }; 124 + };
+8
drivers/regulator/Kconfig
··· 514 514 Say y here to support the regulators found on the Freescale 515 515 PFUZE100/PFUZE200 PMIC. 516 516 517 + config REGULATOR_PV88060 518 + tristate "Powerventure Semiconductor PV88060 regulator" 519 + depends on I2C 520 + select REGMAP_I2C 521 + help 522 + Say y here to support the voltage regulators and convertors 523 + PV88060 524 + 517 525 config REGULATOR_PWM 518 526 tristate "PWM voltage regulator" 519 527 depends on PWM
+1
drivers/regulator/Makefile
··· 67 67 obj-$(CONFIG_REGULATOR_QCOM_SPMI) += qcom_spmi-regulator.o 68 68 obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o 69 69 obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o 70 + obj-$(CONFIG_REGULATOR_PV88060) += pv88060-regulator.o 70 71 obj-$(CONFIG_REGULATOR_PWM) += pwm-regulator.o 71 72 obj-$(CONFIG_REGULATOR_TPS51632) += tps51632-regulator.o 72 73 obj-$(CONFIG_REGULATOR_PBIAS) += pbias-regulator.o
+4 -2
drivers/regulator/core.c
··· 3446 3446 consumers[i].consumer = NULL; 3447 3447 3448 3448 for (i = 0; i < num_consumers; i++) { 3449 - consumers[i].consumer = regulator_get(dev, 3450 - consumers[i].supply); 3449 + consumers[i].consumer = _regulator_get(dev, 3450 + consumers[i].supply, 3451 + false, 3452 + !consumers[i].optional); 3451 3453 if (IS_ERR(consumers[i].consumer)) { 3452 3454 ret = PTR_ERR(consumers[i].consumer); 3453 3455 dev_err(dev, "Failed to get supply '%s': %d\n",
+5 -2
drivers/regulator/devres.c
··· 164 164 consumers[i].consumer = NULL; 165 165 166 166 for (i = 0; i < num_consumers; i++) { 167 - consumers[i].consumer = devm_regulator_get(dev, 168 - consumers[i].supply); 167 + consumers[i].consumer = _devm_regulator_get(dev, 168 + consumers[i].supply, 169 + consumers[i].optional ? 170 + OPTIONAL_GET : 171 + NORMAL_GET); 169 172 if (IS_ERR(consumers[i].consumer)) { 170 173 ret = PTR_ERR(consumers[i].consumer); 171 174 dev_err(dev, "Failed to get supply '%s': %d\n",
+2 -2
drivers/regulator/lp8788-buck.c
··· 344 344 REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL; 345 345 } 346 346 347 - static struct regulator_ops lp8788_buck12_ops = { 347 + static const struct regulator_ops lp8788_buck12_ops = { 348 348 .list_voltage = regulator_list_voltage_table, 349 349 .map_voltage = regulator_map_voltage_ascend, 350 350 .set_voltage_sel = lp8788_buck12_set_voltage_sel, ··· 357 357 .get_mode = lp8788_buck_get_mode, 358 358 }; 359 359 360 - static struct regulator_ops lp8788_buck34_ops = { 360 + static const struct regulator_ops lp8788_buck34_ops = { 361 361 .list_voltage = regulator_list_voltage_table, 362 362 .map_voltage = regulator_map_voltage_ascend, 363 363 .set_voltage_sel = regulator_set_voltage_sel_regmap,
+9 -11
drivers/regulator/lp8788-ldo.c
··· 170 170 return ENABLE_TIME_USEC * val; 171 171 } 172 172 173 - static struct regulator_ops lp8788_ldo_voltage_table_ops = { 173 + static const struct regulator_ops lp8788_ldo_voltage_table_ops = { 174 174 .list_voltage = regulator_list_voltage_table, 175 175 .set_voltage_sel = regulator_set_voltage_sel_regmap, 176 176 .get_voltage_sel = regulator_get_voltage_sel_regmap, ··· 180 180 .enable_time = lp8788_ldo_enable_time, 181 181 }; 182 182 183 - static struct regulator_ops lp8788_ldo_voltage_fixed_ops = { 183 + static const struct regulator_ops lp8788_ldo_voltage_fixed_ops = { 184 184 .list_voltage = regulator_list_voltage_linear, 185 185 .enable = regulator_enable_regmap, 186 186 .disable = regulator_disable_regmap, ··· 613 613 }, 614 614 }; 615 615 616 + static struct platform_driver * const drivers[] = { 617 + &lp8788_dldo_driver, 618 + &lp8788_aldo_driver, 619 + }; 620 + 616 621 static int __init lp8788_ldo_init(void) 617 622 { 618 - int ret; 619 - 620 - ret = platform_driver_register(&lp8788_dldo_driver); 621 - if (ret) 622 - return ret; 623 - 624 - return platform_driver_register(&lp8788_aldo_driver); 623 + return platform_register_drivers(drivers, ARRAY_SIZE(drivers)); 625 624 } 626 625 subsys_initcall(lp8788_ldo_init); 627 626 628 627 static void __exit lp8788_ldo_exit(void) 629 628 { 630 - platform_driver_unregister(&lp8788_aldo_driver); 631 - platform_driver_unregister(&lp8788_dldo_driver); 629 + platform_unregister_drivers(drivers, ARRAY_SIZE(drivers)); 632 630 } 633 631 module_exit(lp8788_ldo_exit); 634 632
+1
drivers/regulator/mt6311-regulator.c
··· 30 30 .reg_bits = 8, 31 31 .val_bits = 8, 32 32 .max_register = MT6311_FQMTR_CON4, 33 + .cache_type = REGCACHE_RBTREE, 33 34 }; 34 35 35 36 /* Default limits measured in millivolts and milliamps */
+39
drivers/regulator/palmas-regulator.c
··· 612 612 .map_voltage = regulator_map_voltage_linear, 613 613 }; 614 614 615 + static struct regulator_ops palmas_ops_ldo9 = { 616 + .is_enabled = palmas_is_enabled_ldo, 617 + .enable = regulator_enable_regmap, 618 + .disable = regulator_disable_regmap, 619 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 620 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 621 + .list_voltage = regulator_list_voltage_linear, 622 + .map_voltage = regulator_map_voltage_linear, 623 + .set_bypass = regulator_set_bypass_regmap, 624 + .get_bypass = regulator_get_bypass_regmap, 625 + }; 626 + 615 627 static struct regulator_ops palmas_ops_ext_control_ldo = { 616 628 .get_voltage_sel = regulator_get_voltage_sel_regmap, 617 629 .set_voltage_sel = regulator_set_voltage_sel_regmap, ··· 649 637 .list_voltage = regulator_list_voltage_linear, 650 638 .map_voltage = regulator_map_voltage_linear, 651 639 .set_voltage_time_sel = regulator_set_voltage_time_sel, 640 + }; 641 + 642 + static struct regulator_ops tps65917_ops_ldo_1_2 = { 643 + .is_enabled = palmas_is_enabled_ldo, 644 + .enable = regulator_enable_regmap, 645 + .disable = regulator_disable_regmap, 646 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 647 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 648 + .list_voltage = regulator_list_voltage_linear, 649 + .map_voltage = regulator_map_voltage_linear, 650 + .set_voltage_time_sel = regulator_set_voltage_time_sel, 651 + .set_bypass = regulator_set_bypass_regmap, 652 + .get_bypass = regulator_get_bypass_regmap, 652 653 }; 653 654 654 655 static int palmas_regulator_config_external(struct palmas *palmas, int id, ··· 940 915 if (pdata && pdata->ldo6_vibrator && 941 916 (id == PALMAS_REG_LDO6)) 942 917 desc->enable_time = 2000; 918 + 919 + if (id == PALMAS_REG_LDO9) { 920 + desc->ops = &palmas_ops_ldo9; 921 + desc->bypass_reg = desc->enable_reg; 922 + desc->bypass_mask = 923 + PALMAS_LDO9_CTRL_LDO_BYPASS_EN; 924 + } 943 925 } else { 944 926 if (!ddata->has_regen3 && id == PALMAS_REG_REGEN3) 945 927 continue; ··· 1051 1019 * It is of the order of ~60mV/uS. 1052 1020 */ 1053 1021 desc->ramp_delay = 2500; 1022 + if (id == TPS65917_REG_LDO1 || 1023 + id == TPS65917_REG_LDO2) { 1024 + desc->ops = &tps65917_ops_ldo_1_2; 1025 + desc->bypass_reg = desc->enable_reg; 1026 + desc->bypass_mask = 1027 + TPS65917_LDO1_CTRL_BYPASS_EN; 1028 + } 1054 1029 } else { 1055 1030 desc->n_voltages = 1; 1056 1031 if (reg_init && reg_init->roof_floor)
+437
drivers/regulator/pv88060-regulator.c
··· 1 + /* 2 + * pv88060-regulator.c - Regulator device driver for PV88060 3 + * Copyright (C) 2015 Powerventure Semiconductor Ltd. 4 + * 5 + * This program is free software; you can redistribute it and/or 6 + * modify it under the terms of the GNU General Public License 7 + * as published by the Free Software Foundation; either version 2 8 + * of the License, or (at your option) any later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + */ 15 + 16 + #include <linux/err.h> 17 + #include <linux/gpio.h> 18 + #include <linux/i2c.h> 19 + #include <linux/module.h> 20 + #include <linux/init.h> 21 + #include <linux/slab.h> 22 + #include <linux/regulator/driver.h> 23 + #include <linux/regulator/machine.h> 24 + #include <linux/regmap.h> 25 + #include <linux/irq.h> 26 + #include <linux/interrupt.h> 27 + #include <linux/regulator/of_regulator.h> 28 + #include <linux/proc_fs.h> 29 + #include <linux/uaccess.h> 30 + #include "pv88060-regulator.h" 31 + 32 + #define PV88060_MAX_REGULATORS 14 33 + 34 + /* PV88060 REGULATOR IDs */ 35 + enum { 36 + /* BUCKs */ 37 + PV88060_ID_BUCK1, 38 + 39 + /* LDOs */ 40 + PV88060_ID_LDO1, 41 + PV88060_ID_LDO2, 42 + PV88060_ID_LDO3, 43 + PV88060_ID_LDO4, 44 + PV88060_ID_LDO5, 45 + PV88060_ID_LDO6, 46 + PV88060_ID_LDO7, 47 + 48 + /* SWTs */ 49 + PV88060_ID_SW1, 50 + PV88060_ID_SW2, 51 + PV88060_ID_SW3, 52 + PV88060_ID_SW4, 53 + PV88060_ID_SW5, 54 + PV88060_ID_SW6, 55 + }; 56 + 57 + struct pv88060_regulator { 58 + struct regulator_desc desc; 59 + /* Current limiting */ 60 + unsigned n_current_limits; 61 + const int *current_limits; 62 + unsigned int limit_mask; 63 + unsigned int conf; /* buck configuration register */ 64 + }; 65 + 66 + struct pv88060 { 67 + struct device *dev; 68 + struct regmap *regmap; 69 + struct regulator_dev *rdev[PV88060_MAX_REGULATORS]; 70 + }; 71 + 72 + static const struct regmap_config pv88060_regmap_config = { 73 + .reg_bits = 8, 74 + .val_bits = 8, 75 + }; 76 + 77 + /* Current limits array (in uA) for BUCK1 78 + * Entry indexes corresponds to register values. 79 + */ 80 + 81 + static const int pv88060_buck1_limits[] = { 82 + 1496000, 2393000, 3291000, 4189000 83 + }; 84 + 85 + static unsigned int pv88060_buck_get_mode(struct regulator_dev *rdev) 86 + { 87 + struct pv88060_regulator *info = rdev_get_drvdata(rdev); 88 + unsigned int data; 89 + int ret, mode = 0; 90 + 91 + ret = regmap_read(rdev->regmap, info->conf, &data); 92 + if (ret < 0) 93 + return ret; 94 + 95 + switch (data & PV88060_BUCK_MODE_MASK) { 96 + case PV88060_BUCK_MODE_SYNC: 97 + mode = REGULATOR_MODE_FAST; 98 + break; 99 + case PV88060_BUCK_MODE_AUTO: 100 + mode = REGULATOR_MODE_NORMAL; 101 + break; 102 + case PV88060_BUCK_MODE_SLEEP: 103 + mode = REGULATOR_MODE_STANDBY; 104 + break; 105 + } 106 + 107 + return mode; 108 + } 109 + 110 + static int pv88060_buck_set_mode(struct regulator_dev *rdev, 111 + unsigned int mode) 112 + { 113 + struct pv88060_regulator *info = rdev_get_drvdata(rdev); 114 + int val = 0; 115 + 116 + switch (mode) { 117 + case REGULATOR_MODE_FAST: 118 + val = PV88060_BUCK_MODE_SYNC; 119 + break; 120 + case REGULATOR_MODE_NORMAL: 121 + val = PV88060_BUCK_MODE_AUTO; 122 + break; 123 + case REGULATOR_MODE_STANDBY: 124 + val = PV88060_BUCK_MODE_SLEEP; 125 + break; 126 + default: 127 + return -EINVAL; 128 + } 129 + 130 + return regmap_update_bits(rdev->regmap, info->conf, 131 + PV88060_BUCK_MODE_MASK, val); 132 + } 133 + 134 + static int pv88060_set_current_limit(struct regulator_dev *rdev, int min, 135 + int max) 136 + { 137 + struct pv88060_regulator *info = rdev_get_drvdata(rdev); 138 + int i; 139 + 140 + /* search for closest to maximum */ 141 + for (i = info->n_current_limits; i >= 0; i--) { 142 + if (min <= info->current_limits[i] 143 + && max >= info->current_limits[i]) { 144 + return regmap_update_bits(rdev->regmap, 145 + info->conf, 146 + info->limit_mask, 147 + i << PV88060_BUCK_ILIM_SHIFT); 148 + } 149 + } 150 + 151 + return -EINVAL; 152 + } 153 + 154 + static int pv88060_get_current_limit(struct regulator_dev *rdev) 155 + { 156 + struct pv88060_regulator *info = rdev_get_drvdata(rdev); 157 + unsigned int data; 158 + int ret; 159 + 160 + ret = regmap_read(rdev->regmap, info->conf, &data); 161 + if (ret < 0) 162 + return ret; 163 + 164 + data = (data & info->limit_mask) >> PV88060_BUCK_ILIM_SHIFT; 165 + return info->current_limits[data]; 166 + } 167 + 168 + static struct regulator_ops pv88060_buck_ops = { 169 + .get_mode = pv88060_buck_get_mode, 170 + .set_mode = pv88060_buck_set_mode, 171 + .enable = regulator_enable_regmap, 172 + .disable = regulator_disable_regmap, 173 + .is_enabled = regulator_is_enabled_regmap, 174 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 175 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 176 + .list_voltage = regulator_list_voltage_linear, 177 + .set_current_limit = pv88060_set_current_limit, 178 + .get_current_limit = pv88060_get_current_limit, 179 + }; 180 + 181 + static struct regulator_ops pv88060_ldo_ops = { 182 + .enable = regulator_enable_regmap, 183 + .disable = regulator_disable_regmap, 184 + .is_enabled = regulator_is_enabled_regmap, 185 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 186 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 187 + .list_voltage = regulator_list_voltage_linear, 188 + }; 189 + 190 + #define PV88060_BUCK(chip, regl_name, min, step, max, limits_array) \ 191 + {\ 192 + .desc = {\ 193 + .id = chip##_ID_##regl_name,\ 194 + .name = __stringify(chip##_##regl_name),\ 195 + .of_match = of_match_ptr(#regl_name),\ 196 + .regulators_node = of_match_ptr("regulators"),\ 197 + .type = REGULATOR_VOLTAGE,\ 198 + .owner = THIS_MODULE,\ 199 + .ops = &pv88060_buck_ops,\ 200 + .min_uV = min,\ 201 + .uV_step = step,\ 202 + .n_voltages = ((max) - (min))/(step) + 1,\ 203 + .enable_reg = PV88060_REG_##regl_name##_CONF0,\ 204 + .enable_mask = PV88060_BUCK_EN, \ 205 + .vsel_reg = PV88060_REG_##regl_name##_CONF0,\ 206 + .vsel_mask = PV88060_VBUCK_MASK,\ 207 + },\ 208 + .current_limits = limits_array,\ 209 + .n_current_limits = ARRAY_SIZE(limits_array),\ 210 + .limit_mask = PV88060_BUCK_ILIM_MASK, \ 211 + .conf = PV88060_REG_##regl_name##_CONF1,\ 212 + } 213 + 214 + #define PV88060_LDO(chip, regl_name, min, step, max) \ 215 + {\ 216 + .desc = {\ 217 + .id = chip##_ID_##regl_name,\ 218 + .name = __stringify(chip##_##regl_name),\ 219 + .of_match = of_match_ptr(#regl_name),\ 220 + .regulators_node = of_match_ptr("regulators"),\ 221 + .type = REGULATOR_VOLTAGE,\ 222 + .owner = THIS_MODULE,\ 223 + .ops = &pv88060_ldo_ops,\ 224 + .min_uV = min, \ 225 + .uV_step = step, \ 226 + .n_voltages = (step) ? ((max - min) / step + 1) : 1, \ 227 + .enable_reg = PV88060_REG_##regl_name##_CONF, \ 228 + .enable_mask = PV88060_LDO_EN, \ 229 + .vsel_reg = PV88060_REG_##regl_name##_CONF, \ 230 + .vsel_mask = PV88060_VLDO_MASK, \ 231 + },\ 232 + } 233 + 234 + #define PV88060_SW(chip, regl_name, max) \ 235 + {\ 236 + .desc = {\ 237 + .id = chip##_ID_##regl_name,\ 238 + .name = __stringify(chip##_##regl_name),\ 239 + .of_match = of_match_ptr(#regl_name),\ 240 + .regulators_node = of_match_ptr("regulators"),\ 241 + .type = REGULATOR_VOLTAGE,\ 242 + .owner = THIS_MODULE,\ 243 + .ops = &pv88060_ldo_ops,\ 244 + .min_uV = max,\ 245 + .uV_step = 0,\ 246 + .n_voltages = 1,\ 247 + .enable_reg = PV88060_REG_##regl_name##_CONF,\ 248 + .enable_mask = PV88060_SW_EN,\ 249 + },\ 250 + } 251 + 252 + static const struct pv88060_regulator pv88060_regulator_info[] = { 253 + PV88060_BUCK(PV88060, BUCK1, 2800000, 12500, 4387500, 254 + pv88060_buck1_limits), 255 + PV88060_LDO(PV88060, LDO1, 1200000, 50000, 3350000), 256 + PV88060_LDO(PV88060, LDO2, 1200000, 50000, 3350000), 257 + PV88060_LDO(PV88060, LDO3, 1200000, 50000, 3350000), 258 + PV88060_LDO(PV88060, LDO4, 1200000, 50000, 3350000), 259 + PV88060_LDO(PV88060, LDO5, 1200000, 50000, 3350000), 260 + PV88060_LDO(PV88060, LDO6, 1200000, 50000, 3350000), 261 + PV88060_LDO(PV88060, LDO7, 1200000, 50000, 3350000), 262 + PV88060_SW(PV88060, SW1, 5000000), 263 + PV88060_SW(PV88060, SW2, 5000000), 264 + PV88060_SW(PV88060, SW3, 5000000), 265 + PV88060_SW(PV88060, SW4, 5000000), 266 + PV88060_SW(PV88060, SW5, 5000000), 267 + PV88060_SW(PV88060, SW6, 5000000), 268 + }; 269 + 270 + static irqreturn_t pv88060_irq_handler(int irq, void *data) 271 + { 272 + struct pv88060 *chip = data; 273 + int i, reg_val, err, ret = IRQ_NONE; 274 + 275 + err = regmap_read(chip->regmap, PV88060_REG_EVENT_A, &reg_val); 276 + if (err < 0) 277 + goto error_i2c; 278 + 279 + if (reg_val & PV88060_E_VDD_FLT) { 280 + for (i = 0; i < PV88060_MAX_REGULATORS; i++) { 281 + if (chip->rdev[i] != NULL) { 282 + regulator_notifier_call_chain(chip->rdev[i], 283 + REGULATOR_EVENT_UNDER_VOLTAGE, 284 + NULL); 285 + } 286 + } 287 + 288 + err = regmap_update_bits(chip->regmap, PV88060_REG_EVENT_A, 289 + PV88060_E_VDD_FLT, PV88060_E_VDD_FLT); 290 + if (err < 0) 291 + goto error_i2c; 292 + 293 + ret = IRQ_HANDLED; 294 + } 295 + 296 + if (reg_val & PV88060_E_OVER_TEMP) { 297 + for (i = 0; i < PV88060_MAX_REGULATORS; i++) { 298 + if (chip->rdev[i] != NULL) { 299 + regulator_notifier_call_chain(chip->rdev[i], 300 + REGULATOR_EVENT_OVER_TEMP, 301 + NULL); 302 + } 303 + } 304 + 305 + err = regmap_update_bits(chip->regmap, PV88060_REG_EVENT_A, 306 + PV88060_E_OVER_TEMP, PV88060_E_OVER_TEMP); 307 + if (err < 0) 308 + goto error_i2c; 309 + 310 + ret = IRQ_HANDLED; 311 + } 312 + 313 + return ret; 314 + 315 + error_i2c: 316 + dev_err(chip->dev, "I2C error : %d\n", err); 317 + return IRQ_NONE; 318 + } 319 + 320 + /* 321 + * I2C driver interface functions 322 + */ 323 + static int pv88060_i2c_probe(struct i2c_client *i2c, 324 + const struct i2c_device_id *id) 325 + { 326 + struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev); 327 + struct pv88060 *chip; 328 + struct regulator_config config = { }; 329 + int error, i, ret = 0; 330 + 331 + chip = devm_kzalloc(&i2c->dev, sizeof(struct pv88060), GFP_KERNEL); 332 + if (!chip) 333 + return -ENOMEM; 334 + 335 + chip->dev = &i2c->dev; 336 + chip->regmap = devm_regmap_init_i2c(i2c, &pv88060_regmap_config); 337 + if (IS_ERR(chip->regmap)) { 338 + error = PTR_ERR(chip->regmap); 339 + dev_err(chip->dev, "Failed to allocate register map: %d\n", 340 + error); 341 + return error; 342 + } 343 + 344 + i2c_set_clientdata(i2c, chip); 345 + 346 + if (i2c->irq != 0) { 347 + ret = regmap_write(chip->regmap, PV88060_REG_MASK_A, 0xFF); 348 + if (ret < 0) { 349 + dev_err(chip->dev, 350 + "Failed to mask A reg: %d\n", ret); 351 + return ret; 352 + } 353 + 354 + ret = regmap_write(chip->regmap, PV88060_REG_MASK_B, 0xFF); 355 + if (ret < 0) { 356 + dev_err(chip->dev, 357 + "Failed to mask B reg: %d\n", ret); 358 + return ret; 359 + } 360 + 361 + ret = regmap_write(chip->regmap, PV88060_REG_MASK_C, 0xFF); 362 + if (ret < 0) { 363 + dev_err(chip->dev, 364 + "Failed to mask C reg: %d\n", ret); 365 + return ret; 366 + } 367 + 368 + ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL, 369 + pv88060_irq_handler, 370 + IRQF_TRIGGER_LOW|IRQF_ONESHOT, 371 + "pv88060", chip); 372 + if (ret != 0) { 373 + dev_err(chip->dev, "Failed to request IRQ: %d\n", 374 + i2c->irq); 375 + return ret; 376 + } 377 + 378 + ret = regmap_update_bits(chip->regmap, PV88060_REG_MASK_A, 379 + PV88060_M_VDD_FLT | PV88060_M_OVER_TEMP, 0); 380 + if (ret < 0) { 381 + dev_err(chip->dev, 382 + "Failed to update mask reg: %d\n", ret); 383 + return ret; 384 + } 385 + 386 + } else { 387 + dev_warn(chip->dev, "No IRQ configured\n"); 388 + } 389 + 390 + config.dev = chip->dev; 391 + config.regmap = chip->regmap; 392 + 393 + for (i = 0; i < PV88060_MAX_REGULATORS; i++) { 394 + if (init_data) 395 + config.init_data = &init_data[i]; 396 + 397 + config.driver_data = (void *)&pv88060_regulator_info[i]; 398 + chip->rdev[i] = devm_regulator_register(chip->dev, 399 + &pv88060_regulator_info[i].desc, &config); 400 + if (IS_ERR(chip->rdev[i])) { 401 + dev_err(chip->dev, 402 + "Failed to register PV88060 regulator\n"); 403 + return PTR_ERR(chip->rdev[i]); 404 + } 405 + } 406 + 407 + return 0; 408 + } 409 + 410 + static const struct i2c_device_id pv88060_i2c_id[] = { 411 + {"pv88060", 0}, 412 + {}, 413 + }; 414 + MODULE_DEVICE_TABLE(i2c, pv88060_i2c_id); 415 + 416 + #ifdef CONFIG_OF 417 + static const struct of_device_id pv88060_dt_ids[] = { 418 + { .compatible = "pvs,pv88060", .data = &pv88060_i2c_id[0] }, 419 + {}, 420 + }; 421 + MODULE_DEVICE_TABLE(of, pv88060_dt_ids); 422 + #endif 423 + 424 + static struct i2c_driver pv88060_regulator_driver = { 425 + .driver = { 426 + .name = "pv88060", 427 + .of_match_table = of_match_ptr(pv88060_dt_ids), 428 + }, 429 + .probe = pv88060_i2c_probe, 430 + .id_table = pv88060_i2c_id, 431 + }; 432 + 433 + module_i2c_driver(pv88060_regulator_driver); 434 + 435 + MODULE_AUTHOR("James Ban <James.Ban.opensource@diasemi.com>"); 436 + MODULE_DESCRIPTION("Regulator device driver for Powerventure PV88060"); 437 + MODULE_LICENSE("GPL");
+69
drivers/regulator/pv88060-regulator.h
··· 1 + /* 2 + * pv88060-regulator.h - Regulator definitions for PV88060 3 + * Copyright (C) 2015 Powerventure Semiconductor Ltd. 4 + * 5 + * This program is free software; you can redistribute it and/or 6 + * modify it under the terms of the GNU General Public License 7 + * as published by the Free Software Foundation; either version 2 8 + * of the License, or (at your option) any later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + */ 15 + 16 + #ifndef __PV88060_REGISTERS_H__ 17 + #define __PV88060_REGISTERS_H__ 18 + 19 + /* System Control and Event Registers */ 20 + #define PV88060_REG_EVENT_A 0x04 21 + #define PV88060_REG_MASK_A 0x08 22 + #define PV88060_REG_MASK_B 0x09 23 + #define PV88060_REG_MASK_C 0x0A 24 + 25 + /* Regulator Registers */ 26 + #define PV88060_REG_BUCK1_CONF0 0x1B 27 + #define PV88060_REG_BUCK1_CONF1 0x1C 28 + #define PV88060_REG_LDO1_CONF 0x1D 29 + #define PV88060_REG_LDO2_CONF 0x1E 30 + #define PV88060_REG_LDO3_CONF 0x1F 31 + #define PV88060_REG_LDO4_CONF 0x20 32 + #define PV88060_REG_LDO5_CONF 0x21 33 + #define PV88060_REG_LDO6_CONF 0x22 34 + #define PV88060_REG_LDO7_CONF 0x23 35 + 36 + #define PV88060_REG_SW1_CONF 0x3B 37 + #define PV88060_REG_SW2_CONF 0x3C 38 + #define PV88060_REG_SW3_CONF 0x3D 39 + #define PV88060_REG_SW4_CONF 0x3E 40 + #define PV88060_REG_SW5_CONF 0x3F 41 + #define PV88060_REG_SW6_CONF 0x40 42 + 43 + /* PV88060_REG_EVENT_A (addr=0x04) */ 44 + #define PV88060_E_VDD_FLT 0x01 45 + #define PV88060_E_OVER_TEMP 0x02 46 + 47 + /* PV88060_REG_MASK_A (addr=0x08) */ 48 + #define PV88060_M_VDD_FLT 0x01 49 + #define PV88060_M_OVER_TEMP 0x02 50 + 51 + /* PV88060_REG_BUCK1_CONF0 (addr=0x1B) */ 52 + #define PV88060_BUCK_EN 0x80 53 + #define PV88060_VBUCK_MASK 0x7F 54 + /* PV88060_REG_LDO1/2/3/4/5/6/7_CONT */ 55 + #define PV88060_LDO_EN 0x40 56 + #define PV88060_VLDO_MASK 0x3F 57 + /* PV88060_REG_SW1/2/3/4/5_CONF */ 58 + #define PV88060_SW_EN 0x80 59 + 60 + /* PV88060_REG_BUCK1_CONF1 (addr=0x1C) */ 61 + #define PV88060_BUCK_ILIM_SHIFT 2 62 + #define PV88060_BUCK_ILIM_MASK 0x0C 63 + #define PV88060_BUCK_MODE_SHIFT 0 64 + #define PV88060_BUCK_MODE_MASK 0x03 65 + #define PV88060_BUCK_MODE_SLEEP 0x00 66 + #define PV88060_BUCK_MODE_AUTO 0x01 67 + #define PV88060_BUCK_MODE_SYNC 0x02 68 + 69 + #endif /* __PV88060_REGISTERS_H__ */
+3
include/linux/regulator/consumer.h
··· 140 140 * 141 141 * @supply: The name of the supply. Initialised by the user before 142 142 * using the bulk regulator APIs. 143 + * @optional: The supply should be considered optional. Initialised by the user 144 + * before using the bulk regulator APIs. 143 145 * @consumer: The regulator consumer for the supply. This will be managed 144 146 * by the bulk API. 145 147 * ··· 151 149 */ 152 150 struct regulator_bulk_data { 153 151 const char *supply; 152 + bool optional; 154 153 struct regulator *consumer; 155 154 156 155 /* private: Internal use */