regulator: Updates for v6.9

This has been a very quiet release, mostly cleanups, API updates and
 simple device additions.  I messed up slightly and there are a couple of
 duplicated commits resulting from me leaving things in my inbox which
 didn't seem worth removing by the time I noticed them.
 
  - Conversion of several drivers to GPIO descriptors.
  - Build out the features of of the MP8859 driver.
  - Support for Qualcomm PM4125 and PM6150.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmXvFPUACgkQJNaLcl1U
 h9C11wf+LkEBZ/oaidhjWlDdnd6oVHCVG7du5YXRSDcobm9dqigfnhRPvcF3WqlQ
 DfPBq5/VN/yCAxD3tsUS+bhPfCEMfSnEHN4uaYy7NjLulW3zh++Dxib3FPD7HURY
 aw5u8gm4AuB+x4nJOtrA6tiBisfHyCM7uSIfnUcs0LVlksCibdOe0OfHVsO2BNW+
 gbLxZc8gr5VdORfHqb6oeUtcoiA/2gALNvdagMooguzolDtVEs1yLQkbD4CCOGHg
 EPqE7YxdJrTOtbd7hiR5z2G8plPqmsbCG//Jb9jJuEAtefm57pyJ5SfMBGKs0hS9
 p/o5Vk4ygghArRnl0KsItgphFCZt0A==
 =GuVG
 -----END PGP SIGNATURE-----

Merge tag 'regulator-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator

Pull regulator updates from Mark Brown:
 "This has been a very quiet release, mostly cleanups, API updates and
  simple device additions. I messed up slightly and there are a couple
  of duplicated commits resulting from me leaving things in my inbox
  which didn't seem worth removing by the time I noticed them.

   - Conversion of several drivers to GPIO descriptors

   - Build out the features of of the MP8859 driver

   - Support for Qualcomm PM4125 and PM6150"

* tag 'regulator-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (31 commits)
  regulator: lp8788-buck: fix copy and paste bug in lp8788_dvs_gpio_request()
  regulator: core: make regulator_class constant
  regulator: da9121: Remove unused of_gpio.h
  regulator: userspace-consumer: add module device table
  regulator: dt-bindings: gpio-regulator: Fix "gpios-states" and "states" array bounds
  regulator: mp8859: Implement set_current_limit()
  regulator: mp8859: Report slew rate
  regulator: mp8859: Support status and error readback
  regulator: mp8859: Support active discharge control
  regulator: mp8859: Support mode operations
  regulator: mp8859: Support enable control
  regulator: mp8859: Validate and log device identifier information
  regulator: mp8859: Specify register accessibility and enable caching
  regulator: max8998: Convert to GPIO descriptors
  regulator: max8997: Convert to GPIO descriptors
  regulator: lp8788-buck: Fully convert to GPIO descriptors
  regulator: da9055: Fully convert to GPIO descriptors
  regulator: max8973: Finalize switch to GPIO descriptors
  regulator: dt-bindings: qcom,usb-vbus-regulator: add support for PM4125
  regulator: dt-bindings: qcom,usb-vbus-regulator: add support for PM4125
  ...
This commit is contained in:
Linus Torvalds 2024-03-13 11:05:20 -07:00
commit 21ac5a9651
26 changed files with 702 additions and 506 deletions

View File

@ -47,6 +47,7 @@ properties:
1: HIGH
Default is LOW if nothing else is specified.
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 1
maxItems: 8
items:
enum: [0, 1]
@ -57,7 +58,8 @@ properties:
regulator and matching GPIO configurations to achieve them. If there are
no states in the "states" array, use a fixed regulator instead.
$ref: /schemas/types.yaml#/definitions/uint32-matrix
maxItems: 8
minItems: 2
maxItems: 256
items:
items:
- description: Voltage in microvolts

View File

@ -1,144 +0,0 @@
MCP16502 PMIC
Required properties:
- compatible: "microchip,mcp16502"
- reg: I2C slave address
- lpm-gpios: GPIO for LPM pin. Note that this GPIO *must* remain high during
suspend-to-ram, keeping the PMIC into HIBERNATE mode; this
property is optional;
- regulators: A node that houses a sub-node for each regulator within
the device. Each sub-node is identified using the node's
name. The content of each sub-node is defined by the
standard binding for regulators; see regulator.txt.
Regulators of MCP16502 PMIC:
1) VDD_IO - Buck (1.2 - 3.7 V)
2) VDD_DDR - Buck (0.6 - 1.85 V)
3) VDD_CORE - Buck (0.6 - 1.85 V)
4) VDD_OTHER - BUCK (0.6 - 1.85 V)
5) LDO1 - LDO (1.2 - 3.7 V)
6) LDO2 - LDO (1.2 - 3.7 V)
Regulator modes:
2 - FPWM: higher precision, higher consumption
4 - AutoPFM: lower precision, lower consumption
Each regulator is defined using the standard binding for regulators.
Example:
mcp16502@5b {
compatible = "microchip,mcp16502";
reg = <0x5b>;
status = "okay";
lpm-gpios = <&pioBU 7 GPIO_ACTIVE_HIGH>;
regulators {
VDD_IO {
regulator-name = "VDD_IO";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3700000>;
regulator-initial-mode = <2>;
regulator-allowed-modes = <2>, <4>;
regulator-always-on;
regulator-state-standby {
regulator-on-in-suspend;
regulator-mode = <4>;
};
regulator-state-mem {
regulator-off-in-suspend;
regulator-mode = <4>;
};
};
VDD_DDR {
regulator-name = "VDD_DDR";
regulator-min-microvolt = <600000>;
regulator-max-microvolt = <1850000>;
regulator-initial-mode = <2>;
regulator-allowed-modes = <2>, <4>;
regulator-always-on;
regulator-state-standby {
regulator-on-in-suspend;
regulator-mode = <4>;
};
regulator-state-mem {
regulator-on-in-suspend;
regulator-mode = <4>;
};
};
VDD_CORE {
regulator-name = "VDD_CORE";
regulator-min-microvolt = <600000>;
regulator-max-microvolt = <1850000>;
regulator-initial-mode = <2>;
regulator-allowed-modes = <2>, <4>;
regulator-always-on;
regulator-state-standby {
regulator-on-in-suspend;
regulator-mode = <4>;
};
regulator-state-mem {
regulator-off-in-suspend;
regulator-mode = <4>;
};
};
VDD_OTHER {
regulator-name = "VDD_OTHER";
regulator-min-microvolt = <600000>;
regulator-max-microvolt = <1850000>;
regulator-initial-mode = <2>;
regulator-allowed-modes = <2>, <4>;
regulator-always-on;
regulator-state-standby {
regulator-on-in-suspend;
regulator-mode = <4>;
};
regulator-state-mem {
regulator-off-in-suspend;
regulator-mode = <4>;
};
};
LDO1 {
regulator-name = "LDO1";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3700000>;
regulator-always-on;
regulator-state-standby {
regulator-on-in-suspend;
};
regulator-state-mem {
regulator-off-in-suspend;
};
};
LDO2 {
regulator-name = "LDO2";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3700000>;
regulator-always-on;
regulator-state-standby {
regulator-on-in-suspend;
};
regulator-state-mem {
regulator-off-in-suspend;
};
};
};
};

View File

