Commit c10383b3 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull regulator updates from Mark Brown:
 "The main core change this release is generic support for handling of
  hardware errors from Matti Vaittinen, including some small updates to
  the reboot and thermal code so we can share support for powering off
  the system if things are going wrong enough.

  Otherwise this release we've mainly seen the addition of new drivers,
  including MT6359 which has pulled in some small changes from the MFD
  tree for build dependencies.

   - Support for controlling the trigger points for hardware error
     detection, and shared handlers for this.

   - Support for Maxim MAX8993, Mediatek MT6359 and MT6359P, Qualcomm
     PM8226 and SA8115P-ADP, and Sylergy TCS4526"

* tag 'regulator-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (91 commits)
  regulator: bd9576: Fix uninitializes variable may_have_irqs
  regulator: max8893: Select REGMAP_I2C to fix build error
  regulator: da9052: Ensure enough delay time for .set_voltage_time_sel
  regulator: mt6358: Fix vdram2 .vsel_mask
  regulator: hi6421v600: Fix setting wrong driver_data
  MAINTAINERS: Add reviewer for regulator irq_helpers
  regulator: bd9576: Fix the driver name in id table
  regulator: bd9576: Support error reporting
  regulator: bd9576 add FET ON-resistance for OCW
  regulator: add property parsing and callbacks to set protection limits
  regulator: IRQ based event/error notification helpers
  regulator: move rdev_print helpers to internal.h
  regulator: add warning flags
  thermal: Use generic HW-protection shutdown API
  reboot: Add hardware protection power-off
  regulator: Add protection limit properties
  regulator: hi6421v600: Fix setting idle mode
  regulator: Add MAX8893 bindings
  regulator: max8893: add regulator driver
  regulator: hi6421: Use correct variable type for regmap api val argument
  ...
parents 52f8cf8b 7fb593cb
......@@ -21,6 +21,7 @@ Required properties:
compatible:
"mediatek,mt6323" for PMIC MT6323
"mediatek,mt6358" for PMIC MT6358
"mediatek,mt6359" for PMIC MT6359
"mediatek,mt6397" for PMIC MT6397
Optional subnodes:
......
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/max8893.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Regulator driver for MAX8893 PMIC from Maxim Integrated.
maintainers:
- Sergey Larin <cerg2010cerg2010@mail.ru>
description: |
The device has 5 LDO regulators and a single BUCK regulator.
Programming is done through I2C bus.
properties:
compatible:
const: maxim,max8893
reg:
maxItems: 1
regulators:
type: object
patternProperties:
"^(ldo[1-5]|buck)$":
$ref: "regulator.yaml#"
additionalProperties: false
additionalProperties: false
required:
- compatible
- reg
- regulators
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
pmic@3e {
compatible = "maxim,max8893";
reg = <0x3e>;
regulators {
/* Front camera - s5k6aafx, back - m5mo */
/* Numbers used to indicate the sequence */
front_1_back_1: buck {
regulator-name = "cam_isp_core_1v2";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
};
front_4_back_5: ldo1 {
regulator-name = "vt_io_1v8,cam_isp_1v8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
front_3_back_4: ldo2 {
regulator-name = "vt_core_1v5";
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <1500000>;
};
front_5_back_6: ldo3 {
regulator-name = "vt_cam_1v8,vt_sensor_io_1v8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
ldo4 {
/* not used */
};
back_7: ldo5 {
regulator-name = "cam_sensor_io_1v8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
};
};
};
...
......@@ -33,6 +33,9 @@ description: |
The names used for regulator nodes must match those supported by a given
PMIC. Supported regulator node names are
For PM6150, smps1 - smps5, ldo1 - ldo19
For PM6150L, smps1 - smps8, ldo1 - ldo11, bob
For PM7325, smps1 - smps8, ldo1 - ldo19
For PM8005, smps1 - smps4
For PM8009, smps1 - smps2, ldo1 - ldo7
For PM8150, smps1 - smps10, ldo1 - ldo18
......@@ -41,15 +44,15 @@ description: |
For PM8350C, smps1 - smps10, ldo1 - ldo13, bob
For PM8998, smps1 - smps13, ldo1 - ldo28, lvs1 - lvs2
For PMI8998, bob
For PM6150, smps1 - smps5, ldo1 - ldo19
For PM6150L, smps1 - smps8, ldo1 - ldo11, bob
For PMX55, smps1 - smps7, ldo1 - ldo16
For PM7325, smps1 - smps8, ldo1 - ldo19
For PMR735A, smps1 - smps3, ldo1 - ldo7
For PMX55, smps1 - smps7, ldo1 - ldo16
properties:
compatible:
enum:
- qcom,pm6150-rpmh-regulators
- qcom,pm6150l-rpmh-regulators
- qcom,pm7325-rpmh-regulators
- qcom,pm8005-rpmh-regulators
- qcom,pm8009-rpmh-regulators
- qcom,pm8009-1-rpmh-regulators
......@@ -59,11 +62,9 @@ properties:
- qcom,pm8350c-rpmh-regulators
- qcom,pm8998-rpmh-regulators
- qcom,pmi8998-rpmh-regulators
- qcom,pm6150-rpmh-regulators
- qcom,pm6150l-rpmh-regulators
- qcom,pmx55-rpmh-regulators
- qcom,pm7325-rpmh-regulators
- qcom,pmm8155au-rpmh-regulators
- qcom,pmr735a-rpmh-regulators
- qcom,pmx55-rpmh-regulators
qcom,pmic-id:
description: |
......
......@@ -24,6 +24,10 @@ description:
For mp5496, s2
For pm8226, s1, s2, s3, s4, s5, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10,
l11, l12, l13, l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, l25,
l26, l27, l28, lvs1
For pm8841, s1, s2, s3, s4, s5, s6, s7, s8
For pm8916, s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11,
......@@ -68,6 +72,7 @@ properties:
compatible:
enum:
- qcom,rpm-mp5496-regulators
- qcom,rpm-pm8226-regulators
- qcom,rpm-pm8841-regulators
- qcom,rpm-pm8916-regulators
- qcom,rpm-pm8941-regulators
......
......@@ -117,6 +117,88 @@ properties:
description: Enable over current protection.
type: boolean
regulator-oc-protection-microamp:
description: Set over current protection limit. This is a limit where
hardware performs emergency shutdown. Zero can be passed to disable
protection and value '1' indicates that protection should be enabled but
limit setting can be omitted.
regulator-oc-error-microamp:
description: Set over current error limit. This is a limit where part of
the hardware propably is malfunctional and damage prevention is requested.
Zero can be passed to disable error detection and value '1' indicates
that detection should be enabled but limit setting can be omitted.
regulator-oc-warn-microamp:
description: Set over current warning limit. This is a limit where hardware
is assumed still to be functional but approaching limit where it gets
damaged. Recovery actions should be initiated. Zero can be passed to
disable detection and value '1' indicates that detection should
be enabled but limit setting can be omitted.
regulator-ov-protection-microvolt:
description: Set over voltage protection limit. This is a limit where
hardware performs emergency shutdown. Zero can be passed to disable
protection and value '1' indicates that protection should be enabled but
limit setting can be omitted. Limit is given as microvolt offset from
voltage set to regulator.
regulator-ov-error-microvolt:
description: Set over voltage error limit. This is a limit where part of
the hardware propably is malfunctional and damage prevention is requested
Zero can be passed to disable error detection and value '1' indicates
that detection should be enabled but limit setting can be omitted. Limit
is given as microvolt offset from voltage set to regulator.
regulator-ov-warn-microvolt:
description: Set over voltage warning limit. This is a limit where hardware
is assumed still to be functional but approaching limit where it gets
damaged. Recovery actions should be initiated. Zero can be passed to
disable detection and value '1' indicates that detection should
be enabled but limit setting can be omitted. Limit is given as microvolt
offset from voltage set to regulator.
regulator-uv-protection-microvolt:
description: Set over under voltage protection limit. This is a limit where
hardware performs emergency shutdown. Zero can be passed to disable
protection and value '1' indicates that protection should be enabled but
limit setting can be omitted. Limit is given as microvolt offset from
voltage set to regulator.
regulator-uv-error-microvolt:
description: Set under voltage error limit. This is a limit where part of
the hardware propably is malfunctional and damage prevention is requested
Zero can be passed to disable error detection and value '1' indicates
that detection should be enabled but limit setting can be omitted. Limit
is given as microvolt offset from voltage set to regulator.
regulator-uv-warn-microvolt:
description: Set over under voltage warning limit. This is a limit where
hardware is assumed still to be functional but approaching limit where
it gets damaged. Recovery actions should be initiated. Zero can be passed
to disable detection and value '1' indicates that detection should
be enabled but limit setting can be omitted. Limit is given as microvolt
offset from voltage set to regulator.
regulator-temp-protection-kelvin:
description: Set over temperature protection limit. This is a limit where
hardware performs emergency shutdown. Zero can be passed to disable
protection and value '1' indicates that protection should be enabled but
limit setting can be omitted.
regulator-temp-error-kelvin:
description: Set over temperature error limit. This is a limit where part of
the hardware propably is malfunctional and damage prevention is requested
Zero can be passed to disable error detection and value '1' indicates
that detection should be enabled but limit setting can be omitted.
regulator-temp-warn-kelvin:
description: Set over temperature warning limit. This is a limit where
hardware is assumed still to be functional but approaching limit where it
gets damaged. Recovery actions should be initiated. Zero can be passed to
disable detection and value '1' indicates that detection should
be enabled but limit setting can be omitted.
regulator-active-discharge:
description: |
tristate, enable/disable active discharge of regulators. The values are:
......
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/richtek,rt6160-regulator.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Richtek RT6160 BuckBoost converter
maintainers:
- ChiYuan Huang <cy_huang@richtek.com>
description: |
The RT6160 is a high-efficiency buck-boost converter that can provide
up to 3A output current from 2025mV to 5200mV. And it support the wide
input voltage range from 2200mV to 5500mV.
Datasheet is available at
https://www.richtek.com/assets/product_file/RT6160A/DS6160A-00.pdf
allOf:
- $ref: regulator.yaml#
properties:
compatible:
enum:
- richtek,rt6160
reg:
maxItems: 1
enable-gpios:
description: A connection of the 'enable' gpio line.
maxItems: 1
richtek,vsel-active-low:
description: |
Used to indicate the 'vsel' pin active level. if not specified, use
high active level as the default.
type: boolean
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
rt6160@75 {
compatible = "richtek,rt6160";
reg = <0x75>;
enable-gpios = <&gpio26 2 0>;
regulator-name = "rt6160-buckboost";
regulator-min-microvolt = <2025000>;
regulator-max-microvolt = <5200000>;
};
};
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/richtek,rt6245-regulator.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Richtek RT6245 High Current Voltage Regulator
maintainers:
- ChiYuan Huang <cy_huang@richtek.com>
description: |
The RT6245 is a high-performance, synchronous step-down converter
that can deliver up to 14A output current with an input supply
voltage range of 4.5V to 17V.
allOf:
- $ref: regulator.yaml#
properties:
compatible:
enum:
- richtek,rt6245
reg:
maxItems: 1
enable-gpios:
description: |
A connection of the chip 'enable' gpio line. If not provided,
it will be treat as a default-on power.
maxItems: 1
richtek,oc-level-select:
$ref: "/schemas/types.yaml#/definitions/uint8"
enum: [0, 1, 2, 3]
description: |
Over current level selection. Each respective value means the current
limit 8A, 14A, 12A, 10A. If this property is missing then keep in
in chip default.
richtek,ot-level-select:
$ref: "/schemas/types.yaml#/definitions/uint8"
enum: [0, 1, 2]
description: |
Over temperature level selection. Each respective value means the degree
150'c, 130'c, 170'c. If this property is missing then keep in chip
default.
richtek,pgdly-time-select:
$ref: "/schemas/types.yaml#/definitions/uint8"
enum: [0, 1, 2, 3]
description: |
Power good signal delay time selection. Each respective value means the
delay time 0us, 10us, 20us, 40us. If this property is missing then keep
in chip default.
richtek,switch-freq-select:
$ref: "/schemas/types.yaml#/definitions/uint8"
enum: [0, 1, 2]
description: |
Buck switch frequency selection. Each respective value means 400KHz,
800KHz, 1200KHz. If this property is missing then keep in chip default.
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
rt6245@34 {
compatible = "richtek,rt6245";
status = "okay";
reg = <0x34>;
enable-gpios = <&gpio26 2 0>;
regulator-name = "rt6245-regulator";
regulator-min-microvolt = <437500>;
regulator-max-microvolt = <1387500>;
regulator-boot-on;
};
};
......@@ -27,6 +27,12 @@ patternProperties:
Properties for single regulator.
$ref: "regulator.yaml#"
properties:
rohm,ocw-fet-ron-micro-ohms:
description: |
External FET's ON-resistance. Required if VoutS1 OCP/OCW is
to be set.
required:
- regulator-name
......
......@@ -740,21 +740,15 @@ possible.
5. thermal_emergency_poweroff
=============================
On an event of critical trip temperature crossing. Thermal framework
allows the system to shutdown gracefully by calling orderly_poweroff().
In the event of a failure of orderly_poweroff() to shut down the system
we are in danger of keeping the system alive at undesirably high
temperatures. To mitigate this high risk scenario we program a work
queue to fire after a pre-determined number of seconds to start
an emergency shutdown of the device using the kernel_power_off()
function. In case kernel_power_off() fails then finally
emergency_restart() is called in the worst case.
On an event of critical trip temperature crossing the thermal framework
shuts down the system by calling hw_protection_shutdown(). The
hw_protection_shutdown() first attempts to perform an orderly shutdown
but accepts a delay after which it proceeds doing a forced power-off
or as last resort an emergency_restart.
The delay should be carefully profiled so as to give adequate time for
orderly_poweroff(). In case of failure of an orderly_poweroff() the
emergency poweroff kicks in after the delay has elapsed and shuts down
the system.
orderly poweroff.
If set to 0 emergency poweroff will not be supported. So a carefully
profiled non-zero positive value is a must for emergency poweroff to be
triggered.
If the delay is set to 0 emergency poweroff will not be supported. So a
carefully profiled non-zero positive value is a must for emergency
poweroff to be triggered.
......@@ -19561,6 +19561,10 @@ F: include/dt-bindings/regulator/
F: include/linux/regulator/
K: regulator_get_optional
VOLTAGE AND CURRENT REGULATOR IRQ HELPERS
R: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
F: drivers/regulator/irq_helpers.c
VRF
M: David Ahern <dsahern@kernel.org>
L: netdev@vger.kernel.org
......
......@@ -5,6 +5,8 @@
#include <linux/interrupt.h>
#include <linux/mfd/mt6358/core.h>
#include <linux/mfd/mt6358/registers.h>
#include <linux/mfd/mt6359/core.h>
#include <linux/mfd/mt6359/registers.h>
#include <linux/mfd/mt6397/core.h>
#include <linux/module.h>
#include <linux/of.h>
......@@ -13,7 +15,9 @@
#include <linux/platform_device.h>
#include <linux/regmap.h>
static struct irq_top_t mt6358_ints[] = {
#define MTK_PMIC_REG_WIDTH 16
static const struct irq_top_t mt6358_ints[] = {
MT6358_TOP_GEN(BUCK),
MT6358_TOP_GEN(LDO),
MT6358_TOP_GEN(PSC),
......@@ -24,6 +28,31 @@ static struct irq_top_t mt6358_ints[] = {
MT6358_TOP_GEN(MISC),
};
static const struct irq_top_t mt6359_ints[] = {
MT6359_TOP_GEN(BUCK),
MT6359_TOP_GEN(LDO),
MT6359_TOP_GEN(PSC),
MT6359_TOP_GEN(SCK),
MT6359_TOP_GEN(BM),
MT6359_TOP_GEN(HK),
MT6359_TOP_GEN(AUD),
MT6359_TOP_GEN(MISC),
};
static struct pmic_irq_data mt6358_irqd = {
.num_top = ARRAY_SIZE(mt6358_ints),
.num_pmic_irqs = MT6358_IRQ_NR,
.top_int_status_reg = MT6358_TOP_INT_STATUS0,
.pmic_ints = mt6358_ints,
};
static struct pmic_irq_data mt6359_irqd = {
.num_top = ARRAY_SIZE(mt6359_ints),
.num_pmic_irqs = MT6359_IRQ_NR,
.top_int_status_reg = MT6359_TOP_INT_STATUS0,
.pmic_ints = mt6359_ints,
};
static void pmic_irq_enable(struct irq_data *data)
{
unsigned int hwirq = irqd_to_hwirq(data);
......@@ -62,15 +91,15 @@ static void pmic_irq_sync_unlock(struct irq_data *data)
/* Find out the IRQ group */
top_gp = 0;
while ((top_gp + 1) < irqd->num_top &&
i >= mt6358_ints[top_gp + 1].hwirq_base)
i >= irqd->pmic_ints[top_gp + 1].hwirq_base)
top_gp++;
/* Find the IRQ registers */
gp_offset = i - mt6358_ints[top_gp].hwirq_base;
int_regs = gp_offset / MT6358_REG_WIDTH;
shift = gp_offset % MT6358_REG_WIDTH;
en_reg = mt6358_ints[top_gp].en_reg +
(mt6358_ints[top_gp].en_reg_shift * int_regs);
gp_offset = i - irqd->pmic_ints[top_gp].hwirq_base;
int_regs = gp_offset / MTK_PMIC_REG_WIDTH;
shift = gp_offset % MTK_PMIC_REG_WIDTH;
en_reg = irqd->pmic_ints[top_gp].en_reg +
(irqd->pmic_ints[top_gp].en_reg_shift * int_regs);
regmap_update_bits(chip->regmap, en_reg, BIT(shift),
irqd->enable_hwirq[i] << shift);
......@@ -95,10 +124,11 @@ static void mt6358_irq_sp_handler(struct mt6397_chip *chip,
unsigned int irq_status, sta_reg, status;
unsigned int hwirq, virq;
int i, j, ret;
struct pmic_irq_data *irqd = chip->irq_data;
for (i = 0; i < mt6358_ints[top_gp].num_int_regs; i++) {
sta_reg = mt6358_ints[top_gp].sta_reg +
mt6358_ints[top_gp].sta_reg_shift * i;
for (i = 0; i < irqd->pmic_ints[top_gp].num_int_regs; i++) {
sta_reg = irqd->pmic_ints[top_gp].sta_reg +
irqd->pmic_ints[top_gp].sta_reg_shift * i;
ret = regmap_read(chip->regmap, sta_reg, &irq_status);
if (ret) {
......@@ -114,8 +144,8 @@ static void mt6358_irq_sp_handler(struct mt6397_chip *chip,
do {
j = __ffs(status);
hwirq = mt6358_ints[top_gp].hwirq_base +
MT6358_REG_WIDTH * i + j;
hwirq = irqd->pmic_ints[top_gp].hwirq_base +
MTK_PMIC_REG_WIDTH * i + j;
virq = irq_find_mapping(chip->irq_domain, hwirq);
if (virq)
......@@ -131,12 +161,12 @@ static void mt6358_irq_sp_handler(struct mt6397_chip *chip,
static irqreturn_t mt6358_irq_handler(int irq, void *data)
{
struct mt6397_chip *chip = data;
struct pmic_irq_data *mt6358_irq_data = chip->irq_data;
struct pmic_irq_data *irqd = chip->irq_data;
unsigned int bit, i, top_irq_status = 0;
int ret;
ret = regmap_read(chip->regmap,
mt6358_irq_data->top_int_status_reg,
irqd->top_int_status_reg,
&top_irq_status);
if (ret) {
dev_err(chip->dev,
......@@ -144,8 +174,8 @@ static irqreturn_t mt6358_irq_handler(int irq, void *data)
return IRQ_NONE;
}
for (i = 0; i < mt6358_irq_data->num_top; i++) {
bit = BIT(mt6358_ints[i].top_offset);
for (i = 0; i < irqd->num_top; i++) {
bit = BIT(irqd->pmic_ints[i].top_offset);
if (top_irq_status & bit) {
mt6358_irq_sp_handler(chip, i);
top_irq_status &= ~bit;
......@@ -180,17 +210,22 @@ int mt6358_irq_init(struct mt6397_chip *chip)
int i, j, ret;
struct pmic_irq_data *irqd;
irqd = devm_kzalloc(chip->dev, sizeof(*irqd), GFP_KERNEL);
if (!irqd)
return -ENOMEM;
switch (chip->chip_id) {
case MT6358_CHIP_ID:
chip->irq_data = &mt6358_irqd;
break;
chip->irq_data = irqd;
case MT6359_CHIP_ID:
chip->irq_data = &mt6359_irqd;
break;
mutex_init(&chip->irqlock);
irqd->top_int_status_reg = MT6358_TOP_INT_STATUS0;
irqd->num_pmic_irqs = MT6358_IRQ_NR;
irqd->num_top = ARRAY_SIZE(mt6358_ints);
default:
dev_err(chip->dev, "unsupported chip: 0x%x\n", chip->chip_id);
return -ENODEV;
}
mutex_init(&chip->irqlock);
irqd = chip->irq_data;
irqd->enable_hwirq = devm_kcalloc(chip->dev,
irqd->num_pmic_irqs,
sizeof(*irqd->enable_hwirq),
......@@ -207,10 +242,10 @@ int mt6358_irq_init(struct mt6397_chip *chip)
/* Disable all interrupts for initializing */
for (i = 0; i < irqd->num_top; i++) {
for (j = 0; j < mt6358_ints[i].num_int_regs; j++)
for (j = 0; j < irqd->pmic_ints[i].num_int_regs; j++)
regmap_write(chip->regmap,
mt6358_ints[i].en_reg +
mt6358_ints[i].en_reg_shift * j, 0);
irqd->pmic_ints[i].en_reg +
irqd->pmic_ints[i].en_reg_shift * j, 0);
}
chip->irq_domain = irq_domain_add_linear(chip->dev->of_node,
......
......@@ -13,9 +13,11 @@
#include <linux/mfd/core.h>
#include <linux/mfd/mt6323/core.h>
#include <linux/mfd/mt6358/core.h>
#include <linux/mfd/mt6359/core.h>
#include <linux/mfd/mt6397/core.h>
#include <linux/mfd/mt6323/registers.h>
#include <linux/mfd/mt6358/registers.h>
#include <linux/mfd/mt6359/registers.h>
#include <linux/mfd/mt6397/registers.h>
#define MT6323_RTC_BASE 0x8000
......@@ -99,6 +101,17 @@ static const struct mfd_cell mt6358_devs[] = {
},
};
static const struct mfd_cell mt6359_devs[] = {
{ .name = "mt6359-regulator", },
{
.name = "mt6359-rtc",
.num_resources = ARRAY_SIZE(mt6358_rtc_resources),
.resources = mt6358_rtc_resources,
.of_compatible = "mediatek,mt6358-rtc",
},
{ .name = "mt6359-sound", },
};
static const struct mfd_cell mt6397_devs[] = {
{
.name = "mt6397-rtc",
......@@ -149,6 +162,14 @@ static const struct chip_data mt6358_core = {
.irq_init = mt6358_irq_init,
};
static const struct chip_data mt6359_core = {
.cid_addr = MT6359_SWCID,
.cid_shift = 8,
.cells = mt6359_devs,
.cell_size = ARRAY_SIZE(mt6359_devs),
.irq_init = mt6358_irq_init,
};
static const struct chip_data mt6397_core = {
.cid_addr = MT6397_CID,
.cid_shift = 0,
......@@ -218,6 +239,9 @@ static const struct of_device_id mt6397_of_match[] = {
}, {
.compatible = "mediatek,mt6358",
.data = &mt6358_core,
}, {
.compatible = "mediatek,mt6359",
.data = &mt6359_core,
}, {
.compatible = "mediatek,mt6397",
.data = &mt6397_core,
......
......@@ -193,20 +193,10 @@ config REGULATOR_BCM590XX
BCM590xx PMUs. This will enable support for the software
controllable LDO/Switching regulators.
config REGULATOR_BD70528
tristate "ROHM BD70528 Power Regulator"
depends on MFD_ROHM_BD70528
help
This driver supports voltage regulators on ROHM BD70528 PMIC.
This will enable support for the software controllable buck
and LDO regulators.
This driver can also be built as a module. If so, the module
will be called bd70528-regulator.
config REGULATOR_BD71815
tristate "ROHM BD71815 Power Regulator"
depends on MFD_ROHM_BD71828
select REGULATOR_ROHM
help
This driver supports voltage regulators on ROHM BD71815 PMIC.
This will enable support for the software controllable buck
......@@ -588,6 +578,14 @@ config REGULATOR_MAX8660
This driver controls a Maxim 8660/8661 voltage output
regulator via I2C bus.
config REGULATOR_MAX8893
tristate "Maxim 8893 voltage regulator"
depends on I2C
select REGMAP_I2C
help
This driver controls a Maxim 8893 voltage output
regulator via I2C bus.
config REGULATOR_MAX8907
tristate "Maxim 8907 voltage regulator"
depends on MFD_MAX8907 || COMPILE_TEST
......@@ -779,6 +777,15 @@ config REGULATOR_MT6358
This driver supports the control of different power rails of device
through regulator interface.
config REGULATOR_MT6359
tristate "MediaTek MT6359 PMIC"
depends on MFD_MT6397
help
Say y here to select this option to enable the power regulator of
MediaTek MT6359 PMIC.
This driver supports the control of different power rails of device
through regulator interface.
config REGULATOR_MT6360
tristate "MT6360 SubPMIC Regulator"
depends on MFD_MT6360
......@@ -1030,6 +1037,26 @@ config REGULATOR_RT5033
RT5033 PMIC. The device supports multiple regulators like
current source, LDO and Buck.
config REGULATOR_RT6160
tristate "Richtek RT6160 BuckBoost voltage regulator"
depends on I2C
select REGMAP_I2C
help
This adds support for voltage regulator in Richtek RT6160.
This device automatically change voltage output mode from
Buck or Boost. The mode transistion depend on the input source voltage.
The wide output range is from 2025mV to 5200mV and can be used on most
common application scenario.
config REGULATOR_RT6245
tristate "Richtek RT6245 voltage regulator"
depends on I2C
select REGMAP_I2C
help
This adds supprot for Richtek RT6245 voltage regulator.
It can support up to 14A output current and adjustable output voltage
from 0.4375V to 1.3875V, per step 12.5mV.
config REGULATOR_RTMV20
tristate "Richtek RTMV20 Laser Diode Regulator"
depends on I2C
......@@ -1150,6 +1177,12 @@ config REGULATOR_STW481X_VMMC
This driver supports the internal VMMC regulator in the STw481x
PMIC chips.
config REGULATOR_SY7636A
tristate "Silergy SY7636A voltage regulator"
depends on MFD_SY7636A
help
This driver supports Silergy SY3686A voltage regulator.
config REGULATOR_SY8106A
tristate "Silergy SY8106A regulator"
depends on I2C && (OF || COMPILE_TEST)
......
......@@ -4,7 +4,7 @@
#
obj-$(CONFIG_REGULATOR) += core.o dummy.o fixed-helper.o helpers.o devres.o
obj-$(CONFIG_REGULATOR) += core.o dummy.o fixed-helper.o helpers.o devres.o irq_helpers.o
obj-$(CONFIG_OF) += of_regulator.o
obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
......@@ -29,7 +29,6 @@ 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
obj-$(CONFIG_REGULATOR_BD71815) += bd71815-regulator.o
obj-$(CONFIG_REGULATOR_BD71828) += bd71828-regulator.o
obj-$(CONFIG_REGULATOR_BD718XX) += bd718x7-regulator.o
......@@ -72,6 +71,7 @@ obj-$(CONFIG_REGULATOR_MAX77620) += max77620-regulator.o
obj-$(CONFIG_REGULATOR_MAX77650) += max77650-regulator.o
obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o
obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o
obj-$(CONFIG_REGULATOR_MAX8893) += max8893.o
obj-$(CONFIG_REGULATOR_MAX8907) += max8907-regulator.o
obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o
obj-$(CONFIG_REGULATOR_MAX8952) += max8952.o
......@@ -94,6 +94,7 @@ 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_MT6359) += mt6359-regulator.o
obj-$(CONFIG_REGULATOR_MT6360) += mt6360-regulator.o
obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o
obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o
......@@ -124,6 +125,8 @@ 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_RT6160) += rt6160-regulator.o
obj-$(CONFIG_REGULATOR_RT6245) += rt6245-regulator.o
obj-$(CONFIG_REGULATOR_RTMV20) += rtmv20-regulator.o
obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
......@@ -136,6 +139,7 @@ obj-$(CONFIG_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o
obj-$(CONFIG_REGULATOR_STM32_PWR) += stm32-pwr.o
obj-$(CONFIG_REGULATOR_STPMIC1) += stpmic1_regulator.o
obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o
obj-$(CONFIG_REGULATOR_SY7636A) += sy7636a-regulator.o
obj-$(CONFIG_REGULATOR_SY8106A) += sy8106a-regulator.o
obj-$(CONFIG_REGULATOR_SY8824X) += sy8824x.o
obj-$(CONFIG_REGULATOR_SY8827N) += sy8827n.o
......
// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2018 ROHM Semiconductors
// bd70528-regulator.c ROHM BD70528MWV regulator driver
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mfd/rohm-bd70528.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/slab.h>
#define BUCK_RAMPRATE_250MV 0
#define BUCK_RAMPRATE_125MV 1
#define BUCK_RAMP_MAX 250
static const struct linear_range bd70528_buck1_volts[] = {
REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x1, 600000),
REGULATOR_LINEAR_RANGE(2750000, 0x2, 0xf, 50000),
};
static const struct linear_range bd70528_buck2_volts[] = {
REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x1, 300000),
REGULATOR_LINEAR_RANGE(1550000, 0x2, 0xd, 50000),
REGULATOR_LINEAR_RANGE(3000000, 0xe, 0xf, 300000),
};
static const struct linear_range bd70528_buck3_volts[] = {
REGULATOR_LINEAR_RANGE(800000, 0x00, 0xd, 50000),
REGULATOR_LINEAR_RANGE(1800000, 0xe, 0xf, 0),
};
/* All LDOs have same voltage ranges */
static const struct linear_range bd70528_ldo_volts[] = {
REGULATOR_LINEAR_RANGE(1650000, 0x0, 0x07, 50000),
REGULATOR_LINEAR_RANGE(2100000, 0x8, 0x0f, 100000),
REGULATOR_LINEAR_RANGE(2850000, 0x10, 0x19, 50000),
REGULATOR_LINEAR_RANGE(3300000, 0x19, 0x1f, 0),
};
/* Also both LEDs support same voltages */
static const unsigned int led_volts[] = {
20000, 30000
};
static int bd70528_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
{
if (ramp_delay > 0 && ramp_delay <= BUCK_RAMP_MAX) {
unsigned int ramp_value = BUCK_RAMPRATE_250MV;
if (ramp_delay <= 125)
ramp_value = BUCK_RAMPRATE_125MV;
return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
BD70528_MASK_BUCK_RAMP,
ramp_value << BD70528_SIFT_BUCK_RAMP);
}
dev_err(&rdev->dev, "%s: ramp_delay: %d not supported\n",
rdev->desc->name, ramp_delay);
return -EINVAL;
}
static int bd70528_led_set_voltage_sel(struct regulator_dev *rdev,
unsigned int sel)
{
int ret;
ret = regulator_is_enabled_regmap(rdev);
if (ret < 0)
return ret;
if (ret == 0)
return regulator_set_voltage_sel_regmap(rdev, sel);
dev_err(&rdev->dev,
"LED voltage change not allowed when led is enabled\n");
return -EBUSY;
}
static const struct regulator_ops bd70528_buck_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.list_voltage = regulator_list_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,
.set_ramp_delay = bd70528_set_ramp_delay,
};
static const struct regulator_ops bd70528_ldo_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.list_voltage = regulator_list_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,
};
static const struct regulator_ops bd70528_led_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.list_voltage = regulator_list_voltage_table,
.set_voltage_sel = bd70528_led_set_voltage_sel,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
};
static const struct regulator_desc bd70528_desc[] = {
{
.name = "buck1",
.of_match = of_match_ptr("BUCK1"),
.regulators_node = of_match_ptr("regulators"),
.id = BD70528_BUCK1,
.ops = &bd70528_buck_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd70528_buck1_volts,
.n_linear_ranges = ARRAY_SIZE(bd70528_buck1_volts),
.n_voltages = BD70528_BUCK_VOLTS,
.enable_reg = BD70528_REG_BUCK1_EN,
.enable_mask = BD70528_MASK_RUN_EN,
.vsel_reg = BD70528_REG_BUCK1_VOLT,
.vsel_mask = BD70528_MASK_BUCK_VOLT,
.owner = THIS_MODULE,
},
{
.name = "buck2",
.of_match = of_match_ptr("BUCK2"),
.regulators_node = of_match_ptr("regulators"),
.id = BD70528_BUCK2,
.ops = &bd70528_buck_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd70528_buck2_volts,
.n_linear_ranges = ARRAY_SIZE(bd70528_buck2_volts),
.n_voltages = BD70528_BUCK_VOLTS,
.enable_reg = BD70528_REG_BUCK2_EN,
.enable_mask = BD70528_MASK_RUN_EN,
.vsel_reg = BD70528_REG_BUCK2_VOLT,
.vsel_mask = BD70528_MASK_BUCK_VOLT,
.owner = THIS_MODULE,
},
{
.name = "buck3",
.of_match = of_match_ptr("BUCK3"),
.regulators_node = of_match_ptr("regulators"),
.id = BD70528_BUCK3,
.ops = &bd70528_buck_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd70528_buck3_volts,
.n_linear_ranges = ARRAY_SIZE(bd70528_buck3_volts),
.n_voltages = BD70528_BUCK_VOLTS,
.enable_reg = BD70528_REG_BUCK3_EN,
.enable_mask = BD70528_MASK_RUN_EN,
.vsel_reg = BD70528_REG_BUCK3_VOLT,
.vsel_mask = BD70528_MASK_BUCK_VOLT,
.owner = THIS_MODULE,
},
{
.name = "ldo1",
.of_match = of_match_ptr("LDO1"),
.regulators_node = of_match_ptr("regulators"),
.id = BD70528_LDO1,
.ops = &bd70528_ldo_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd70528_ldo_volts,
.n_linear_ranges = ARRAY_SIZE(bd70528_ldo_volts),
.n_voltages = BD70528_LDO_VOLTS,
.enable_reg = BD70528_REG_LDO1_EN,
.enable_mask = BD70528_MASK_RUN_EN,
.vsel_reg = BD70528_REG_LDO1_VOLT,
.vsel_mask = BD70528_MASK_LDO_VOLT,
.owner = THIS_MODULE,
},
{
.name = "ldo2",
.of_match = of_match_ptr("LDO2"),
.regulators_node = of_match_ptr("regulators"),
.id = BD70528_LDO2,
.ops = &bd70528_ldo_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd70528_ldo_volts,
.n_linear_ranges = ARRAY_SIZE(bd70528_ldo_volts),
.n_voltages = BD70528_LDO_VOLTS,
.enable_reg = BD70528_REG_LDO2_EN,
.enable_mask = BD70528_MASK_RUN_EN,
.vsel_reg = BD70528_REG_LDO2_VOLT,
.vsel_mask = BD70528_MASK_LDO_VOLT,
.owner = THIS_MODULE,
},
{
.name = "ldo3",
.of_match = of_match_ptr("LDO3"),
.regulators_node = of_match_ptr("regulators"),
.id = BD70528_LDO3,
.ops = &bd70528_ldo_ops,
.type = REGULATOR_VOLTAGE,
.linear_ranges = bd70528_ldo_volts,
.n_linear_ranges = ARRAY_SIZE(bd70528_ldo_volts),
.n_voltages = BD70528_LDO_VOLTS,
.enable_reg = BD70528_REG_LDO3_EN,
.enable_mask = BD70528_MASK_RUN_EN,
.vsel_reg = BD70528_REG_LDO3_VOLT,
.vsel_mask = BD70528_MASK_LDO_VOLT,
.owner = THIS_MODULE,
},
{
.name = "ldo_led1",
.of_match = of_match_ptr("LDO_LED1"),
.regulators_node = of_match_ptr("regulators"),
.id = BD70528_LED1,
.ops = &bd70528_led_ops,
.type = REGULATOR_VOLTAGE,
.volt_table = &led_volts[0],
.n_voltages = ARRAY_SIZE(led_volts),
.enable_reg = BD70528_REG_LED_EN,
.enable_mask = BD70528_MASK_LED1_EN,
.vsel_reg = BD70528_REG_LED_VOLT,
.vsel_mask = BD70528_MASK_LED1_VOLT,
.owner = THIS_MODULE,
},
{
.name = "ldo_led2",
.of_match = of_match_ptr("LDO_LED2"),
.regulators_node = of_match_ptr("regulators"),
.id = BD70528_LED2,
.ops = &bd70528_led_ops,
.type = REGULATOR_VOLTAGE,
.volt_table = &led_volts[0],
.n_voltages = ARRAY_SIZE(led_volts),
.enable_reg = BD70528_REG_LED_EN,
.enable_mask = BD70528_MASK_LED2_EN,
.vsel_reg = BD70528_REG_LED_VOLT,
.vsel_mask = BD70528_MASK_LED2_VOLT,
.owner = THIS_MODULE,
},
};
static int bd70528_probe(struct platform_device *pdev)
{
int i;
struct regulator_config config = {
.dev = pdev->dev.parent,
};
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;
rdev = devm_regulator_register(&pdev->dev, &bd70528_desc[i],
&config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev,
"failed to register %s regulator\n",
bd70528_desc[i].name);
return PTR_ERR(rdev);
}
}
return 0;
}
static struct platform_driver bd70528_regulator = {
.driver = {
.name = "bd70528-pmic"
},
.probe = bd70528_probe,
};
module_platform_driver(bd70528_regulator);
MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
MODULE_DESCRIPTION("BD70528 voltage regulator driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:bd70528-pmic");
......@@ -13,6 +13,8 @@
#include <linux/init.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/gpio/consumer.h>
#include <linux/regulator/driver.h>
#include <linux/delay.h>
#include <linux/slab.h>
......@@ -26,14 +28,6 @@ struct bd71815_regulator {
const struct rohm_dvs_config *dvs;
};
struct bd71815_pmic {
struct bd71815_regulator descs[BD71815_REGULATOR_CNT];
struct regmap *regmap;
struct device *dev;
struct gpio_descs *gps;
struct regulator_dev *rdev[BD71815_REGULATOR_CNT];
};
static const int bd7181x_wled_currents[] = {
10, 20, 30, 50, 70, 100, 200, 300, 500, 700, 1000, 2000, 3000, 4000,
5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 13000, 14000, 15000,
......@@ -300,14 +294,13 @@ static int bd7181x_led_set_current_limit(struct regulator_dev *rdev,
static int bd7181x_buck12_get_voltage_sel(struct regulator_dev *rdev)
{
struct bd71815_pmic *pmic = rdev_get_drvdata(rdev);
int rid = rdev_get_id(rdev);
int ret, regh, regl, val;
regh = BD71815_REG_BUCK1_VOLT_H + rid * 0x2;
regl = BD71815_REG_BUCK1_VOLT_L + rid * 0x2;
ret = regmap_read(pmic->regmap, regh, &val);
ret = regmap_read(rdev->regmap, regh, &val);
if (ret)
return ret;
......@@ -319,7 +312,7 @@ static int bd7181x_buck12_get_voltage_sel(struct regulator_dev *rdev)
* by BD71815_BUCK_DVSSEL bit
*/
if ((!(val & BD71815_BUCK_STBY_DVS)) && (!(val & BD71815_BUCK_DVSSEL)))
ret = regmap_read(pmic->regmap, regl, &val);
ret = regmap_read(rdev->regmap, regl, &val);
if (ret)
return ret;
......@@ -333,14 +326,13 @@ static int bd7181x_buck12_get_voltage_sel(struct regulator_dev *rdev)
static int bd7181x_buck12_set_voltage_sel(struct regulator_dev *rdev,
unsigned int sel)
{
struct bd71815_pmic *pmic = rdev_get_drvdata(rdev);
int rid = rdev_get_id(rdev);
int ret, val, reg, regh, regl;
regh = BD71815_REG_BUCK1_VOLT_H + rid*0x2;
regl = BD71815_REG_BUCK1_VOLT_L + rid*0x2;
ret = regmap_read(pmic->regmap, regh, &val);
ret = regmap_read(rdev->regmap, regh, &val);
if (ret)
return ret;
......@@ -350,7 +342,7 @@ static int bd7181x_buck12_set_voltage_sel(struct regulator_dev *rdev,
* voltages at runtime is not supported by this driver.
*/
if (((val & BD71815_BUCK_STBY_DVS))) {
return regmap_update_bits(pmic->regmap, regh, BD71815_VOLT_MASK,
return regmap_update_bits(rdev->regmap, regh, BD71815_VOLT_MASK,
sel);
}
/* Update new voltage to the register which is not selected now */
......@@ -359,12 +351,13 @@ static int bd7181x_buck12_set_voltage_sel(struct regulator_dev *rdev,
else
reg = regh;
ret = regmap_update_bits(pmic->regmap, reg, BD71815_VOLT_MASK, sel);
ret = regmap_update_bits(rdev->regmap, reg, BD71815_VOLT_MASK, sel);
if (ret)
return ret;
/* Select the other DVS register to be used */
return regmap_update_bits(pmic->regmap, regh, BD71815_BUCK_DVSSEL, ~val);
return regmap_update_bits(rdev->regmap, regh, BD71815_BUCK_DVSSEL,
~val);
}
static const struct regulator_ops bd7181x_ldo_regulator_ops = {
......@@ -522,7 +515,7 @@ static const struct regulator_ops bd7181x_led_regulator_ops = {
.dvs = (_dvs), \
}
static struct bd71815_regulator bd71815_regulators[] = {
static const struct bd71815_regulator bd71815_regulators[] = {
BD71815_BUCK12_REG(buck1, BD71815_BUCK1, BD71815_REG_BUCK1_VOLT_H,
BD71815_REG_BUCK1_MODE, 800000, 2000000, 25000,
&buck1_dvs),
......@@ -568,24 +561,16 @@ static struct bd71815_regulator bd71815_regulators[] = {
static int bd7181x_probe(struct platform_device *pdev)
{
struct bd71815_pmic *pmic;
struct regulator_config config = {};
int i, ret;
struct gpio_desc *ldo4_en;
struct regmap *regmap;
pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
if (!pmic)
return -ENOMEM;
memcpy(pmic->descs, bd71815_regulators, sizeof(pmic->descs));
pmic->dev = &pdev->dev;
pmic->regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!pmic->regmap) {
dev_err(pmic->dev, "No parent regmap\n");
regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!regmap) {
dev_err(&pdev->dev, "No parent regmap\n");
return -ENODEV;
}
platform_set_drvdata(pdev, pmic);
ldo4_en = devm_gpiod_get_from_of_node(&pdev->dev,
pdev->dev.parent->of_node,
"rohm,vsel-gpios", 0,
......@@ -599,23 +584,23 @@ static int bd7181x_probe(struct platform_device *pdev)
}
/* Disable to go to ship-mode */
ret = regmap_update_bits(pmic->regmap, BD71815_REG_PWRCTRL,
RESTARTEN, 0);
ret = regmap_update_bits(regmap, BD71815_REG_PWRCTRL, RESTARTEN, 0);
if (ret)
return ret;
config.dev = pdev->dev.parent;
config.regmap = pmic->regmap;
config.regmap = regmap;
for (i = 0; i < BD71815_REGULATOR_CNT; i++) {
struct regulator_desc *desc;
const struct regulator_desc *desc;
struct regulator_dev *rdev;
desc = &pmic->descs[i].desc;
desc = &bd71815_regulators[i].desc;
if (i == BD71815_LDO4)
config.ena_gpiod = ldo4_en;
config.driver_data = pmic;
else
config.ena_gpiod = NULL;
rdev = devm_regulator_register(&pdev->dev, desc, &config);
if (IS_ERR(rdev)) {
......@@ -624,8 +609,6 @@ static int bd7181x_probe(struct platform_device *pdev)
desc->name);
return PTR_ERR(rdev);
}
config.ena_gpiod = NULL;
pmic->rdev[i] = rdev;
}
return 0;
}
......@@ -639,7 +622,6 @@ MODULE_DEVICE_TABLE(platform, bd7181x_pmic_id);
static struct platform_driver bd7181x_regulator = {
.driver = {
.name = "bd7181x-pmic",
.owner = THIS_MODULE,
},
.probe = bd7181x_probe,
.id_table = bd7181x_pmic_id,
......
This diff is collapsed.
This diff is collapsed.
......@@ -250,7 +250,8 @@ static int da9052_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
case DA9052_ID_BUCK3:
case DA9052_ID_LDO2:
case DA9052_ID_LDO3:
ret = (new_sel - old_sel) * info->step_uV / 6250;
ret = DIV_ROUND_UP(abs(new_sel - old_sel) * info->step_uV,
6250);
break;
}
......
......@@ -481,3 +481,55 @@ void devm_regulator_unregister_notifier(struct regulator *regulator,
WARN_ON(rc);
}
EXPORT_SYMBOL_GPL(devm_regulator_unregister_notifier);
static void regulator_irq_helper_drop(void *res)
{
regulator_irq_helper_cancel(&res);
}
/**
* devm_regulator_irq_helper - resource managed registration of IRQ based
* regulator event/error notifier
*
* @dev: device to which lifetime the helper's lifetime is
* bound.
* @d: IRQ helper descriptor.
* @irq: IRQ used to inform events/errors to be notified.
* @irq_flags: Extra IRQ flags to be OR'ed with the default
* IRQF_ONESHOT when requesting the (threaded) irq.
* @common_errs: Errors which can be flagged by this IRQ for all rdevs.
* When IRQ is re-enabled these errors will be cleared
* from all associated regulators
* @per_rdev_errs: Optional error flag array describing errors specific
* for only some of the regulators. These errors will be
* or'ed with common errors. If this is given the array
* should contain rdev_amount flags. Can be set to NULL
* if there is no regulator specific error flags for this
* IRQ.
* @rdev: Array of pointers to regulators associated with this
* IRQ.
* @rdev_amount: Amount of regulators associated with this IRQ.
*
* Return: handle to irq_helper or an ERR_PTR() encoded error code.
*/
void *devm_regulator_irq_helper(struct device *dev,
const struct regulator_irq_desc *d, int irq,
int irq_flags, int common_errs,
int *per_rdev_errs,
struct regulator_dev **rdev, int rdev_amount)
{
void *ptr;
int ret;
ptr = regulator_irq_helper(dev, d, irq, irq_flags, common_errs,
per_rdev_errs, rdev, rdev_amount);
if (IS_ERR(ptr))
return ptr;
ret = devm_add_action_or_reset(dev, regulator_irq_helper_drop, ptr);
if (ret)
return ERR_PTR(ret);
return ptr;
}
EXPORT_SYMBOL_GPL(devm_regulator_irq_helper);
......@@ -56,7 +56,6 @@
#define FAN53555_NVOLTAGES 64 /* Numbers of voltages */
#define FAN53526_NVOLTAGES 128
#define TCS_VSEL_NSEL_MASK 0x7f
#define TCS_VSEL0_MODE (1 << 7)
#define TCS_VSEL1_MODE (1 << 6)
......@@ -67,7 +66,7 @@ enum fan53555_vendor {
FAN53526_VENDOR_FAIRCHILD = 0,
FAN53555_VENDOR_FAIRCHILD,
FAN53555_VENDOR_SILERGY,
FAN53555_VENDOR_TCS,
FAN53526_VENDOR_TCS,
};
enum {
......@@ -89,6 +88,14 @@ enum {
FAN53555_CHIP_ID_08 = 8,
};
enum {
TCS4525_CHIP_ID_12 = 12,
};
enum {
TCS4526_CHIP_ID_00 = 0,
};
/* IC mask revision */
enum {
FAN53555_CHIP_REV_00 = 0x3,
......@@ -123,7 +130,8 @@ struct fan53555_device_info {
/* Slew rate */
unsigned int slew_reg;
unsigned int slew_mask;
unsigned int slew_shift;
const unsigned int *ramp_delay_table;
unsigned int n_ramp_values;
unsigned int slew_rate;
};
......@@ -197,7 +205,7 @@ static unsigned int fan53555_get_mode(struct regulator_dev *rdev)
return REGULATOR_MODE_NORMAL;
}
static const int slew_rates[] = {
static const unsigned int slew_rates[] = {
64000,
32000,
16000,
......@@ -208,51 +216,13 @@ static const int slew_rates[] = {
500,
};
static const int tcs_slew_rates[] = {
static const unsigned int tcs_slew_rates[] = {
18700,
9300,
4600,
2300,
};
static int fan53555_set_ramp(struct regulator_dev *rdev, int ramp)
{
struct fan53555_device_info *di = rdev_get_drvdata(rdev);
int regval = -1, i;
const int *slew_rate_t;
int slew_rate_n;
switch (di->vendor) {
case FAN53526_VENDOR_FAIRCHILD:
case FAN53555_VENDOR_FAIRCHILD:
case FAN53555_VENDOR_SILERGY:
slew_rate_t = slew_rates;
slew_rate_n = ARRAY_SIZE(slew_rates);
break;
case FAN53555_VENDOR_TCS:
slew_rate_t = tcs_slew_rates;
slew_rate_n = ARRAY_SIZE(tcs_slew_rates);
break;
default:
return -EINVAL;
}
for (i = 0; i < slew_rate_n; i++) {
if (ramp <= slew_rate_t[i])
regval = i;
else
break;
}
if (regval < 0) {
dev_err(di->dev, "unsupported ramp value %d\n", ramp);
return -EINVAL;
}
return regmap_update_bits(rdev->regmap, di->slew_reg,
di->slew_mask, regval << di->slew_shift);
}
static const struct regulator_ops fan53555_regulator_ops = {
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
......@@ -265,7 +235,7 @@ static const struct regulator_ops fan53555_regulator_ops = {
.is_enabled = regulator_is_enabled_regmap,
.set_mode = fan53555_set_mode,
.get_mode = fan53555_get_mode,
.set_ramp_delay = fan53555_set_ramp,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
.set_suspend_enable = fan53555_set_suspend_enable,
.set_suspend_disable = fan53555_set_suspend_disable,
};
......@@ -293,6 +263,10 @@ static int fan53526_voltages_setup_fairchild(struct fan53555_device_info *di)
return -EINVAL;
}
di->slew_reg = FAN53555_CONTROL;
di->slew_mask = CTL_SLEW_MASK;
di->ramp_delay_table = slew_rates;
di->n_ramp_values = ARRAY_SIZE(slew_rates);
di->vsel_count = FAN53526_NVOLTAGES;
return 0;
......@@ -337,7 +311,8 @@ static int fan53555_voltages_setup_fairchild(struct fan53555_device_info *di)
}
di->slew_reg = FAN53555_CONTROL;
di->slew_mask = CTL_SLEW_MASK;
di->slew_shift = CTL_SLEW_SHIFT;
di->ramp_delay_table = slew_rates;
di->n_ramp_values = ARRAY_SIZE(slew_rates);
di->vsel_count = FAN53555_NVOLTAGES;
return 0;
......@@ -358,24 +333,33 @@ static int fan53555_voltages_setup_silergy(struct fan53555_device_info *di)
return -EINVAL;
}
di->slew_reg = FAN53555_CONTROL;
di->slew_reg = FAN53555_CONTROL;
di->slew_mask = CTL_SLEW_MASK;
di->slew_shift = CTL_SLEW_SHIFT;
di->ramp_delay_table = slew_rates;
di->n_ramp_values = ARRAY_SIZE(slew_rates);
di->vsel_count = FAN53555_NVOLTAGES;
return 0;
}
static int fan53555_voltages_setup_tcs(struct fan53555_device_info *di)
static int fan53526_voltages_setup_tcs(struct fan53555_device_info *di)
{
di->slew_reg = TCS4525_TIME;
di->slew_mask = TCS_SLEW_MASK;
di->slew_shift = TCS_SLEW_MASK;
/* Init voltage range and step */
di->vsel_min = 600000;
di->vsel_step = 6250;
di->vsel_count = FAN53526_NVOLTAGES;
switch (di->chip_id) {
case TCS4525_CHIP_ID_12:
case TCS4526_CHIP_ID_00:
di->slew_reg = TCS4525_TIME;
di->slew_mask = TCS_SLEW_MASK;
di->ramp_delay_table = tcs_slew_rates;
di->n_ramp_values = ARRAY_SIZE(tcs_slew_rates);
/* Init voltage range and step */
di->vsel_min = 600000;
di->vsel_step = 6250;
di->vsel_count = FAN53526_NVOLTAGES;
break;
default:
dev_err(di->dev, "Chip ID %d not supported!\n", di->chip_id);
return -EINVAL;
}
return 0;
}
......@@ -409,7 +393,7 @@ static int fan53555_device_setup(struct fan53555_device_info *di,
return -EINVAL;
}
break;
case FAN53555_VENDOR_TCS:
case FAN53526_VENDOR_TCS:
switch (pdata->sleep_vsel_id) {
case FAN53555_VSEL_ID_0:
di->sleep_reg = TCS4525_VSEL0;
......@@ -448,7 +432,7 @@ static int fan53555_device_setup(struct fan53555_device_info *di,
di->mode_reg = di->vol_reg;
di->mode_mask = VSEL_MODE;
break;
case FAN53555_VENDOR_TCS:
case FAN53526_VENDOR_TCS:
di->mode_reg = TCS4525_COMMAND;
switch (pdata->sleep_vsel_id) {
......@@ -476,8 +460,8 @@ static int fan53555_device_setup(struct fan53555_device_info *di,
case FAN53555_VENDOR_SILERGY:
ret = fan53555_voltages_setup_silergy(di);
break;
case FAN53555_VENDOR_TCS:
ret = fan53555_voltages_setup_tcs(di);
case FAN53526_VENDOR_TCS:
ret = fan53526_voltages_setup_tcs(di);
break;
default:
dev_err(di->dev, "vendor %d not supported!\n", di->vendor);
......@@ -504,6 +488,10 @@ static int fan53555_regulator_register(struct fan53555_device_info *di,
rdesc->uV_step = di->vsel_step;
rdesc->vsel_reg = di->vol_reg;
rdesc->vsel_mask = di->vsel_count - 1;
rdesc->ramp_reg = di->slew_reg;
rdesc->ramp_mask = di->slew_mask;
rdesc->ramp_delay_table = di->ramp_delay_table;
rdesc->n_ramp_values = di->n_ramp_values;
rdesc->owner = THIS_MODULE;
rdev = devm_regulator_register(di->dev, &di->desc, config);
......@@ -552,7 +540,10 @@ static const struct of_device_id __maybe_unused fan53555_dt_ids[] = {
.data = (void *)FAN53555_VENDOR_SILERGY,
}, {
.compatible = "tcs,tcs4525",
.data = (void *)FAN53555_VENDOR_TCS
.data = (void *)FAN53526_VENDOR_TCS
}, {
.compatible = "tcs,tcs4526",
.data = (void *)FAN53526_VENDOR_TCS
},
{ }
};
......@@ -660,7 +651,10 @@ static const struct i2c_device_id fan53555_id[] = {
.driver_data = FAN53555_VENDOR_SILERGY
}, {
.name = "tcs4525",
.driver_data = FAN53555_VENDOR_TCS
.driver_data = FAN53526_VENDOR_TCS
}, {
.name = "tcs4526",
.driver_data = FAN53526_VENDOR_TCS
},
{ },
};
......
......@@ -79,7 +79,7 @@ static const struct regulator_desc fan53880_regulators[] = {
.n_linear_ranges = 2,
.n_voltages = 0xf8,
.vsel_reg = FAN53880_BUCKVOUT,
.vsel_mask = 0x7f,
.vsel_mask = 0xff,
.enable_reg = FAN53880_ENABLE,
.enable_mask = 0x10,
.enable_time = 480,
......@@ -114,8 +114,7 @@ static const struct regmap_config fan53880_regmap = {
.max_register = FAN53880_ENABLE_BOOST,
};
static int fan53880_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int fan53880_i2c_probe(struct i2c_client *i2c)
{
struct regulator_config config = { };
struct regulator_dev *rdev;
......@@ -177,7 +176,7 @@ static struct i2c_driver fan53880_regulator_driver = {
.name = "fan53880",
.of_match_table = of_match_ptr(fan53880_dt_ids),
},
.probe = fan53880_i2c_probe,
.probe_new = fan53880_i2c_probe,
.id_table = fan53880_i2c_id,
};
module_i2c_driver(fan53880_regulator_driver);
......
......@@ -276,7 +276,8 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
*/
cfg.ena_gpiod = gpiod_get_optional(&pdev->dev, NULL, gflags);
if (IS_ERR(cfg.ena_gpiod))
return PTR_ERR(cfg.ena_gpiod);
return dev_err_probe(&pdev->dev, PTR_ERR(cfg.ena_gpiod),
"can't get GPIO\n");
cfg.dev = &pdev->dev;
cfg.init_data = config->init_data;
......
......@@ -386,7 +386,7 @@ static int hi6421_regulator_enable(struct regulator_dev *rdev)
static unsigned int hi6421_regulator_ldo_get_mode(struct regulator_dev *rdev)
{
struct hi6421_regulator_info *info = rdev_get_drvdata(rdev);
u32 reg_val;
unsigned int reg_val;
regmap_read(rdev->regmap, rdev->desc->enable_reg, &reg_val);
if (reg_val & info->mode_mask)
......@@ -398,7 +398,7 @@ static unsigned int hi6421_regulator_ldo_get_mode(struct regulator_dev *rdev)
static unsigned int hi6421_regulator_buck_get_mode(struct regulator_dev *rdev)
{
struct hi6421_regulator_info *info = rdev_get_drvdata(rdev);
u32 reg_val;
unsigned int reg_val;
regmap_read(rdev->regmap, rdev->desc->enable_reg, &reg_val);
if (reg_val & info->mode_mask)
......@@ -411,7 +411,7 @@ static int hi6421_regulator_ldo_set_mode(struct regulator_dev *rdev,
unsigned int mode)
{
struct hi6421_regulator_info *info = rdev_get_drvdata(rdev);
u32 new_mode;
unsigned int new_mode;
switch (mode) {
case REGULATOR_MODE_NORMAL:
......@@ -435,7 +435,7 @@ static int hi6421_regulator_buck_set_mode(struct regulator_dev *rdev,
unsigned int mode)
{
struct hi6421_regulator_info *info = rdev_get_drvdata(rdev);
u32 new_mode;
unsigned int new_mode;
switch (mode) {
case REGULATOR_MODE_NORMAL:
......
......@@ -16,14 +16,15 @@
#include <linux/regulator/driver.h>
#include <linux/spmi.h>
struct hi6421_spmi_reg_priv {
/* Serialize regulator enable logic */
struct mutex enable_mutex;
};
struct hi6421_spmi_reg_info {
struct regulator_desc desc;
struct hi6421_spmi_pmic *pmic;
u8 eco_mode_mask;
u32 eco_uA;
/* Serialize regulator enable logic */
struct mutex enable_mutex;
};
static const unsigned int ldo3_voltages[] = {
......@@ -97,41 +98,31 @@ static const unsigned int ldo34_voltages[] = {
static int hi6421_spmi_regulator_enable(struct regulator_dev *rdev)
{
struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev);
struct hi6421_spmi_pmic *pmic = sreg->pmic;
struct hi6421_spmi_reg_priv *priv;
int ret;
priv = dev_get_drvdata(rdev->dev.parent);
/* cannot enable more than one regulator at one time */
mutex_lock(&sreg->enable_mutex);
mutex_lock(&priv->enable_mutex);
ret = regmap_update_bits(pmic->regmap, rdev->desc->enable_reg,
ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
rdev->desc->enable_mask,
rdev->desc->enable_mask);
/* Avoid powering up multiple devices at the same time */
usleep_range(rdev->desc->off_on_delay, rdev->desc->off_on_delay + 60);
mutex_unlock(&sreg->enable_mutex);
mutex_unlock(&priv->enable_mutex);
return ret;
}
static int hi6421_spmi_regulator_disable(struct regulator_dev *rdev)
{
struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev);
struct hi6421_spmi_pmic *pmic = sreg->pmic;
return regmap_update_bits(pmic->regmap, rdev->desc->enable_reg,
rdev->desc->enable_mask, 0);
}
static unsigned int hi6421_spmi_regulator_get_mode(struct regulator_dev *rdev)
{
struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev);
struct hi6421_spmi_pmic *pmic = sreg->pmic;
u32 reg_val;
unsigned int reg_val;
regmap_read(pmic->regmap, rdev->desc->enable_reg, &reg_val);
regmap_read(rdev->regmap, rdev->desc->enable_reg, &reg_val);
if (reg_val & sreg->eco_mode_mask)
return REGULATOR_MODE_IDLE;
......@@ -143,21 +134,23 @@ static int hi6421_spmi_regulator_set_mode(struct regulator_dev *rdev,
unsigned int mode)
{
struct hi6421_spmi_reg_info *sreg = rdev_get_drvdata(rdev);
struct hi6421_spmi_pmic *pmic = sreg->pmic;
u32 val;
unsigned int val;
switch (mode) {
case REGULATOR_MODE_NORMAL:
val = 0;
break;
case REGULATOR_MODE_IDLE:
val = sreg->eco_mode_mask << (ffs(sreg->eco_mode_mask) - 1);
if (!sreg->eco_mode_mask)
return -EINVAL;
val = sreg->eco_mode_mask;
break;
default:
return -EINVAL;
}
return regmap_update_bits(pmic->regmap, rdev->desc->enable_reg,
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
sreg->eco_mode_mask, val);
}
......@@ -177,9 +170,9 @@ hi6421_spmi_regulator_get_optimum_mode(struct regulator_dev *rdev,
static const struct regulator_ops hi6421_spmi_ldo_rops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = hi6421_spmi_regulator_enable,
.disable = hi6421_spmi_regulator_disable,
.disable = regulator_disable_regmap,
.list_voltage = regulator_list_voltage_table,
.map_voltage = regulator_map_voltage_iterate,
.map_voltage = regulator_map_voltage_ascend,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_mode = hi6421_spmi_regulator_get_mode,
......@@ -238,7 +231,7 @@ static int hi6421_spmi_regulator_probe(struct platform_device *pdev)
{
struct device *pmic_dev = pdev->dev.parent;
struct regulator_config config = { };
struct hi6421_spmi_reg_info *sreg;
struct hi6421_spmi_reg_priv *priv;
struct hi6421_spmi_reg_info *info;
struct device *dev = &pdev->dev;
struct hi6421_spmi_pmic *pmic;
......@@ -254,18 +247,18 @@ static int hi6421_spmi_regulator_probe(struct platform_device *pdev)
if (WARN_ON(!pmic))
return -ENODEV;
sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL);
if (!sreg)
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
sreg->pmic = pmic;
mutex_init(&sreg->enable_mutex);
mutex_init(&priv->enable_mutex);
platform_set_drvdata(pdev, priv);
for (i = 0; i < ARRAY_SIZE(regulator_info); i++) {
info = &regulator_info[i];
config.dev = pdev->dev.parent;
config.driver_data = sreg;
config.driver_data = info;
config.regmap = pmic->regmap;
rdev = devm_regulator_register(dev, &info->desc, &config);
......
......@@ -72,7 +72,7 @@ enum hi655x_regulator_id {
static int hi655x_is_enabled(struct regulator_dev *rdev)
{
unsigned int value = 0;
struct hi655x_regulator *regulator = rdev_get_drvdata(rdev);
const struct hi655x_regulator *regulator = rdev_get_drvdata(rdev);
regmap_read(rdev->regmap, regulator->status_reg, &value);
return (value & rdev->desc->enable_mask);
......@@ -80,7 +80,7 @@ static int hi655x_is_enabled(struct regulator_dev *rdev)
static int hi655x_disable(struct regulator_dev *rdev)
{
struct hi655x_regulator *regulator = rdev_get_drvdata(rdev);
const struct hi655x_regulator *regulator = rdev_get_drvdata(rdev);
return regmap_write(rdev->regmap, regulator->disable_reg,
rdev->desc->enable_mask);
......@@ -169,7 +169,6 @@ static const struct hi655x_regulator regulators[] = {
static int hi655x_regulator_probe(struct platform_device *pdev)
{
unsigned int i;
struct hi655x_regulator *regulator;
struct hi655x_pmic *pmic;
struct regulator_config config = { };
struct regulator_dev *rdev;
......@@ -180,22 +179,17 @@ static int hi655x_regulator_probe(struct platform_device *pdev)
return -ENODEV;
}
regulator = devm_kzalloc(&pdev->dev, sizeof(*regulator), GFP_KERNEL);
if (!regulator)
return -ENOMEM;
platform_set_drvdata(pdev, regulator);
config.dev = pdev->dev.parent;
config.regmap = pmic->regmap;
config.driver_data = regulator;
for (i = 0; i < ARRAY_SIZE(regulators); i++) {
config.driver_data = (void *) &regulators[i];
rdev = devm_regulator_register(&pdev->dev,
&regulators[i].rdesc,
&config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
regulator->rdesc.name);
regulators[i].rdesc.name);
return PTR_ERR(rdev);
}
}
......
......@@ -15,6 +15,17 @@
#define REGULATOR_STATES_NUM (PM_SUSPEND_MAX + 1)
#define rdev_crit(rdev, fmt, ...) \
pr_crit("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
#define rdev_err(rdev, fmt, ...) \
pr_err("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
#define rdev_warn(rdev, fmt, ...) \
pr_warn("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
#define rdev_info(rdev, fmt, ...) \
pr_info("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
#define rdev_dbg(rdev, fmt, ...) \
pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
struct regulator_voltage {
int min_uV;
int max_uV;
......
This diff is collapsed.
......@@ -136,52 +136,9 @@ static unsigned int lp8755_buck_get_mode(struct regulator_dev *rdev)
return 0;
}
static int lp8755_buck_set_ramp(struct regulator_dev *rdev, int ramp)
{
int ret;
unsigned int regval = 0x00;
enum lp8755_bucks id = rdev_get_id(rdev);
/* uV/us */
switch (ramp) {
case 0 ... 230:
regval = 0x07;
break;
case 231 ... 470:
regval = 0x06;
break;
case 471 ... 940:
regval = 0x05;
break;
case 941 ... 1900:
regval = 0x04;
break;
case 1901 ... 3800:
regval = 0x03;
break;
case 3801 ... 7500:
regval = 0x02;
break;
case 7501 ... 15000:
regval = 0x01;
break;
case 15001 ... 30000:
regval = 0x00;
break;
default:
dev_err(&rdev->dev,
"Not supported ramp value %d %s\n", ramp, __func__);
return -EINVAL;
}
ret = regmap_update_bits(rdev->regmap, 0x07 + id, 0x07, regval);
if (ret < 0)
goto err_i2c;
return ret;
err_i2c:
dev_err(&rdev->dev, "i2c access error %s\n", __func__);
return ret;
}
static const unsigned int lp8755_buck_ramp_table[] = {
30000, 15000, 7500, 3800, 1900, 940, 470, 230
};
static const struct regulator_ops lp8755_buck_ops = {
.map_voltage = regulator_map_voltage_linear,
......@@ -194,7 +151,7 @@ static const struct regulator_ops lp8755_buck_ops = {
.enable_time = lp8755_buck_enable_time,
.set_mode = lp8755_buck_set_mode,
.get_mode = lp8755_buck_get_mode,
.set_ramp_delay = lp8755_buck_set_ramp,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
};
#define lp8755_rail(_id) "lp8755_buck"#_id
......@@ -269,6 +226,10 @@ static int lp8755_init_data(struct lp8755_chip *pchip)
.enable_mask = LP8755_BUCK_EN_M,\
.vsel_reg = LP8755_REG_BUCK##_id,\
.vsel_mask = LP8755_BUCK_VOUT_M,\
.ramp_reg = (LP8755_BUCK##_id) + 0x7,\
.ramp_mask = 0x7,\
.ramp_delay_table = lp8755_buck_ramp_table,\
.n_ramp_values = ARRAY_SIZE(lp8755_buck_ramp_table),\
}
static const struct regulator_desc lp8755_regulators[] = {
......
......@@ -54,6 +54,11 @@
#define LTC3589_VCCR_SW3_GO BIT(4)
#define LTC3589_VCCR_LDO2_GO BIT(6)
#define LTC3589_VRRCR_SW1_RAMP_MASK GENMASK(1, 0)
#define LTC3589_VRRCR_SW2_RAMP_MASK GENMASK(3, 2)
#define LTC3589_VRRCR_SW3_RAMP_MASK GENMASK(5, 4)
#define LTC3589_VRRCR_LDO2_RAMP_MASK GENMASK(7, 6)
enum ltc3589_variant {
LTC3589,
LTC3589_1,
......@@ -88,27 +93,9 @@ static const int ltc3589_12_ldo4[] = {
1200000, 1800000, 2500000, 3200000,
};
static int ltc3589_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
{
struct ltc3589 *ltc3589 = rdev_get_drvdata(rdev);
int sel, shift;
if (unlikely(ramp_delay <= 0))
return -EINVAL;
/* VRRCR slew rate offsets are the same as VCCR go bit offsets */
shift = ffs(rdev->desc->apply_bit) - 1;
/* The slew rate can be set to 0.88, 1.75, 3.5, or 7 mV/uS */
for (sel = 0; sel < 4; sel++) {
if ((880 << sel) >= ramp_delay) {
return regmap_update_bits(ltc3589->regmap,
LTC3589_VRRCR,
0x3 << shift, sel << shift);
}
}
return -EINVAL;
}
static const unsigned int ltc3589_ramp_table[] = {
880, 1750, 3500, 7000
};
static int ltc3589_set_suspend_voltage(struct regulator_dev *rdev, int uV)
{
......@@ -149,7 +136,7 @@ static const struct regulator_ops ltc3589_linear_regulator_ops = {
.list_voltage = regulator_list_voltage_linear,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_ramp_delay = ltc3589_set_ramp_delay,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_suspend_voltage = ltc3589_set_suspend_voltage,
.set_suspend_mode = ltc3589_set_suspend_mode,
......@@ -218,16 +205,13 @@ static int ltc3589_of_parse_cb(struct device_node *np,
return 0;
}
#define LTC3589_REG(_name, _of_name, _ops, en_bit, dtv1_reg, dtv_mask, go_bit)\
#define LTC3589_REG(_name, _of_name, _ops, en_bit, dtv1_reg, dtv_mask) \
[LTC3589_ ## _name] = { \
.name = #_name, \
.of_match = of_match_ptr(#_of_name), \
.regulators_node = of_match_ptr("regulators"), \
.of_parse_cb = ltc3589_of_parse_cb, \
.n_voltages = (dtv_mask) + 1, \
.min_uV = (go_bit) ? 362500 : 0, \
.uV_step = (go_bit) ? 12500 : 0, \
.ramp_delay = (go_bit) ? 1750 : 0, \
.fixed_uV = (dtv_mask) ? 0 : 800000, \
.ops = &ltc3589_ ## _ops ## _regulator_ops, \
.type = REGULATOR_VOLTAGE, \
......@@ -235,30 +219,49 @@ static int ltc3589_of_parse_cb(struct device_node *np,
.owner = THIS_MODULE, \
.vsel_reg = (dtv1_reg), \
.vsel_mask = (dtv_mask), \
.apply_reg = (go_bit) ? LTC3589_VCCR : 0, \
.apply_bit = (go_bit), \
.enable_reg = (en_bit) ? LTC3589_OVEN : 0, \
.enable_mask = (en_bit), \
}
#define LTC3589_LINEAR_REG(_name, _of_name, _dtv1) \
LTC3589_REG(_name, _of_name, linear, LTC3589_OVEN_ ## _name, \
LTC3589_ ## _dtv1, 0x1f, \
LTC3589_VCCR_ ## _name ## _GO)
[LTC3589_ ## _name] = { \
.name = #_name, \
.of_match = of_match_ptr(#_of_name), \
.regulators_node = of_match_ptr("regulators"), \
.of_parse_cb = ltc3589_of_parse_cb, \
.n_voltages = 32, \
.min_uV = 362500, \
.uV_step = 12500, \
.ramp_delay = 1750, \
.ops = &ltc3589_linear_regulator_ops, \
.type = REGULATOR_VOLTAGE, \
.id = LTC3589_ ## _name, \
.owner = THIS_MODULE, \
.vsel_reg = LTC3589_ ## _dtv1, \
.vsel_mask = 0x1f, \
.apply_reg = LTC3589_VCCR, \
.apply_bit = LTC3589_VCCR_ ## _name ## _GO, \
.enable_reg = LTC3589_OVEN, \
.enable_mask = (LTC3589_OVEN_ ## _name), \
.ramp_reg = LTC3589_VRRCR, \
.ramp_mask = LTC3589_VRRCR_ ## _name ## _RAMP_MASK, \
.ramp_delay_table = ltc3589_ramp_table, \
.n_ramp_values = ARRAY_SIZE(ltc3589_ramp_table), \
}
#define LTC3589_FIXED_REG(_name, _of_name) \
LTC3589_REG(_name, _of_name, fixed, LTC3589_OVEN_ ## _name, 0, 0, 0)
LTC3589_REG(_name, _of_name, fixed, LTC3589_OVEN_ ## _name, 0, 0)
static const struct regulator_desc ltc3589_regulators[] = {
LTC3589_LINEAR_REG(SW1, sw1, B1DTV1),
LTC3589_LINEAR_REG(SW2, sw2, B2DTV1),
LTC3589_LINEAR_REG(SW3, sw3, B3DTV1),
LTC3589_FIXED_REG(BB_OUT, bb-out),
LTC3589_REG(LDO1, ldo1, fixed_standby, 0, 0, 0, 0),
LTC3589_REG(LDO1, ldo1, fixed_standby, 0, 0, 0),
LTC3589_LINEAR_REG(LDO2, ldo2, L2DTV1),
LTC3589_FIXED_REG(LDO3, ldo3),
LTC3589_REG(LDO4, ldo4, table, LTC3589_OVEN_LDO4, LTC3589_L2DTV2,
0x60, 0),
LTC3589_REG(LDO4, ldo4, table, LTC3589_OVEN_LDO4, LTC3589_L2DTV2, 0x60),
};
static bool ltc3589_writeable_reg(struct device *dev, unsigned int reg)
......
......@@ -67,13 +67,6 @@
#define MAX77686_REGULATORS MAX77686_REG_MAX
#define MAX77686_LDOS 26
enum max77686_ramp_rate {
RAMP_RATE_13P75MV,
RAMP_RATE_27P5MV,
RAMP_RATE_55MV,
RAMP_RATE_NO_CTRL, /* 100mV/us */
};
struct max77686_data {
struct device *dev;
DECLARE_BITMAP(gpio_enabled, MAX77686_REGULATORS);
......@@ -220,31 +213,6 @@ static int max77686_enable(struct regulator_dev *rdev)
max77686->opmode[id] << shift);
}
static int max77686_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
{
unsigned int ramp_value = RAMP_RATE_NO_CTRL;
switch (ramp_delay) {
case 1 ... 13750:
ramp_value = RAMP_RATE_13P75MV;
break;
case 13751 ... 27500:
ramp_value = RAMP_RATE_27P5MV;
break;
case 27501 ... 55000:
ramp_value = RAMP_RATE_55MV;
break;
case 55001 ... 100000:
break;
default:
pr_warn("%s: ramp_delay: %d not supported, setting 100000\n",
rdev->desc->name, ramp_delay);
}
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
MAX77686_RAMP_RATE_MASK, ramp_value << 6);
}
static int max77686_of_parse_cb(struct device_node *np,
const struct regulator_desc *desc,
struct regulator_config *config)
......@@ -284,6 +252,10 @@ static int max77686_of_parse_cb(struct device_node *np,
return 0;
}
static const unsigned int max77686_buck_dvs_ramp_table[] = {
13750, 27500, 55000, 100000
};
static const struct regulator_ops max77686_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
......@@ -330,7 +302,7 @@ static const struct regulator_ops max77686_buck_dvs_ops = {
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_ramp_delay = max77686_set_ramp_delay,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
.set_suspend_disable = max77686_set_suspend_disable,
};
......@@ -462,6 +434,10 @@ static const struct regulator_ops max77686_buck_dvs_ops = {
.enable_reg = MAX77686_REG_BUCK2CTRL1 + (num - 2) * 10, \
.enable_mask = MAX77686_OPMODE_MASK \
<< MAX77686_OPMODE_BUCK234_SHIFT, \
.ramp_reg = MAX77686_REG_BUCK2CTRL1 + (num - 2) * 10, \
.ramp_mask = MAX77686_RAMP_RATE_MASK, \
.ramp_delay_table = max77686_buck_dvs_ramp_table, \
.n_ramp_values = ARRAY_SIZE(max77686_buck_dvs_ramp_table), \
}
static const struct regulator_desc regulators[] = {
......
......@@ -43,15 +43,14 @@
#define MAX77802_OFF_PWRREQ 0x1
#define MAX77802_LP_PWRREQ 0x2
/* MAX77802 has two register formats: 2-bit and 4-bit */
static const unsigned int ramp_table_77802_2bit[] = {
static const unsigned int max77802_buck234_ramp_table[] = {
12500,
25000,
50000,
100000,
};
static unsigned int ramp_table_77802_4bit[] = {
static const unsigned int max77802_buck16_ramp_table[] = {
1000, 2000, 3030, 4000,
5000, 5880, 7140, 8330,
9090, 10000, 11110, 12500,
......@@ -221,58 +220,6 @@ static int max77802_enable(struct regulator_dev *rdev)
max77802->opmode[id] << shift);
}
static int max77802_find_ramp_value(struct regulator_dev *rdev,
const unsigned int limits[], int size,
unsigned int ramp_delay)
{
int i;
for (i = 0; i < size; i++) {
if (ramp_delay <= limits[i])
return i;
}
/* Use maximum value for no ramp control */
dev_warn(&rdev->dev, "%s: ramp_delay: %d not supported, setting 100000\n",
rdev->desc->name, ramp_delay);
return size - 1;
}
/* Used for BUCKs 2-4 */
static int max77802_set_ramp_delay_2bit(struct regulator_dev *rdev,
int ramp_delay)
{
int id = rdev_get_id(rdev);
unsigned int ramp_value;
if (id > MAX77802_BUCK4) {
dev_warn(&rdev->dev,
"%s: regulator: ramp delay not supported\n",
rdev->desc->name);
return -EINVAL;
}
ramp_value = max77802_find_ramp_value(rdev, ramp_table_77802_2bit,
ARRAY_SIZE(ramp_table_77802_2bit), ramp_delay);
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
MAX77802_RAMP_RATE_MASK_2BIT,
ramp_value << MAX77802_RAMP_RATE_SHIFT_2BIT);
}
/* For BUCK1, 6 */
static int max77802_set_ramp_delay_4bit(struct regulator_dev *rdev,
int ramp_delay)
{
unsigned int ramp_value;
ramp_value = max77802_find_ramp_value(rdev, ramp_table_77802_4bit,
ARRAY_SIZE(ramp_table_77802_4bit), ramp_delay);
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
MAX77802_RAMP_RATE_MASK_4BIT,
ramp_value << MAX77802_RAMP_RATE_SHIFT_4BIT);
}
/*
* LDOs 2, 4-19, 22-35
*/
......@@ -316,7 +263,7 @@ static const struct regulator_ops max77802_buck_16_dvs_ops = {
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_ramp_delay = max77802_set_ramp_delay_4bit,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
.set_suspend_disable = max77802_set_suspend_disable,
};
......@@ -330,7 +277,7 @@ static const struct regulator_ops max77802_buck_234_ops = {
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_ramp_delay = max77802_set_ramp_delay_2bit,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
.set_suspend_disable = max77802_set_suspend_disable,
.set_suspend_mode = max77802_set_suspend_mode,
};
......@@ -345,7 +292,6 @@ static const struct regulator_ops max77802_buck_dvs_ops = {
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_ramp_delay = max77802_set_ramp_delay_2bit,
.set_suspend_disable = max77802_set_suspend_disable,
};
......@@ -409,6 +355,10 @@ static const struct regulator_ops max77802_buck_dvs_ops = {
.vsel_mask = MAX77802_DVS_VSEL_MASK, \
.enable_reg = MAX77802_REG_BUCK ## num ## CTRL, \
.enable_mask = MAX77802_OPMODE_MASK, \
.ramp_reg = MAX77802_REG_BUCK ## num ## CTRL, \
.ramp_mask = MAX77802_RAMP_RATE_MASK_4BIT, \
.ramp_delay_table = max77802_buck16_ramp_table, \
.n_ramp_values = ARRAY_SIZE(max77802_buck16_ramp_table), \
.of_map_mode = max77802_map_mode, \
}
......@@ -431,6 +381,10 @@ static const struct regulator_ops max77802_buck_dvs_ops = {
.enable_reg = MAX77802_REG_BUCK ## num ## CTRL1, \
.enable_mask = MAX77802_OPMODE_MASK << \
MAX77802_OPMODE_BUCK234_SHIFT, \
.ramp_reg = MAX77802_REG_BUCK ## num ## CTRL1, \
.ramp_mask = MAX77802_RAMP_RATE_MASK_2BIT, \
.ramp_delay_table = max77802_buck234_ramp_table, \
.n_ramp_values = ARRAY_SIZE(max77802_buck234_ramp_table), \
.of_map_mode = max77802_map_mode, \
}
......
// SPDX-License-Identifier: GPL-2.0+
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
static const struct regulator_ops max8893_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
};
static const struct regulator_desc max8893_regulators[] = {
{
.name = "BUCK",
.supply_name = "in-buck",
.of_match = of_match_ptr("buck"),
.regulators_node = of_match_ptr("regulators"),
.n_voltages = 0x11,
.id = 6,
.ops = &max8893_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.min_uV = 800000,
.uV_step = 100000,
.vsel_reg = 0x4,
.vsel_mask = 0x1f,
.enable_reg = 0x0,
.enable_mask = BIT(7),
},
{
.name = "LDO1",
.supply_name = "in-ldo1",
.of_match = of_match_ptr("ldo1"),
.regulators_node = of_match_ptr("regulators"),
.n_voltages = 0x12,
.id = 1,
.ops = &max8893_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.min_uV = 1600000,
.uV_step = 100000,
.vsel_reg = 0x5,
.vsel_mask = 0x1f,
.enable_reg = 0x0,
.enable_mask = BIT(5),
},
{
.name = "LDO2",
.supply_name = "in-ldo2",
.of_match = of_match_ptr("ldo2"),
.regulators_node = of_match_ptr("regulators"),
.n_voltages = 0x16,
.id = 2,
.ops = &max8893_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.min_uV = 1200000,
.uV_step = 100000,
.vsel_reg = 0x6,
.vsel_mask = 0x1f,
.enable_reg = 0x0,
.enable_mask = BIT(4),
},
{
.name = "LDO3",
.supply_name = "in-ldo3",
.of_match = of_match_ptr("ldo3"),
.regulators_node = of_match_ptr("regulators"),
.n_voltages = 0x12,
.id = 3,
.ops = &max8893_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.min_uV = 1600000,
.uV_step = 100000,
.vsel_reg = 0x7,
.vsel_mask = 0x1f,
.enable_reg = 0x0,
.enable_mask = BIT(3),
},
{
.name = "LDO4",
.supply_name = "in-ldo4",
.of_match = of_match_ptr("ldo4"),
.regulators_node = of_match_ptr("regulators"),
.n_voltages = 0x1a,
.id = 4,
.ops = &max8893_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.min_uV = 800000,
.uV_step = 100000,
.vsel_reg = 0x8,
.vsel_mask = 0x1f,
.enable_reg = 0x0,
.enable_mask = BIT(2),
},
{
.name = "LDO5",
.supply_name = "in-ldo5",
.of_match = of_match_ptr("ldo5"),
.regulators_node = of_match_ptr("regulators"),
.n_voltages = 0x1a,
.id = 5,
.ops = &max8893_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.min_uV = 800000,
.uV_step = 100000,
.vsel_reg = 0x9,
.vsel_mask = 0x1f,
.enable_reg = 0x0,
.enable_mask = BIT(1),
}
};
static const struct regmap_config max8893_regmap = {
.reg_bits = 8,
.val_bits = 8,
};
static int max8893_probe_new(struct i2c_client *i2c)
{
int id, ret;
struct regulator_config config = {.dev = &i2c->dev};
struct regmap *regmap = devm_regmap_init_i2c(i2c, &max8893_regmap);
if (IS_ERR(regmap)) {
ret = PTR_ERR(regmap);
dev_err(&i2c->dev, "regmap init failed: %d\n", ret);
return ret;
}
for (id = 0; id < ARRAY_SIZE(max8893_regulators); id++) {
struct regulator_dev *rdev;
rdev = devm_regulator_register(&i2c->dev,
&max8893_regulators[id],
&config);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(&i2c->dev, "failed to register %s: %d\n",
max8893_regulators[id].name, ret);
return ret;
}
}
return 0;
}
#ifdef CONFIG_OF
static const struct of_device_id max8893_dt_match[] = {
{ .compatible = "maxim,max8893" },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, max8893_dt_match);
#endif
static const struct i2c_device_id max8893_ids[] = {
{ "max8893", 0 },
{ },
};
MODULE_DEVICE_TABLE(i2c, max8893_ids);
static struct i2c_driver max8893_driver = {
.probe_new = max8893_probe_new,
.driver = {
.name = "max8893",
.of_match_table = of_match_ptr(max8893_dt_match),
},
.id_table = max8893_ids,
};
module_i2c_driver(max8893_driver);
MODULE_DESCRIPTION("Maxim MAX8893 PMIC driver");
MODULE_AUTHOR("Sergey Larin <cerg2010cerg2010@mail.ru>");
MODULE_LICENSE("GPL");
......@@ -265,33 +265,6 @@ static unsigned int max8973_dcdc_get_mode(struct regulator_dev *rdev)
REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
}
static int max8973_set_ramp_delay(struct regulator_dev *rdev,
int ramp_delay)
{
struct max8973_chip *max = rdev_get_drvdata(rdev);
unsigned int control;
int ret;
/* Set ramp delay */
if (ramp_delay <= 12000)
control = MAX8973_RAMP_12mV_PER_US;
else if (ramp_delay <= 25000)
control = MAX8973_RAMP_25mV_PER_US;
else if (ramp_delay <= 50000)
control = MAX8973_RAMP_50mV_PER_US;
else if (ramp_delay <= 200000)
control = MAX8973_RAMP_200mV_PER_US;
else
return -EINVAL;
ret = regmap_update_bits(max->regmap, MAX8973_CONTROL1,
MAX8973_RAMP_MASK, control);
if (ret < 0)
dev_err(max->dev, "register %d update failed, %d",
MAX8973_CONTROL1, ret);
return ret;
}
static int max8973_set_current_limit(struct regulator_dev *rdev,
int min_ua, int max_ua)
{
......@@ -341,6 +314,10 @@ static int max8973_get_current_limit(struct regulator_dev *rdev)
return 9000000;
}
static const unsigned int max8973_buck_ramp_table[] = {
12000, 25000, 50000, 200000
};
static const struct regulator_ops max8973_dcdc_ops = {
.get_voltage_sel = max8973_dcdc_get_voltage_sel,
.set_voltage_sel = max8973_dcdc_set_voltage_sel,
......@@ -348,7 +325,7 @@ static const struct regulator_ops max8973_dcdc_ops = {
.set_mode = max8973_dcdc_set_mode,
.get_mode = max8973_dcdc_get_mode,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_ramp_delay = max8973_set_ramp_delay,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
};
static int max8973_init_dcdc(struct max8973_chip *max,
......@@ -694,6 +671,10 @@ static int max8973_probe(struct i2c_client *client,
max->desc.min_uV = MAX8973_MIN_VOLATGE;
max->desc.uV_step = MAX8973_VOLATGE_STEP;
max->desc.n_voltages = MAX8973_BUCK_N_VOLTAGE;
max->desc.ramp_reg = MAX8973_CONTROL1;
max->desc.ramp_mask = MAX8973_RAMP_MASK;
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;
......
This diff is collapsed.
......@@ -67,6 +67,10 @@
.vsel_mask = MP5416_MASK_VSET, \
.enable_reg = MP5416_REG_BUCK ## _id, \
.enable_mask = MP5416_REGULATOR_EN, \
.ramp_reg = MP5416_REG_CTL2, \
.ramp_mask = MP5416_MASK_DVS_SLEWRATE, \
.ramp_delay_table = mp5416_buck_ramp_table, \
.n_ramp_values = ARRAY_SIZE(mp5416_buck_ramp_table), \
.active_discharge_on = _dval, \
.active_discharge_reg = _dreg, \
.active_discharge_mask = _dval, \
......@@ -123,7 +127,16 @@ static const unsigned int mp5416_I_limits2[] = {
2200000, 3200000, 4200000, 5200000
};
static int mp5416_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay);
/*
* DVS ramp rate BUCK1 to BUCK4
* 00: 32mV/us
* 01: 16mV/us
* 10: 8mV/us
* 11: 4mV/us
*/
static const unsigned int mp5416_buck_ramp_table[] = {
32000, 16000, 8000, 4000
};
static const struct regulator_ops mp5416_ldo_ops = {
.enable = regulator_enable_regmap,
......@@ -147,7 +160,7 @@ static const struct regulator_ops mp5416_buck_ops = {
.set_active_discharge = regulator_set_active_discharge_regmap,
.get_current_limit = regulator_get_current_limit_regmap,
.set_current_limit = regulator_set_current_limit_regmap,
.set_ramp_delay = mp5416_set_ramp_delay,
.set_ramp_delay = regulator_set_ramp_delay_regmap,
};
static struct regulator_desc mp5416_regulators_desc[MP5416_MAX_REGULATORS] = {
......@@ -161,33 +174,6 @@ static struct regulator_desc mp5416_regulators_desc[MP5416_MAX_REGULATORS] = {
MP5416LDO("ldo4", 4, BIT(1)),
};
/*
* DVS ramp rate BUCK1 to BUCK4
* 00: 32mV/us
* 01: 16mV/us
* 10: 8mV/us
* 11: 4mV/us
*/
static int mp5416_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
{
unsigned int ramp_val;
if (ramp_delay > 32000 || ramp_delay < 0)
return -EINVAL;
if (ramp_delay <= 4000)
ramp_val = 3;
else if (ramp_delay <= 8000)
ramp_val = 2;
else if (ramp_delay <= 16000)
ramp_val = 1;
else
ramp_val = 0;
return regmap_update_bits(rdev->regmap, MP5416_REG_CTL2,
MP5416_MASK_DVS_SLEWRATE, ramp_val << 6);
}
static int mp5416_i2c_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -201,6 +201,7 @@ static const struct of_device_id uniphier_regulator_match[] = {
},
{ /* Sentinel */ },
};
MODULE_DEVICE_TABLE(of, uniphier_regulator_match);
static struct platform_driver uniphier_regulator_driver = {
.probe = uniphier_regulator_probe,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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