Commit f03e2a72 authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branch 'regulator/for-5.12' into regulator-next

parents 8571bdc2 27866e3e
......@@ -35,6 +35,7 @@ Optional properties:
- interrupts: Interrupt specifiers for two interrupt sources.
- First interrupt specifier is for 'irq1' interrupt.
- Second interrupt specifier is for 'alert' interrupt.
- charger-supply: regulator node for charging current.
- max8997,pmic-buck1-uses-gpio-dvs: 'buck1' can be controlled by gpio dvs.
- max8997,pmic-buck2-uses-gpio-dvs: 'buck2' can be controlled by gpio dvs.
- max8997,pmic-buck5-uses-gpio-dvs: 'buck5' can be controlled by gpio dvs.
......
......@@ -4,7 +4,8 @@ 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.
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
......
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/mt6315-regulator.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Mediatek MT6315 Regulator
maintainers:
- Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>
description: |
The MT6315 is a power management IC (PMIC) configurable with SPMI.
that contains 4 BUCKs output which can combine with each other
by different efuse settings.
properties:
compatible:
const: mediatek,mt6315-regulator
reg:
maxItems: 1
regulators:
type: object
description: List of regulators and its properties
patternProperties:
"^vbuck[1-4]$":
type: object
$ref: "regulator.yaml#"
properties:
regulator-name:
pattern: "^vbuck[1-4]$"
additionalProperties: false
required:
- compatible
- reg
- regulators
additionalProperties: false
examples:
- |
pmic@6 {
compatible = "mediatek,mt6315-regulator";
reg = <0x6 0>;
regulators {
vbuck1 {
regulator-compatible = "vbuck1";
regulator-min-microvolt = <300000>;
regulator-max-microvolt = <1193750>;
regulator-enable-ramp-delay = <256>;
regulator-allowed-modes = <0 1 2 4>;
};
vbuck3 {
regulator-compatible = "vbuck3";
regulator-min-microvolt = <300000>;
regulator-max-microvolt = <1193750>;
regulator-enable-ramp-delay = <256>;
regulator-allowed-modes = <0 1 2 4>;
};
};
};
......@@ -87,6 +87,11 @@ properties:
additionalProperties: false
sd-vsel-gpios:
description: GPIO that is used to switch LDO5 between being configured by
LDO5CTRL_L or LDO5CTRL_H register. Use this if the SD_VSEL signal is
connected to a host GPIO.
required:
- compatible
- reg
......
......@@ -62,8 +62,11 @@ properties:
$ref: "/schemas/types.yaml#/definitions/uint32"
minimum: 2100
maximum: 4500
deprecated: true
description:
BUCK regulators current limit in mA.
This property is deprecated, please use
"regulator-max-microamp" instead.
Listed current limits in mA are,
2100 (default)
......@@ -73,21 +76,11 @@ properties:
nxp,phase-shift:
$ref: "/schemas/types.yaml#/definitions/uint32"
minimum: 45
maximum: 0
default: 0
enum: [ 0, 45, 90, 135, 180, 225, 270, 315 ]
description:
BUCK regulators phase shift control in degrees.
Listed phase shift control values in degrees are,
45
90
135
180
225
270
315
0 (default)
unevaluatedProperties: false
"^vsnvs$":
......
......@@ -50,6 +50,8 @@ First Level Nodes - PMIC
"qcom,pm8350-rpmh-regulators"
"qcom,pm8350c-rpmh-regulators"
"qcom,pm8998-rpmh-regulators"
"qcom,pmc8180-rpmh-regulators"
"qcom,pmc8180c-rpmh-regulators"
"qcom,pmi8998-rpmh-regulators"
"qcom,pm6150-rpmh-regulators"
"qcom,pm6150l-rpmh-regulators"
......
......@@ -22,11 +22,17 @@ properties:
type: object
properties:
qcom,soft-start-us:
$ref: /schemas/types.yaml#/definitions/uint32
description: Regulator soft start time in microseconds.
enum: [200, 400, 600, 800]
default: 200
interrupts:
maxItems: 1
minItems: 1
maxItems: 2
description:
Short-circuit interrupt for lab.
Short-circuit and over-current interrupts for lab.
required:
- interrupts
......@@ -35,11 +41,17 @@ properties:
type: object
properties:
qcom,discharge-resistor-kohms:
$ref: /schemas/types.yaml#/definitions/uint32
description: Discharge resistor value in KiloOhms.
enum: [300, 64, 32, 16]
default: 300
interrupts:
maxItems: 1
minItems: 1
maxItems: 2
description:
Short-circuit interrupt for lab.
Short-circuit and over-current interrupts for ibb.
required:
- interrupts
......@@ -57,13 +69,15 @@ examples:
compatible = "qcom,pmi8998-lab-ibb";
lab {
interrupts = <0x3 0x0 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "sc-err";
interrupts = <0x3 0xde 0x1 IRQ_TYPE_EDGE_RISING>,
<0x3 0xde 0x0 IRQ_TYPE_LEVEL_LOW>;
interrupt-names = "sc-err", "ocp";
};
ibb {
interrupts = <0x3 0x2 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "sc-err";
interrupts = <0x3 0xdc 0x2 IRQ_TYPE_EDGE_RISING>,
<0x3 0xdc 0x0 IRQ_TYPE_LEVEL_LOW>;
interrupt-names = "sc-err", "ocp";
};
};
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/richtek,rt4831-regulator.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Richtek RT4831 Display Bias Voltage Regulator
maintainers:
- ChiYuan Huang <cy_huang@richtek.com>
description: |
RT4831 is a multifunctional device that can provide power to the LCD display
and LCD backlight.
For Display Bias Voltage DSVP and DSVN, the output range is about 4V to 6.5V.
It is sufficient to meet the current LCD power requirement.
DSVLCM is a boost regulator in IC internal as DSVP and DSVN input power.
Its voltage should be configured above 0.15V to 0.2V gap larger than the
voltage needed for DSVP and DSVN. Too much voltage gap could improve the
voltage drop from the heavy loading scenario. But it also make the power
efficiency worse. It's a trade-off.
Datasheet is available at
https://www.richtek.com/assets/product_file/RT4831A/DS4831A-05.pdf
patternProperties:
"^DSV(LCM|P|N)$":
type: object
$ref: regulator.yaml#
description:
Properties for single Display Bias Voltage regulator.
additionalProperties: false
......@@ -11684,9 +11684,9 @@ F: drivers/video/fbdev/atmel_lcdfb.c
F: include/video/atmel_lcdc.h
MICROCHIP MCP16502 PMIC DRIVER
M: Andrei Stefanescu <andrei.stefanescu@microchip.com>
M: Claudiu Beznea <claudiu.beznea@microchip.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
S: Supported
F: Documentation/devicetree/bindings/regulator/mcp16502-regulator.txt
F: drivers/regulator/mcp16502.c
......
......@@ -122,7 +122,7 @@ vreg_s4a_1p8: vreg-s4a-1p8 {
&apps_rsc {
pm8009-rpmh-regulators {
compatible = "qcom,pm8009-rpmh-regulators";
compatible = "qcom,pm8009-1-rpmh-regulators";
qcom,pmic-id = "f";
vdd-s1-supply = <&vph_pwr>;
......@@ -131,6 +131,13 @@ pm8009-rpmh-regulators {
vdd-l5-l6-supply = <&vreg_bob>;
vdd-l7-supply = <&vreg_s4a_1p8>;
vreg_s2f_0p95: smps2 {
regulator-name = "vreg_s2f_0p95";
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <952000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
};
vreg_l1f_1p1: ldo1 {
regulator-name = "vreg_l1f_1p1";
regulator-min-microvolt = <1104000>;
......
......@@ -21,7 +21,6 @@
#include <linux/mfd/abx500/ab8500.h>
#include <linux/mfd/abx500/ab8500-bm.h>
#include <linux/mfd/dbx500-prcmu.h>
#include <linux/regulator/ab8500.h>
#include <linux/of.h>
#include <linux/of_device.h>
......
......@@ -122,15 +122,6 @@ config REGULATOR_AAT2870
If you have a AnalogicTech AAT2870 say Y to enable the
regulator driver.
config REGULATOR_AB3100
tristate "ST-Ericsson AB3100 Regulator functions"
depends on AB3100_CORE
default y if AB3100_CORE
help
These regulators correspond to functionality in the
AB3100 analog baseband dealing with power regulators
for the system.
config REGULATOR_AB8500
bool "ST-Ericsson AB8500 Power Regulators"
depends on AB8500_CORE
......@@ -179,6 +170,14 @@ config REGULATOR_AS3722
AS3722 PMIC. This will enable support for all the software
controllable DCDC/LDO regulators.
config REGULATOR_ATC260X
tristate "Actions Semi ATC260x PMIC Regulators"
depends on MFD_ATC260X
help
This driver provides support for the voltage regulators on the
ATC260x PMICs. This will enable support for all the software
controllable DCDC/LDO regulators.
config REGULATOR_AXP20X
tristate "X-POWERS AXP20X PMIC Regulators"
depends on MFD_AXP20X
......@@ -732,6 +731,16 @@ config REGULATOR_MT6311
This driver supports the control of different power rails of device
through regulator interface.
config REGULATOR_MT6315
tristate "MediaTek MT6315 PMIC"
depends on SPMI
select REGMAP_SPMI
help
Say y here to select this option to enable the power regulator of
MediaTek MT6315 PMIC.
This driver supports the control of different power rails of device
through regulator interface.
config REGULATOR_MT6323
tristate "MediaTek MT6323 PMIC"
depends on MFD_MT6397
......@@ -777,6 +786,16 @@ config REGULATOR_MT6397
This driver supports the control of different power rails of device
through regulator interface.
config REGULATOR_MTK_DVFSRC
tristate "MediaTek DVFSRC regulator driver"
depends on MTK_DVFSRC
help
Say y here to control regulator by DVFSRC (dynamic voltage
and frequency scaling resource collector).
This driver supports to control regulators via the DVFSRC
of Mediatek. It allows for voting on regulator state
between multiple users.
config REGULATOR_PALMAS
tristate "TI Palmas PMIC Regulators"
depends on MFD_PALMAS
......@@ -828,6 +847,10 @@ config REGULATOR_PF8X00
Say y here to support the regulators found on the NXP
PF8100/PF8121A/PF8200 PMIC.
Say M here if you want to support for the regulators found
on the NXP PF8100/PF8121A/PF8200 PMIC. The module will be named
"pf8x00-regulator".
config REGULATOR_PFUZE100
tristate "Freescale PFUZE100/200/3000/3001 regulator driver"
depends on I2C && OF
......@@ -969,6 +992,16 @@ config REGULATOR_RT4801
This adds support for voltage regulators in Richtek RT4801 Display Bias IC.
The device supports two regulators (DSVP/DSVN).
config REGULATOR_RT4831
tristate "Richtek RT4831 DSV Regulators"
depends on MFD_RT4831
help
This adds support for voltage regulators in Richtek RT4831.
There are three regulators (VLCM/DSVP/DSVN).
VLCM is a virtual voltage input for DSVP/DSVN inside IC.
And DSVP/DSVN is the real Vout range from 4V to 6.5V.
It's common used to provide the power for the display panel.
config REGULATOR_RT5033
tristate "Richtek RT5033 Regulators"
depends on MFD_RT5033
......
......@@ -16,7 +16,6 @@ obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
obj-$(CONFIG_REGULATOR_CROS_EC) += cros-ec-regulator.o
obj-$(CONFIG_REGULATOR_CPCAP) += cpcap-regulator.o
obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o
obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
obj-$(CONFIG_REGULATOR_AB8500) += ab8500-ext.o ab8500.o
obj-$(CONFIG_REGULATOR_ACT8865) += act8865-regulator.o
obj-$(CONFIG_REGULATOR_ACT8945A) += act8945a-regulator.o
......@@ -27,6 +26,7 @@ obj-$(CONFIG_REGULATOR_ARIZONA_MICSUPP) += arizona-micsupp.o
obj-$(CONFIG_REGULATOR_ARM_SCMI) += scmi-regulator.o
obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o
obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o
obj-$(CONFIG_REGULATOR_ATC260X) += atc260x-regulator.o
obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o
obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o
obj-$(CONFIG_REGULATOR_BD70528) += bd70528-regulator.o
......@@ -89,11 +89,13 @@ obj-$(CONFIG_REGULATOR_MP8859) += mp8859.o
obj-$(CONFIG_REGULATOR_MP886X) += mp886x.o
obj-$(CONFIG_REGULATOR_MPQ7920) += mpq7920.o
obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o
obj-$(CONFIG_REGULATOR_MT6315) += mt6315-regulator.o
obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
obj-$(CONFIG_REGULATOR_MT6358) += mt6358-regulator.o
obj-$(CONFIG_REGULATOR_MT6360) += mt6360-regulator.o
obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o
obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o
obj-$(CONFIG_REGULATOR_MTK_DVFSRC) += mtk-dvfsrc-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_LABIBB) += qcom-labibb-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_RPMH) += qcom-rpmh-regulator.o
......@@ -118,6 +120,7 @@ obj-$(CONFIG_REGULATOR_RK808) += rk808-regulator.o
obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o
obj-$(CONFIG_REGULATOR_ROHM) += rohm-regulator.o
obj-$(CONFIG_REGULATOR_RT4801) += rt4801-regulator.o
obj-$(CONFIG_REGULATOR_RT4831) += rt4831-regulator.o
obj-$(CONFIG_REGULATOR_RT5033) += rt5033-regulator.o
obj-$(CONFIG_REGULATOR_RTMV20) += rtmv20-regulator.o
obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
......
This diff is collapsed.
This diff is collapsed.
......@@ -25,9 +25,123 @@
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/ab8500.h>
#include <linux/slab.h>
/* AB8500 regulators */
enum ab8500_regulator_id {
AB8500_LDO_AUX1,
AB8500_LDO_AUX2,
AB8500_LDO_AUX3,
AB8500_LDO_INTCORE,
AB8500_LDO_TVOUT,
AB8500_LDO_AUDIO,
AB8500_LDO_ANAMIC1,
AB8500_LDO_ANAMIC2,
AB8500_LDO_DMIC,
AB8500_LDO_ANA,
AB8500_NUM_REGULATORS,
};
/* AB8505 regulators */
enum ab8505_regulator_id {
AB8505_LDO_AUX1,
AB8505_LDO_AUX2,
AB8505_LDO_AUX3,
AB8505_LDO_AUX4,
AB8505_LDO_AUX5,
AB8505_LDO_AUX6,
AB8505_LDO_INTCORE,
AB8505_LDO_ADC,
AB8505_LDO_AUDIO,
AB8505_LDO_ANAMIC1,
AB8505_LDO_ANAMIC2,
AB8505_LDO_AUX8,
AB8505_LDO_ANA,
AB8505_NUM_REGULATORS,
};
/* AB8500 registers */
enum ab8500_regulator_reg {
AB8500_REGUREQUESTCTRL2,
AB8500_REGUREQUESTCTRL3,
AB8500_REGUREQUESTCTRL4,
AB8500_REGUSYSCLKREQ1HPVALID1,
AB8500_REGUSYSCLKREQ1HPVALID2,
AB8500_REGUHWHPREQ1VALID1,
AB8500_REGUHWHPREQ1VALID2,
AB8500_REGUHWHPREQ2VALID1,
AB8500_REGUHWHPREQ2VALID2,
AB8500_REGUSWHPREQVALID1,
AB8500_REGUSWHPREQVALID2,
AB8500_REGUSYSCLKREQVALID1,
AB8500_REGUSYSCLKREQVALID2,
AB8500_REGUMISC1,
AB8500_VAUDIOSUPPLY,
AB8500_REGUCTRL1VAMIC,
AB8500_VPLLVANAREGU,
AB8500_VREFDDR,
AB8500_EXTSUPPLYREGU,
AB8500_VAUX12REGU,
AB8500_VRF1VAUX3REGU,
AB8500_VAUX1SEL,
AB8500_VAUX2SEL,
AB8500_VRF1VAUX3SEL,
AB8500_REGUCTRL2SPARE,
AB8500_REGUCTRLDISCH,
AB8500_REGUCTRLDISCH2,
AB8500_NUM_REGULATOR_REGISTERS,
};
/* AB8505 registers */
enum ab8505_regulator_reg {
AB8505_REGUREQUESTCTRL1,
AB8505_REGUREQUESTCTRL2,
AB8505_REGUREQUESTCTRL3,
AB8505_REGUREQUESTCTRL4,
AB8505_REGUSYSCLKREQ1HPVALID1,
AB8505_REGUSYSCLKREQ1HPVALID2,
AB8505_REGUHWHPREQ1VALID1,
AB8505_REGUHWHPREQ1VALID2,
AB8505_REGUHWHPREQ2VALID1,
AB8505_REGUHWHPREQ2VALID2,
AB8505_REGUSWHPREQVALID1,
AB8505_REGUSWHPREQVALID2,
AB8505_REGUSYSCLKREQVALID1,
AB8505_REGUSYSCLKREQVALID2,
AB8505_REGUVAUX4REQVALID,
AB8505_REGUMISC1,
AB8505_VAUDIOSUPPLY,
AB8505_REGUCTRL1VAMIC,
AB8505_VSMPSAREGU,
AB8505_VSMPSBREGU,
AB8505_VSAFEREGU, /* NOTE! PRCMU register */
AB8505_VPLLVANAREGU,
AB8505_EXTSUPPLYREGU,
AB8505_VAUX12REGU,
AB8505_VRF1VAUX3REGU,
AB8505_VSMPSASEL1,
AB8505_VSMPSASEL2,
AB8505_VSMPSASEL3,
AB8505_VSMPSBSEL1,
AB8505_VSMPSBSEL2,
AB8505_VSMPSBSEL3,
AB8505_VSAFESEL1, /* NOTE! PRCMU register */
AB8505_VSAFESEL2, /* NOTE! PRCMU register */
AB8505_VSAFESEL3, /* NOTE! PRCMU register */
AB8505_VAUX1SEL,
AB8505_VAUX2SEL,
AB8505_VRF1VAUX3SEL,
AB8505_VAUX4REQCTRL,
AB8505_VAUX4REGU,
AB8505_VAUX4SEL,
AB8505_REGUCTRLDISCH,
AB8505_REGUCTRLDISCH2,
AB8505_REGUCTRLDISCH3,
AB8505_CTRLVAUX5,
AB8505_CTRLVAUX6,
AB8505_NUM_REGULATOR_REGISTERS,
};
/**
* struct ab8500_shared_mode - is used when mode is shared between
* two regulators.
......
This diff is collapsed.
......@@ -1070,7 +1070,7 @@ static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
static int axp20x_regulator_parse_dt(struct platform_device *pdev)
{
struct device_node *np, *regulators;
int ret;
int ret = 0;
u32 dcdcfreq = 0;
np = of_node_get(pdev->dev.parent->of_node);
......@@ -1085,13 +1085,12 @@ static int axp20x_regulator_parse_dt(struct platform_device *pdev)
ret = axp20x_set_dcdc_freq(pdev, dcdcfreq);
if (ret < 0) {
dev_err(&pdev->dev, "Error setting dcdc frequency: %d\n", ret);
return ret;
}
of_node_put(regulators);
}
return 0;
of_node_put(np);
return ret;
}
static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 workmode)
......
......@@ -244,19 +244,14 @@ static const struct regulator_desc bd70528_desc[] = {
static int bd70528_probe(struct platform_device *pdev)
{
struct rohm_regmap_dev *bd70528;
int i;
struct regulator_config config = {
.dev = pdev->dev.parent,
};
bd70528 = dev_get_drvdata(pdev->dev.parent);
if (!bd70528) {
dev_err(&pdev->dev, "No MFD driver data\n");
return -EINVAL;
}
config.regmap = bd70528->regmap;
config.regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!config.regmap)
return -ENODEV;
for (i = 0; i < ARRAY_SIZE(bd70528_desc); i++) {
struct regulator_dev *rdev;
......
......@@ -749,19 +749,14 @@ static const struct bd71828_regulator_data bd71828_rdata[] = {
static int bd71828_probe(struct platform_device *pdev)
{
struct rohm_regmap_dev *bd71828;
int i, j, ret;
struct regulator_config config = {
.dev = pdev->dev.parent,
};
bd71828 = dev_get_drvdata(pdev->dev.parent);
if (!bd71828) {
dev_err(&pdev->dev, "No MFD driver data\n");
return -EINVAL;
}
config.regmap = bd71828->regmap;
config.regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!config.regmap)
return -ENODEV;
for (i = 0; i < ARRAY_SIZE(bd71828_rdata); i++) {
struct regulator_dev *rdev;
......@@ -777,7 +772,7 @@ static int bd71828_probe(struct platform_device *pdev)
return PTR_ERR(rdev);
}
for (j = 0; j < rd->reg_init_amnt; j++) {
ret = regmap_update_bits(bd71828->regmap,
ret = regmap_update_bits(config.regmap,
rd->reg_inits[j].reg,
rd->reg_inits[j].mask,
rd->reg_inits[j].val);
......
......@@ -1554,7 +1554,7 @@ static int get_special_regulators(struct device *dev,
static int bd718xx_probe(struct platform_device *pdev)
{
struct bd718xx *mfd;
struct regmap *regmap;
struct regulator_config config = { 0 };
int i, j, err, omit_enable;
bool use_snvs;
......@@ -1563,11 +1563,10 @@ static int bd718xx_probe(struct platform_device *pdev)
enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data;
const struct regulator_ops **swops, **hwops;
mfd = dev_get_drvdata(pdev->dev.parent);
if (!mfd) {
regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!regmap) {
dev_err(&pdev->dev, "No MFD driver data\n");
err = -EINVAL;
goto err;
return -EINVAL;
}
switch (chip) {
......@@ -1590,7 +1589,7 @@ static int bd718xx_probe(struct platform_device *pdev)
}
/* Register LOCK release */
err = regmap_update_bits(mfd->chip.regmap, BD718XX_REG_REGLOCK,
err = regmap_update_bits(regmap, BD718XX_REG_REGLOCK,
(REGLOCK_PWRSEQ | REGLOCK_VREG), 0);
if (err) {
dev_err(&pdev->dev, "Failed to unlock PMIC (%d)\n", err);
......@@ -1609,8 +1608,7 @@ static int bd718xx_probe(struct platform_device *pdev)
* bit allowing HW defaults for power rails to be used
*/
if (!use_snvs) {
err = regmap_update_bits(mfd->chip.regmap,
BD718XX_REG_TRANS_COND1,
err = regmap_update_bits(regmap, BD718XX_REG_TRANS_COND1,
BD718XX_ON_REQ_POWEROFF_MASK |
BD718XX_SWRESET_POWEROFF_MASK |
BD718XX_WDOG_POWEROFF_MASK |
......@@ -1626,7 +1624,7 @@ static int bd718xx_probe(struct platform_device *pdev)
}
config.dev = pdev->dev.parent;
config.regmap = mfd->chip.regmap;
config.regmap = regmap;
/*
* There are cases when we want to leave the enable-control for
* the HW state machine and use this driver only for voltage control.
......@@ -1685,7 +1683,7 @@ static int bd718xx_probe(struct platform_device *pdev)
if (!no_enable_control && (!use_snvs ||
!rdev->constraints->always_on ||
!rdev->constraints->boot_on)) {
err = regmap_update_bits(mfd->chip.regmap, r->init.reg,
err = regmap_update_bits(regmap, r->init.reg,
r->init.mask, r->init.val);
if (err) {
dev_err(&pdev->dev,
......@@ -1695,7 +1693,7 @@ static int bd718xx_probe(struct platform_device *pdev)
}
}
for (j = 0; j < r->additional_init_amnt; j++) {
err = regmap_update_bits(mfd->chip.regmap,
err = regmap_update_bits(regmap,
r->additional_inits[j].reg,
r->additional_inits[j].mask,
r->additional_inits[j].val);
......
......@@ -1617,7 +1617,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
const char *supply_name)
{
struct regulator *regulator;
int err;
int err = 0;
if (dev) {
char buf[REG_STR_SIZE];
......@@ -1663,8 +1663,8 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
}
}
regulator->debugfs = debugfs_create_dir(supply_name,
rdev->debugfs);
if (err != -EEXIST)
regulator->debugfs = debugfs_create_dir(supply_name, rdev->debugfs);
if (!regulator->debugfs) {
rdev_dbg(rdev, "Failed to create debugfs directory\n");
} else {
......@@ -2042,7 +2042,7 @@ struct regulator *_regulator_get(struct device *dev, const char *id,
* Returns a struct regulator corresponding to the regulator producer,
* or IS_ERR() condition containing errno.
*
* Use of supply names configured via regulator_set_device_supply() is
* Use of supply names configured via set_consumer_device_supply() is
* strongly encouraged. It is recommended that the supply name used
* should match the name used for the supply and/or the relevant
* device pins in the datasheet.
......@@ -2069,7 +2069,7 @@ EXPORT_SYMBOL_GPL(regulator_get);
* regulator off for correct operation of the hardware they are
* controlling.
*
* Use of supply names configured via regulator_set_device_supply() is
* Use of supply names configured via set_consumer_device_supply() is
* strongly encouraged. It is recommended that the supply name used
* should match the name used for the supply and/or the relevant
* device pins in the datasheet.
......@@ -2095,7 +2095,7 @@ EXPORT_SYMBOL_GPL(regulator_get_exclusive);
* disrupting the operation of drivers that can handle absent
* supplies.
*
* Use of supply names configured via regulator_set_device_supply() is
* Use of supply names configured via set_consumer_device_supply() is
* strongly encouraged. It is recommended that the supply name used
* should match the name used for the supply and/or the relevant
* device pins in the datasheet.
......@@ -4153,7 +4153,11 @@ int regulator_sync_voltage(struct regulator *regulator)
if (ret < 0)
goto out;
ret = _regulator_do_set_voltage(rdev, min_uV, max_uV);
/* balance only, if regulator is coupled */
if (rdev->coupling_desc.n_coupled > 1)
ret = regulator_balance_voltage(rdev, PM_SUSPEND_ON);
else
ret = _regulator_do_set_voltage(rdev, min_uV, max_uV);
out:
regulator_unlock(rdev);
......
......@@ -550,7 +550,7 @@ static int mcp16502_probe(struct i2c_client *client,
config.regmap = rmap;
config.driver_data = mcp;
mcp->lpm = devm_gpiod_get(dev, "lpm", GPIOD_OUT_LOW);
mcp->lpm = devm_gpiod_get_optional(dev, "lpm", GPIOD_OUT_LOW);
if (IS_ERR(mcp->lpm)) {
dev_err(dev, "failed to get lpm pin: %ld\n", PTR_ERR(mcp->lpm));
return PTR_ERR(mcp->lpm);
......
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2021 MediaTek Inc.
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/mt6315-regulator.h>
#include <linux/regulator/of_regulator.h>
#include <linux/spmi.h>
#define MT6315_BUCK_MODE_AUTO 0
#define MT6315_BUCK_MODE_FORCE_PWM 1
#define MT6315_BUCK_MODE_LP 2
struct mt6315_regulator_info {
struct regulator_desc desc;
u32 status_reg;
u32 lp_mode_mask;
u32 lp_mode_shift;
};
struct mt_regulator_init_data {
u32 modeset_mask[MT6315_VBUCK_MAX];
};
struct mt6315_chip {
struct device *dev;
struct regmap *regmap;
};
#define MT_BUCK(_name, _bid, _vsel) \
[_bid] = { \
.desc = { \
.name = _name, \
.of_match = of_match_ptr(_name), \
.regulators_node = "regulators", \
.ops = &mt6315_volt_range_ops, \
.type = REGULATOR_VOLTAGE, \
.id = _bid, \
.owner = THIS_MODULE, \
.n_voltages = 0xbf, \
.linear_ranges = mt_volt_range1, \
.n_linear_ranges = ARRAY_SIZE(mt_volt_range1), \
.vsel_reg = _vsel, \
.vsel_mask = 0xff, \
.enable_reg = MT6315_BUCK_TOP_CON0, \
.enable_mask = BIT(_bid), \
.of_map_mode = mt6315_map_mode, \
}, \
.status_reg = _bid##_DBG4, \
.lp_mode_mask = BIT(_bid), \
.lp_mode_shift = _bid, \
}
static const struct linear_range mt_volt_range1[] = {
REGULATOR_LINEAR_RANGE(0, 0, 0xbf, 6250),
};
static unsigned int mt6315_map_mode(u32 mode)
{
switch (mode) {
case MT6315_BUCK_MODE_AUTO:
return REGULATOR_MODE_NORMAL;
case MT6315_BUCK_MODE_FORCE_PWM:
return REGULATOR_MODE_FAST;
case MT6315_BUCK_MODE_LP:
return REGULATOR_MODE_IDLE;
default:
return -EINVAL;
}
}
static unsigned int mt6315_regulator_get_mode(struct regulator_dev *rdev)
{
struct mt_regulator_init_data *init = rdev_get_drvdata(rdev);
const struct mt6315_regulator_info *info;
int ret, regval;
u32 modeset_mask;
info = container_of(rdev->desc, struct mt6315_regulator_info, desc);
modeset_mask = init->modeset_mask[rdev_get_id(rdev)];
ret = regmap_read(rdev->regmap, MT6315_BUCK_TOP_4PHASE_ANA_CON42, &regval);
if (ret != 0) {
dev_notice(&rdev->dev, "Failed to get mode: %d\n", ret);
return ret;
}
if ((regval & modeset_mask) == modeset_mask)
return REGULATOR_MODE_FAST;
ret = regmap_read(rdev->regmap, MT6315_BUCK_TOP_CON1, &regval);
if (ret != 0) {
dev_notice(&rdev->dev, "Failed to get lp mode: %d\n", ret);
return ret;
}
if (regval & info->lp_mode_mask)
return REGULATOR_MODE_IDLE;
else
return REGULATOR_MODE_NORMAL;
}
static int mt6315_regulator_set_mode(struct regulator_dev *rdev,
u32 mode)
{
struct mt_regulator_init_data *init = rdev_get_drvdata(rdev);
const struct mt6315_regulator_info *info;
int ret, val, curr_mode;
u32 modeset_mask;
info = container_of(rdev->desc, struct mt6315_regulator_info, desc);
modeset_mask = init->modeset_mask[rdev_get_id(rdev)];
curr_mode = mt6315_regulator_get_mode(rdev);
switch (mode) {
case REGULATOR_MODE_FAST:
ret = regmap_update_bits(rdev->regmap,
MT6315_BUCK_TOP_4PHASE_ANA_CON42,
modeset_mask,
modeset_mask);
break;
case REGULATOR_MODE_NORMAL:
if (curr_mode == REGULATOR_MODE_FAST) {
ret = regmap_update_bits(rdev->regmap,
MT6315_BUCK_TOP_4PHASE_ANA_CON42,
modeset_mask,
0);
} else if (curr_mode == REGULATOR_MODE_IDLE) {
ret = regmap_update_bits(rdev->regmap,
MT6315_BUCK_TOP_CON1,
info->lp_mode_mask,
0);
usleep_range(100, 110);
} else {
ret = -EINVAL;
}
break;
case REGULATOR_MODE_IDLE:
val = MT6315_BUCK_MODE_LP >> 1;
val <<= info->lp_mode_shift;
ret = regmap_update_bits(rdev->regmap,
MT6315_BUCK_TOP_CON1,
info->lp_mode_mask,
val);
break;
default:
ret = -EINVAL;
dev_notice(&rdev->dev, "Unsupported mode: %d\n", mode);
break;
}
if (ret != 0) {
dev_notice(&rdev->dev, "Failed to set mode: %d\n", ret);
return ret;
}
return 0;
}
static int mt6315_get_status(struct regulator_dev *rdev)
{
const struct mt6315_regulator_info *info;
int ret;
u32 regval;
info = container_of(rdev->desc, struct mt6315_regulator_info, desc);
ret = regmap_read(rdev->regmap, info->status_reg, &regval);
if (ret < 0) {
dev_notice(&rdev->dev, "Failed to get enable reg: %d\n", ret);
return ret;
}
return (regval & BIT(0)) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF;
}
static const struct regulator_ops mt6315_volt_range_ops = {
.list_voltage = regulator_list_voltage_linear_range,
.map_voltage = regulator_map_voltage_linear_range,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.get_status = mt6315_get_status,
.set_mode = mt6315_regulator_set_mode,
.get_mode = mt6315_regulator_get_mode,
};
static const struct mt6315_regulator_info mt6315_regulators[MT6315_VBUCK_MAX] = {
MT_BUCK("vbuck1", MT6315_VBUCK1, MT6315_BUCK_TOP_ELR0),
MT_BUCK("vbuck2", MT6315_VBUCK2, MT6315_BUCK_TOP_ELR2),
MT_BUCK("vbuck3", MT6315_VBUCK3, MT6315_BUCK_TOP_ELR4),
MT_BUCK("vbuck4", MT6315_VBUCK4, MT6315_BUCK_TOP_ELR6),
};
static const struct regmap_config mt6315_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
.max_register = 0x16d0,
.fast_io = true,
};
static const struct of_device_id mt6315_of_match[] = {
{
.compatible = "mediatek,mt6315-regulator",
}, {
/* sentinel */
},
};
MODULE_DEVICE_TABLE(of, mt6315_of_match);
static int mt6315_regulator_probe(struct spmi_device *pdev)
{
struct device *dev = &pdev->dev;
struct regmap *regmap;
struct mt6315_chip *chip;
struct mt_regulator_init_data *init_data;
struct regulator_config config = {};
struct regulator_dev *rdev;
int i;
regmap = devm_regmap_init_spmi_ext(pdev, &mt6315_regmap_config);
if (!regmap)
return -ENODEV;
chip = devm_kzalloc(dev, sizeof(struct mt6315_chip), GFP_KERNEL);
if (!chip)
return -ENOMEM;
init_data = devm_kzalloc(dev, sizeof(struct mt_regulator_init_data), GFP_KERNEL);
if (!init_data)
return -ENOMEM;
switch (pdev->usid) {
case MT6315_PP:
init_data->modeset_mask[MT6315_VBUCK1] = BIT(MT6315_VBUCK1) | BIT(MT6315_VBUCK2) |
BIT(MT6315_VBUCK4);
break;
case MT6315_SP:
case MT6315_RP:
init_data->modeset_mask[MT6315_VBUCK1] = BIT(MT6315_VBUCK1) | BIT(MT6315_VBUCK2);
break;
default:
init_data->modeset_mask[MT6315_VBUCK1] = BIT(MT6315_VBUCK1);
break;
}
for (i = MT6315_VBUCK2; i < MT6315_VBUCK_MAX; i++)
init_data->modeset_mask[i] = BIT(i);
chip->dev = dev;
chip->regmap = regmap;
dev_set_drvdata(dev, chip);
config.dev = dev;
config.regmap = regmap;
for (i = MT6315_VBUCK1; i < MT6315_VBUCK_MAX; i++) {
config.driver_data = init_data;
rdev = devm_regulator_register(dev, &mt6315_regulators[i].desc, &config);
if (IS_ERR(rdev)) {
dev_notice(dev, "Failed to register %s\n", mt6315_regulators[i].desc.name);
continue;
}
}
return 0;
}
static void mt6315_regulator_shutdown(struct spmi_device *pdev)
{
struct mt6315_chip *chip = dev_get_drvdata(&pdev->dev);
int ret = 0;
ret |= regmap_write(chip->regmap, MT6315_TOP_TMA_KEY_H, PROTECTION_KEY_H);
ret |= regmap_write(chip->regmap, MT6315_TOP_TMA_KEY, PROTECTION_KEY);
ret |= regmap_update_bits(chip->regmap, MT6315_TOP2_ELR7, 1, 1);
ret |= regmap_write(chip->regmap, MT6315_TOP_TMA_KEY, 0);
ret |= regmap_write(chip->regmap, MT6315_TOP_TMA_KEY_H, 0);
if (ret < 0)
dev_notice(&pdev->dev, "[%#x] Failed to enable power off sequence. %d\n",
pdev->usid, ret);
}
static struct spmi_driver mt6315_regulator_driver = {
.driver = {
.name = "mt6315-regulator",
.of_match_table = mt6315_of_match,
},
.probe = mt6315_regulator_probe,
.shutdown = mt6315_regulator_shutdown,
};
module_spmi_driver(mt6315_regulator_driver);
MODULE_AUTHOR("Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>");
MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6315 PMIC");
MODULE_LICENSE("GPL");
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2020 MediaTek Inc.
#include <linux/err.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
#include <linux/soc/mediatek/mtk_dvfsrc.h>
#define DVFSRC_ID_VCORE 0
#define DVFSRC_ID_VSCP 1
#define MT_DVFSRC_REGULAR(match, _name, _volt_table) \
[DVFSRC_ID_##_name] = { \
.desc = { \
.name = match, \
.of_match = of_match_ptr(match), \
.ops = &dvfsrc_vcore_ops, \
.type = REGULATOR_VOLTAGE, \
.id = DVFSRC_ID_##_name, \
.owner = THIS_MODULE, \
.n_voltages = ARRAY_SIZE(_volt_table), \
.volt_table = _volt_table, \
}, \
}
/*
* DVFSRC regulators' information
*
* @desc: standard fields of regulator description.
* @voltage_selector: Selector used for get_voltage_sel() and
* set_voltage_sel() callbacks
*/
struct dvfsrc_regulator {
struct regulator_desc desc;
};
/*
* MTK DVFSRC regulators' init data
*
* @size: num of regulators
* @regulator_info: regulator info.
*/
struct dvfsrc_regulator_init_data {
u32 size;
struct dvfsrc_regulator *regulator_info;
};
static inline struct device *to_dvfsrc_dev(struct regulator_dev *rdev)
{
return rdev_get_dev(rdev)->parent;
}
static int dvfsrc_set_voltage_sel(struct regulator_dev *rdev,
unsigned int selector)
{
struct device *dvfsrc_dev = to_dvfsrc_dev(rdev);
int id = rdev_get_id(rdev);
if (id == DVFSRC_ID_VCORE)
mtk_dvfsrc_send_request(dvfsrc_dev,
MTK_DVFSRC_CMD_VCORE_REQUEST,
selector);
else if (id == DVFSRC_ID_VSCP)
mtk_dvfsrc_send_request(dvfsrc_dev,
MTK_DVFSRC_CMD_VSCP_REQUEST,
selector);
else
return -EINVAL;
return 0;
}
static int dvfsrc_get_voltage_sel(struct regulator_dev *rdev)
{
struct device *dvfsrc_dev = to_dvfsrc_dev(rdev);
int id = rdev_get_id(rdev);
int val, ret;
if (id == DVFSRC_ID_VCORE)
ret = mtk_dvfsrc_query_info(dvfsrc_dev,
MTK_DVFSRC_CMD_VCORE_LEVEL_QUERY,
&val);
else if (id == DVFSRC_ID_VSCP)
ret = mtk_dvfsrc_query_info(dvfsrc_dev,
MTK_DVFSRC_CMD_VSCP_LEVEL_QUERY,
&val);
else
return -EINVAL;
if (ret != 0)
return ret;
return val;
}
static const struct regulator_ops dvfsrc_vcore_ops = {
.list_voltage = regulator_list_voltage_table,
.get_voltage_sel = dvfsrc_get_voltage_sel,
.set_voltage_sel = dvfsrc_set_voltage_sel,
};
static const unsigned int mt8183_voltages[] = {
725000,
800000,
};
static struct dvfsrc_regulator mt8183_regulators[] = {
MT_DVFSRC_REGULAR("dvfsrc-vcore", VCORE,
mt8183_voltages),
};
static const struct dvfsrc_regulator_init_data regulator_mt8183_data = {
.size = ARRAY_SIZE(mt8183_regulators),
.regulator_info = &mt8183_regulators[0],
};
static const unsigned int mt6873_voltages[] = {
575000,
600000,
650000,
725000,
};
static struct dvfsrc_regulator mt6873_regulators[] = {
MT_DVFSRC_REGULAR("dvfsrc-vcore", VCORE,
mt6873_voltages),
MT_DVFSRC_REGULAR("dvfsrc-vscp", VSCP,
mt6873_voltages),
};
static const struct dvfsrc_regulator_init_data regulator_mt6873_data = {
.size = ARRAY_SIZE(mt6873_regulators),
.regulator_info = &mt6873_regulators[0],
};
static const struct of_device_id mtk_dvfsrc_regulator_match[] = {
{
.compatible = "mediatek,mt8183-dvfsrc",
.data = &regulator_mt8183_data,
}, {
.compatible = "mediatek,mt8192-dvfsrc",
.data = &regulator_mt6873_data,
}, {
.compatible = "mediatek,mt6873-dvfsrc",
.data = &regulator_mt6873_data,
}, {
/* sentinel */
},
};
MODULE_DEVICE_TABLE(of, mtk_dvfsrc_regulator_match);
static int dvfsrc_vcore_regulator_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
struct device *dev = &pdev->dev;
struct regulator_config config = { };
struct regulator_dev *rdev;
const struct dvfsrc_regulator_init_data *regulator_init_data;
struct dvfsrc_regulator *mt_regulators;
int i;
match = of_match_node(mtk_dvfsrc_regulator_match, dev->parent->of_node);
if (!match) {
dev_err(dev, "invalid compatible string\n");
return -ENODEV;
}
regulator_init_data = match->data;
mt_regulators = regulator_init_data->regulator_info;
for (i = 0; i < regulator_init_data->size; i++) {
config.dev = dev->parent;
config.driver_data = (mt_regulators + i);
rdev = devm_regulator_register(dev->parent,
&(mt_regulators + i)->desc,
&config);
if (IS_ERR(rdev)) {
dev_err(dev, "failed to register %s\n",
(mt_regulators + i)->desc.name);
return PTR_ERR(rdev);
}
}
return 0;
}
static struct platform_driver mtk_dvfsrc_regulator_driver = {
.driver = {
.name = "mtk-dvfsrc-regulator",
},
.probe = dvfsrc_vcore_regulator_probe,
};
static int __init mtk_dvfsrc_regulator_init(void)
{
return platform_driver_register(&mtk_dvfsrc_regulator_driver);
}
subsys_initcall(mtk_dvfsrc_regulator_init);
static void __exit mtk_dvfsrc_regulator_exit(void)
{
platform_driver_unregister(&mtk_dvfsrc_regulator_driver);
}
module_exit(mtk_dvfsrc_regulator_exit);
MODULE_AUTHOR("Arvin wang <arvin.wang@mediatek.com>");
MODULE_LICENSE("GPL v2");
......@@ -5,6 +5,7 @@
*/
#include <linux/err.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
......@@ -32,6 +33,7 @@ struct pca9450_regulator_desc {
struct pca9450 {
struct device *dev;
struct regmap *regmap;
struct gpio_desc *sd_vsel_gpio;
enum pca9450_chip_type type;
unsigned int rcnt;
int irq;
......@@ -795,6 +797,26 @@ static int pca9450_i2c_probe(struct i2c_client *i2c,
return ret;
}
/* Set reset behavior on assertion of WDOG_B signal */
ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_RESET_CTRL,
WDOG_B_CFG_MASK, WDOG_B_CFG_COLD_LDO12);
if (ret) {
dev_err(&i2c->dev, "Failed to set WDOG_B reset behavior\n");
return ret;
}
/*
* The driver uses the LDO5CTRL_H register to control the LDO5 regulator.
* This is only valid if the SD_VSEL input of the PMIC is high. Let's
* check if the pin is available as GPIO and set it to high.
*/
pca9450->sd_vsel_gpio = gpiod_get_optional(pca9450->dev, "sd-vsel", GPIOD_OUT_HIGH);
if (IS_ERR(pca9450->sd_vsel_gpio)) {
dev_err(&i2c->dev, "Failed to get SD_VSEL GPIO\n");
return ret;
}
dev_info(&i2c->dev, "%s probed.\n",
type == PCA9450_TYPE_PCA9450A ? "pca9450a" : "pca9450bc");
......
This diff is collapsed.
This diff is collapsed.
......@@ -732,6 +732,15 @@ static const struct rpmh_vreg_hw_data pmic5_hfsmps515 = {
.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
};
static const struct rpmh_vreg_hw_data pmic5_hfsmps515_1 = {
.regulator_type = VRM,
.ops = &rpmh_regulator_vrm_ops,
.voltage_range = REGULATOR_LINEAR_RANGE(900000, 0, 4, 16000),
.n_voltages = 5,
.pmic_mode_map = pmic_mode_map_pmic5_smps,
.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
};
static const struct rpmh_vreg_hw_data pmic5_bob = {
.regulator_type = VRM,
.ops = &rpmh_regulator_vrm_bypass_ops,
......@@ -932,6 +941,19 @@ static const struct rpmh_vreg_init_data pm8009_vreg_data[] = {
{},
};
static const struct rpmh_vreg_init_data pm8009_1_vreg_data[] = {
RPMH_VREG("smps1", "smp%s1", &pmic5_hfsmps510, "vdd-s1"),
RPMH_VREG("smps2", "smp%s2", &pmic5_hfsmps515_1, "vdd-s2"),
RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo, "vdd-l1"),
RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo, "vdd-l2"),
RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo, "vdd-l3"),
RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo, "vdd-l4"),
RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo, "vdd-l5-l6"),
RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo, "vdd-l5-l6"),
RPMH_VREG("ldo7", "ldo%s6", &pmic5_pldo_lv, "vdd-l7"),
{},
};
static const struct rpmh_vreg_init_data pm6150_vreg_data[] = {
RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps510, "vdd-s1"),
RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps510, "vdd-s2"),
......@@ -1057,6 +1079,10 @@ static const struct of_device_id __maybe_unused rpmh_regulator_match_table[] = {
.compatible = "qcom,pm8009-rpmh-regulators",
.data = pm8009_vreg_data,
},
{
.compatible = "qcom,pm8009-1-rpmh-regulators",
.data = pm8009_1_vreg_data,
},
{
.compatible = "qcom,pm8150-rpmh-regulators",
.data = pm8150_vreg_data,
......@@ -1089,6 +1115,14 @@ static const struct of_device_id __maybe_unused rpmh_regulator_match_table[] = {
.compatible = "qcom,pm6150l-rpmh-regulators",
.data = pm6150l_vreg_data,
},
{
.compatible = "qcom,pmc8180-rpmh-regulators",
.data = pm8150_vreg_data,
},
{
.compatible = "qcom,pmc8180c-rpmh-regulators",
.data = pm8150l_vreg_data,
},
{
.compatible = "qcom,pmx55-rpmh-regulators",
.data = pmx55_vreg_data,
......
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/driver.h>
enum {
DSV_OUT_VLCM = 0,
DSV_OUT_VPOS,
DSV_OUT_VNEG,
DSV_OUT_MAX
};
#define RT4831_REG_DSVEN 0x09
#define RT4831_REG_VLCM 0x0c
#define RT4831_REG_VPOS 0x0d
#define RT4831_REG_VNEG 0x0e
#define RT4831_REG_FLAGS 0x0f
#define RT4831_VOLT_MASK GENMASK(5, 0)
#define RT4831_DSVMODE_SHIFT 5
#define RT4831_DSVMODE_MASK GENMASK(7, 5)
#define RT4831_POSADEN_MASK BIT(4)
#define RT4831_NEGADEN_MASK BIT(3)
#define RT4831_POSEN_MASK BIT(2)
#define RT4831_NEGEN_MASK BIT(1)
#define RT4831_OTP_MASK BIT(6)
#define RT4831_LCMOVP_MASK BIT(5)
#define RT4831_VPOSSCP_MASK BIT(3)
#define RT4831_VNEGSCP_MASK BIT(2)
#define DSV_MODE_NORMAL (0x4 << RT4831_DSVMODE_SHIFT)
#define DSV_MODE_BYPASS (0x6 << RT4831_DSVMODE_SHIFT)
#define STEP_UV 50000
#define VLCM_MIN_UV 4000000
#define VLCM_MAX_UV 7150000
#define VLCM_N_VOLTAGES ((VLCM_MAX_UV - VLCM_MIN_UV) / STEP_UV + 1)
#define VPN_MIN_UV 4000000
#define VPN_MAX_UV 6500000
#define VPN_N_VOLTAGES ((VPN_MAX_UV - VPN_MIN_UV) / STEP_UV + 1)
static int rt4831_get_error_flags(struct regulator_dev *rdev, unsigned int *flags)
{
struct regmap *regmap = rdev_get_regmap(rdev);
int rid = rdev_get_id(rdev);
unsigned int val, events = 0;
int ret;
ret = regmap_read(regmap, RT4831_REG_FLAGS, &val);
if (ret)
return ret;
if (val & RT4831_OTP_MASK)
events |= REGULATOR_ERROR_OVER_TEMP;
if (rid == DSV_OUT_VLCM && (val & RT4831_LCMOVP_MASK))
events |= REGULATOR_ERROR_OVER_CURRENT;
if (rid == DSV_OUT_VPOS && (val & RT4831_VPOSSCP_MASK))
events |= REGULATOR_ERROR_OVER_CURRENT;
if (rid == DSV_OUT_VNEG && (val & RT4831_VNEGSCP_MASK))
events |= REGULATOR_ERROR_OVER_CURRENT;
*flags = events;
return 0;
}
static const struct regulator_ops rt4831_dsvlcm_ops = {
.list_voltage = regulator_list_voltage_linear,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_bypass = regulator_set_bypass_regmap,
.get_bypass = regulator_get_bypass_regmap,
.get_error_flags = rt4831_get_error_flags,
};
static const struct regulator_ops rt4831_dsvpn_ops = {
.list_voltage = regulator_list_voltage_linear,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.set_active_discharge = regulator_set_active_discharge_regmap,
.get_error_flags = rt4831_get_error_flags,
};
static const struct regulator_desc rt4831_regulator_descs[] = {
{
.name = "DSVLCM",
.ops = &rt4831_dsvlcm_ops,
.of_match = of_match_ptr("DSVLCM"),
.regulators_node = of_match_ptr("regulators"),
.type = REGULATOR_VOLTAGE,
.id = DSV_OUT_VLCM,
.n_voltages = VLCM_N_VOLTAGES,
.min_uV = VLCM_MIN_UV,
.uV_step = STEP_UV,
.vsel_reg = RT4831_REG_VLCM,
.vsel_mask = RT4831_VOLT_MASK,
.bypass_reg = RT4831_REG_DSVEN,
.bypass_val_on = DSV_MODE_BYPASS,
.bypass_val_off = DSV_MODE_NORMAL,
},
{
.name = "DSVP",
.ops = &rt4831_dsvpn_ops,
.of_match = of_match_ptr("DSVP"),
.regulators_node = of_match_ptr("regulators"),
.type = REGULATOR_VOLTAGE,
.id = DSV_OUT_VPOS,
.n_voltages = VPN_N_VOLTAGES,
.min_uV = VPN_MIN_UV,
.uV_step = STEP_UV,
.vsel_reg = RT4831_REG_VPOS,
.vsel_mask = RT4831_VOLT_MASK,
.enable_reg = RT4831_REG_DSVEN,
.enable_mask = RT4831_POSEN_MASK,
.active_discharge_reg = RT4831_REG_DSVEN,
.active_discharge_mask = RT4831_POSADEN_MASK,
},
{
.name = "DSVN",
.ops = &rt4831_dsvpn_ops,
.of_match = of_match_ptr("DSVN"),
.regulators_node = of_match_ptr("regulators"),
.type = REGULATOR_VOLTAGE,
.id = DSV_OUT_VNEG,
.n_voltages = VPN_N_VOLTAGES,
.min_uV = VPN_MIN_UV,
.uV_step = STEP_UV,
.vsel_reg = RT4831_REG_VNEG,
.vsel_mask = RT4831_VOLT_MASK,
.enable_reg = RT4831_REG_DSVEN,
.enable_mask = RT4831_NEGEN_MASK,
.active_discharge_reg = RT4831_REG_DSVEN,
.active_discharge_mask = RT4831_NEGADEN_MASK,
}
};
static int rt4831_regulator_probe(struct platform_device *pdev)
{
struct regmap *regmap;
struct regulator_dev *rdev;
struct regulator_config config = {};
int i, ret;
regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (IS_ERR(regmap)) {
dev_err(&pdev->dev, "Failed to init regmap\n");
return PTR_ERR(regmap);
}
/* Configure DSV mode to normal by default */
ret = regmap_update_bits(regmap, RT4831_REG_DSVEN, RT4831_DSVMODE_MASK, DSV_MODE_NORMAL);
if (ret) {
dev_err(&pdev->dev, "Failed to configure dsv mode to normal\n");
return ret;
}
config.dev = pdev->dev.parent;
config.regmap = regmap;
for (i = 0; i < DSV_OUT_MAX; i++) {
rdev = devm_regulator_register(&pdev->dev, rt4831_regulator_descs + i, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "Failed to register %d regulator\n", i);
return PTR_ERR(rdev);
}
}
return 0;
}
static const struct platform_device_id rt4831_regulator_match[] = {
{ "rt4831-regulator", 0 },
{}
};
MODULE_DEVICE_TABLE(platform, rt4831_regulator_match);
static struct platform_driver rt4831_regulator_driver = {
.driver = {
.name = "rt4831-regulator",
},
.id_table = rt4831_regulator_match,
.probe = rt4831_regulator_probe,
};
module_platform_driver(rt4831_regulator_driver);
MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");
MODULE_LICENSE("GPL v2");
......@@ -544,14 +544,18 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev,
rdata = devm_kcalloc(&pdev->dev,
pdata->num_regulators, sizeof(*rdata),
GFP_KERNEL);
if (!rdata)
if (!rdata) {
of_node_put(regulators_np);
return -ENOMEM;
}
rmode = devm_kcalloc(&pdev->dev,
pdata->num_regulators, sizeof(*rmode),
GFP_KERNEL);
if (!rmode)
if (!rmode) {
of_node_put(regulators_np);
return -ENOMEM;
}
pdata->regulators = rdata;
pdata->opmode = rmode;
......@@ -573,10 +577,13 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev,
"s5m8767,pmic-ext-control",
GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_NONEXCLUSIVE,
"s5m8767");
if (PTR_ERR(rdata->ext_control_gpiod) == -ENOENT)
if (PTR_ERR(rdata->ext_control_gpiod) == -ENOENT) {
rdata->ext_control_gpiod = NULL;
else if (IS_ERR(rdata->ext_control_gpiod))
} else if (IS_ERR(rdata->ext_control_gpiod)) {
of_node_put(reg_np);
of_node_put(regulators_np);
return PTR_ERR(rdata->ext_control_gpiod);
}
rdata->id = i;
rdata->initdata = of_get_regulator_init_data(
......
......@@ -368,7 +368,6 @@ struct ab8500 {
int it_latchhier_num;
};
struct ab8500_regulator_platform_data;
struct ab8500_codec_platform_data;
struct ab8500_sysctrl_platform_data;
......@@ -376,11 +375,9 @@ struct ab8500_sysctrl_platform_data;
* struct ab8500_platform_data - AB8500 platform data
* @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used
* @init: board-specific initialization after detection of ab8500
* @regulator: machine-specific constraints for regulators
*/
struct ab8500_platform_data {
void (*init) (struct ab8500 *);
struct ab8500_regulator_platform_data *regulator;
struct ab8500_codec_platform_data *codec;
struct ab8500_sysctrl_platform_data *sysctrl;
};
......
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) ST-Ericsson SA 2010
*
* Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson
* Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson
* Daniel Willerud <daniel.willerud@stericsson.com> for ST-Ericsson
*/
#ifndef __LINUX_MFD_AB8500_REGULATOR_H
#define __LINUX_MFD_AB8500_REGULATOR_H
#include <linux/platform_device.h>
/* AB8500 regulators */
enum ab8500_regulator_id {
AB8500_LDO_AUX1,
AB8500_LDO_AUX2,
AB8500_LDO_AUX3,
AB8500_LDO_INTCORE,
AB8500_LDO_TVOUT,
AB8500_LDO_AUDIO,
AB8500_LDO_ANAMIC1,
AB8500_LDO_ANAMIC2,
AB8500_LDO_DMIC,
AB8500_LDO_ANA,
AB8500_NUM_REGULATORS,
};
/* AB8505 regulators */
enum ab8505_regulator_id {
AB8505_LDO_AUX1,
AB8505_LDO_AUX2,
AB8505_LDO_AUX3,
AB8505_LDO_AUX4,
AB8505_LDO_AUX5,
AB8505_LDO_AUX6,
AB8505_LDO_INTCORE,
AB8505_LDO_ADC,
AB8505_LDO_AUDIO,
AB8505_LDO_ANAMIC1,
AB8505_LDO_ANAMIC2,
AB8505_LDO_AUX8,
AB8505_LDO_ANA,
AB8505_NUM_REGULATORS,
};
/* AB8500 and AB8505 register initialization */
struct ab8500_regulator_reg_init {
int id;
u8 mask;
u8 value;
};
#define INIT_REGULATOR_REGISTER(_id, _mask, _value) \
{ \
.id = _id, \
.mask = _mask, \
.value = _value, \
}
/* AB8500 registers */
enum ab8500_regulator_reg {
AB8500_REGUREQUESTCTRL2,
AB8500_REGUREQUESTCTRL3,
AB8500_REGUREQUESTCTRL4,
AB8500_REGUSYSCLKREQ1HPVALID1,
AB8500_REGUSYSCLKREQ1HPVALID2,
AB8500_REGUHWHPREQ1VALID1,
AB8500_REGUHWHPREQ1VALID2,
AB8500_REGUHWHPREQ2VALID1,
AB8500_REGUHWHPREQ2VALID2,
AB8500_REGUSWHPREQVALID1,
AB8500_REGUSWHPREQVALID2,
AB8500_REGUSYSCLKREQVALID1,
AB8500_REGUSYSCLKREQVALID2,
AB8500_REGUMISC1,
AB8500_VAUDIOSUPPLY,
AB8500_REGUCTRL1VAMIC,
AB8500_VPLLVANAREGU,
AB8500_VREFDDR,
AB8500_EXTSUPPLYREGU,
AB8500_VAUX12REGU,
AB8500_VRF1VAUX3REGU,
AB8500_VAUX1SEL,
AB8500_VAUX2SEL,
AB8500_VRF1VAUX3SEL,
AB8500_REGUCTRL2SPARE,
AB8500_REGUCTRLDISCH,
AB8500_REGUCTRLDISCH2,
AB8500_NUM_REGULATOR_REGISTERS,
};
/* AB8505 registers */
enum ab8505_regulator_reg {
AB8505_REGUREQUESTCTRL1,
AB8505_REGUREQUESTCTRL2,
AB8505_REGUREQUESTCTRL3,
AB8505_REGUREQUESTCTRL4,
AB8505_REGUSYSCLKREQ1HPVALID1,
AB8505_REGUSYSCLKREQ1HPVALID2,
AB8505_REGUHWHPREQ1VALID1,
AB8505_REGUHWHPREQ1VALID2,
AB8505_REGUHWHPREQ2VALID1,
AB8505_REGUHWHPREQ2VALID2,
AB8505_REGUSWHPREQVALID1,
AB8505_REGUSWHPREQVALID2,
AB8505_REGUSYSCLKREQVALID1,
AB8505_REGUSYSCLKREQVALID2,
AB8505_REGUVAUX4REQVALID,
AB8505_REGUMISC1,
AB8505_VAUDIOSUPPLY,
AB8505_REGUCTRL1VAMIC,
AB8505_VSMPSAREGU,
AB8505_VSMPSBREGU,
AB8505_VSAFEREGU, /* NOTE! PRCMU register */
AB8505_VPLLVANAREGU,
AB8505_EXTSUPPLYREGU,
AB8505_VAUX12REGU,
AB8505_VRF1VAUX3REGU,
AB8505_VSMPSASEL1,
AB8505_VSMPSASEL2,
AB8505_VSMPSASEL3,
AB8505_VSMPSBSEL1,
AB8505_VSMPSBSEL2,
AB8505_VSMPSBSEL3,
AB8505_VSAFESEL1, /* NOTE! PRCMU register */
AB8505_VSAFESEL2, /* NOTE! PRCMU register */
AB8505_VSAFESEL3, /* NOTE! PRCMU register */
AB8505_VAUX1SEL,
AB8505_VAUX2SEL,
AB8505_VRF1VAUX3SEL,
AB8505_VAUX4REQCTRL,
AB8505_VAUX4REGU,
AB8505_VAUX4SEL,
AB8505_REGUCTRLDISCH,
AB8505_REGUCTRLDISCH2,
AB8505_REGUCTRLDISCH3,
AB8505_CTRLVAUX5,
AB8505_CTRLVAUX6,
AB8505_NUM_REGULATOR_REGISTERS,
};
/* AB8500 external regulators */
struct ab8500_ext_regulator_cfg {
bool hwreq; /* requires hw mode or high power mode */
};
enum ab8500_ext_regulator_id {
AB8500_EXT_SUPPLY1,
AB8500_EXT_SUPPLY2,
AB8500_EXT_SUPPLY3,
AB8500_NUM_EXT_REGULATORS,
};
/* AB8500 regulator platform data */
struct ab8500_regulator_platform_data {
int num_reg_init;
struct ab8500_regulator_reg_init *reg_init;
int num_regulator;
struct regulator_init_data *regulator;
int num_ext_regulator;
struct regulator_init_data *ext_regulator;
};
#endif
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2021 MediaTek Inc.
*/
#ifndef __LINUX_REGULATOR_MT6315_H
#define __LINUX_REGULATOR_MT6315_H
#define MT6315_RP 3
#define MT6315_PP 6
#define MT6315_SP 7
enum {
MT6315_VBUCK1 = 0,
MT6315_VBUCK2,
MT6315_VBUCK3,
MT6315_VBUCK4,
MT6315_VBUCK_MAX,
};
/* Register */
#define MT6315_TOP2_ELR7 0x139
#define MT6315_TOP_TMA_KEY 0x39F
#define MT6315_TOP_TMA_KEY_H 0x3A0
#define MT6315_BUCK_TOP_CON0 0x1440
#define MT6315_BUCK_TOP_CON1 0x1443
#define MT6315_BUCK_TOP_ELR0 0x1449
#define MT6315_BUCK_TOP_ELR2 0x144B
#define MT6315_BUCK_TOP_ELR4 0x144D
#define MT6315_BUCK_TOP_ELR6 0x144F
#define MT6315_VBUCK1_DBG0 0x1499
#define MT6315_VBUCK1_DBG4 0x149D
#define MT6315_VBUCK2_DBG0 0x1519
#define MT6315_VBUCK2_DBG4 0x151D
#define MT6315_VBUCK3_DBG0 0x1599
#define MT6315_VBUCK3_DBG4 0x159D
#define MT6315_VBUCK4_DBG0 0x1619
#define MT6315_VBUCK4_DBG4 0x161D
#define MT6315_BUCK_TOP_4PHASE_ANA_CON42 0x16B1
#define PROTECTION_KEY_H 0x9C
#define PROTECTION_KEY 0xEA
#endif /* __LINUX_REGULATOR_MT6315_H */
......@@ -216,4 +216,11 @@ enum {
#define IRQ_THERM_105 0x02
#define IRQ_THERM_125 0x01
/* PCA9450_REG_RESET_CTRL bits */
#define WDOG_B_CFG_MASK 0xC0
#define WDOG_B_CFG_NONE 0x00
#define WDOG_B_CFG_WARM 0x40
#define WDOG_B_CFG_COLD_LDO12 0x80
#define WDOG_B_CFG_COLD 0xC0
#endif /* __LINUX_REG_PCA9450_H__ */
......@@ -128,7 +128,7 @@ EXPORT_SYMBOL_GPL(linear_range_get_value_array);
* @selector: address where found selector value is updated
* @found: flag to indicate that given value was in the range
*
* Return selector which which range value is closest match for given
* Return selector for which range value is closest match for given
* input value. Value is matching if it is equal or smaller than given
* value. If given value is in the range, then @found is set true.
*
......@@ -168,11 +168,11 @@ EXPORT_SYMBOL_GPL(linear_range_get_selector_low);
* @selector: address where found selector value is updated
* @found: flag to indicate that given value was in the range
*
* Scan array of ranges for selector which which range value matches given
* Scan array of ranges for selector for which range value matches given
* input value. Value is matching if it is equal or smaller than given
* value. If given value is found to be in a range scanning is stopped and
* @found is set true. If a range with values smaller than given value is found
* but the range max is being smaller than given value, then the ranges
* but the range max is being smaller than given value, then the range's
* biggest selector is updated to @selector but scanning ranges is continued
* and @found is set to false.
*
......@@ -209,7 +209,7 @@ EXPORT_SYMBOL_GPL(linear_range_get_selector_low_array);
* @selector: address where found selector value is updated
* @found: flag to indicate that given value was in the range
*
* Return selector which which range value is closest match for given
* Return selector for which range value is closest match for given
* input value. Value is matching if it is equal or higher than given
* value. If given value is in the range, then @found is set true.
*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment