From f307a7e9b7af401d459d26f98497c9cec766a41f Mon Sep 17 00:00:00 2001 From: James Ban Date: Thu, 19 Nov 2015 09:59:15 +0900 Subject: regulator: pv88060: new regulator driver This is the driver for the Powerventure PV88060 BUCKs and LDOs regulator. It communicates via an I2C bus to the device. Signed-off-by: James Ban Signed-off-by: Mark Brown --- .../devicetree/bindings/regulator/pv88060.txt | 124 +++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/pv88060.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/regulator/pv88060.txt b/Documentation/devicetree/bindings/regulator/pv88060.txt new file mode 100644 index 000000000000..10a6dadc008e --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/pv88060.txt @@ -0,0 +1,124 @@ +* Powerventure Semiconductor PV88060 Voltage Regulator + +Required properties: +- compatible: "pvs,pv88060". +- reg: I2C slave address, usually 0x49. +- interrupts: the interrupt outputs of the controller +- regulators: A node that houses a sub-node for each regulator within the + device. Each sub-node is identified using the node's name, with valid + values listed below. The content of each sub-node is defined by the + standard binding for regulators; see regulator.txt. + BUCK1, LDO1, LDO2, LDO3, LDO4, LDO5, LDO6, LDO7, SW1, SW2, SW3, SW4, + SW5, and SW6. + +Optional properties: +- Any optional property defined in regulator.txt + +Example + + pmic: pv88060@49 { + compatible = "pvs,pv88060"; + reg = <0x49>; + interrupt-parent = <&gpio>; + interrupts = <24 24>; + + regulators { + BUCK1 { + regulator-name = "buck1"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <4387500>; + regulator-min-microamp = <1496000>; + regulator-max-microamp = <4189000>; + regulator-boot-on; + }; + + LDO1 { + regulator-name = "ldo1"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3350000>; + regulator-boot-on; + }; + + LDO2 { + regulator-name = "ldo2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3350000>; + regulator-boot-on; + }; + + LDO3 { + regulator-name = "ldo3"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3350000>; + regulator-boot-on; + }; + + LDO4 { + regulator-name = "ldo4"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3350000>; + regulator-boot-on; + }; + + LDO5 { + regulator-name = "ldo5"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3350000>; + regulator-boot-on; + }; + + LDO6 { + regulator-name = "ldo6"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3350000>; + regulator-boot-on; + }; + + LDO7 { + regulator-name = "ldo7"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3350000>; + regulator-boot-on; + }; + + SW1 { + regulator-name = "sw1"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + SW2 { + regulator-name = "sw2"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + }; + + SW3 { + regulator-name = "sw3"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + }; + + SW4 { + regulator-name = "sw4"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + }; + + SW5 { + regulator-name = "sw5"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + }; + + SW6 { + regulator-name = "sw6"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + }; + }; \ No newline at end of file -- cgit v1.2.3-59-g8ed1b From eaea7d27129b9b493c3029608486c157827a92ce Mon Sep 17 00:00:00 2001 From: Milo Kim Date: Thu, 26 Nov 2015 15:57:00 +0900 Subject: regulator: lm363x: add LM363x regulator binding information This binding describes LM3631 and LM3632 regulator properties. Signed-off-by: Milo Kim Signed-off-by: Mark Brown --- .../bindings/regulator/lm363x-regulator.txt | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/lm363x-regulator.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/regulator/lm363x-regulator.txt b/Documentation/devicetree/bindings/regulator/lm363x-regulator.txt new file mode 100644 index 000000000000..8f14df9d1205 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/lm363x-regulator.txt @@ -0,0 +1,34 @@ +TI LMU LM363x regulator device tree bindings + +LM363x regulator driver supports LM3631 and LM3632. +LM3631 has five regulators and LM3632 supports three regulators. + +Required property: + - compatible: "ti,lm363x-regulator" + +Optional properties: + LM3632 has external enable pins for two LDOs. + - ti,lcm-en1-gpio: A GPIO specifier for Vpos control pin. + - ti,lcm-en2-gpio: A GPIO specifier for Vneg control pin. + +Child nodes: + LM3631 + - vboost + - vcont + - voref + - vpos + - vneg + + LM3632 + - vboost + - vpos + - vneg + + Optional properties of a child node: + Each sub-node should contain the constraints and initialization. + Please refer to [1]. + +Examples: Please refer to ti-lmu dt-bindings [2]. + +[1] ../regulator/regulator.txt +[2] ../mfd/ti-lmu.txt -- cgit v1.2.3-59-g8ed1b From c90456e36d9c89de0b6e9c8f21003208e0ad7f13 Mon Sep 17 00:00:00 2001 From: James Ban Date: Tue, 8 Dec 2015 10:57:29 +0900 Subject: regulator: pv88090: new regulator driver This is the driver for the Powerventure PV88090 BUCKs and LDOs regulator. It communicates via an I2C bus to the device. Signed-off-by: James Ban Signed-off-by: Mark Brown --- .../devicetree/bindings/regulator/pv88090.txt | 65 +++ drivers/regulator/Kconfig | 8 + drivers/regulator/Makefile | 1 + drivers/regulator/pv88090-regulator.c | 458 +++++++++++++++++++++ drivers/regulator/pv88090-regulator.h | 98 +++++ 5 files changed, 630 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/pv88090.txt create mode 100644 drivers/regulator/pv88090-regulator.c create mode 100644 drivers/regulator/pv88090-regulator.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/regulator/pv88090.txt b/Documentation/devicetree/bindings/regulator/pv88090.txt new file mode 100644 index 000000000000..e52b2a95cdde --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/pv88090.txt @@ -0,0 +1,65 @@ +* Powerventure Semiconductor PV88090 Voltage Regulator + +Required properties: +- compatible: "pvs,pv88090". +- reg: I2C slave address, usually 0x48. +- interrupts: the interrupt outputs of the controller +- regulators: A node that houses a sub-node for each regulator within the + device. Each sub-node is identified using the node's name, with valid + values listed below. The content of each sub-node is defined by the + standard binding for regulators; see regulator.txt. + BUCK1, BUCK2, BUCK3, LDO1, and LDO2. + +Optional properties: +- Any optional property defined in regulator.txt + +Example + + pmic: pv88090@48 { + compatible = "pvs,pv88090"; + reg = <0x48>; + interrupt-parent = <&gpio>; + interrupts = <24 24>; + + regulators { + BUCK1 { + regulator-name = "buck1"; + regulator-min-microvolt = < 600000>; + regulator-max-microvolt = <1393750>; + regulator-min-microamp = < 220000>; + regulator-max-microamp = <7040000>; + regulator-boot-on; + }; + + BUCK2 { + regulator-name = "buck2"; + regulator-min-microvolt = < 600000>; + regulator-max-microvolt = <1393750>; + regulator-min-microamp = <1496000>; + regulator-max-microamp = <4189000>; + }; + + BUCK3 { + regulator-name = "buck3"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1393750>; + regulator-min-microamp = <1496000>; + regulator-max-microamp = <4189000>; + regulator-boot-on; + }; + + LDO1 { + regulator-name = "ldo1"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <4350000>; + regulator-boot-on; + }; + + LDO2 { + regulator-name = "ldo2"; + regulator-min-microvolt = < 650000>; + regulator-max-microvolt = <2225000>; + regulator-boot-on; + }; + }; + }; diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index c61f72ff1dfd..5433c448aff2 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -512,6 +512,14 @@ config REGULATOR_PV88060 Say y here to support the voltage regulators and convertors PV88060 +config REGULATOR_PV88090 + tristate "Powerventure Semiconductor PV88090 regulator" + depends on I2C + select REGMAP_I2C + help + Say y here to support the voltage regulators and convertors + on PV88090 + config REGULATOR_PWM tristate "PWM voltage regulator" depends on PWM diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index b11c8a4f873a..29cda9d53787 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -67,6 +67,7 @@ obj-$(CONFIG_REGULATOR_QCOM_SPMI) += qcom_spmi-regulator.o obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o obj-$(CONFIG_REGULATOR_PV88060) += pv88060-regulator.o +obj-$(CONFIG_REGULATOR_PV88090) += pv88090-regulator.o obj-$(CONFIG_REGULATOR_PWM) += pwm-regulator.o obj-$(CONFIG_REGULATOR_TPS51632) += tps51632-regulator.o obj-$(CONFIG_REGULATOR_PBIAS) += pbias-regulator.o diff --git a/drivers/regulator/pv88090-regulator.c b/drivers/regulator/pv88090-regulator.c new file mode 100644 index 000000000000..3ec5f2bdfc51 --- /dev/null +++ b/drivers/regulator/pv88090-regulator.c @@ -0,0 +1,458 @@ +/* + * pv88090-regulator.c - Regulator device driver for PV88090 + * Copyright (C) 2015 Powerventure Semiconductor Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pv88090-regulator.h" + +#define PV88090_MAX_REGULATORS 5 + +/* PV88090 REGULATOR IDs */ +enum { + /* BUCKs */ + PV88090_ID_BUCK1, + PV88090_ID_BUCK2, + PV88090_ID_BUCK3, + + /* LDOs */ + PV88090_ID_LDO1, + PV88090_ID_LDO2, +}; + +struct pv88090_regulator { + struct regulator_desc desc; + /* Current limiting */ + unsigned n_current_limits; + const int *current_limits; + unsigned int limit_mask; + unsigned int conf; + unsigned int conf2; +}; + +struct pv88090 { + struct device *dev; + struct regmap *regmap; + struct regulator_dev *rdev[PV88090_MAX_REGULATORS]; +}; + +struct pv88090_buck_voltage { + int min_uV; + int max_uV; + int uV_step; +}; + +static const struct regmap_config pv88090_regmap_config = { + .reg_bits = 8, + .val_bits = 8, +}; + +/* Current limits array (in uA) for BUCK1, BUCK2, BUCK3. + * Entry indexes corresponds to register values. + */ + +static const int pv88090_buck1_limits[] = { + 220000, 440000, 660000, 880000, 1100000, 1320000, 1540000, 1760000, + 1980000, 2200000, 2420000, 2640000, 2860000, 3080000, 3300000, 3520000, + 3740000, 3960000, 4180000, 4400000, 4620000, 4840000, 5060000, 5280000, + 5500000, 5720000, 5940000, 6160000, 6380000, 6600000, 6820000, 7040000 +}; + +static const int pv88090_buck23_limits[] = { + 1496000, 2393000, 3291000, 4189000 +}; + +static const struct pv88090_buck_voltage pv88090_buck_vol[3] = { + { + .min_uV = 600000, + .max_uV = 1393750, + .uV_step = 6250, + }, + + { + .min_uV = 1400000, + .max_uV = 2193750, + .uV_step = 6250, + }, + { + .min_uV = 1250000, + .max_uV = 2837500, + .uV_step = 12500, + }, +}; + +static unsigned int pv88090_buck_get_mode(struct regulator_dev *rdev) +{ + struct pv88090_regulator *info = rdev_get_drvdata(rdev); + unsigned int data; + int ret, mode = 0; + + ret = regmap_read(rdev->regmap, info->conf, &data); + if (ret < 0) + return ret; + + switch (data & PV88090_BUCK1_MODE_MASK) { + case PV88090_BUCK_MODE_SYNC: + mode = REGULATOR_MODE_FAST; + break; + case PV88090_BUCK_MODE_AUTO: + mode = REGULATOR_MODE_NORMAL; + break; + case PV88090_BUCK_MODE_SLEEP: + mode = REGULATOR_MODE_STANDBY; + break; + } + + return mode; +} + +static int pv88090_buck_set_mode(struct regulator_dev *rdev, + unsigned int mode) +{ + struct pv88090_regulator *info = rdev_get_drvdata(rdev); + int val = 0; + + switch (mode) { + case REGULATOR_MODE_FAST: + val = PV88090_BUCK_MODE_SYNC; + break; + case REGULATOR_MODE_NORMAL: + val = PV88090_BUCK_MODE_AUTO; + break; + case REGULATOR_MODE_STANDBY: + val = PV88090_BUCK_MODE_SLEEP; + break; + default: + return -EINVAL; + } + + return regmap_update_bits(rdev->regmap, info->conf, + PV88090_BUCK1_MODE_MASK, val); +} + +static int pv88090_set_current_limit(struct regulator_dev *rdev, int min, + int max) +{ + struct pv88090_regulator *info = rdev_get_drvdata(rdev); + int i; + + /* search for closest to maximum */ + for (i = info->n_current_limits; i >= 0; i--) { + if (min <= info->current_limits[i] + && max >= info->current_limits[i]) { + return regmap_update_bits(rdev->regmap, + info->conf, + info->limit_mask, + i << PV88090_BUCK1_ILIM_SHIFT); + } + } + + return -EINVAL; +} + +static int pv88090_get_current_limit(struct regulator_dev *rdev) +{ + struct pv88090_regulator *info = rdev_get_drvdata(rdev); + unsigned int data; + int ret; + + ret = regmap_read(rdev->regmap, info->conf, &data); + if (ret < 0) + return ret; + + data = (data & info->limit_mask) >> PV88090_BUCK1_ILIM_SHIFT; + return info->current_limits[data]; +} + +static struct regulator_ops pv88090_buck_ops = { + .get_mode = pv88090_buck_get_mode, + .set_mode = pv88090_buck_set_mode, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear, + .set_current_limit = pv88090_set_current_limit, + .get_current_limit = pv88090_get_current_limit, +}; + +static struct regulator_ops pv88090_ldo_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear, +}; + +#define PV88090_BUCK(chip, regl_name, min, step, max, limits_array) \ +{\ + .desc = {\ + .id = chip##_ID_##regl_name,\ + .name = __stringify(chip##_##regl_name),\ + .of_match = of_match_ptr(#regl_name),\ + .regulators_node = of_match_ptr("regulators"),\ + .type = REGULATOR_VOLTAGE,\ + .owner = THIS_MODULE,\ + .ops = &pv88090_buck_ops,\ + .min_uV = min, \ + .uV_step = step, \ + .n_voltages = ((max) - (min))/(step) + 1, \ + .enable_reg = PV88090_REG_##regl_name##_CONF0, \ + .enable_mask = PV88090_##regl_name##_EN, \ + .vsel_reg = PV88090_REG_##regl_name##_CONF0, \ + .vsel_mask = PV88090_V##regl_name##_MASK, \ + },\ + .current_limits = limits_array, \ + .n_current_limits = ARRAY_SIZE(limits_array), \ + .limit_mask = PV88090_##regl_name##_ILIM_MASK, \ + .conf = PV88090_REG_##regl_name##_CONF1, \ + .conf2 = PV88090_REG_##regl_name##_CONF2, \ +} + +#define PV88090_LDO(chip, regl_name, min, step, max) \ +{\ + .desc = {\ + .id = chip##_ID_##regl_name,\ + .name = __stringify(chip##_##regl_name),\ + .of_match = of_match_ptr(#regl_name),\ + .regulators_node = of_match_ptr("regulators"),\ + .type = REGULATOR_VOLTAGE,\ + .owner = THIS_MODULE,\ + .ops = &pv88090_ldo_ops,\ + .min_uV = min, \ + .uV_step = step, \ + .n_voltages = ((max) - (min))/(step) + 1, \ + .enable_reg = PV88090_REG_##regl_name##_CONT, \ + .enable_mask = PV88090_##regl_name##_EN, \ + .vsel_reg = PV88090_REG_##regl_name##_CONT, \ + .vsel_mask = PV88090_V##regl_name##_MASK, \ + },\ +} + +static struct pv88090_regulator pv88090_regulator_info[] = { + PV88090_BUCK(PV88090, BUCK1, 600000, 6250, 1393750, + pv88090_buck1_limits), + PV88090_BUCK(PV88090, BUCK2, 600000, 6250, 1393750, + pv88090_buck23_limits), + PV88090_BUCK(PV88090, BUCK3, 600000, 6250, 1393750, + pv88090_buck23_limits), + PV88090_LDO(PV88090, LDO1, 1200000, 50000, 4350000), + PV88090_LDO(PV88090, LDO2, 650000, 25000, 2225000), +}; + +static irqreturn_t pv88090_irq_handler(int irq, void *data) +{ + struct pv88090 *chip = data; + int i, reg_val, err, ret = IRQ_NONE; + + err = regmap_read(chip->regmap, PV88090_REG_EVENT_A, ®_val); + if (err < 0) + goto error_i2c; + + if (reg_val & PV88090_E_VDD_FLT) { + for (i = 0; i < PV88090_MAX_REGULATORS; i++) { + if (chip->rdev[i] != NULL) { + regulator_notifier_call_chain(chip->rdev[i], + REGULATOR_EVENT_UNDER_VOLTAGE, + NULL); + } + } + + err = regmap_update_bits(chip->regmap, PV88090_REG_EVENT_A, + PV88090_E_VDD_FLT, PV88090_E_VDD_FLT); + if (err < 0) + goto error_i2c; + + ret = IRQ_HANDLED; + } + + if (reg_val & PV88090_E_OVER_TEMP) { + for (i = 0; i < PV88090_MAX_REGULATORS; i++) { + if (chip->rdev[i] != NULL) { + regulator_notifier_call_chain(chip->rdev[i], + REGULATOR_EVENT_OVER_TEMP, + NULL); + } + } + + err = regmap_update_bits(chip->regmap, PV88090_REG_EVENT_A, + PV88090_E_OVER_TEMP, PV88090_E_OVER_TEMP); + if (err < 0) + goto error_i2c; + + ret = IRQ_HANDLED; + } + + return ret; + +error_i2c: + dev_err(chip->dev, "I2C error : %d\n", err); + return IRQ_NONE; +} + +/* + * I2C driver interface functions + */ +static int pv88090_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev); + struct pv88090 *chip; + struct regulator_config config = { }; + int error, i, ret = 0; + unsigned int conf2, range, index; + + chip = devm_kzalloc(&i2c->dev, sizeof(struct pv88090), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + chip->dev = &i2c->dev; + chip->regmap = devm_regmap_init_i2c(i2c, &pv88090_regmap_config); + if (IS_ERR(chip->regmap)) { + error = PTR_ERR(chip->regmap); + dev_err(chip->dev, "Failed to allocate register map: %d\n", + error); + return error; + } + + i2c_set_clientdata(i2c, chip); + + if (i2c->irq != 0) { + ret = regmap_write(chip->regmap, PV88090_REG_MASK_A, 0xFF); + if (ret < 0) { + dev_err(chip->dev, + "Failed to mask A reg: %d\n", ret); + return ret; + } + + ret = regmap_write(chip->regmap, PV88090_REG_MASK_B, 0xFF); + if (ret < 0) { + dev_err(chip->dev, + "Failed to mask B reg: %d\n", ret); + return ret; + } + + ret = request_threaded_irq(i2c->irq, NULL, + pv88090_irq_handler, + IRQF_TRIGGER_LOW|IRQF_ONESHOT, + "pv88090", chip); + if (ret != 0) { + dev_err(chip->dev, "Failed to request IRQ: %d\n", + i2c->irq); + return ret; + } + + ret = regmap_update_bits(chip->regmap, PV88090_REG_MASK_A, + PV88090_M_VDD_FLT | PV88090_M_OVER_TEMP, 0); + if (ret < 0) { + dev_err(chip->dev, + "Failed to update mask reg: %d\n", ret); + return ret; + } + + } else { + dev_warn(chip->dev, "No IRQ configured\n"); + } + + config.dev = chip->dev; + config.regmap = chip->regmap; + + for (i = 0; i < PV88090_MAX_REGULATORS; i++) { + if (init_data) + config.init_data = &init_data[i]; + + if (i == PV88090_ID_BUCK2 || i == PV88090_ID_BUCK3) { + ret = regmap_read(chip->regmap, + pv88090_regulator_info[i].conf2, &conf2); + if (ret < 0) + return ret; + + conf2 = ((conf2 >> PV88090_BUCK_VDAC_RANGE_SHIFT) + && PV88090_BUCK_VDAC_RANGE_MASK); + + ret = regmap_read(chip->regmap, + PV88090_REG_BUCK_FOLD_RANGE, &range); + if (ret < 0) + return ret; + + range = ((range + >> (PV88080_BUCK_VRANGE_GAIN_SHIFT + i - 1)) + && PV88080_BUCK_VRANGE_GAIN_MASK); + index = ((range << 1) | conf2); + + pv88090_regulator_info[i].desc.min_uV + = pv88090_buck_vol[index].min_uV; + pv88090_regulator_info[i].desc.uV_step + = pv88090_buck_vol[index].uV_step; + pv88090_regulator_info[i].desc.n_voltages + = ((pv88090_buck_vol[index].max_uV) + - (pv88090_buck_vol[index].min_uV)) + /(pv88090_buck_vol[index].uV_step) + 1; + } + + config.driver_data = (void *)&pv88090_regulator_info[i]; + chip->rdev[i] = devm_regulator_register(chip->dev, + &pv88090_regulator_info[i].desc, &config); + if (IS_ERR(chip->rdev[i])) { + dev_err(chip->dev, + "Failed to register PV88090 regulator\n"); + return PTR_ERR(chip->rdev[i]); + } + } + + return 0; +} + +static const struct i2c_device_id pv88090_i2c_id[] = { + {"pv88090", 0}, + {}, +}; +MODULE_DEVICE_TABLE(i2c, pv88090_i2c_id); + +#ifdef CONFIG_OF +static const struct of_device_id pv88090_dt_ids[] = { + { .compatible = "pvs,pv88090", .data = &pv88090_i2c_id[0] }, + {}, +}; +MODULE_DEVICE_TABLE(of, pv88090_dt_ids); +#endif + +static struct i2c_driver pv88090_regulator_driver = { + .driver = { + .name = "pv88090", + .of_match_table = of_match_ptr(pv88090_dt_ids), + }, + .probe = pv88090_i2c_probe, + .id_table = pv88090_i2c_id, +}; + +module_i2c_driver(pv88090_regulator_driver); + +MODULE_AUTHOR("James Ban "); +MODULE_DESCRIPTION("Regulator device driver for Powerventure PV88090"); +MODULE_LICENSE("GPL"); diff --git a/drivers/regulator/pv88090-regulator.h b/drivers/regulator/pv88090-regulator.h new file mode 100644 index 000000000000..d7aca8d8266d --- /dev/null +++ b/drivers/regulator/pv88090-regulator.h @@ -0,0 +1,98 @@ +/* + * pv88090-regulator.h - Regulator definitions for PV88090 + * Copyright (C) 2015 Powerventure Semiconductor Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __PV88090_REGISTERS_H__ +#define __PV88090_REGISTERS_H__ + +/* System Control and Event Registers */ +#define PV88090_REG_EVENT_A 0x03 +#define PV88090_REG_MASK_A 0x06 +#define PV88090_REG_MASK_B 0x07 + +/* Regulator Registers */ +#define PV88090_REG_BUCK1_CONF0 0x18 +#define PV88090_REG_BUCK1_CONF1 0x19 +#define PV88090_REG_BUCK1_CONF2 0x1a +#define PV88090_REG_BUCK2_CONF0 0x1b +#define PV88090_REG_BUCK2_CONF1 0x1c +#define PV88090_REG_BUCK2_CONF2 0x58 +#define PV88090_REG_BUCK3_CONF0 0x1d +#define PV88090_REG_BUCK3_CONF1 0x1e +#define PV88090_REG_BUCK3_CONF2 0x5c + +#define PV88090_REG_LDO1_CONT 0x1f +#define PV88090_REG_LDO2_CONT 0x20 +#define PV88090_REG_LDO3_CONT 0x21 +#define PV88090_REG_BUCK_FOLD_RANGE 0x61 + +/* PV88090_REG_EVENT_A (addr=0x03) */ +#define PV88090_E_VDD_FLT 0x01 +#define PV88090_E_OVER_TEMP 0x02 + +/* PV88090_REG_MASK_A (addr=0x06) */ +#define PV88090_M_VDD_FLT 0x01 +#define PV88090_M_OVER_TEMP 0x02 + +/* PV88090_REG_BUCK1_CONF0 (addr=0x18) */ +#define PV88090_BUCK1_EN 0x80 +#define PV88090_VBUCK1_MASK 0x7F +/* PV88090_REG_BUCK2_CONF0 (addr=0x1b) */ +#define PV88090_BUCK2_EN 0x80 +#define PV88090_VBUCK2_MASK 0x7F +/* PV88090_REG_BUCK3_CONF0 (addr=0x1d) */ +#define PV88090_BUCK3_EN 0x80 +#define PV88090_VBUCK3_MASK 0x7F +/* PV88090_REG_LDO1_CONT (addr=0x1f) */ +#define PV88090_LDO1_EN 0x40 +#define PV88090_VLDO1_MASK 0x3F +/* PV88090_REG_LDO2_CONT (addr=0x20) */ +#define PV88090_LDO2_EN 0x40 +#define PV88090_VLDO2_MASK 0x3F + +/* PV88090_REG_BUCK1_CONF1 (addr=0x19) */ +#define PV88090_BUCK1_ILIM_SHIFT 2 +#define PV88090_BUCK1_ILIM_MASK 0x7C +#define PV88090_BUCK1_MODE_MASK 0x03 + +/* PV88090_REG_BUCK2_CONF1 (addr=0x1c) */ +#define PV88090_BUCK2_ILIM_SHIFT 2 +#define PV88090_BUCK2_ILIM_MASK 0x0C +#define PV88090_BUCK2_MODE_MASK 0x03 + +/* PV88090_REG_BUCK3_CONF1 (addr=0x1e) */ +#define PV88090_BUCK3_ILIM_SHIFT 2 +#define PV88090_BUCK3_ILIM_MASK 0x0C +#define PV88090_BUCK3_MODE_MASK 0x03 + +#define PV88090_BUCK_MODE_SLEEP 0x00 +#define PV88090_BUCK_MODE_AUTO 0x01 +#define PV88090_BUCK_MODE_SYNC 0x02 + +/* PV88090_REG_BUCK2_CONF2 (addr=0x58) */ +/* PV88090_REG_BUCK3_CONF2 (addr=0x5c) */ +#define PV88090_BUCK_VDAC_RANGE_SHIFT 7 +#define PV88090_BUCK_VDAC_RANGE_MASK 0x01 + +#define PV88090_BUCK_VDAC_RANGE_1 0x00 +#define PV88090_BUCK_VDAC_RANGE_2 0x01 + +/* PV88090_REG_BUCK_FOLD_RANGE (addr=0x61) */ +#define PV88080_BUCK_VRANGE_GAIN_SHIFT 3 +#define PV88080_BUCK_VRANGE_GAIN_MASK 0x01 + +#define PV88080_BUCK_VRANGE_GAIN_1 0x00 +#define PV88080_BUCK_VRANGE_GAIN_2 0x01 + +#endif /* __PV88090_REGISTERS_H__ */ -- cgit v1.2.3-59-g8ed1b From 7a400585893e7aa52a845027bce1bf529bdf65d1 Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Mon, 14 Dec 2015 23:30:43 -0600 Subject: soc: qcom: documentation: Update SMD/RPM Docs This patch moves the qcom,smd-rpm.txt to the correct location and splits out the smd and rpm documentation. In addition, a smd-rpm-regulator document is added. Signed-off-by: Andy Gross Acked-by: Bjorn Andersson Signed-off-by: Mark Brown --- .../bindings/regulator/qcom,smd-rpm-regulator.txt | 106 +++++++++++++++++++ .../devicetree/bindings/soc/qcom,smd-rpm.txt | 117 --------------------- .../devicetree/bindings/soc/qcom/qcom,smd-rpm.txt | 58 ++++++++++ 3 files changed, 164 insertions(+), 117 deletions(-) create mode 100644 Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt delete mode 100644 Documentation/devicetree/bindings/soc/qcom,smd-rpm.txt create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt new file mode 100644 index 000000000000..bda2ed96ba66 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt @@ -0,0 +1,106 @@ +QCOM SMD RPM REGULATOR + +The Qualcomm RPM over SMD regulator is modelled as a subdevice of the RPM. +Because SMD is used as the communication transport mechanism, the RPM resides as +a subnode of the SMD. As such, the SMD-RPM regulator requires that the SMD and +RPM nodes be present. + +Please refer to Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt for +information pertaining to the SMD node. + +Please refer to Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.txt for +information regarding the RPM node. + +== Regulator + +Regulator nodes are identified by their compatible: + +- compatible: + Usage: required + Value type: + Definition: must be one of: + "qcom,rpm-pm8841-regulators" + "qcom,rpm-pm8941-regulators" + +- vdd_s1-supply: +- vdd_s2-supply: +- vdd_s3-supply: +- vdd_s4-supply: +- vdd_s5-supply: +- vdd_s6-supply: +- vdd_s7-supply: +- vdd_s8-supply: + Usage: optional (pm8841 only) + Value type: + Definition: reference to regulator supplying the input pin, as + described in the data sheet + +- vdd_s1-supply: +- vdd_s2-supply: +- vdd_s3-supply: +- vdd_l1_l3-supply: +- vdd_l2_lvs1_2_3-supply: +- vdd_l4_l11-supply: +- vdd_l5_l7-supply: +- vdd_l6_l12_l14_l15-supply: +- vdd_l8_l16_l18_l19-supply: +- vdd_l9_l10_l17_l22-supply: +- vdd_l13_l20_l23_l24-supply: +- vdd_l21-supply: +- vin_5vs-supply: + Usage: optional (pm8941 only) + Value type: + Definition: reference to regulator supplying the input pin, as + described in the data sheet + +The regulator node houses sub-nodes for each regulator within the device. Each +sub-node is identified using the node's name, with valid values listed for each +of the pmics below. + +pm8841: + s1, s2, s3, s4, s5, s6, s7, s8 + +pm8941: + s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, + l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, + lvs3, 5vs1, 5vs2 + +The content of each sub-node is defined by the standard binding for regulators - +see regulator.txt. + += EXAMPLE + + smd { + compatible = "qcom,smd"; + + rpm { + interrupts = <0 168 1>; + qcom,ipc = <&apcs 8 0>; + qcom,smd-edge = <15>; + + rpm_requests { + compatible = "qcom,rpm-msm8974"; + qcom,smd-channels = "rpm_requests"; + + pm8941-regulators { + compatible = "qcom,rpm-pm8941-regulators"; + vdd_l13_l20_l23_l24-supply = <&pm8941_boost>; + + pm8941_s3: s3 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + pm8941_boost: s4 { + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + pm8941_l20: l20 { + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; + }; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/soc/qcom,smd-rpm.txt b/Documentation/devicetree/bindings/soc/qcom,smd-rpm.txt deleted file mode 100644 index e27f5c4c54fd..000000000000 --- a/Documentation/devicetree/bindings/soc/qcom,smd-rpm.txt +++ /dev/null @@ -1,117 +0,0 @@ -Qualcomm Resource Power Manager (RPM) over SMD - -This driver is used to interface with the Resource Power Manager (RPM) found in -various Qualcomm platforms. The RPM allows each component in the system to vote -for state of the system resources, such as clocks, regulators and bus -frequencies. - -- compatible: - Usage: required - Value type: - Definition: must be one of: - "qcom,rpm-msm8974" - -- qcom,smd-channels: - Usage: required - Value type: - Definition: Shared Memory channel used for communication with the RPM - -= SUBDEVICES - -The RPM exposes resources to its subnodes. The below bindings specify the set -of valid subnodes that can operate on these resources. - -== Regulators - -Regulator nodes are identified by their compatible: - -- compatible: - Usage: required - Value type: - Definition: must be one of: - "qcom,rpm-pm8841-regulators" - "qcom,rpm-pm8941-regulators" - -- vdd_s1-supply: -- vdd_s2-supply: -- vdd_s3-supply: -- vdd_s4-supply: -- vdd_s5-supply: -- vdd_s6-supply: -- vdd_s7-supply: -- vdd_s8-supply: - Usage: optional (pm8841 only) - Value type: - Definition: reference to regulator supplying the input pin, as - described in the data sheet - -- vdd_s1-supply: -- vdd_s2-supply: -- vdd_s3-supply: -- vdd_l1_l3-supply: -- vdd_l2_lvs1_2_3-supply: -- vdd_l4_l11-supply: -- vdd_l5_l7-supply: -- vdd_l6_l12_l14_l15-supply: -- vdd_l8_l16_l18_l19-supply: -- vdd_l9_l10_l17_l22-supply: -- vdd_l13_l20_l23_l24-supply: -- vdd_l21-supply: -- vin_5vs-supply: - Usage: optional (pm8941 only) - Value type: - Definition: reference to regulator supplying the input pin, as - described in the data sheet - -The regulator node houses sub-nodes for each regulator within the device. Each -sub-node is identified using the node's name, with valid values listed for each -of the pmics below. - -pm8841: - s1, s2, s3, s4, s5, s6, s7, s8 - -pm8941: - s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, - l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, - lvs3, 5vs1, 5vs2 - -The content of each sub-node is defined by the standard binding for regulators - -see regulator.txt. - -= EXAMPLE - - smd { - compatible = "qcom,smd"; - - rpm { - interrupts = <0 168 1>; - qcom,ipc = <&apcs 8 0>; - qcom,smd-edge = <15>; - - rpm_requests { - compatible = "qcom,rpm-msm8974"; - qcom,smd-channels = "rpm_requests"; - - pm8941-regulators { - compatible = "qcom,rpm-pm8941-regulators"; - vdd_l13_l20_l23_l24-supply = <&pm8941_boost>; - - pm8941_s3: s3 { - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - }; - - pm8941_boost: s4 { - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - }; - - pm8941_l20: l20 { - regulator-min-microvolt = <2950000>; - regulator-max-microvolt = <2950000>; - }; - }; - }; - }; - }; - diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.txt new file mode 100644 index 000000000000..a48049ccf6d0 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.txt @@ -0,0 +1,58 @@ +Qualcomm Resource Power Manager (RPM) over SMD + +This driver is used to interface with the Resource Power Manager (RPM) found in +various Qualcomm platforms. The RPM allows each component in the system to vote +for state of the system resources, such as clocks, regulators and bus +frequencies. + +The SMD information for the RPM edge should be filled out. See qcom,smd.txt for +the required edge properties. All SMD related properties will reside within the +RPM node itself. + += SUBDEVICES + +The RPM exposes resources to its subnodes. The rpm_requests node must be +present and this subnode may contain children that designate regulator +resources. + +- compatible: + Usage: required + Value type: + Definition: must be one of: + "qcom,rpm-apq8084" + "qcom,rpm-msm8916" + "qcom,rpm-msm8974" + +- qcom,smd-channels: + Usage: required + Value type: + Definition: must be "rpm_requests" + +Refer to Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt +for information on the regulator subnodes that can exist under the rpm_requests. + +Example: + + soc { + apcs: syscon@f9011000 { + compatible = "syscon"; + reg = <0xf9011000 0x1000>; + }; + }; + + smd { + compatible = "qcom,smd"; + + rpm { + interrupts = <0 168 1>; + qcom,ipc = <&apcs 8 0>; + qcom,smd-edge = <15>; + + rpm_requests { + compatible = "qcom,rpm-msm8974"; + qcom,smd-channels = "rpm_requests"; + + ... + }; + }; + }; -- cgit v1.2.3-59-g8ed1b From 57d6567680edf9075d14b7fad9473e9c4a4b337e Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Mon, 14 Dec 2015 23:30:44 -0600 Subject: regulator: qcom-smd: Add PM8916 support This patch adds support and documentation for the PM8916 regulators found on MSM8916 platforms. Acked-by: Bjorn Andersson Signed-off-by: Andy Gross Signed-off-by: Mark Brown --- .../bindings/regulator/qcom,smd-rpm-regulator.txt | 18 ++++++ drivers/regulator/qcom_smd-regulator.c | 64 ++++++++++++++++++++++ 2 files changed, 82 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt index bda2ed96ba66..82557e174258 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt @@ -20,6 +20,7 @@ Regulator nodes are identified by their compatible: Value type: Definition: must be one of: "qcom,rpm-pm8841-regulators" + "qcom,rpm-pm8916-regulators" "qcom,rpm-pm8941-regulators" - vdd_s1-supply: @@ -35,6 +36,19 @@ Regulator nodes are identified by their compatible: Definition: reference to regulator supplying the input pin, as described in the data sheet +- vdd_s1-supply: +- vdd_s2-supply: +- vdd_s3-supply: +- vdd_s4-supply: +- vdd_l1_l2_l3-supply: +- vdd_l4_l5_l6-supply: +- vdd_l7-supply: +- vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18-supply: + Usage: optional (pm8916 only) + Value type: + Definition: reference to regulator supplying the input pin, as + described in the data sheet + - vdd_s1-supply: - vdd_s2-supply: - vdd_s3-supply: @@ -60,6 +74,10 @@ of the pmics below. pm8841: s1, s2, s3, s4, s5, s6, s7, s8 +pm8916: + s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, + l14, l15, l16, l17, l18 + pm8941: s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c index 6fa0c7d13290..8464eadf2c85 100644 --- a/drivers/regulator/qcom_smd-regulator.c +++ b/drivers/regulator/qcom_smd-regulator.c @@ -211,6 +211,43 @@ static const struct regulator_desc pm8941_switch = { .ops = &rpm_switch_ops, }; +static const struct regulator_desc pm8916_pldo = { + .linear_ranges = (struct regulator_linear_range[]) { + REGULATOR_LINEAR_RANGE(750000, 0, 208, 12500), + }, + .n_linear_ranges = 1, + .n_voltages = 209, + .ops = &rpm_smps_ldo_ops, +}; + +static const struct regulator_desc pm8916_nldo = { + .linear_ranges = (struct regulator_linear_range[]) { + REGULATOR_LINEAR_RANGE(375000, 0, 93, 12500), + }, + .n_linear_ranges = 1, + .n_voltages = 94, + .ops = &rpm_smps_ldo_ops, +}; + +static const struct regulator_desc pm8916_buck_lvo_smps = { + .linear_ranges = (struct regulator_linear_range[]) { + REGULATOR_LINEAR_RANGE(375000, 0, 95, 12500), + REGULATOR_LINEAR_RANGE(750000, 96, 127, 25000), + }, + .n_linear_ranges = 2, + .n_voltages = 128, + .ops = &rpm_smps_ldo_ops, +}; + +static const struct regulator_desc pm8916_buck_hvo_smps = { + .linear_ranges = (struct regulator_linear_range[]) { + REGULATOR_LINEAR_RANGE(1550000, 0, 31, 25000), + }, + .n_linear_ranges = 1, + .n_voltages = 32, + .ops = &rpm_smps_ldo_ops, +}; + struct rpm_regulator_data { const char *name; u32 type; @@ -231,6 +268,32 @@ static const struct rpm_regulator_data rpm_pm8841_regulators[] = { {} }; +static const struct rpm_regulator_data rpm_pm8916_regulators[] = { + { "s1", QCOM_SMD_RPM_SMPA, 1, &pm8916_buck_lvo_smps, "vdd_s1" }, + { "s2", QCOM_SMD_RPM_SMPA, 2, &pm8916_buck_lvo_smps, "vdd_s2" }, + { "s3", QCOM_SMD_RPM_SMPA, 3, &pm8916_buck_lvo_smps, "vdd_s3" }, + { "s4", QCOM_SMD_RPM_SMPA, 4, &pm8916_buck_hvo_smps, "vdd_s4" }, + { "l1", QCOM_SMD_RPM_LDOA, 1, &pm8916_nldo, "vdd_l1_l2_l3" }, + { "l2", QCOM_SMD_RPM_LDOA, 2, &pm8916_nldo, "vdd_l1_l2_l3" }, + { "l3", QCOM_SMD_RPM_LDOA, 3, &pm8916_nldo, "vdd_l1_l2_l3" }, + { "l4", QCOM_SMD_RPM_LDOA, 4, &pm8916_pldo, "vdd_l4_l5_l6" }, + { "l5", QCOM_SMD_RPM_LDOA, 5, &pm8916_pldo, "vdd_l4_l5_l6" }, + { "l6", QCOM_SMD_RPM_LDOA, 6, &pm8916_pldo, "vdd_l4_l5_l6" }, + { "l7", QCOM_SMD_RPM_LDOA, 7, &pm8916_pldo, "vdd_l7" }, + { "l8", QCOM_SMD_RPM_LDOA, 8, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18" }, + { "l9", QCOM_SMD_RPM_LDOA, 9, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18" }, + { "l10", QCOM_SMD_RPM_LDOA, 10, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, + { "l11", QCOM_SMD_RPM_LDOA, 11, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, + { "l12", QCOM_SMD_RPM_LDOA, 12, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, + { "l13", QCOM_SMD_RPM_LDOA, 13, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, + { "l14", QCOM_SMD_RPM_LDOA, 14, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, + { "l15", QCOM_SMD_RPM_LDOA, 15, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, + { "l16", QCOM_SMD_RPM_LDOA, 16, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, + { "l17", QCOM_SMD_RPM_LDOA, 17, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, + { "l18", QCOM_SMD_RPM_LDOA, 18, &pm8916_pldo, "vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18"}, + {} +}; + static const struct rpm_regulator_data rpm_pm8941_regulators[] = { { "s1", QCOM_SMD_RPM_SMPA, 1, &pm8x41_hfsmps, "vdd_s1" }, { "s2", QCOM_SMD_RPM_SMPA, 2, &pm8x41_hfsmps, "vdd_s2" }, @@ -274,6 +337,7 @@ static const struct rpm_regulator_data rpm_pm8941_regulators[] = { static const struct of_device_id rpm_of_match[] = { { .compatible = "qcom,rpm-pm8841-regulators", .data = &rpm_pm8841_regulators }, + { .compatible = "qcom,rpm-pm8916-regulators", .data = &rpm_pm8916_regulators }, { .compatible = "qcom,rpm-pm8941-regulators", .data = &rpm_pm8941_regulators }, {} }; -- cgit v1.2.3-59-g8ed1b From ee01d0c91ef1c198fd7819c2eb166580e41dc2ea Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Mon, 14 Dec 2015 23:30:45 -0600 Subject: regulator: qcom-smd: Add support for PMA8084 This patch adds support and documentation for the PMA8084 regulators found on APQ8084 platforms. Signed-off-by: Andy Gross Acked-by: Bjorn Andersson Signed-off-by: Mark Brown --- .../bindings/regulator/qcom,smd-rpm-regulator.txt | 35 ++++++++ drivers/regulator/qcom_smd-regulator.c | 95 ++++++++++++++++++++++ 2 files changed, 130 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt index 82557e174258..1f8d6f84b657 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt @@ -22,6 +22,7 @@ Regulator nodes are identified by their compatible: "qcom,rpm-pm8841-regulators" "qcom,rpm-pm8916-regulators" "qcom,rpm-pm8941-regulators" + "qcom,rpm-pma8084-regulators" - vdd_s1-supply: - vdd_s2-supply: @@ -67,6 +68,35 @@ Regulator nodes are identified by their compatible: Definition: reference to regulator supplying the input pin, as described in the data sheet +- vdd_s1-supply: +- vdd_s2-supply: +- vdd_s3-supply: +- vdd_s4-supply: +- vdd_s5-supply: +- vdd_s6-supply: +- vdd_s7-supply: +- vdd_s8-supply: +- vdd_s9-supply: +- vdd_s10-supply: +- vdd_s11-supply: +- vdd_s12-supply: +- vdd_l1_l11-supply: +- vdd_l2_l3_l4_l27-supply: +- vdd_l5_l7-supply: +- vdd_l6_l12_l14_l15_l26-supply: +- vdd_l8-supply: +- vdd_l9_l10_l13_l20_l23_l24-supply: +- vdd_l16_l25-supply: +- vdd_l17-supply: +- vdd_l18-supply: +- vdd_l19-supply: +- vdd_l21-supply: +- vdd_l22-supply: + Usage: optional (pma8084 only) + Value type: + Definition: reference to regulator supplying the input pin, as + described in the data sheet + The regulator node houses sub-nodes for each regulator within the device. Each sub-node is identified using the node's name, with valid values listed for each of the pmics below. @@ -83,6 +113,11 @@ pm8941: l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, lvs3, 5vs1, 5vs2 +pma8084: + s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, l1, l2, l3, l4, l5, + l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19, l20, + l21, l22, l23, l24, l25, l26, l27, lvs1, lvs2, lvs3, lvs4, 5vs1 + The content of each sub-node is defined by the standard binding for regulators - see regulator.txt. diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c index 8464eadf2c85..56a17ec5b5ef 100644 --- a/drivers/regulator/qcom_smd-regulator.c +++ b/drivers/regulator/qcom_smd-regulator.c @@ -153,6 +153,49 @@ static const struct regulator_ops rpm_switch_ops = { .is_enabled = rpm_reg_is_enabled, }; +static const struct regulator_desc pma8084_hfsmps = { + .linear_ranges = (struct regulator_linear_range[]) { + REGULATOR_LINEAR_RANGE(375000, 0, 95, 12500), + REGULATOR_LINEAR_RANGE(1550000, 96, 158, 25000), + }, + .n_linear_ranges = 2, + .n_voltages = 159, + .ops = &rpm_smps_ldo_ops, +}; + +static const struct regulator_desc pma8084_ftsmps = { + .linear_ranges = (struct regulator_linear_range[]) { + REGULATOR_LINEAR_RANGE(350000, 0, 184, 5000), + REGULATOR_LINEAR_RANGE(700000, 185, 339, 10000), + }, + .n_linear_ranges = 2, + .n_voltages = 340, + .ops = &rpm_smps_ldo_ops, +}; + +static const struct regulator_desc pma8084_pldo = { + .linear_ranges = (struct regulator_linear_range[]) { + REGULATOR_LINEAR_RANGE(750000, 0, 30, 25000), + REGULATOR_LINEAR_RANGE(1500000, 31, 99, 50000), + }, + .n_linear_ranges = 2, + .n_voltages = 100, + .ops = &rpm_smps_ldo_ops, +}; + +static const struct regulator_desc pma8084_nldo = { + .linear_ranges = (struct regulator_linear_range[]) { + REGULATOR_LINEAR_RANGE(750000, 0, 63, 12500), + }, + .n_linear_ranges = 1, + .n_voltages = 64, + .ops = &rpm_smps_ldo_ops, +}; + +static const struct regulator_desc pma8084_switch = { + .ops = &rpm_switch_ops, +}; + static const struct regulator_desc pm8x41_hfsmps = { .linear_ranges = (struct regulator_linear_range[]) { REGULATOR_LINEAR_RANGE( 375000, 0, 95, 12500), @@ -335,10 +378,62 @@ static const struct rpm_regulator_data rpm_pm8941_regulators[] = { {} }; +static const struct rpm_regulator_data rpm_pma8084_regulators[] = { + { "s1", QCOM_SMD_RPM_SMPA, 1, &pma8084_ftsmps, "vdd_s1" }, + { "s2", QCOM_SMD_RPM_SMPA, 2, &pma8084_ftsmps, "vdd_s2" }, + { "s3", QCOM_SMD_RPM_SMPA, 3, &pma8084_hfsmps, "vdd_s3" }, + { "s4", QCOM_SMD_RPM_SMPA, 4, &pma8084_hfsmps, "vdd_s4" }, + { "s5", QCOM_SMD_RPM_SMPA, 5, &pma8084_hfsmps, "vdd_s5" }, + { "s6", QCOM_SMD_RPM_SMPA, 6, &pma8084_ftsmps, "vdd_s6" }, + { "s7", QCOM_SMD_RPM_SMPA, 7, &pma8084_ftsmps, "vdd_s7" }, + { "s8", QCOM_SMD_RPM_SMPA, 8, &pma8084_ftsmps, "vdd_s8" }, + { "s9", QCOM_SMD_RPM_SMPA, 9, &pma8084_ftsmps, "vdd_s9" }, + { "s10", QCOM_SMD_RPM_SMPA, 10, &pma8084_ftsmps, "vdd_s10" }, + { "s11", QCOM_SMD_RPM_SMPA, 11, &pma8084_ftsmps, "vdd_s11" }, + { "s12", QCOM_SMD_RPM_SMPA, 12, &pma8084_ftsmps, "vdd_s12" }, + + { "l1", QCOM_SMD_RPM_LDOA, 1, &pma8084_nldo, "vdd_l1_l11" }, + { "l2", QCOM_SMD_RPM_LDOA, 2, &pma8084_nldo, "vdd_l2_l3_l4_l27" }, + { "l3", QCOM_SMD_RPM_LDOA, 3, &pma8084_nldo, "vdd_l2_l3_l4_l27" }, + { "l4", QCOM_SMD_RPM_LDOA, 4, &pma8084_nldo, "vdd_l2_l3_l4_l27" }, + { "l5", QCOM_SMD_RPM_LDOA, 5, &pma8084_pldo, "vdd_l5_l7" }, + { "l6", QCOM_SMD_RPM_LDOA, 6, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" }, + { "l7", QCOM_SMD_RPM_LDOA, 7, &pma8084_pldo, "vdd_l5_l7" }, + { "l8", QCOM_SMD_RPM_LDOA, 8, &pma8084_pldo, "vdd_l8" }, + { "l9", QCOM_SMD_RPM_LDOA, 9, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" }, + { "l10", QCOM_SMD_RPM_LDOA, 10, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" }, + { "l11", QCOM_SMD_RPM_LDOA, 11, &pma8084_nldo, "vdd_l1_l11" }, + { "l12", QCOM_SMD_RPM_LDOA, 12, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" }, + { "l13", QCOM_SMD_RPM_LDOA, 13, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" }, + { "l14", QCOM_SMD_RPM_LDOA, 14, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" }, + { "l15", QCOM_SMD_RPM_LDOA, 15, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" }, + { "l16", QCOM_SMD_RPM_LDOA, 16, &pma8084_pldo, "vdd_l16_l25" }, + { "l17", QCOM_SMD_RPM_LDOA, 17, &pma8084_pldo, "vdd_l17" }, + { "l18", QCOM_SMD_RPM_LDOA, 18, &pma8084_pldo, "vdd_l18" }, + { "l19", QCOM_SMD_RPM_LDOA, 19, &pma8084_pldo, "vdd_l19" }, + { "l20", QCOM_SMD_RPM_LDOA, 20, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" }, + { "l21", QCOM_SMD_RPM_LDOA, 21, &pma8084_pldo, "vdd_l21" }, + { "l22", QCOM_SMD_RPM_LDOA, 22, &pma8084_pldo, "vdd_l22" }, + { "l23", QCOM_SMD_RPM_LDOA, 23, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" }, + { "l24", QCOM_SMD_RPM_LDOA, 24, &pma8084_pldo, "vdd_l9_l10_l13_l20_l23_l24" }, + { "l25", QCOM_SMD_RPM_LDOA, 25, &pma8084_pldo, "vdd_l16_l25" }, + { "l26", QCOM_SMD_RPM_LDOA, 26, &pma8084_pldo, "vdd_l6_l12_l14_l15_l26" }, + { "l27", QCOM_SMD_RPM_LDOA, 27, &pma8084_nldo, "vdd_l2_l3_l4_l27" }, + + { "lvs1", QCOM_SMD_RPM_VSA, 1, &pma8084_switch }, + { "lvs2", QCOM_SMD_RPM_VSA, 2, &pma8084_switch }, + { "lvs3", QCOM_SMD_RPM_VSA, 3, &pma8084_switch }, + { "lvs4", QCOM_SMD_RPM_VSA, 4, &pma8084_switch }, + { "5vs1", QCOM_SMD_RPM_VSA, 5, &pma8084_switch }, + + {} +}; + static const struct of_device_id rpm_of_match[] = { { .compatible = "qcom,rpm-pm8841-regulators", .data = &rpm_pm8841_regulators }, { .compatible = "qcom,rpm-pm8916-regulators", .data = &rpm_pm8916_regulators }, { .compatible = "qcom,rpm-pm8941-regulators", .data = &rpm_pm8941_regulators }, + { .compatible = "qcom,rpm-pma8084-regulators", .data = &rpm_pma8084_regulators }, {} }; MODULE_DEVICE_TABLE(of, rpm_of_match); -- cgit v1.2.3-59-g8ed1b