@ -0,0 +1,180 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/microchip,mcp16502.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: MCP16502 - High-Performance PMIC
maintainers:
- Andrei Simion <andrei.simion@microchip.com>
description:
The MCP16502 is an optimally integrated PMIC compatible
with Microchip's eMPUs(Embedded Microprocessor Units),
requiring Dynamic Voltage Scaling (DVS) with the use
of High-Performance mode (HPM).
properties:
compatible:
const: microchip,mcp16502
lpm-gpios:
maxItems: 1
description: GPIO for LPM pin.
Note that this GPIO must remain high during
suspend-to-ram, keeping the PMIC into HIBERNATE mode.
reg:
maxItems: 1
regulators:
type: object
additionalProperties: false
description: List of regulators and its properties.
patternProperties:
"^(VDD_(IO|CORE|DDR|OTHER)|LDO[1-2])$":
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
properties:
regulator-initial-mode:
enum: [2, 4]
default: 2
description: Initial operating mode
regulator-allowed-modes:
items:
enum: [2, 4]
description: Supported modes
2 - FPWM higher precision, higher consumption
4 - AutoPFM lower precision, lower consumption
required:
- compatible
- reg
- regulators
additionalProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
pmic@5b {
compatible = "microchip,mcp16502";
reg = <0x5b>;
regulators {
VDD_IO {
regulator-name = "VDD_IO";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-initial-mode = <2>;
regulator-allowed-modes = <2>, <4>;
regulator-always-on;
regulator-state-standby {
regulator-on-in-suspend;
regulator-mode = <4>;
};
regulator-state-mem {
regulator-off-in-suspend;
regulator-mode = <4>;
};
};
VDD_DDR {
regulator-name = "VDD_DDR";
regulator-min-microvolt = <1350000>;
regulator-max-microvolt = <1350000>;
regulator-initial-mode = <2>;
regulator-allowed-modes = <2>, <4>;
regulator-always-on;
regulator-state-standby {
regulator-on-in-suspend;
regulator-mode = <4>;
};
regulator-state-mem {
regulator-on-in-suspend;
regulator-mode = <4>;
};
};
VDD_CORE {
regulator-name = "VDD_CORE";
regulator-min-microvolt = <1150000>;
regulator-max-microvolt = <1150000>;
regulator-initial-mode = <2>;
regulator-allowed-modes = <2>, <4>;
regulator-always-on;
regulator-state-standby {
regulator-on-in-suspend;
regulator-mode = <4>;
};
regulator-state-mem {
regulator-off-in-suspend;
regulator-mode = <4>;
};
};
VDD_OTHER {
regulator-name = "VDD_OTHER";
regulator-min-microvolt = <1050000>;
regulator-max-microvolt = <1250000>;
regulator-initial-mode = <2>;
regulator-allowed-modes = <2>, <4>;
regulator-always-on;
regulator-state-standby {
regulator-on-in-suspend;
regulator-mode = <4>;
};
regulator-state-mem {
regulator-off-in-suspend;
regulator-mode = <4>;
};
};
LDO1 {
regulator-name = "LDO1";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-state-standby {
regulator-on-in-suspend;
};
regulator-state-mem {
regulator-off-in-suspend;
};
};
LDO2 {
regulator-name = "LDO2";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3700000>;
regulator-always-on;
regulator-state-standby {
regulator-on-in-suspend;
};
regulator-state-mem {
regulator-off-in-suspend;
};
};
};
};
};

View File

@ -19,8 +19,14 @@ allOf:
properties:
compatible:
enum:
- qcom,pm8150b-vbus-reg
oneOf:
- enum:
- qcom,pm8150b-vbus-reg
- items:
- enum:
- qcom,pm4125-vbus-reg
- qcom,pm6150-vbus-reg
- const: qcom,pm8150b-vbus-reg
reg:
maxItems: 1

View File

@ -0,0 +1,84 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/ti,tps65132.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: TI TPS65132 Dual Output Power Regulators
maintainers:
- devicetree@vger.kernel.org
description: |
The TPS65132 is designed to supply positive/negative driven applications.
Datasheet is available at:
https://www.ti.com/lit/gpn/tps65132
properties:
compatible:
enum:
- ti,tps65132
reg:
maxItems: 1
patternProperties:
"^out[pn]$":
type: object
$ref: regulator.yaml#
unevaluatedProperties: false
description:
Properties for single regulator.
properties:
enable-gpios:
maxItems: 1
description:
GPIO specifier to enable the GPIO control (on/off) for regulator.
active-discharge-gpios:
maxItems: 1
description:
GPIO specifier to actively discharge the delay mechanism.
ti,active-discharge-time-us:
description: Regulator active discharge time in microseconds.
dependencies:
active-discharge-gpios: [ 'ti,active-discharge-time-us' ]
required:
- compatible
- reg
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
regulator@3e {
compatible = "ti,tps65132";
reg = <0x3e>;
outp {
regulator-name = "outp";
regulator-boot-on;
regulator-always-on;
enable-gpios = <&gpio 23 GPIO_ACTIVE_HIGH>;
};
outn {
regulator-name = "outn";
regulator-boot-on;
regulator-always-on;
regulator-active-discharge = <0>;
enable-gpios = <&gpio 40 GPIO_ACTIVE_HIGH>;
};
};
};

View File

@ -1,46 +0,0 @@
TPS65132 regulators
Required properties:
- compatible: "ti,tps65132"
- reg: I2C slave address
Optional Subnode:
Device supports two regulators OUTP and OUTN. A sub node within the
device node describe the properties of these regulators. The sub-node
names must be as follows:
-For regulator outp, the sub node name should be "outp".
-For regulator outn, the sub node name should be "outn".
-enable-gpios:(active high, output) Regulators are controlled by the input pins.
If it is connected to GPIO through host system then provide the
gpio number as per gpio.txt.
-active-discharge-gpios: (active high, output) Some configurations use delay mechanisms
on the enable pin, to keep the regulator enabled for some time after
the enable signal goes low. This GPIO is used to actively discharge
the delay mechanism. Requires specification of ti,active-discharge-time-us
-ti,active-discharge-time-us: how long the active discharge gpio should be
asserted for during active discharge, in microseconds.
Each regulator is defined using the standard binding for regulators.
Example:
tps65132@3e {
compatible = "ti,tps65132";
reg = <0x3e>;
outp {
regulator-name = "outp";
regulator-boot-on;
regulator-always-on;
enable-gpios = <&gpio 23 0>;
};
outn {
regulator-name = "outn";
regulator-boot-on;
regulator-always-on;
regulator-active-discharge = <0>;
enable-gpios = <&gpio 40 0>;
};
};

View File

@ -3932,7 +3932,6 @@ static int regulator_get_optimal_voltage(struct regulator_dev *rdev,
if (ret < 0)
return ret;
possible_uV = desired_min_uV;
done = true;
goto finish;
@ -5891,7 +5890,7 @@ static const struct dev_pm_ops __maybe_unused regulator_pm_ops = {
};
#endif
struct class regulator_class = {
const struct class regulator_class = {
.name = "regulator",
.dev_release = regulator_dev_release,
.dev_groups = regulator_dev_groups,

View File

@ -9,7 +9,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
@ -413,31 +412,35 @@ static struct da9055_regulator_info da9055_regulator_info[] = {
* GPIO can control regulator state and/or select the regulator register
* set A/B for voltage ramping.
*/
static int da9055_gpio_init(struct da9055_regulator *regulator,
static int da9055_gpio_init(struct device *dev,
struct da9055_regulator *regulator,
struct regulator_config *config,
struct da9055_pdata *pdata, int id)
{
struct da9055_regulator_info *info = regulator->info;
struct gpio_desc *ren;
struct gpio_desc *ena;
struct gpio_desc *rsel;
int ret = 0;
if (!pdata)
return 0;
/* Look for "regulator-enable-gpios" GPIOs in the regulator node */
ren = devm_gpiod_get_optional(dev, "regulator-enable", GPIOD_IN);
if (IS_ERR(ren))
return PTR_ERR(ren);
if (pdata->gpio_ren && pdata->gpio_ren[id]) {
char name[18];
int gpio_mux = pdata->gpio_ren[id];
if (ren) {
/* This GPIO is not optional at this point */
ena = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH);
if (IS_ERR(ena))
return PTR_ERR(ena);
config->ena_gpiod = pdata->ena_gpiods[id];
config->ena_gpiod = ena;
/*
* GPI pin is muxed with regulator to control the
* regulator state.
*/
sprintf(name, "DA9055 GPI %d", gpio_mux);
ret = devm_gpio_request_one(config->dev, gpio_mux, GPIOF_DIR_IN,
name);
if (ret < 0)
goto err;
gpiod_set_consumer_name(ren, "DA9055 ren GPI");
/*
* Let the regulator know that its state is controlled
@ -448,24 +451,22 @@ static int da9055_gpio_init(struct da9055_regulator *regulator,
pdata->reg_ren[id]
<< DA9055_E_GPI_SHIFT);
if (ret < 0)
goto err;
return ret;
}
if (pdata->gpio_rsel && pdata->gpio_rsel[id]) {
char name[18];
int gpio_mux = pdata->gpio_rsel[id];
/* Look for "regulator-select-gpios" GPIOs in the regulator node */
rsel = devm_gpiod_get_optional(dev, "regulator-select", GPIOD_IN);
if (IS_ERR(rsel))
return PTR_ERR(rsel);
if (rsel) {
regulator->reg_rselect = pdata->reg_rsel[id];
/*
* GPI pin is muxed with regulator to select the
* regulator register set A/B for voltage ramping.
*/
sprintf(name, "DA9055 GPI %d", gpio_mux);
ret = devm_gpio_request_one(config->dev, gpio_mux, GPIOF_DIR_IN,
name);
if (ret < 0)
goto err;
gpiod_set_consumer_name(rsel, "DA9055 rsel GPI");
/*
* Let the regulator know that its register set A/B
@ -477,7 +478,6 @@ static int da9055_gpio_init(struct da9055_regulator *regulator,
<< DA9055_V_GPI_SHIFT);
}
err:
return ret;
}
@ -532,7 +532,7 @@ static int da9055_regulator_probe(struct platform_device *pdev)
if (pdata)
config.init_data = pdata->regulators[pdev->id];
ret = da9055_gpio_init(regulator, &config, pdata, pdev->id);
ret = da9055_gpio_init(&pdev->dev, regulator, &config, pdata, pdev->id);
if (ret < 0)
return ret;

View File

@ -14,7 +14,6 @@
// Copyright (C) 2020 Dialog Semiconductor
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/machine.h>

View File

@ -15,7 +15,7 @@ static void regulator_fixed_release(struct device *dev)
{
struct fixed_regulator_data *data = container_of(dev,
struct fixed_regulator_data, pdev.dev);
kfree(data->cfg.supply_name);
kfree_const(data->cfg.supply_name);
kfree(data);
}
@ -36,7 +36,7 @@ struct platform_device *regulator_register_always_on(int id, const char *name,
if (!data)
return NULL;
data->cfg.supply_name = kstrdup(name, GFP_KERNEL);
data->cfg.supply_name = kstrdup_const(name, GFP_KERNEL);
if (!data->cfg.supply_name) {
kfree(data);
return NULL;

View File

@ -58,7 +58,7 @@ struct regulator {
struct dentry *debugfs;
};
extern struct class regulator_class;
extern const struct class regulator_class;
static inline struct regulator_dev *dev_to_rdev(struct device *dev)
{

View File

@ -5,6 +5,7 @@
* Copyright (C) 2016 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <linux/bitfield.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
@ -93,7 +94,7 @@ static int lp873x_buck_set_ramp_delay(struct regulator_dev *rdev,
ret = regmap_update_bits(lp873->regmap, regulators[id].ctrl2_reg,
LP873X_BUCK0_CTRL_2_BUCK0_SLEW_RATE,
reg << __ffs(LP873X_BUCK0_CTRL_2_BUCK0_SLEW_RATE));
FIELD_PREP(LP873X_BUCK0_CTRL_2_BUCK0_SLEW_RATE, reg));
if (ret) {
dev_err(lp873->dev, "SLEW RATE write failed: %d\n", ret);
return ret;

View File

@ -5,6 +5,7 @@
* Copyright (C) 2017 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <linux/bitfield.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
@ -99,7 +100,7 @@ static int lp87565_buck_set_ramp_delay(struct regulator_dev *rdev,
ret = regmap_update_bits(rdev->regmap, regulators[id].ctrl2_reg,
LP87565_BUCK_CTRL_2_SLEW_RATE,
reg << __ffs(LP87565_BUCK_CTRL_2_SLEW_RATE));
FIELD_PREP(LP87565_BUCK_CTRL_2_SLEW_RATE, reg));
if (ret) {
dev_err(&rdev->dev, "SLEW RATE write failed: %d\n", ret);
return ret;

View File

@ -13,7 +13,7 @@
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/mfd/lp8788.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
/* register address */
#define LP8788_EN_BUCK 0x0C
@ -69,8 +69,8 @@
#define BUCK_FPWM_SHIFT(x) (x)
enum lp8788_dvs_state {
DVS_LOW = GPIOF_OUT_INIT_LOW,
DVS_HIGH = GPIOF_OUT_INIT_HIGH,
DVS_LOW = 0,
DVS_HIGH = 1,
};
enum lp8788_dvs_mode {
@ -89,6 +89,8 @@ struct lp8788_buck {
struct lp8788 *lp;
struct regulator_dev *regulator;
void *dvs;
struct gpio_desc *gpio1;
struct gpio_desc *gpio2; /* Only used on BUCK2 */
};
/* BUCK 1 ~ 4 voltage ranges */
@ -106,8 +108,7 @@ static void lp8788_buck1_set_dvs(struct lp8788_buck *buck)
return;
pinstate = dvs->vsel == DVS_SEL_V0 ? DVS_LOW : DVS_HIGH;
if (gpio_is_valid(dvs->gpio))
gpio_set_value(dvs->gpio, pinstate);
gpiod_set_value(buck->gpio1, pinstate);
}
static void lp8788_buck2_set_dvs(struct lp8788_buck *buck)
@ -139,11 +140,8 @@ static void lp8788_buck2_set_dvs(struct lp8788_buck *buck)
return;
}
if (gpio_is_valid(dvs->gpio[0]))
gpio_set_value(dvs->gpio[0], pin1);
if (gpio_is_valid(dvs->gpio[1]))
gpio_set_value(dvs->gpio[1], pin2);
gpiod_set_value(buck->gpio1, pin1);
gpiod_set_value(buck->gpio2, pin2);
}
static void lp8788_set_dvs(struct lp8788_buck *buck, enum lp8788_buck_id id)
@ -202,19 +200,13 @@ static u8 lp8788_select_buck_vout_addr(struct lp8788_buck *buck,
enum lp8788_buck_id id)
{
enum lp8788_dvs_mode mode = lp8788_get_buck_dvs_ctrl_mode(buck, id);
struct lp8788_buck1_dvs *b1_dvs;
struct lp8788_buck2_dvs *b2_dvs;
u8 val, idx, addr;
int pin1, pin2;
switch (id) {
case BUCK1:
if (mode == EXTPIN) {
b1_dvs = (struct lp8788_buck1_dvs *)buck->dvs;
if (!b1_dvs)
goto err;
idx = gpio_get_value(b1_dvs->gpio) ? 1 : 0;
idx = gpiod_get_value(buck->gpio1);
} else {
lp8788_read_byte(buck->lp, LP8788_BUCK_DVS_SEL, &val);
idx = (val & LP8788_BUCK1_DVS_M) >> LP8788_BUCK1_DVS_S;
@ -223,12 +215,8 @@ static u8 lp8788_select_buck_vout_addr(struct lp8788_buck *buck,
break;
case BUCK2:
if (mode == EXTPIN) {
b2_dvs = (struct lp8788_buck2_dvs *)buck->dvs;
if (!b2_dvs)
goto err;
pin1 = gpio_get_value(b2_dvs->gpio[0]);
pin2 = gpio_get_value(b2_dvs->gpio[1]);
pin1 = gpiod_get_value(buck->gpio1);
pin2 = gpiod_get_value(buck->gpio2);
if (pin1 == PIN_LOW && pin2 == PIN_LOW)
idx = 0;
@ -424,28 +412,28 @@ static int lp8788_dvs_gpio_request(struct platform_device *pdev,
enum lp8788_buck_id id)
{
struct lp8788_platform_data *pdata = buck->lp->pdata;
char *b1_name = "LP8788_B1_DVS";
char *b2_name[] = { "LP8788_B2_DVS1", "LP8788_B2_DVS2" };
int i, gpio, ret;
struct device *dev = &pdev->dev;
switch (id) {
case BUCK1:
gpio = pdata->buck1_dvs->gpio;
ret = devm_gpio_request_one(&pdev->dev, gpio, DVS_LOW,
b1_name);
if (ret)
return ret;
buck->gpio1 = devm_gpiod_get(dev, "dvs", GPIOD_OUT_LOW);
if (IS_ERR(buck->gpio1))
return PTR_ERR(buck->gpio1);
gpiod_set_consumer_name(buck->gpio1, "LP8788_B1_DVS");
buck->dvs = pdata->buck1_dvs;
break;
case BUCK2:
for (i = 0; i < LP8788_NUM_BUCK2_DVS; i++) {
gpio = pdata->buck2_dvs->gpio[i];
ret = devm_gpio_request_one(&pdev->dev, gpio,
DVS_LOW, b2_name[i]);
if (ret)
return ret;
}
buck->gpio1 = devm_gpiod_get_index(dev, "dvs", 0, GPIOD_OUT_LOW);
if (IS_ERR(buck->gpio1))
return PTR_ERR(buck->gpio1);
gpiod_set_consumer_name(buck->gpio1, "LP8788_B2_DVS1");
buck->gpio2 = devm_gpiod_get_index(dev, "dvs", 1, GPIOD_OUT_LOW);
if (IS_ERR(buck->gpio2))
return PTR_ERR(buck->gpio2);
gpiod_set_consumer_name(buck->gpio2, "LP8788_B2_DVS2");
buck->dvs = pdata->buck2_dvs;
break;
default:

View File

@ -20,9 +20,7 @@
#include <linux/regulator/machine.h>
#include <linux/regulator/max8973-regulator.h>
#include <linux/regulator/of_regulator.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/of_gpio.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/regmap.h>
@ -102,7 +100,7 @@ struct max8973_chip {
struct regulator_desc desc;
struct regmap *regmap;
bool enable_external_control;
int dvs_gpio;
struct gpio_desc *dvs_gpiod;
int lru_index[MAX8973_MAX_VOUT_REG];
int curr_vout_val[MAX8973_MAX_VOUT_REG];
int curr_vout_reg;
@ -184,7 +182,7 @@ static int max8973_dcdc_set_voltage_sel(struct regulator_dev *rdev,
* If gpios are available to select the VOUT register then least
* recently used register for new configuration.
*/
if (gpio_is_valid(max->dvs_gpio))
if (max->dvs_gpiod)
found = find_voltage_set_register(max, vsel,
&vout_reg, &gpio_val);
@ -201,8 +199,8 @@ static int max8973_dcdc_set_voltage_sel(struct regulator_dev *rdev,
}
/* Select proper VOUT register vio gpios */
if (gpio_is_valid(max->dvs_gpio)) {
gpio_set_value_cansleep(max->dvs_gpio, gpio_val & 0x1);
if (max->dvs_gpiod) {
gpiod_set_value_cansleep(max->dvs_gpiod, gpio_val & 0x1);
max->curr_gpio_val = gpio_val;
}
return 0;
@ -531,7 +529,6 @@ static struct max8973_regulator_platform_data *max8973_parse_dt(
pdata->enable_ext_control = of_property_read_bool(np,
"maxim,externally-enable");
pdata->dvs_gpio = of_get_named_gpio(np, "maxim,dvs-gpio", 0);
ret = of_property_read_u32(np, "maxim,dvs-default-state", &pval);
if (!ret)
@ -612,13 +609,17 @@ static int max8973_probe(struct i2c_client *client)
return -EIO;
}
if (pdata->dvs_gpio == -EPROBE_DEFER)
return -EPROBE_DEFER;
max = devm_kzalloc(&client->dev, sizeof(*max), GFP_KERNEL);
if (!max)
return -ENOMEM;
max->dvs_gpiod = devm_gpiod_get_optional(&client->dev, "maxim,dvs",
(pdata->dvs_def_state) ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW);
if (IS_ERR(max->dvs_gpiod))
return dev_err_probe(&client->dev, PTR_ERR(max->dvs_gpiod),
"failed to obtain dvs gpio\n");
gpiod_set_consumer_name(max->dvs_gpiod, "max8973-dvs");
max->regmap = devm_regmap_init_i2c(client, &max8973_regmap_config);
if (IS_ERR(max->regmap)) {
ret = PTR_ERR(max->regmap);
@ -663,7 +664,6 @@ static int max8973_probe(struct i2c_client *client)
max->desc.ramp_delay_table = max8973_buck_ramp_table;
max->desc.n_ramp_values = ARRAY_SIZE(max8973_buck_ramp_table);
max->dvs_gpio = (pdata->dvs_gpio) ? pdata->dvs_gpio : -EINVAL;
max->enable_external_control = pdata->enable_ext_control;
max->curr_gpio_val = pdata->dvs_def_state;
max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state;
@ -671,21 +671,9 @@ static int max8973_probe(struct i2c_client *client)
max->lru_index[0] = max->curr_vout_reg;
if (gpio_is_valid(max->dvs_gpio)) {
int gpio_flags;
if (max->dvs_gpiod) {
int i;
gpio_flags = (pdata->dvs_def_state) ?
GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
ret = devm_gpio_request_one(&client->dev, max->dvs_gpio,
gpio_flags, "max8973-dvs");
if (ret) {
dev_err(&client->dev,
"gpio_request for gpio %d failed, err = %d\n",
max->dvs_gpio, ret);
return ret;
}
/*
* Initialize the lru index with vout_reg id
* The index 0 will be most recently used and

View File

@ -9,8 +9,7 @@
#include <linux/bug.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/platform_device.h>
@ -32,7 +31,7 @@ struct max8997_data {
u8 buck1_vol[8];
u8 buck2_vol[8];
u8 buck5_vol[8];
int buck125_gpios[3];
struct gpio_desc *buck125_gpiods[3];
int buck125_gpioindex;
bool ignore_gpiodvs_side_effect;
@ -52,9 +51,9 @@ static inline void max8997_set_gpio(struct max8997_data *max8997)
int set2 = ((max8997->buck125_gpioindex) >> 1) & 0x1;
int set1 = ((max8997->buck125_gpioindex) >> 2) & 0x1;
gpio_set_value(max8997->buck125_gpios[0], set1);
gpio_set_value(max8997->buck125_gpios[1], set2);
gpio_set_value(max8997->buck125_gpios[2], set3);
gpiod_set_value(max8997->buck125_gpiods[0], set1);
gpiod_set_value(max8997->buck125_gpiods[1], set2);
gpiod_set_value(max8997->buck125_gpiods[2], set3);
}
struct voltage_map_desc {
@ -873,31 +872,13 @@ static struct regulator_desc regulators[] = {
};
#ifdef CONFIG_OF
static int max8997_pmic_dt_parse_dvs_gpio(struct platform_device *pdev,
struct max8997_platform_data *pdata,
struct device_node *pmic_np)
{
int i, gpio;
for (i = 0; i < 3; i++) {
gpio = of_get_named_gpio(pmic_np,
"max8997,pmic-buck125-dvs-gpios", i);
if (!gpio_is_valid(gpio)) {
dev_err(&pdev->dev, "invalid gpio[%d]: %d\n", i, gpio);
return -EINVAL;
}
pdata->buck125_gpios[i] = gpio;
}
return 0;
}
static int max8997_pmic_dt_parse_pdata(struct platform_device *pdev,
struct max8997_platform_data *pdata)
{
struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
struct device_node *pmic_np, *regulators_np, *reg_np;
struct max8997_regulator_data *rdata;
unsigned int i, dvs_voltage_nr = 1, ret;
unsigned int i, dvs_voltage_nr = 1;
pmic_np = iodev->dev->of_node;
if (!pmic_np) {
@ -949,10 +930,6 @@ static int max8997_pmic_dt_parse_pdata(struct platform_device *pdev,
if (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs ||
pdata->buck5_gpiodvs) {
ret = max8997_pmic_dt_parse_dvs_gpio(pdev, pdata, pmic_np);
if (ret)
return -EINVAL;
if (of_property_read_u32(pmic_np,
"max8997,pmic-buck125-default-dvs-idx",
&pdata->buck125_default_idx)) {
@ -1039,7 +1016,6 @@ static int max8997_pmic_probe(struct platform_device *pdev)
max8997->buck1_gpiodvs = pdata->buck1_gpiodvs;
max8997->buck2_gpiodvs = pdata->buck2_gpiodvs;
max8997->buck5_gpiodvs = pdata->buck5_gpiodvs;
memcpy(max8997->buck125_gpios, pdata->buck125_gpios, sizeof(int) * 3);
max8997->ignore_gpiodvs_side_effect = pdata->ignore_gpiodvs_side_effect;
nr_dvs = (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs ||
@ -1110,38 +1086,27 @@ static int max8997_pmic_probe(struct platform_device *pdev)
*/
if (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs ||
pdata->buck5_gpiodvs) {
const char *gpio_names[3] = {"MAX8997 SET1", "MAX8997 SET2", "MAX8997 SET3"};
if (!gpio_is_valid(pdata->buck125_gpios[0]) ||
!gpio_is_valid(pdata->buck125_gpios[1]) ||
!gpio_is_valid(pdata->buck125_gpios[2])) {
dev_err(&pdev->dev, "GPIO NOT VALID\n");
return -EINVAL;
for (i = 0; i < 3; i++) {
enum gpiod_flags flags;
if (max8997->buck125_gpioindex & BIT(2 - i))
flags = GPIOD_OUT_HIGH;
else
flags = GPIOD_OUT_LOW;
max8997->buck125_gpiods[i] = devm_gpiod_get_index(iodev->dev,
"max8997,pmic-buck125-dvs",
i,
flags);
if (IS_ERR(max8997->buck125_gpiods[i])) {
ret = PTR_ERR(max8997->buck125_gpiods[i]);
return dev_err_probe(iodev->dev, ret, "cant get GPIO %d (%d)\n",
i, ret);
}
gpiod_set_consumer_name(max8997->buck125_gpiods[i], gpio_names[i]);
}
ret = devm_gpio_request(&pdev->dev, pdata->buck125_gpios[0],
"MAX8997 SET1");
if (ret)
return ret;
ret = devm_gpio_request(&pdev->dev, pdata->buck125_gpios[1],
"MAX8997 SET2");
if (ret)
return ret;
ret = devm_gpio_request(&pdev->dev, pdata->buck125_gpios[2],
"MAX8997 SET3");
if (ret)
return ret;
gpio_direction_output(pdata->buck125_gpios[0],
(max8997->buck125_gpioindex >> 2)
& 0x1); /* SET1 */
gpio_direction_output(pdata->buck125_gpios[1],
(max8997->buck125_gpioindex >> 1)
& 0x1); /* SET2 */
gpio_direction_output(pdata->buck125_gpios[2],
(max8997->buck125_gpioindex >> 0)
& 0x1); /* SET3 */
}
/* DVS-GPIO disabled */

View File

@ -10,12 +10,12 @@
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/bits.h>
#include <linux/gpio/consumer.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
@ -31,6 +31,9 @@ struct max8998_data {
unsigned int buck1_idx; /* index to last changed voltage */
/* value in a set */
unsigned int buck2_idx;
struct gpio_desc *buck1_gpio1;
struct gpio_desc *buck1_gpio2;
struct gpio_desc *buck2_gpio;
};
static const unsigned int charger_current_table[] = {
@ -227,15 +230,15 @@ static int max8998_set_voltage_ldo_sel(struct regulator_dev *rdev,
return ret;
}
static inline void buck1_gpio_set(int gpio1, int gpio2, int v)
static inline void buck1_gpio_set(struct gpio_desc *gpio1, struct gpio_desc *gpio2, int v)
{
gpio_set_value(gpio1, v & 0x1);
gpio_set_value(gpio2, (v >> 1) & 0x1);
gpiod_set_value(gpio1, v & 0x1);
gpiod_set_value(gpio2, (v >> 1) & 0x1);
}
static inline void buck2_gpio_set(int gpio, int v)
static inline void buck2_gpio_set(struct gpio_desc *gpio, int v)
{
gpio_set_value(gpio, v & 0x1);
gpiod_set_value(gpio, v & 0x1);
}
static int max8998_set_voltage_buck_sel(struct regulator_dev *rdev,
@ -260,16 +263,15 @@ static int max8998_set_voltage_buck_sel(struct regulator_dev *rdev,
selector, max8998->buck1_vol[0], max8998->buck1_vol[1],
max8998->buck1_vol[2], max8998->buck1_vol[3]);
if (gpio_is_valid(pdata->buck1_set1) &&
gpio_is_valid(pdata->buck1_set2)) {
if (max8998->buck1_gpio1 && max8998->buck1_gpio2) {
/* check if requested voltage */
/* value is already defined */
for (j = 0; j < ARRAY_SIZE(max8998->buck1_vol); j++) {
if (max8998->buck1_vol[j] == selector) {
max8998->buck1_idx = j;
buck1_gpio_set(pdata->buck1_set1,
pdata->buck1_set2, j);
buck1_gpio_set(max8998->buck1_gpio1,
max8998->buck1_gpio2, j);
goto buck1_exit;
}
}
@ -286,13 +288,13 @@ static int max8998_set_voltage_buck_sel(struct regulator_dev *rdev,
&shift,
&mask);
ret = max8998_write_reg(i2c, reg, selector);
buck1_gpio_set(pdata->buck1_set1,
pdata->buck1_set2, max8998->buck1_idx);
buck1_gpio_set(max8998->buck1_gpio1,
max8998->buck1_gpio2, max8998->buck1_idx);
buck1_last_val++;
buck1_exit:
dev_dbg(max8998->dev, "%s: SET1:%d, SET2:%d\n",
i2c->name, gpio_get_value(pdata->buck1_set1),
gpio_get_value(pdata->buck1_set2));
i2c->name, gpiod_get_value(max8998->buck1_gpio1),
gpiod_get_value(max8998->buck1_gpio2));
break;
} else {
ret = max8998_write_reg(i2c, reg, selector);
@ -303,14 +305,13 @@ buck1_exit:
dev_dbg(max8998->dev,
"BUCK2, selector:%d buck2_vol1:%d, buck2_vol2:%d\n",
selector, max8998->buck2_vol[0], max8998->buck2_vol[1]);
if (gpio_is_valid(pdata->buck2_set3)) {
if (max8998->buck2_gpio) {
/* check if requested voltage */
/* value is already defined */
for (j = 0; j < ARRAY_SIZE(max8998->buck2_vol); j++) {
if (max8998->buck2_vol[j] == selector) {
max8998->buck2_idx = j;
buck2_gpio_set(pdata->buck2_set3, j);
buck2_gpio_set(max8998->buck2_gpio, j);
goto buck2_exit;
}
}
@ -322,10 +323,10 @@ buck1_exit:
&reg, &shift, &mask);
ret = max8998_write_reg(i2c, reg, selector);
max8998->buck2_vol[max8998->buck2_idx] = selector;
buck2_gpio_set(pdata->buck2_set3, max8998->buck2_idx);
buck2_gpio_set(max8998->buck2_gpio, max8998->buck2_idx);
buck2_exit:
dev_dbg(max8998->dev, "%s: SET3:%d\n", i2c->name,
gpio_get_value(pdata->buck2_set3));
gpiod_get_value(max8998->buck2_gpio));
} else {
ret = max8998_write_reg(i2c, reg, selector);
}
@ -539,36 +540,6 @@ static const struct regulator_desc regulators[] = {
charger_current_table, MAX8998_REG_CHGR1, 0x7),
};
static int max8998_pmic_dt_parse_dvs_gpio(struct max8998_dev *iodev,
struct max8998_platform_data *pdata,
struct device_node *pmic_np)
{
int gpio;
gpio = of_get_named_gpio(pmic_np, "max8998,pmic-buck1-dvs-gpios", 0);
if (!gpio_is_valid(gpio)) {
dev_err(iodev->dev, "invalid buck1 gpio[0]: %d\n", gpio);
return -EINVAL;
}
pdata->buck1_set1 = gpio;
gpio = of_get_named_gpio(pmic_np, "max8998,pmic-buck1-dvs-gpios", 1);
if (!gpio_is_valid(gpio)) {
dev_err(iodev->dev, "invalid buck1 gpio[1]: %d\n", gpio);
return -EINVAL;
}
pdata->buck1_set2 = gpio;
gpio = of_get_named_gpio(pmic_np, "max8998,pmic-buck2-dvs-gpio", 0);
if (!gpio_is_valid(gpio)) {
dev_err(iodev->dev, "invalid buck 2 gpio: %d\n", gpio);
return -EINVAL;
}
pdata->buck2_set3 = gpio;
return 0;
}
static int max8998_pmic_dt_parse_pdata(struct max8998_dev *iodev,
struct max8998_platform_data *pdata)
{
@ -614,10 +585,6 @@ static int max8998_pmic_dt_parse_pdata(struct max8998_dev *iodev,
of_node_put(reg_np);
of_node_put(regulators_np);
ret = max8998_pmic_dt_parse_dvs_gpio(iodev, pdata, pmic_np);
if (ret)
return -EINVAL;
pdata->buck_voltage_lock = of_property_read_bool(pmic_np, "max8998,pmic-buck-voltage-lock");
ret = of_property_read_u32(pmic_np,
@ -665,6 +632,7 @@ static int max8998_pmic_probe(struct platform_device *pdev)
struct regulator_dev *rdev;
struct max8998_data *max8998;
struct i2c_client *i2c;
enum gpiod_flags flags;
int i, ret;
unsigned int v;
@ -693,37 +661,38 @@ static int max8998_pmic_probe(struct platform_device *pdev)
max8998->buck1_idx = pdata->buck1_default_idx;
max8998->buck2_idx = pdata->buck2_default_idx;
/* NOTE: */
/* For unused GPIO NOT marked as -1 (thereof equal to 0) WARN_ON */
/* will be displayed */
/* Check if MAX8998 voltage selection GPIOs are defined */
if (gpio_is_valid(pdata->buck1_set1) &&
gpio_is_valid(pdata->buck1_set2)) {
/* Check if SET1 is not equal to 0 */
if (!pdata->buck1_set1) {
dev_err(&pdev->dev,
"MAX8998 SET1 GPIO defined as 0 !\n");
WARN_ON(!pdata->buck1_set1);
return -EIO;
}
/* Check if SET2 is not equal to 0 */
if (!pdata->buck1_set2) {
dev_err(&pdev->dev,
"MAX8998 SET2 GPIO defined as 0 !\n");
WARN_ON(!pdata->buck1_set2);
return -EIO;
}
flags = (max8998->buck1_idx & BIT(0)) ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW;
max8998->buck1_gpio1 = devm_gpiod_get_index_optional(iodev->dev,
"max8998,pmic-buck1-dvs",
0,
flags);
if (IS_ERR(max8998->buck1_gpio1))
return dev_err_probe(&pdev->dev, PTR_ERR(max8998->buck1_gpio1),
"could not get BUCK1 GPIO1\n");
gpiod_set_consumer_name(max8998->buck1_gpio1, "MAX8998 BUCK1_SET1");
gpio_request(pdata->buck1_set1, "MAX8998 BUCK1_SET1");
gpio_direction_output(pdata->buck1_set1,
max8998->buck1_idx & 0x1);
flags = (max8998->buck1_idx & BIT(1)) ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW;
max8998->buck1_gpio2 = devm_gpiod_get_index_optional(iodev->dev,
"max8998,pmic-buck1-dvs",
1,
flags);
if (IS_ERR(max8998->buck1_gpio2))
return dev_err_probe(&pdev->dev, PTR_ERR(max8998->buck1_gpio2),
"could not get BUCK1 GPIO2\n");
gpiod_set_consumer_name(max8998->buck1_gpio1, "MAX8998 BUCK1_SET2");
flags = (max8998->buck2_idx & BIT(0)) ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW;
max8998->buck2_gpio = devm_gpiod_get_index_optional(iodev->dev,
"max8998,pmic-buck2-dvs",
0,
flags);
if (IS_ERR(max8998->buck2_gpio))
return dev_err_probe(&pdev->dev, PTR_ERR(max8998->buck2_gpio),
"could not get BUCK2 GPIO\n");
gpiod_set_consumer_name(max8998->buck1_gpio1, "MAX8998 BUCK2_SET3");
gpio_request(pdata->buck1_set2, "MAX8998 BUCK1_SET2");
gpio_direction_output(pdata->buck1_set2,
(max8998->buck1_idx >> 1) & 0x1);
if (max8998->buck1_gpio1 && max8998->buck1_gpio2) {
/* Set predefined values for BUCK1 registers */
for (v = 0; v < ARRAY_SIZE(pdata->buck1_voltage); ++v) {
int index = MAX8998_BUCK1 - MAX8998_LDO2;
@ -742,18 +711,7 @@ static int max8998_pmic_probe(struct platform_device *pdev)
}
}
if (gpio_is_valid(pdata->buck2_set3)) {
/* Check if SET3 is not equal to 0 */
if (!pdata->buck2_set3) {
dev_err(&pdev->dev,
"MAX8998 SET3 GPIO defined as 0 !\n");
WARN_ON(!pdata->buck2_set3);
return -EIO;
}
gpio_request(pdata->buck2_set3, "MAX8998 BUCK2_SET3");
gpio_direction_output(pdata->buck2_set3,
max8998->buck2_idx & 0x1);
if (max8998->buck2_gpio) {
/* Set predefined values for BUCK2 registers */
for (v = 0; v < ARRAY_SIZE(pdata->buck2_voltage); ++v) {
int index = MAX8998_BUCK2 - MAX8998_LDO2;

View File

@ -35,6 +35,16 @@
#define MP8859_GO_BIT 0x01
#define MP8859_IOUT_LIM_MASK 0x7f
#define MP8859_ENABLE_MASK 0x80
#define MP8859_DISCHG_EN_MASK 0x10
#define MP8859_MODE_MASK 0x08
#define MP8859_PG_MASK 0x80
#define MP8859_OTP_MASK 0x40
#define MP8859_OTW_MASK 0x20
#define MP8859_CC_CV_MASK 0x10
static int mp8859_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel)
{
@ -73,21 +83,221 @@ static int mp8859_get_voltage_sel(struct regulator_dev *rdev)
return val;
}
static int mp8859_set_voltage_time_sel(struct regulator_dev *rdev,
unsigned int from, unsigned int to)
{
int change;
/* The voltage ramps at 1mV/uS, selectors are 10mV */
if (from > to)
change = from - to;
else
change = to - from;
return change * 10 * 1000;
}
static unsigned int mp8859_get_mode(struct regulator_dev *rdev)
{
unsigned int val;
int ret;
ret = regmap_read(rdev->regmap, MP8859_CTL1_REG, &val);
if (ret != 0) {
dev_err(&rdev->dev, "Failed to read mode: %d\n", ret);
return 0;
}
if (val & MP8859_MODE_MASK)
return REGULATOR_MODE_FAST;
else
return REGULATOR_MODE_NORMAL;
}
static int mp8859_set_mode(struct regulator_dev *rdev, unsigned int mode)
{
unsigned int val;
switch (mode) {
case REGULATOR_MODE_FAST:
val = MP8859_MODE_MASK;
break;
case REGULATOR_MODE_NORMAL:
val = 0;
break;
default:
return -EINVAL;
}
return regmap_update_bits(rdev->regmap, MP8859_CTL1_REG,
MP8859_MODE_MASK, val);
}
static int mp8859_set_current_limit(struct regulator_dev *rdev,
int min_uA, int max_uA)
{
unsigned int cur_val, new_val;
int ret, i;
/* Steps of 50mA */
new_val = max_uA / 50000;
if (new_val > MP8859_IOUT_LIM_MASK)
return -EINVAL;
if (new_val == 0)
return -EINVAL;
/*
* If the regulator is limiting then ramp gradually as per
* datasheet, otherwise just set the value directly.
*/
ret = regmap_read(rdev->regmap, MP8859_STATUS_REG, &cur_val);
if (ret != 0)
return ret;
if (!(cur_val & MP8859_CC_CV_MASK)) {
return regmap_update_bits(rdev->regmap, MP8859_IOUT_LIM_REG,
MP8859_IOUT_LIM_MASK, new_val);
}
ret = regmap_read(rdev->regmap, MP8859_IOUT_LIM_REG, &cur_val);
if (ret != 0)
return ret;
if (cur_val >= new_val) {
for (i = cur_val; i >= new_val; i--) {
ret = regmap_update_bits(rdev->regmap,
MP8859_IOUT_LIM_REG,
MP8859_IOUT_LIM_MASK,
cur_val - i);
if (ret != 0)
return ret;
}
} else {
for (i = cur_val; i <= new_val; i++) {
ret = regmap_update_bits(rdev->regmap,
MP8859_IOUT_LIM_REG,
MP8859_IOUT_LIM_MASK,
cur_val + i);
if (ret != 0)
return ret;
}
}
return 0;
}
static int mp8859_get_status(struct regulator_dev *rdev)
{
unsigned int val;
int ret;
/* Output status is only meaingful when enabled */
ret = regmap_read(rdev->regmap, MP8859_CTL1_REG, &val);
if (ret != 0)
return ret;
if (!(val & MP8859_ENABLE_MASK))
return REGULATOR_STATUS_UNDEFINED;
ret = regmap_read(rdev->regmap, MP8859_STATUS_REG, &val);
if (ret != 0)
return ret;
if (val & MP8859_PG_MASK)
return REGULATOR_STATUS_ON;
else
return REGULATOR_STATUS_ERROR;
}
static int mp8859_get_error_flags(struct regulator_dev *rdev,
unsigned int *flags)
{
unsigned int status, enabled;
int ret;
*flags = 0;
/* Output status is only meaingful when enabled */
ret = regmap_read(rdev->regmap, MP8859_CTL1_REG, &enabled);
if (ret != 0)
return ret;
enabled &= MP8859_ENABLE_MASK;
ret = regmap_read(rdev->regmap, MP8859_STATUS_REG, &status);
if (ret != 0)
return ret;
if (enabled && !(status & MP8859_PG_MASK))
status |= REGULATOR_ERROR_FAIL;
if (status & MP8859_OTP_MASK)
status |= REGULATOR_ERROR_OVER_TEMP;
if (status & MP8859_OTW_MASK)
status |= REGULATOR_ERROR_OVER_TEMP_WARN;
if (status & MP8859_CC_CV_MASK)
status |= REGULATOR_ERROR_OVER_CURRENT;
return 0;
}
static const struct linear_range mp8859_dcdc_ranges[] = {
REGULATOR_LINEAR_RANGE(0, VOL_MIN_IDX, VOL_MAX_IDX, 10000),
};
static bool mp8859_readable(struct device *dev, unsigned int reg)
{
switch (reg) {
case MP8859_VOUT_L_REG:
case MP8859_VOUT_H_REG:
case MP8859_VOUT_GO_REG:
case MP8859_IOUT_LIM_REG:
case MP8859_CTL1_REG:
case MP8859_CTL2_REG:
case MP8859_STATUS_REG:
case MP8859_INTERRUPT_REG:
case MP8859_MASK_REG:
case MP8859_ID1_REG:
case MP8859_MFR_ID_REG:
case MP8859_DEV_ID_REG:
case MP8859_IC_REV_REG:
return true;
default:
return false;
}
}
static bool mp8859_volatile(struct device *dev, unsigned int reg)
{
switch (reg) {
case MP8859_VOUT_GO_REG:
case MP8859_STATUS_REG:
case MP8859_INTERRUPT_REG:
return true;
default:
return false;
}
}
static const struct regmap_config mp8859_regmap = {
.reg_bits = 8,
.val_bits = 8,
.max_register = MP8859_MAX_REG,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.readable_reg = mp8859_readable,
.volatile_reg = mp8859_volatile,
};
static const struct regulator_ops mp8859_ops = {
.set_voltage_sel = mp8859_set_voltage_sel,
.get_voltage_sel = mp8859_get_voltage_sel,
.list_voltage = regulator_list_voltage_linear_range,
.set_voltage_time_sel = mp8859_set_voltage_time_sel,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.set_mode = mp8859_set_mode,
.get_mode = mp8859_get_mode,
.set_active_discharge = regulator_set_active_discharge_regmap,
.set_current_limit = mp8859_set_current_limit,
.get_status = mp8859_get_status,
.get_error_flags = mp8859_get_error_flags,
};
static const struct regulator_desc mp8859_regulators[] = {
@ -100,6 +310,12 @@ static const struct regulator_desc mp8859_regulators[] = {
.n_voltages = VOL_MAX_IDX + 1,
.linear_ranges = mp8859_dcdc_ranges,
.n_linear_ranges = 1,
.enable_reg = MP8859_CTL1_REG,
.enable_mask = MP8859_ENABLE_MASK,
.enable_val = MP8859_ENABLE_MASK,
.active_discharge_reg = MP8859_CTL1_REG,
.active_discharge_on = MP8859_DISCHG_EN_MASK,
.active_discharge_mask = MP8859_DISCHG_EN_MASK,
.ops = &mp8859_ops,
.owner = THIS_MODULE,
},
@ -111,12 +327,46 @@ static int mp8859_i2c_probe(struct i2c_client *i2c)
struct regulator_config config = {.dev = &i2c->dev};
struct regmap *regmap = devm_regmap_init_i2c(i2c, &mp8859_regmap);
struct regulator_dev *rdev;
unsigned int val, rev;
if (IS_ERR(regmap)) {
ret = PTR_ERR(regmap);
dev_err(&i2c->dev, "regmap init failed: %d\n", ret);
return ret;
}
ret = regmap_read(regmap, MP8859_MFR_ID_REG, &val);
if (ret != 0) {
dev_err(&i2c->dev, "Failed to read manufacturer ID: %d\n", ret);
return ret;
}
if (val != 0x9) {
dev_err(&i2c->dev, "Manufacturer ID %x != 9\n", val);
return -EINVAL;
}
ret = regmap_read(regmap, MP8859_DEV_ID_REG, &val);
if (ret != 0) {
dev_err(&i2c->dev, "Failed to read device ID: %d\n", ret);
return ret;
}
if (val != 0x58) {
dev_err(&i2c->dev, "Manufacturer ID %x != 0x58\n", val);
return -EINVAL;
}
ret = regmap_read(regmap, MP8859_IC_REV_REG, &rev);
if (ret != 0) {
dev_err(&i2c->dev, "Failed to read device revision: %d\n", ret);
return ret;
}
ret = regmap_read(regmap, MP8859_ID1_REG, &val);
if (ret != 0) {
dev_err(&i2c->dev, "Failed to read device ID1: %d\n", ret);
return ret;
}
dev_info(&i2c->dev, "MP8859-%04d revision %d\n", val, rev);
rdev = devm_regulator_register(&i2c->dev, &mp8859_regulators[0],
&config);

View File

@ -271,11 +271,10 @@ static int pwm_regulator_init_table(struct platform_device *pdev,
of_find_property(np, "voltage-table", &length);
if ((length < sizeof(*duty_cycle_table)) ||
(length % sizeof(*duty_cycle_table))) {
dev_err(&pdev->dev, "voltage-table length(%d) is invalid\n",
length);
return -EINVAL;
}
(length % sizeof(*duty_cycle_table)))
return dev_err_probe(&pdev->dev, -EINVAL,
"voltage-table length(%d) is invalid\n",
length);
duty_cycle_table = devm_kzalloc(&pdev->dev, length, GFP_KERNEL);
if (!duty_cycle_table)
@ -284,10 +283,9 @@ static int pwm_regulator_init_table(struct platform_device *pdev,
ret = of_property_read_u32_array(np, "voltage-table",
(u32 *)duty_cycle_table,
length / sizeof(u32));
if (ret) {
dev_err(&pdev->dev, "Failed to read voltage-table: %d\n", ret);
return ret;
}
if (ret)
return dev_err_probe(&pdev->dev, ret,
"Failed to read voltage-table\n");
drvdata->state = -ENOTRECOVERABLE;
drvdata->duty_cycle_table = duty_cycle_table;
@ -359,10 +357,9 @@ static int pwm_regulator_probe(struct platform_device *pdev)
enum gpiod_flags gpio_flags;
int ret;
if (!np) {
dev_err(&pdev->dev, "Device Tree node missing\n");
return -EINVAL;
}
if (!np)
return dev_err_probe(&pdev->dev, -EINVAL,
"Device Tree node missing\n");
drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata)
@ -400,8 +397,7 @@ static int pwm_regulator_probe(struct platform_device *pdev)
gpio_flags);
if (IS_ERR(drvdata->enb_gpio)) {
ret = PTR_ERR(drvdata->enb_gpio);
dev_err(&pdev->dev, "Failed to get enable GPIO: %d\n", ret);
return ret;
return dev_err_probe(&pdev->dev, ret, "Failed to get enable GPIO\n");
}
ret = pwm_adjust_config(drvdata->pwm);
@ -409,19 +405,17 @@ static int pwm_regulator_probe(struct platform_device *pdev)
return ret;
ret = pwm_regulator_init_boot_on(pdev, drvdata, init_data);
if (ret) {
dev_err(&pdev->dev, "Failed to apply boot_on settings: %d\n",
ret);
return ret;
}
if (ret)
return dev_err_probe(&pdev->dev, ret,
"Failed to apply boot_on settings\n");
regulator = devm_regulator_register(&pdev->dev,
&drvdata->desc, &config);
if (IS_ERR(regulator)) {
ret = PTR_ERR(regulator);
dev_err(&pdev->dev, "Failed to register regulator %s: %d\n",
drvdata->desc.name, ret);
return ret;
return dev_err_probe(&pdev->dev, ret,
"Failed to register regulator %s\n",
drvdata->desc.name);
}
return 0;

View File

@ -11,11 +11,10 @@
#include <linux/regulator/of_regulator.h>
#include <linux/soc/qcom/smd-rpm.h>
struct qcom_smd_rpm *smd_vreg_rpm;
struct qcom_rpm_reg {
struct device *dev;
struct qcom_smd_rpm *rpm;
u32 type;
u32 id;
@ -70,7 +69,7 @@ static int rpm_reg_write_active(struct qcom_rpm_reg *vreg)
if (!reqlen)
return 0;
ret = qcom_rpm_smd_write(vreg->rpm, QCOM_SMD_RPM_ACTIVE_STATE,
ret = qcom_rpm_smd_write(smd_vreg_rpm, QCOM_SMD_RPM_ACTIVE_STATE,
vreg->type, vreg->id,
req, sizeof(req[0]) * reqlen);
if (!ret) {
@ -1384,14 +1383,13 @@ MODULE_DEVICE_TABLE(of, rpm_of_match);
* @dev: Pointer to the top level qcom_smd-regulator PMIC device
* @node: Pointer to the individual qcom_smd-regulator resource
* device node
* @rpm: Pointer to the rpm bus node
* @pmic_rpm_data: Pointer to a null-terminated array of qcom_smd-regulator
* resources defined for the top level PMIC device
*
* Return: 0 on success, errno on failure
*/
static int rpm_regulator_init_vreg(struct qcom_rpm_reg *vreg, struct device *dev,
struct device_node *node, struct qcom_smd_rpm *rpm,
struct device_node *node,
const struct rpm_regulator_data *pmic_rpm_data)
{
struct regulator_config config = {};
@ -1409,7 +1407,6 @@ static int rpm_regulator_init_vreg(struct qcom_rpm_reg *vreg, struct device *dev
}
vreg->dev = dev;
vreg->rpm = rpm;
vreg->type = rpm_data->type;
vreg->id = rpm_data->id;
@ -1449,6 +1446,11 @@ static int rpm_reg_probe(struct platform_device *pdev)
return -ENODEV;
}
if (smd_vreg_rpm && rpm != smd_vreg_rpm)
return dev_err_probe(dev, -EINVAL, "RPM mismatch\n");
smd_vreg_rpm = rpm;
vreg_data = of_device_get_match_data(dev);
if (!vreg_data)
return -ENODEV;
@ -1460,8 +1462,7 @@ static int rpm_reg_probe(struct platform_device *pdev)
return -ENOMEM;
}
ret = rpm_regulator_init_vreg(vreg, dev, node, rpm, vreg_data);
ret = rpm_regulator_init_vreg(vreg, dev, node, vreg_data);
if (ret < 0) {
of_node_put(node);
return ret;

View File

@ -208,6 +208,7 @@ static const struct of_device_id regulator_userspace_consumer_of_match[] = {
{ .compatible = "regulator-output", },
{},
};
MODULE_DEVICE_TABLE(of, regulator_userspace_consumer_of_match);
static struct platform_driver regulator_userspace_consumer_driver = {
.probe = regulator_userspace_consumer_probe,

View File

@ -7,7 +7,6 @@
#define DA9055_MAX_REGULATORS 8
struct da9055;
struct gpio_desc;
enum gpio_select {
NO_GPIO = 0,
@ -23,16 +22,6 @@ struct da9055_pdata {
struct regulator_init_data *regulators[DA9055_MAX_REGULATORS];
/* Enable RTC in RESET Mode */
bool reset_enable;
/*
* GPI muxed pin to control
* regulator state A/B, 0 if not available.
*/
int *gpio_ren;
/*
* GPI muxed pin to control
* regulator set, 0 if not available.
*/
int *gpio_rsel;
/*
* Regulator mode control bits value (GPI offset) that
* controls the regulator state, 0 if not available.
@ -43,7 +32,5 @@ struct da9055_pdata {
* controls the regulator set A/B, 0 if not available.
*/
enum gpio_select *reg_rsel;
/* GPIO descriptors to enable regulator, NULL if not available */
struct gpio_desc **ena_gpiods;
};
#endif /* __DA9055_PDATA_H */

View File

@ -10,7 +10,6 @@
#ifndef __MFD_LP8788_H__
#define __MFD_LP8788_H__
#include <linux/gpio.h>
#include <linux/irqdomain.h>
#include <linux/pwm.h>
#include <linux/regmap.h>
@ -159,21 +158,17 @@ struct lp8788;
/*
* lp8788_buck1_dvs
* @gpio : gpio pin number for dvs control
* @vsel : dvs selector for buck v1 register
*/
struct lp8788_buck1_dvs {
int gpio;
enum lp8788_dvs_sel vsel;
};
/*
* lp8788_buck2_dvs
* @gpio : two gpio pin numbers are used for dvs
* @vsel : dvs selector for buck v2 register
*/
struct lp8788_buck2_dvs {
int gpio[LP8788_NUM_BUCK2_DVS];
enum lp8788_dvs_sel vsel;
};
@ -268,8 +263,8 @@ struct lp8788_vib_platform_data {
* @buck_data : regulator initial data for buck
* @dldo_data : regulator initial data for digital ldo
* @aldo_data : regulator initial data for analog ldo
* @buck1_dvs : gpio configurations for buck1 dvs
* @buck2_dvs : gpio configurations for buck2 dvs
* @buck1_dvs : configurations for buck1 dvs
* @buck2_dvs : configurations for buck2 dvs
* @chg_pdata : platform data for charger driver
* @alarm_sel : rtc alarm selection (1 or 2)
* @bl_pdata : configurable data for backlight driver

View File

@ -178,7 +178,6 @@ struct max8997_platform_data {
*
*/
bool ignore_gpiodvs_side_effect;
int buck125_gpios[3]; /* GPIO of [0]SET1, [1]SET2, [2]SET3 */
int buck125_default_idx; /* Default value of SET1, 2, 3 */
unsigned int buck1_voltage[8]; /* buckx_voltage in uV */
bool buck1_gpiodvs;

View File

@ -65,10 +65,7 @@ struct max8998_regulator_data {
* be other than the preset values.
* @buck1_voltage: BUCK1 DVS mode 1 voltage registers
* @buck2_voltage: BUCK2 DVS mode 2 voltage registers
* @buck1_set1: BUCK1 gpio pin 1 to set output voltage
* @buck1_set2: BUCK1 gpio pin 2 to set output voltage
* @buck1_default_idx: Default for BUCK1 gpio pin 1, 2
* @buck2_set3: BUCK2 gpio pin to set output voltage
* @buck2_default_idx: Default for BUCK2 gpio pin.
* @wakeup: Allow to wake up from suspend
* @rtc_delay: LP3974 RTC chip bug that requires delay after a register
@ -91,10 +88,7 @@ struct max8998_platform_data {
bool buck_voltage_lock;
int buck1_voltage[4];
int buck2_voltage[2];
int buck1_set1;
int buck1_set2;
int buck1_default_idx;
int buck2_set3;
int buck2_default_idx;
bool wakeup;
bool rtc_delay;

View File

@ -48,10 +48,6 @@
* control signal from EN input pin. If it is false then
* voltage output will be enabled/disabled through EN bit of
* device register.
* @enable_gpio: Enable GPIO. If EN pin is controlled through GPIO from host
* then GPIO number can be provided. If no GPIO controlled then
* it should be -1.
* @dvs_gpio: GPIO for dvs. It should be -1 if this is tied with fixed logic.
* @dvs_def_state: Default state of dvs. 1 if it is high else 0.
*/
struct max8973_regulator_platform_data {
@ -59,8 +55,6 @@ struct max8973_regulator_platform_data {
unsigned long control_flags;
unsigned long junction_temp_warning;
bool enable_ext_control;
int enable_gpio;
int dvs_gpio;
unsigned dvs_def_state:1;
};