forked from Minki/linux
Merge branch 'regulator-5.1' into regulator-next
This commit is contained in:
commit
88f268a5bc
1
.mailmap
1
.mailmap
@ -123,6 +123,7 @@ Mark Brown <broonie@sirena.org.uk>
|
||||
Mark Yao <markyao0591@gmail.com> <mark.yao@rock-chips.com>
|
||||
Martin Kepplinger <martink@posteo.de> <martin.kepplinger@theobroma-systems.com>
|
||||
Martin Kepplinger <martink@posteo.de> <martin.kepplinger@ginzinger.com>
|
||||
Mathieu Othacehe <m.othacehe@gmail.com>
|
||||
Matthew Wilcox <willy@infradead.org> <matthew.r.wilcox@intel.com>
|
||||
Matthew Wilcox <willy@infradead.org> <matthew@wil.cx>
|
||||
Matthew Wilcox <willy@infradead.org> <mawilcox@linuxonhyperv.com>
|
||||
|
@ -23,6 +23,20 @@ Required properties:
|
||||
|
||||
Optional properties:
|
||||
- clock-output-names : Should contain name for output clock.
|
||||
- rohm,reset-snvs-powered : Transfer BD718x7 to SNVS state at reset.
|
||||
|
||||
The BD718x7 supports two different HW states as reset target states. States
|
||||
are called as SNVS and READY. At READY state all the PMIC power outputs go
|
||||
down and OTP is reload. At the SNVS state all other logic and external
|
||||
devices apart from the SNVS power domain are shut off. Please refer to NXP
|
||||
i.MX8 documentation for further information regarding SNVS state. When a
|
||||
reset is done via SNVS state the PMIC OTP data is not reload. This causes
|
||||
power outputs that have been under SW control to stay down when reset has
|
||||
switched power state to SNVS. If reset is done via READY state the power
|
||||
outputs will be returned to HW control by OTP loading. Thus the reset
|
||||
target state is set to READY by default. If SNVS state is used the boot
|
||||
crucial regulators must have the regulator-always-on and regulator-boot-on
|
||||
properties set in regulator node.
|
||||
|
||||
Example:
|
||||
|
||||
@ -43,6 +57,7 @@ Example:
|
||||
#clock-cells = <0>;
|
||||
clocks = <&osc 0>;
|
||||
clock-output-names = "bd71837-32k-out";
|
||||
rohm,reset-snvs-powered;
|
||||
|
||||
regulators {
|
||||
buck1: BUCK1 {
|
||||
@ -50,8 +65,10 @@ Example:
|
||||
regulator-min-microvolt = <700000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-ramp-delay = <1250>;
|
||||
};
|
||||
// [...]
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
Binding for Fairchild FAN53555 regulators
|
||||
|
||||
Required properties:
|
||||
- compatible: one of "fcs,fan53555", "silergy,syr827", "silergy,syr828"
|
||||
- compatible: one of "fcs,fan53555", "fcs,fan53526", "silergy,syr827" or
|
||||
"silergy,syr828"
|
||||
- reg: I2C address
|
||||
|
||||
Optional properties:
|
||||
|
@ -1,35 +0,0 @@
|
||||
Fixed Voltage regulators
|
||||
|
||||
Required properties:
|
||||
- compatible: Must be "regulator-fixed";
|
||||
- regulator-name: Defined in regulator.txt as optional, but required here.
|
||||
|
||||
Optional properties:
|
||||
- gpio: gpio to use for enable control
|
||||
- startup-delay-us: startup time in microseconds
|
||||
- enable-active-high: Polarity of GPIO is Active high
|
||||
If this property is missing, the default assumed is Active low.
|
||||
- gpio-open-drain: GPIO is open drain type.
|
||||
If this property is missing then default assumption is false.
|
||||
-vin-supply: Input supply name.
|
||||
|
||||
Any property defined as part of the core regulator
|
||||
binding, defined in regulator.txt, can also be used.
|
||||
However a fixed voltage regulator is expected to have the
|
||||
regulator-min-microvolt and regulator-max-microvolt
|
||||
to be the same.
|
||||
|
||||
Example:
|
||||
|
||||
abc: fixedregulator@0 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "fixed-supply";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
gpio = <&gpio1 16 0>;
|
||||
startup-delay-us = <70000>;
|
||||
enable-active-high;
|
||||
regulator-boot-on;
|
||||
gpio-open-drain;
|
||||
vin-supply = <&parent_reg>;
|
||||
};
|
@ -0,0 +1,67 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/regulator/fixed-regulator.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Fixed Voltage regulators
|
||||
|
||||
maintainers:
|
||||
- Liam Girdwood <lgirdwood@gmail.com>
|
||||
- Mark Brown <broonie@kernel.org>
|
||||
|
||||
description:
|
||||
Any property defined as part of the core regulator binding, defined in
|
||||
regulator.txt, can also be used. However a fixed voltage regulator is
|
||||
expected to have the regulator-min-microvolt and regulator-max-microvolt
|
||||
to be the same.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: regulator-fixed
|
||||
|
||||
regulator-name: true
|
||||
|
||||
gpio:
|
||||
description: gpio to use for enable control
|
||||
maxItems: 1
|
||||
|
||||
startup-delay-us:
|
||||
description: startup time in microseconds
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
enable-active-high:
|
||||
description:
|
||||
Polarity of GPIO is Active high. If this property is missing,
|
||||
the default assumed is Active low.
|
||||
type: boolean
|
||||
|
||||
gpio-open-drain:
|
||||
description:
|
||||
GPIO is open drain type. If this property is missing then default
|
||||
assumption is false.
|
||||
type: boolean
|
||||
|
||||
vin-supply:
|
||||
description: Input supply phandle.
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- regulator-name
|
||||
|
||||
examples:
|
||||
- |
|
||||
reg_1v8: regulator-1v8 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "1v8";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
gpio = <&gpio1 16 0>;
|
||||
startup-delay-us = <70000>;
|
||||
enable-active-high;
|
||||
regulator-boot-on;
|
||||
gpio-open-drain;
|
||||
vin-supply = <&parent_reg>;
|
||||
};
|
||||
...
|
@ -0,0 +1,41 @@
|
||||
Regulator driver for MAX77650 PMIC from Maxim Integrated.
|
||||
|
||||
This module is part of the MAX77650 MFD device. For more details
|
||||
see Documentation/devicetree/bindings/mfd/max77650.txt.
|
||||
|
||||
The regulator controller is represented as a sub-node of the PMIC node
|
||||
on the device tree.
|
||||
|
||||
The device has a single LDO regulator and a SIMO buck-boost regulator with
|
||||
three independent power rails.
|
||||
|
||||
Required properties:
|
||||
--------------------
|
||||
- compatible: Must be "maxim,max77650-regulator"
|
||||
|
||||
Each rail must be instantiated under the regulators subnode of the top PMIC
|
||||
node. Up to four regulators can be defined. For standard regulator properties
|
||||
refer to Documentation/devicetree/bindings/regulator/regulator.txt.
|
||||
|
||||
Available regulator compatible strings are: "ldo", "sbb0", "sbb1", "sbb2".
|
||||
|
||||
Example:
|
||||
--------
|
||||
|
||||
regulators {
|
||||
compatible = "maxim,max77650-regulator";
|
||||
|
||||
max77650_ldo: regulator@0 {
|
||||
regulator-compatible = "ldo";
|
||||
regulator-name = "max77650-ldo";
|
||||
regulator-min-microvolt = <1350000>;
|
||||
regulator-max-microvolt = <2937500>;
|
||||
};
|
||||
|
||||
max77650_sbb0: regulator@1 {
|
||||
regulator-compatible = "sbb0";
|
||||
regulator-name = "max77650-sbb0";
|
||||
regulator-min-microvolt = <800000>;
|
||||
regulator-max-microvolt = <1587500>;
|
||||
};
|
||||
};
|
@ -8,7 +8,7 @@ Optional properties:
|
||||
- fsl,pfuze-support-disable-sw: Boolean, if present disable all unused switch
|
||||
regulators to save power consumption. Attention, ensure that all important
|
||||
regulators (e.g. DDR ref, DDR supply) has set the "regulator-always-on"
|
||||
property. If not present, the switched regualtors are always on and can't be
|
||||
property. If not present, the switched regulators are always on and can't be
|
||||
disabled. This binding is a workaround to keep backward compatibility with
|
||||
old dtb's which rely on the fact that the switched regulators are always on
|
||||
and don't mark them explicit as "regulator-always-on".
|
||||
|
@ -0,0 +1,68 @@
|
||||
ROHM BD70528 Power Management Integrated Circuit regulator bindings
|
||||
|
||||
Required properties:
|
||||
- regulator-name: should be "buck1", "buck2", "buck3", "ldo1", "ldo2", "ldo3",
|
||||
"led_ldo1", "led_ldo2"
|
||||
|
||||
List of regulators provided by this controller. BD70528 regulators node
|
||||
should be sub node of the BD70528 MFD node. See BD70528 MFD bindings at
|
||||
Documentation/devicetree/bindings/mfd/rohm,bd70528-pmic.txt
|
||||
|
||||
The valid names for BD70528 regulator nodes are:
|
||||
BUCK1, BUCK2, BUCK3, LDO1, LDO2, LDO3, LED_LDO1, LED_LDO2
|
||||
|
||||
Optional properties:
|
||||
- Any optional property defined in bindings/regulator/regulator.txt
|
||||
|
||||
Example:
|
||||
regulators {
|
||||
buck1: BUCK1 {
|
||||
regulator-name = "buck1";
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <3400000>;
|
||||
regulator-boot-on;
|
||||
regulator-ramp-delay = <125>;
|
||||
};
|
||||
buck2: BUCK2 {
|
||||
regulator-name = "buck2";
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
regulator-ramp-delay = <125>;
|
||||
};
|
||||
buck3: BUCK3 {
|
||||
regulator-name = "buck3";
|
||||
regulator-min-microvolt = <800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-boot-on;
|
||||
regulator-ramp-delay = <250>;
|
||||
};
|
||||
ldo1: LDO1 {
|
||||
regulator-name = "ldo1";
|
||||
regulator-min-microvolt = <1650000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
ldo2: LDO2 {
|
||||
regulator-name = "ldo2";
|
||||
regulator-min-microvolt = <1650000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
ldo3: LDO3 {
|
||||
regulator-name = "ldo3";
|
||||
regulator-min-microvolt = <1650000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
led_ldo1: LED_LDO1 {
|
||||
regulator-name = "led_ldo1";
|
||||
regulator-min-microvolt = <200000>;
|
||||
regulator-max-microvolt = <300000>;
|
||||
};
|
||||
led_ldo2: LED_LDO2 {
|
||||
regulator-name = "led_ldo2";
|
||||
regulator-min-microvolt = <200000>;
|
||||
regulator-max-microvolt = <300000>;
|
||||
};
|
||||
};
|
@ -27,8 +27,38 @@ BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6
|
||||
LDO1, LDO2, LDO3, LDO4, LDO5, LDO6
|
||||
|
||||
Optional properties:
|
||||
- rohm,dvs-run-voltage : PMIC default "RUN" state voltage in uV.
|
||||
See below table for bucks which support this.
|
||||
- rohm,dvs-idle-voltage : PMIC default "IDLE" state voltage in uV.
|
||||
See below table for bucks which support this.
|
||||
- rohm,dvs-suspend-voltage : PMIC default "SUSPEND" state voltage in uV.
|
||||
See below table for bucks which support this.
|
||||
- Any optional property defined in bindings/regulator/regulator.txt
|
||||
|
||||
Supported default DVS states:
|
||||
|
||||
BD71837:
|
||||
buck | dvs-run-voltage | dvs-idle-voltage | dvs-suspend-voltage
|
||||
-----------------------------------------------------------------------------
|
||||
1 | supported | supported | supported
|
||||
----------------------------------------------------------------------------
|
||||
2 | supported | supported | not supported
|
||||
----------------------------------------------------------------------------
|
||||
3 | supported | not supported | not supported
|
||||
----------------------------------------------------------------------------
|
||||
4 | supported | not supported | not supported
|
||||
----------------------------------------------------------------------------
|
||||
rest | not supported | not supported | not supported
|
||||
|
||||
BD71847:
|
||||
buck | dvs-run-voltage | dvs-idle-voltage | dvs-suspend-voltage
|
||||
-----------------------------------------------------------------------------
|
||||
1 | supported | supported | supported
|
||||
----------------------------------------------------------------------------
|
||||
2 | supported | supported | not supported
|
||||
----------------------------------------------------------------------------
|
||||
rest | not supported | not supported | not supported
|
||||
|
||||
Example:
|
||||
regulators {
|
||||
buck1: BUCK1 {
|
||||
@ -36,7 +66,11 @@ regulators {
|
||||
regulator-min-microvolt = <700000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-ramp-delay = <1250>;
|
||||
rohm,dvs-run-voltage = <900000>;
|
||||
rohm,dvs-idle-voltage = <850000>;
|
||||
rohm,dvs-suspend-voltage = <800000>;
|
||||
};
|
||||
buck2: BUCK2 {
|
||||
regulator-name = "buck2";
|
||||
@ -45,18 +79,22 @@ regulators {
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-ramp-delay = <1250>;
|
||||
rohm,dvs-run-voltage = <1000000>;
|
||||
rohm,dvs-idle-voltage = <900000>;
|
||||
};
|
||||
buck3: BUCK3 {
|
||||
regulator-name = "buck3";
|
||||
regulator-min-microvolt = <700000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
regulator-boot-on;
|
||||
rohm,dvs-run-voltage = <1000000>;
|
||||
};
|
||||
buck4: BUCK4 {
|
||||
regulator-name = "buck4";
|
||||
regulator-min-microvolt = <700000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
regulator-boot-on;
|
||||
rohm,dvs-run-voltage = <1000000>;
|
||||
};
|
||||
buck5: BUCK5 {
|
||||
regulator-name = "buck5";
|
||||
|
@ -23,16 +23,14 @@ Switches are fixed voltage regulators with only enable/disable capability.
|
||||
Optional properties:
|
||||
- st,mask-reset: mask reset for this regulator: the regulator configuration
|
||||
is maintained during pmic reset.
|
||||
- regulator-pull-down: enable high pull down
|
||||
if not specified light pull down is used
|
||||
- regulator-over-current-protection:
|
||||
if set, all regulators are switched off in case of over-current detection
|
||||
on this regulator,
|
||||
if not set, the driver only sends an over-current event.
|
||||
- interrupt-parent: phandle to the parent interrupt controller
|
||||
- interrupts: index of current limit detection interrupt
|
||||
- <regulator>-supply: phandle to the parent supply/regulator node
|
||||
each regulator supply can be described except vref_ddr.
|
||||
- regulator-active-discharge: can be used on pwr_sw1 and pwr_sw2.
|
||||
|
||||
Example:
|
||||
regulators {
|
||||
@ -43,7 +41,6 @@ regulators {
|
||||
vdd_core: buck1 {
|
||||
regulator-name = "vdd_core";
|
||||
interrupts = <IT_CURLIM_BUCK1 0>;
|
||||
interrupt-parent = <&pmic>;
|
||||
st,mask-reset;
|
||||
regulator-pull-down;
|
||||
regulator-min-microvolt = <700000>;
|
||||
@ -53,7 +50,6 @@ regulators {
|
||||
v3v3: buck4 {
|
||||
regulator-name = "v3v3";
|
||||
interrupts = <IT_CURLIM_BUCK4 0>;
|
||||
interrupt-parent = <&mypmic>;
|
||||
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
|
@ -71,8 +71,13 @@ tps65218: tps65218@24 {
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
ls2: regulator-ls2 {
|
||||
regulator-min-microamp = <100000>;
|
||||
regulator-max-microamp = <1000000>;
|
||||
};
|
||||
|
||||
ls3: regulator-ls3 {
|
||||
regulator-min-microvolt = <100000>;
|
||||
regulator-max-microvolt = <1000000>;
|
||||
regulator-min-microamp = <100000>;
|
||||
regulator-max-microamp = <1000000>;
|
||||
};
|
||||
};
|
||||
|
@ -205,7 +205,6 @@ static struct regulator_init_data mx21ads_lcd_regulator_init_data = {
|
||||
static struct fixed_voltage_config mx21ads_lcd_regulator_pdata = {
|
||||
.supply_name = "LCD",
|
||||
.microvolts = 3300000,
|
||||
.enable_high = 1,
|
||||
.init_data = &mx21ads_lcd_regulator_init_data,
|
||||
};
|
||||
|
||||
|
@ -237,7 +237,7 @@ static struct fixed_voltage_config mx27ads_lcd_regulator_pdata = {
|
||||
static struct gpiod_lookup_table mx27ads_lcd_regulator_gpiod_table = {
|
||||
.dev_id = "reg-fixed-voltage.0", /* Let's hope ID 0 is what we get */
|
||||
.table = {
|
||||
GPIO_LOOKUP("LCD", 0, NULL, GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP("LCD", 0, NULL, GPIO_ACTIVE_LOW),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
@ -149,7 +149,6 @@ static struct regulator_init_data brownstone_v_5vp_data = {
|
||||
static struct fixed_voltage_config brownstone_v_5vp = {
|
||||
.supply_name = "v_5vp",
|
||||
.microvolts = 5000000,
|
||||
.enable_high = 1,
|
||||
.enabled_at_boot = 1,
|
||||
.init_data = &brownstone_v_5vp_data,
|
||||
};
|
||||
|
@ -267,7 +267,6 @@ static struct fixed_voltage_config modem_nreset_config = {
|
||||
.supply_name = "modem_nreset",
|
||||
.microvolts = 3300000,
|
||||
.startup_delay = 25000,
|
||||
.enable_high = 1,
|
||||
.enabled_at_boot = 1,
|
||||
.init_data = &modem_nreset_data,
|
||||
};
|
||||
@ -533,7 +532,6 @@ static struct regulator_init_data keybrd_pwr_initdata = {
|
||||
static struct fixed_voltage_config keybrd_pwr_config = {
|
||||
.supply_name = "keybrd_pwr",
|
||||
.microvolts = 5000000,
|
||||
.enable_high = 1,
|
||||
.init_data = &keybrd_pwr_initdata,
|
||||
};
|
||||
|
||||
|
@ -330,7 +330,6 @@ static struct fixed_voltage_config pandora_vwlan = {
|
||||
.supply_name = "vwlan",
|
||||
.microvolts = 1800000, /* 1.8V */
|
||||
.startup_delay = 50000, /* 50ms */
|
||||
.enable_high = 1,
|
||||
.init_data = &pandora_vmmc3,
|
||||
};
|
||||
|
||||
|
@ -976,7 +976,6 @@ static struct fixed_voltage_config camera_dummy_config = {
|
||||
.supply_name = "camera_vdd",
|
||||
.input_supply = "vcc cam",
|
||||
.microvolts = 2800000,
|
||||
.enable_high = 0,
|
||||
.init_data = &camera_dummy_initdata,
|
||||
};
|
||||
|
||||
|
@ -714,7 +714,6 @@ static struct regulator_init_data camera_regulator_initdata = {
|
||||
static struct fixed_voltage_config camera_regulator_config = {
|
||||
.supply_name = "camera_vdd",
|
||||
.microvolts = 2800000,
|
||||
.enable_high = 0,
|
||||
.init_data = &camera_regulator_initdata,
|
||||
};
|
||||
|
||||
@ -730,7 +729,7 @@ static struct gpiod_lookup_table camera_supply_gpiod_table = {
|
||||
.dev_id = "reg-fixed-voltage.1",
|
||||
.table = {
|
||||
GPIO_LOOKUP("gpio-pxa", GPIO50_nCAM_EN,
|
||||
NULL, GPIO_ACTIVE_HIGH),
|
||||
NULL, GPIO_ACTIVE_LOW),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/input.h>
|
||||
@ -702,9 +703,7 @@ static struct regulator_init_data bq24022_init_data = {
|
||||
.consumer_supplies = bq24022_consumers,
|
||||
};
|
||||
|
||||
static struct gpio bq24022_gpios[] = {
|
||||
{ GPIO96_HX4700_BQ24022_ISET2, GPIOF_OUT_INIT_LOW, "bq24022_iset2" },
|
||||
};
|
||||
static enum gpiod_flags bq24022_gpiod_gflags[] = { GPIOD_OUT_LOW };
|
||||
|
||||
static struct gpio_regulator_state bq24022_states[] = {
|
||||
{ .value = 100000, .gpios = (0 << 0) },
|
||||
@ -714,12 +713,10 @@ static struct gpio_regulator_state bq24022_states[] = {
|
||||
static struct gpio_regulator_config bq24022_info = {
|
||||
.supply_name = "bq24022",
|
||||
|
||||
.enable_gpio = GPIO72_HX4700_BQ24022_nCHARGE_EN,
|
||||
.enable_high = 0,
|
||||
.enabled_at_boot = 0,
|
||||
|
||||
.gpios = bq24022_gpios,
|
||||
.nr_gpios = ARRAY_SIZE(bq24022_gpios),
|
||||
.gflags = bq24022_gpiod_gflags,
|
||||
.ngpios = ARRAY_SIZE(bq24022_gpiod_gflags),
|
||||
|
||||
.states = bq24022_states,
|
||||
.nr_states = ARRAY_SIZE(bq24022_states),
|
||||
@ -736,6 +733,17 @@ static struct platform_device bq24022 = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table bq24022_gpiod_table = {
|
||||
.dev_id = "gpio-regulator",
|
||||
.table = {
|
||||
GPIO_LOOKUP("gpio-pxa", GPIO96_HX4700_BQ24022_ISET2,
|
||||
NULL, GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP("gpio-pxa", GPIO72_HX4700_BQ24022_nCHARGE_EN,
|
||||
"enable", GPIO_ACTIVE_LOW),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* StrataFlash
|
||||
*/
|
||||
@ -878,6 +886,7 @@ static void __init hx4700_init(void)
|
||||
pxa_set_btuart_info(NULL);
|
||||
pxa_set_stuart_info(NULL);
|
||||
|
||||
gpiod_add_lookup_table(&bq24022_gpiod_table);
|
||||
platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
pwm_add_table(hx4700_pwm_lookup, ARRAY_SIZE(hx4700_pwm_lookup));
|
||||
|
||||
|
@ -645,9 +645,8 @@ static struct regulator_init_data bq24022_init_data = {
|
||||
.consumer_supplies = bq24022_consumers,
|
||||
};
|
||||
|
||||
static struct gpio bq24022_gpios[] = {
|
||||
{ EGPIO_MAGICIAN_BQ24022_ISET2, GPIOF_OUT_INIT_LOW, "bq24022_iset2" },
|
||||
};
|
||||
|
||||
static enum gpiod_flags bq24022_gpiod_gflags[] = { GPIOD_OUT_LOW };
|
||||
|
||||
static struct gpio_regulator_state bq24022_states[] = {
|
||||
{ .value = 100000, .gpios = (0 << 0) },
|
||||
@ -657,12 +656,10 @@ static struct gpio_regulator_state bq24022_states[] = {
|
||||
static struct gpio_regulator_config bq24022_info = {
|
||||
.supply_name = "bq24022",
|
||||
|
||||
.enable_gpio = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,
|
||||
.enable_high = 0,
|
||||
.enabled_at_boot = 1,
|
||||
|
||||
.gpios = bq24022_gpios,
|
||||
.nr_gpios = ARRAY_SIZE(bq24022_gpios),
|
||||
.gflags = bq24022_gpiod_gflags,
|
||||
.ngpios = ARRAY_SIZE(bq24022_gpiod_gflags),
|
||||
|
||||
.states = bq24022_states,
|
||||
.nr_states = ARRAY_SIZE(bq24022_states),
|
||||
@ -679,6 +676,17 @@ static struct platform_device bq24022 = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table bq24022_gpiod_table = {
|
||||
.dev_id = "gpio-regulator",
|
||||
.table = {
|
||||
GPIO_LOOKUP("gpio-pxa", EGPIO_MAGICIAN_BQ24022_ISET2,
|
||||
NULL, GPIO_ACTIVE_HIGH),
|
||||
GPIO_LOOKUP("gpio-pxa", GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,
|
||||
"enable", GPIO_ACTIVE_LOW),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* fixed regulator for ads7846
|
||||
*/
|
||||
@ -1027,6 +1035,7 @@ static void __init magician_init(void)
|
||||
regulator_register_always_on(0, "power", pwm_backlight_supply,
|
||||
ARRAY_SIZE(pwm_backlight_supply), 5000000);
|
||||
|
||||
gpiod_add_lookup_table(&bq24022_gpiod_table);
|
||||
platform_add_devices(ARRAY_AND_SIZE(devices));
|
||||
}
|
||||
|
||||
|
@ -883,7 +883,6 @@ static struct regulator_init_data audio_va_initdata = {
|
||||
static struct fixed_voltage_config audio_va_config = {
|
||||
.supply_name = "audio_va",
|
||||
.microvolts = 5000000,
|
||||
.enable_high = 1,
|
||||
.enabled_at_boot = 0,
|
||||
.init_data = &audio_va_initdata,
|
||||
};
|
||||
|
@ -426,7 +426,7 @@ static struct gpiod_lookup_table can_regulator_gpiod_table = {
|
||||
.dev_id = "reg-fixed-voltage.0",
|
||||
.table = {
|
||||
GPIO_LOOKUP("gpio-pxa", ZEUS_CAN_SHDN_GPIO,
|
||||
NULL, GPIO_ACTIVE_HIGH),
|
||||
NULL, GPIO_ACTIVE_LOW),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
@ -547,7 +547,6 @@ static struct regulator_init_data zeus_ohci_regulator_data = {
|
||||
static struct fixed_voltage_config zeus_ohci_regulator_config = {
|
||||
.supply_name = "vbus2",
|
||||
.microvolts = 5000000, /* 5.0V */
|
||||
.enable_high = 1,
|
||||
.startup_delay = 0,
|
||||
.init_data = &zeus_ohci_regulator_data,
|
||||
};
|
||||
|
@ -469,7 +469,6 @@ static struct regulator_consumer_supply assabet_cf_vcc_consumers[] = {
|
||||
static struct fixed_voltage_config assabet_cf_vcc_pdata __initdata = {
|
||||
.supply_name = "cf-power",
|
||||
.microvolts = 3300000,
|
||||
.enable_high = 1,
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table assabet_cf_vcc_gpio_table = {
|
||||
|
@ -630,7 +630,6 @@ static struct regulator_init_data cn12_power_init_data = {
|
||||
static struct fixed_voltage_config cn12_power_info = {
|
||||
.supply_name = "CN12 SD/MMC Vdd",
|
||||
.microvolts = 3300000,
|
||||
.enable_high = 1,
|
||||
.init_data = &cn12_power_init_data,
|
||||
};
|
||||
|
||||
@ -671,7 +670,6 @@ static struct regulator_init_data sdhi0_power_init_data = {
|
||||
static struct fixed_voltage_config sdhi0_power_info = {
|
||||
.supply_name = "CN11 SD/MMC Vdd",
|
||||
.microvolts = 3300000,
|
||||
.enable_high = 1,
|
||||
.init_data = &sdhi0_power_init_data,
|
||||
};
|
||||
|
||||
|
@ -44,7 +44,6 @@ static struct fixed_voltage_config bcm43xx_vmmc = {
|
||||
*/
|
||||
.microvolts = 2000000, /* 1.8V */
|
||||
.startup_delay = 250 * 1000, /* 250ms */
|
||||
.enable_high = 1, /* active high */
|
||||
.enabled_at_boot = 0, /* disabled at boot */
|
||||
.init_data = &bcm43xx_vmmc_data,
|
||||
};
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/platform_device.h>
|
||||
@ -22,12 +21,7 @@
|
||||
|
||||
struct pm8607_regulator_info {
|
||||
struct regulator_desc desc;
|
||||
struct pm860x_chip *chip;
|
||||
struct regulator_dev *regulator;
|
||||
struct i2c_client *i2c;
|
||||
struct i2c_client *i2c_8606;
|
||||
|
||||
unsigned int *vol_table;
|
||||
unsigned int *vol_suspend;
|
||||
|
||||
int slope_double;
|
||||
@ -210,13 +204,15 @@ static const unsigned int LDO14_suspend_table[] = {
|
||||
static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
|
||||
{
|
||||
struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
int ret = -EINVAL;
|
||||
int ret;
|
||||
|
||||
ret = regulator_list_voltage_table(rdev, index);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (info->slope_double)
|
||||
ret <<= 1;
|
||||
|
||||
if (info->vol_table && (index < rdev->desc->n_voltages)) {
|
||||
ret = info->vol_table[index];
|
||||
if (info->slope_double)
|
||||
ret <<= 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -257,6 +253,7 @@ static const struct regulator_ops pm8606_preg_ops = {
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.id = PM8607_ID_##vreg, \
|
||||
.owner = THIS_MODULE, \
|
||||
.volt_table = vreg##_table, \
|
||||
.n_voltages = ARRAY_SIZE(vreg##_table), \
|
||||
.vsel_reg = PM8607_##vreg, \
|
||||
.vsel_mask = ARRAY_SIZE(vreg##_table) - 1, \
|
||||
@ -266,7 +263,6 @@ static const struct regulator_ops pm8606_preg_ops = {
|
||||
.enable_mask = 1 << (ebit), \
|
||||
}, \
|
||||
.slope_double = (0), \
|
||||
.vol_table = (unsigned int *)&vreg##_table, \
|
||||
.vol_suspend = (unsigned int *)&vreg##_suspend_table, \
|
||||
}
|
||||
|
||||
@ -278,6 +274,7 @@ static const struct regulator_ops pm8606_preg_ops = {
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.id = PM8607_ID_LDO##_id, \
|
||||
.owner = THIS_MODULE, \
|
||||
.volt_table = LDO##_id##_table, \
|
||||
.n_voltages = ARRAY_SIZE(LDO##_id##_table), \
|
||||
.vsel_reg = PM8607_##vreg, \
|
||||
.vsel_mask = (ARRAY_SIZE(LDO##_id##_table) - 1) << (shift), \
|
||||
@ -285,7 +282,6 @@ static const struct regulator_ops pm8606_preg_ops = {
|
||||
.enable_mask = 1 << (ebit), \
|
||||
}, \
|
||||
.slope_double = (0), \
|
||||
.vol_table = (unsigned int *)&LDO##_id##_table, \
|
||||
.vol_suspend = (unsigned int *)&LDO##_id##_suspend_table, \
|
||||
}
|
||||
|
||||
@ -349,6 +345,7 @@ static int pm8607_regulator_probe(struct platform_device *pdev)
|
||||
struct pm8607_regulator_info *info = NULL;
|
||||
struct regulator_init_data *pdata = dev_get_platdata(&pdev->dev);
|
||||
struct regulator_config config = { };
|
||||
struct regulator_dev *rdev;
|
||||
struct resource *res;
|
||||
int i;
|
||||
|
||||
@ -371,13 +368,9 @@ static int pm8607_regulator_probe(struct platform_device *pdev)
|
||||
/* i is used to check regulator ID */
|
||||
i = -1;
|
||||
}
|
||||
info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
|
||||
info->i2c_8606 = (chip->id == CHIP_PM8607) ? chip->companion :
|
||||
chip->client;
|
||||
info->chip = chip;
|
||||
|
||||
/* check DVC ramp slope double */
|
||||
if ((i == PM8607_ID_BUCK3) && info->chip->buck3_double)
|
||||
if ((i == PM8607_ID_BUCK3) && chip->buck3_double)
|
||||
info->slope_double = 1;
|
||||
|
||||
config.dev = &pdev->dev;
|
||||
@ -392,12 +385,11 @@ static int pm8607_regulator_probe(struct platform_device *pdev)
|
||||
else
|
||||
config.regmap = chip->regmap_companion;
|
||||
|
||||
info->regulator = devm_regulator_register(&pdev->dev, &info->desc,
|
||||
&config);
|
||||
if (IS_ERR(info->regulator)) {
|
||||
rdev = devm_regulator_register(&pdev->dev, &info->desc, &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(&pdev->dev, "failed to register regulator %s\n",
|
||||
info->desc.name);
|
||||
return PTR_ERR(info->regulator);
|
||||
return PTR_ERR(rdev);
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, info);
|
||||
|
@ -180,6 +180,17 @@ 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_BD718XX
|
||||
tristate "ROHM BD71837 Power Regulator"
|
||||
depends on MFD_ROHM_BD718XX
|
||||
@ -457,6 +468,14 @@ config REGULATOR_MAX77620
|
||||
chip to control Step-Down DC-DC and LDOs. Say Y here to
|
||||
enable the regulator driver.
|
||||
|
||||
config REGULATOR_MAX77650
|
||||
tristate "Maxim MAX77650/77651 regulator support"
|
||||
depends on MFD_MAX77650
|
||||
help
|
||||
Regulator driver for MAX77650/77651 PMIC from Maxim
|
||||
Semiconductor. This device has a SIMO with three independent
|
||||
power rails and an LDO.
|
||||
|
||||
config REGULATOR_MAX8649
|
||||
tristate "Maxim 8649 voltage regulator"
|
||||
depends on I2C
|
||||
@ -484,7 +503,7 @@ config REGULATOR_MAX8925
|
||||
tristate "Maxim MAX8925 Power Management IC"
|
||||
depends on MFD_MAX8925
|
||||
help
|
||||
Say y here to support the voltage regulaltor of Maxim MAX8925 PMIC.
|
||||
Say y here to support the voltage regulator of Maxim MAX8925 PMIC.
|
||||
|
||||
config REGULATOR_MAX8952
|
||||
tristate "Maxim MAX8952 Power Management IC"
|
||||
@ -501,7 +520,7 @@ config REGULATOR_MAX8973
|
||||
select REGMAP_I2C
|
||||
help
|
||||
The MAXIM MAX8973 high-efficiency. three phase, DC-DC step-down
|
||||
switching regulator delievers up to 9A of output current. Each
|
||||
switching regulator delivers up to 9A of output current. Each
|
||||
phase operates at a 2MHz fixed frequency with a 120 deg shift
|
||||
from the adjacent phase, allowing the use of small magnetic component.
|
||||
|
||||
@ -646,7 +665,7 @@ config REGULATOR_PCF50633
|
||||
tristate "NXP PCF50633 regulator driver"
|
||||
depends on MFD_PCF50633
|
||||
help
|
||||
Say Y here to support the voltage regulators and convertors
|
||||
Say Y here to support the voltage regulators and converters
|
||||
on PCF50633
|
||||
|
||||
config REGULATOR_PFUZE100
|
||||
@ -924,7 +943,7 @@ config REGULATOR_TPS65132
|
||||
select REGMAP_I2C
|
||||
help
|
||||
This driver supports TPS65132 single inductor - dual output
|
||||
power supply specifcally designed for display panels.
|
||||
power supply specifically designed for display panels.
|
||||
|
||||
config REGULATOR_TPS65217
|
||||
tristate "TI TPS65217 Power regulators"
|
||||
|
@ -27,6 +27,7 @@ obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_AS3722) += as3722-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_BD718XX) += bd718x7-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
|
||||
@ -60,6 +61,7 @@ obj-$(CONFIG_REGULATOR_LTC3676) += ltc3676.o
|
||||
obj-$(CONFIG_REGULATOR_MAX14577) += max14577-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
|
||||
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_MAX8907) += max8907-regulator.o
|
||||
|
@ -131,7 +131,7 @@
|
||||
* ACT8865 voltage number
|
||||
*/
|
||||
#define ACT8865_VOLTAGE_NUM 64
|
||||
#define ACT8600_SUDCDC_VOLTAGE_NUM 255
|
||||
#define ACT8600_SUDCDC_VOLTAGE_NUM 256
|
||||
|
||||
struct act8865 {
|
||||
struct regmap *regmap;
|
||||
@ -222,7 +222,8 @@ static const struct regulator_linear_range act8600_sudcdc_voltage_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(3000000, 0, 63, 0),
|
||||
REGULATOR_LINEAR_RANGE(3000000, 64, 159, 100000),
|
||||
REGULATOR_LINEAR_RANGE(12600000, 160, 191, 200000),
|
||||
REGULATOR_LINEAR_RANGE(19000000, 191, 255, 400000),
|
||||
REGULATOR_LINEAR_RANGE(19000000, 192, 247, 400000),
|
||||
REGULATOR_LINEAR_RANGE(41400000, 248, 255, 0),
|
||||
};
|
||||
|
||||
static struct regulator_ops act8865_ops = {
|
||||
|
@ -87,7 +87,8 @@ static const struct regulator_linear_range act8945a_voltage_ranges[] = {
|
||||
static int act8945a_set_suspend_state(struct regulator_dev *rdev, bool enable)
|
||||
{
|
||||
struct regmap *regmap = rdev->regmap;
|
||||
int id = rdev->desc->id, reg, val;
|
||||
int id = rdev_get_id(rdev);
|
||||
int reg, val;
|
||||
|
||||
switch (id) {
|
||||
case ACT8945A_ID_DCDC1:
|
||||
@ -159,7 +160,7 @@ static int act8945a_set_mode(struct regulator_dev *rdev, unsigned int mode)
|
||||
{
|
||||
struct act8945a_pmic *act8945a = rdev_get_drvdata(rdev);
|
||||
struct regmap *regmap = rdev->regmap;
|
||||
int id = rdev->desc->id;
|
||||
int id = rdev_get_id(rdev);
|
||||
int reg, ret, val = 0;
|
||||
|
||||
switch (id) {
|
||||
@ -190,11 +191,11 @@ static int act8945a_set_mode(struct regulator_dev *rdev, unsigned int mode)
|
||||
|
||||
switch (mode) {
|
||||
case REGULATOR_MODE_STANDBY:
|
||||
if (rdev->desc->id > ACT8945A_ID_DCDC3)
|
||||
if (id > ACT8945A_ID_DCDC3)
|
||||
val = BIT(5);
|
||||
break;
|
||||
case REGULATOR_MODE_NORMAL:
|
||||
if (rdev->desc->id <= ACT8945A_ID_DCDC3)
|
||||
if (id <= ACT8945A_ID_DCDC3)
|
||||
val = BIT(5);
|
||||
break;
|
||||
default:
|
||||
@ -213,7 +214,7 @@ static int act8945a_set_mode(struct regulator_dev *rdev, unsigned int mode)
|
||||
static unsigned int act8945a_get_mode(struct regulator_dev *rdev)
|
||||
{
|
||||
struct act8945a_pmic *act8945a = rdev_get_drvdata(rdev);
|
||||
int id = rdev->desc->id;
|
||||
int id = rdev_get_id(rdev);
|
||||
|
||||
if (id < ACT8945A_ID_DCDC1 || id >= ACT8945A_ID_MAX)
|
||||
return -EINVAL;
|
||||
|
@ -40,35 +40,10 @@ struct arizona_ldo1 {
|
||||
struct gpio_desc *ena_gpiod;
|
||||
};
|
||||
|
||||
static int arizona_ldo1_hc_list_voltage(struct regulator_dev *rdev,
|
||||
unsigned int selector)
|
||||
{
|
||||
if (selector >= rdev->desc->n_voltages)
|
||||
return -EINVAL;
|
||||
|
||||
if (selector == rdev->desc->n_voltages - 1)
|
||||
return 1800000;
|
||||
else
|
||||
return rdev->desc->min_uV + (rdev->desc->uV_step * selector);
|
||||
}
|
||||
|
||||
static int arizona_ldo1_hc_map_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV)
|
||||
{
|
||||
int sel;
|
||||
|
||||
sel = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step);
|
||||
if (sel >= rdev->desc->n_voltages)
|
||||
sel = rdev->desc->n_voltages - 1;
|
||||
|
||||
return sel;
|
||||
}
|
||||
|
||||
static int arizona_ldo1_hc_set_voltage_sel(struct regulator_dev *rdev,
|
||||
unsigned sel)
|
||||
{
|
||||
struct arizona_ldo1 *ldo = rdev_get_drvdata(rdev);
|
||||
struct regmap *regmap = ldo->regmap;
|
||||
struct regmap *regmap = rdev_get_regmap(rdev);
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
@ -85,16 +60,12 @@ static int arizona_ldo1_hc_set_voltage_sel(struct regulator_dev *rdev,
|
||||
if (val)
|
||||
return 0;
|
||||
|
||||
val = sel << ARIZONA_LDO1_VSEL_SHIFT;
|
||||
|
||||
return regmap_update_bits(regmap, ARIZONA_LDO1_CONTROL_1,
|
||||
ARIZONA_LDO1_VSEL_MASK, val);
|
||||
return regulator_set_voltage_sel_regmap(rdev, sel);
|
||||
}
|
||||
|
||||
static int arizona_ldo1_hc_get_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
struct arizona_ldo1 *ldo = rdev_get_drvdata(rdev);
|
||||
struct regmap *regmap = ldo->regmap;
|
||||
struct regmap *regmap = rdev_get_regmap(rdev);
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
@ -105,32 +76,35 @@ static int arizona_ldo1_hc_get_voltage_sel(struct regulator_dev *rdev)
|
||||
if (val & ARIZONA_LDO1_HI_PWR)
|
||||
return rdev->desc->n_voltages - 1;
|
||||
|
||||
ret = regmap_read(regmap, ARIZONA_LDO1_CONTROL_1, &val);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
return (val & ARIZONA_LDO1_VSEL_MASK) >> ARIZONA_LDO1_VSEL_SHIFT;
|
||||
return regulator_get_voltage_sel_regmap(rdev);
|
||||
}
|
||||
|
||||
static const struct regulator_ops arizona_ldo1_hc_ops = {
|
||||
.list_voltage = arizona_ldo1_hc_list_voltage,
|
||||
.map_voltage = arizona_ldo1_hc_map_voltage,
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
.get_voltage_sel = arizona_ldo1_hc_get_voltage_sel,
|
||||
.set_voltage_sel = arizona_ldo1_hc_set_voltage_sel,
|
||||
.get_bypass = regulator_get_bypass_regmap,
|
||||
.set_bypass = regulator_set_bypass_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range arizona_ldo1_hc_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(900000, 0, 0x6, 50000),
|
||||
REGULATOR_LINEAR_RANGE(1800000, 0x7, 0x7, 0),
|
||||
};
|
||||
|
||||
static const struct regulator_desc arizona_ldo1_hc = {
|
||||
.name = "LDO1",
|
||||
.supply_name = "LDOVDD",
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.ops = &arizona_ldo1_hc_ops,
|
||||
|
||||
.vsel_reg = ARIZONA_LDO1_CONTROL_1,
|
||||
.vsel_mask = ARIZONA_LDO1_VSEL_MASK,
|
||||
.bypass_reg = ARIZONA_LDO1_CONTROL_1,
|
||||
.bypass_mask = ARIZONA_LDO1_BYPASS,
|
||||
.min_uV = 900000,
|
||||
.uV_step = 50000,
|
||||
.linear_ranges = arizona_ldo1_hc_ranges,
|
||||
.n_linear_ranges = ARRAY_SIZE(arizona_ldo1_hc_ranges),
|
||||
.n_voltages = 8,
|
||||
.enable_time = 1500,
|
||||
.ramp_delay = 24000,
|
||||
|
@ -886,7 +886,7 @@ static int as3722_regulator_probe(struct platform_device *pdev)
|
||||
as3722_regs->desc[id].min_uV = 410000;
|
||||
} else {
|
||||
as3722_regs->desc[id].n_voltages =
|
||||
AS3722_SD0_VSEL_MAX + 1,
|
||||
AS3722_SD0_VSEL_MAX + 1;
|
||||
as3722_regs->desc[id].min_uV = 610000;
|
||||
}
|
||||
as3722_regs->desc[id].uV_step = 10000;
|
||||
|
@ -367,13 +367,12 @@ static const int axp209_dcdc2_ldo3_slew_rates[] = {
|
||||
static int axp20x_set_ramp_delay(struct regulator_dev *rdev, int ramp)
|
||||
{
|
||||
struct axp20x_dev *axp20x = rdev_get_drvdata(rdev);
|
||||
const struct regulator_desc *desc = rdev->desc;
|
||||
const struct regulator_desc *desc;
|
||||
u8 reg, mask, enable, cfg = 0xff;
|
||||
const int *slew_rates;
|
||||
int rate_count = 0;
|
||||
|
||||
if (!rdev)
|
||||
return -EINVAL;
|
||||
desc = rdev->desc;
|
||||
|
||||
switch (axp20x->variant) {
|
||||
case AXP209_ID:
|
||||
@ -436,11 +435,13 @@ static int axp20x_set_ramp_delay(struct regulator_dev *rdev, int ramp)
|
||||
static int axp20x_regulator_enable_regmap(struct regulator_dev *rdev)
|
||||
{
|
||||
struct axp20x_dev *axp20x = rdev_get_drvdata(rdev);
|
||||
const struct regulator_desc *desc = rdev->desc;
|
||||
const struct regulator_desc *desc;
|
||||
|
||||
if (!rdev)
|
||||
return -EINVAL;
|
||||
|
||||
desc = rdev->desc;
|
||||
|
||||
switch (axp20x->variant) {
|
||||
case AXP209_ID:
|
||||
if ((desc->id == AXP20X_LDO3) &&
|
||||
|
289
drivers/regulator/bd70528-regulator.c
Normal file
289
drivers/regulator/bd70528-regulator.c
Normal file
@ -0,0 +1,289 @@
|
||||
// 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/gpio.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 regulator_linear_range bd70528_buck1_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x1, 600000),
|
||||
REGULATOR_LINEAR_RANGE(2750000, 0x2, 0xf, 50000),
|
||||
};
|
||||
static const struct regulator_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 regulator_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 regulator_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,
|
||||
.set_ramp_delay = bd70528_set_ramp_delay,
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
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");
|
@ -79,7 +79,7 @@ static int bd718xx_set_voltage_sel_pickable_restricted(
|
||||
return regulator_set_voltage_sel_pickable_regmap(rdev, sel);
|
||||
}
|
||||
|
||||
static struct regulator_ops bd718xx_pickable_range_ldo_ops = {
|
||||
static const struct regulator_ops bd718xx_pickable_range_ldo_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
@ -88,7 +88,7 @@ static struct regulator_ops bd718xx_pickable_range_ldo_ops = {
|
||||
.get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
|
||||
};
|
||||
|
||||
static struct regulator_ops bd718xx_pickable_range_buck_ops = {
|
||||
static const struct regulator_ops bd718xx_pickable_range_buck_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
@ -98,7 +98,7 @@ static struct regulator_ops bd718xx_pickable_range_buck_ops = {
|
||||
.set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||
};
|
||||
|
||||
static struct regulator_ops bd718xx_ldo_regulator_ops = {
|
||||
static const struct regulator_ops bd718xx_ldo_regulator_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
@ -107,7 +107,7 @@ static struct regulator_ops bd718xx_ldo_regulator_ops = {
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
};
|
||||
|
||||
static struct regulator_ops bd718xx_ldo_regulator_nolinear_ops = {
|
||||
static const struct regulator_ops bd718xx_ldo_regulator_nolinear_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
@ -116,7 +116,7 @@ static struct regulator_ops bd718xx_ldo_regulator_nolinear_ops = {
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
};
|
||||
|
||||
static struct regulator_ops bd718xx_buck_regulator_ops = {
|
||||
static const struct regulator_ops bd718xx_buck_regulator_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
@ -126,7 +126,7 @@ static struct regulator_ops bd718xx_buck_regulator_ops = {
|
||||
.set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||
};
|
||||
|
||||
static struct regulator_ops bd718xx_buck_regulator_nolinear_ops = {
|
||||
static const struct regulator_ops bd718xx_buck_regulator_nolinear_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
@ -137,7 +137,7 @@ static struct regulator_ops bd718xx_buck_regulator_nolinear_ops = {
|
||||
.set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||
};
|
||||
|
||||
static struct regulator_ops bd718xx_dvs_buck_regulator_ops = {
|
||||
static const struct regulator_ops bd718xx_dvs_buck_regulator_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
@ -350,6 +350,135 @@ static const struct reg_init bd71837_ldo6_inits[] = {
|
||||
},
|
||||
};
|
||||
|
||||
#define NUM_DVS_BUCKS 4
|
||||
|
||||
struct of_dvs_setting {
|
||||
const char *prop;
|
||||
unsigned int reg;
|
||||
};
|
||||
|
||||
static int set_dvs_levels(const struct of_dvs_setting *dvs,
|
||||
struct device_node *np,
|
||||
const struct regulator_desc *desc,
|
||||
struct regmap *regmap)
|
||||
{
|
||||
int ret, i;
|
||||
unsigned int uv;
|
||||
|
||||
ret = of_property_read_u32(np, dvs->prop, &uv);
|
||||
if (ret) {
|
||||
if (ret != -EINVAL)
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < desc->n_voltages; i++) {
|
||||
ret = regulator_desc_list_voltage_linear_range(desc, i);
|
||||
if (ret < 0)
|
||||
continue;
|
||||
if (ret == uv) {
|
||||
i <<= ffs(desc->vsel_mask) - 1;
|
||||
ret = regmap_update_bits(regmap, dvs->reg,
|
||||
DVS_BUCK_RUN_MASK, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int buck4_set_hw_dvs_levels(struct device_node *np,
|
||||
const struct regulator_desc *desc,
|
||||
struct regulator_config *cfg)
|
||||
{
|
||||
int ret, i;
|
||||
const struct of_dvs_setting dvs[] = {
|
||||
{
|
||||
.prop = "rohm,dvs-run-voltage",
|
||||
.reg = BD71837_REG_BUCK4_VOLT_RUN,
|
||||
},
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dvs); i++) {
|
||||
ret = set_dvs_levels(&dvs[i], np, desc, cfg->regmap);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
static int buck3_set_hw_dvs_levels(struct device_node *np,
|
||||
const struct regulator_desc *desc,
|
||||
struct regulator_config *cfg)
|
||||
{
|
||||
int ret, i;
|
||||
const struct of_dvs_setting dvs[] = {
|
||||
{
|
||||
.prop = "rohm,dvs-run-voltage",
|
||||
.reg = BD71837_REG_BUCK3_VOLT_RUN,
|
||||
},
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dvs); i++) {
|
||||
ret = set_dvs_levels(&dvs[i], np, desc, cfg->regmap);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int buck2_set_hw_dvs_levels(struct device_node *np,
|
||||
const struct regulator_desc *desc,
|
||||
struct regulator_config *cfg)
|
||||
{
|
||||
int ret, i;
|
||||
const struct of_dvs_setting dvs[] = {
|
||||
{
|
||||
.prop = "rohm,dvs-run-voltage",
|
||||
.reg = BD718XX_REG_BUCK2_VOLT_RUN,
|
||||
},
|
||||
{
|
||||
.prop = "rohm,dvs-idle-voltage",
|
||||
.reg = BD718XX_REG_BUCK2_VOLT_IDLE,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dvs); i++) {
|
||||
ret = set_dvs_levels(&dvs[i], np, desc, cfg->regmap);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int buck1_set_hw_dvs_levels(struct device_node *np,
|
||||
const struct regulator_desc *desc,
|
||||
struct regulator_config *cfg)
|
||||
{
|
||||
int ret, i;
|
||||
const struct of_dvs_setting dvs[] = {
|
||||
{
|
||||
.prop = "rohm,dvs-run-voltage",
|
||||
.reg = BD718XX_REG_BUCK1_VOLT_RUN,
|
||||
},
|
||||
{
|
||||
.prop = "rohm,dvs-idle-voltage",
|
||||
.reg = BD718XX_REG_BUCK1_VOLT_IDLE,
|
||||
},
|
||||
{
|
||||
.prop = "rohm,dvs-suspend-voltage",
|
||||
.reg = BD718XX_REG_BUCK1_VOLT_SUSP,
|
||||
},
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dvs); i++) {
|
||||
ret = set_dvs_levels(&dvs[i], np, desc, cfg->regmap);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct bd718xx_regulator_data bd71847_regulators[] = {
|
||||
{
|
||||
.desc = {
|
||||
@ -368,6 +497,7 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
|
||||
.enable_reg = BD718XX_REG_BUCK1_CTRL,
|
||||
.enable_mask = BD718XX_BUCK_EN,
|
||||
.owner = THIS_MODULE,
|
||||
.of_parse_cb = buck1_set_hw_dvs_levels,
|
||||
},
|
||||
.init = {
|
||||
.reg = BD718XX_REG_BUCK1_CTRL,
|
||||
@ -391,6 +521,7 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
|
||||
.enable_reg = BD718XX_REG_BUCK2_CTRL,
|
||||
.enable_mask = BD718XX_BUCK_EN,
|
||||
.owner = THIS_MODULE,
|
||||
.of_parse_cb = buck2_set_hw_dvs_levels,
|
||||
},
|
||||
.init = {
|
||||
.reg = BD718XX_REG_BUCK2_CTRL,
|
||||
@ -662,6 +793,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
|
||||
.enable_reg = BD718XX_REG_BUCK1_CTRL,
|
||||
.enable_mask = BD718XX_BUCK_EN,
|
||||
.owner = THIS_MODULE,
|
||||
.of_parse_cb = buck1_set_hw_dvs_levels,
|
||||
},
|
||||
.init = {
|
||||
.reg = BD718XX_REG_BUCK1_CTRL,
|
||||
@ -685,6 +817,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
|
||||
.enable_reg = BD718XX_REG_BUCK2_CTRL,
|
||||
.enable_mask = BD718XX_BUCK_EN,
|
||||
.owner = THIS_MODULE,
|
||||
.of_parse_cb = buck2_set_hw_dvs_levels,
|
||||
},
|
||||
.init = {
|
||||
.reg = BD718XX_REG_BUCK2_CTRL,
|
||||
@ -708,6 +841,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
|
||||
.enable_reg = BD71837_REG_BUCK3_CTRL,
|
||||
.enable_mask = BD718XX_BUCK_EN,
|
||||
.owner = THIS_MODULE,
|
||||
.of_parse_cb = buck3_set_hw_dvs_levels,
|
||||
},
|
||||
.init = {
|
||||
.reg = BD71837_REG_BUCK3_CTRL,
|
||||
@ -731,6 +865,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
|
||||
.enable_reg = BD71837_REG_BUCK4_CTRL,
|
||||
.enable_mask = BD718XX_BUCK_EN,
|
||||
.owner = THIS_MODULE,
|
||||
.of_parse_cb = buck4_set_hw_dvs_levels,
|
||||
},
|
||||
.init = {
|
||||
.reg = BD71837_REG_BUCK4_CTRL,
|
||||
@ -1029,6 +1164,7 @@ static int bd718xx_probe(struct platform_device *pdev)
|
||||
};
|
||||
|
||||
int i, j, err;
|
||||
bool use_snvs;
|
||||
|
||||
mfd = dev_get_drvdata(pdev->dev.parent);
|
||||
if (!mfd) {
|
||||
@ -1055,27 +1191,28 @@ static int bd718xx_probe(struct platform_device *pdev)
|
||||
BD718XX_REG_REGLOCK);
|
||||
}
|
||||
|
||||
/* At poweroff transition PMIC HW disables EN bit for regulators but
|
||||
* leaves SEL bit untouched. So if state transition from POWEROFF
|
||||
* is done to SNVS - then all power rails controlled by SW (having
|
||||
* SEL bit set) stay disabled as EN is cleared. This may result boot
|
||||
* failure if any crucial systems are powered by these rails.
|
||||
*
|
||||
use_snvs = of_property_read_bool(pdev->dev.parent->of_node,
|
||||
"rohm,reset-snvs-powered");
|
||||
|
||||
/*
|
||||
* Change the next stage from poweroff to be READY instead of SNVS
|
||||
* for all reset types because OTP loading at READY will clear SEL
|
||||
* bit allowing HW defaults for power rails to be used
|
||||
*/
|
||||
err = regmap_update_bits(mfd->regmap, BD718XX_REG_TRANS_COND1,
|
||||
BD718XX_ON_REQ_POWEROFF_MASK |
|
||||
BD718XX_SWRESET_POWEROFF_MASK |
|
||||
BD718XX_WDOG_POWEROFF_MASK |
|
||||
BD718XX_KEY_L_POWEROFF_MASK,
|
||||
BD718XX_POWOFF_TO_RDY);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "Failed to change reset target\n");
|
||||
goto err;
|
||||
} else {
|
||||
dev_dbg(&pdev->dev, "Changed all resets from SVNS to READY\n");
|
||||
if (!use_snvs) {
|
||||
err = regmap_update_bits(mfd->regmap, BD718XX_REG_TRANS_COND1,
|
||||
BD718XX_ON_REQ_POWEROFF_MASK |
|
||||
BD718XX_SWRESET_POWEROFF_MASK |
|
||||
BD718XX_WDOG_POWEROFF_MASK |
|
||||
BD718XX_KEY_L_POWEROFF_MASK,
|
||||
BD718XX_POWOFF_TO_RDY);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "Failed to change reset target\n");
|
||||
goto err;
|
||||
} else {
|
||||
dev_dbg(&pdev->dev,
|
||||
"Changed all resets from SVNS to READY\n");
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < pmic_regulators[mfd->chip_type].r_amount; i++) {
|
||||
@ -1098,19 +1235,33 @@ static int bd718xx_probe(struct platform_device *pdev)
|
||||
err = PTR_ERR(rdev);
|
||||
goto err;
|
||||
}
|
||||
/* Regulator register gets the regulator constraints and
|
||||
|
||||
/*
|
||||
* Regulator register gets the regulator constraints and
|
||||
* applies them (set_machine_constraints). This should have
|
||||
* turned the control register(s) to correct values and we
|
||||
* can now switch the control from PMIC state machine to the
|
||||
* register interface
|
||||
*
|
||||
* At poweroff transition PMIC HW disables EN bit for
|
||||
* regulators but leaves SEL bit untouched. So if state
|
||||
* transition from POWEROFF is done to SNVS - then all power
|
||||
* rails controlled by SW (having SEL bit set) stay disabled
|
||||
* as EN is cleared. This will result boot failure if any
|
||||
* crucial systems are powered by these rails. We don't
|
||||
* enable SW control for crucial regulators if snvs state is
|
||||
* used
|
||||
*/
|
||||
err = regmap_update_bits(mfd->regmap, r->init.reg,
|
||||
r->init.mask, r->init.val);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev,
|
||||
"Failed to write BUCK/LDO SEL bit for (%s)\n",
|
||||
desc->name);
|
||||
goto err;
|
||||
if (!use_snvs || !rdev->constraints->always_on ||
|
||||
!rdev->constraints->boot_on) {
|
||||
err = regmap_update_bits(mfd->regmap, r->init.reg,
|
||||
r->init.mask, r->init.val);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev,
|
||||
"Failed to take control for (%s)\n",
|
||||
desc->name);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
for (j = 0; j < r->additional_init_amnt; j++) {
|
||||
err = regmap_update_bits(mfd->regmap,
|
||||
|
@ -100,7 +100,7 @@ static int bd9571mwv_reg_set_voltage_sel_regmap(struct regulator_dev *rdev,
|
||||
}
|
||||
|
||||
/* Operations permitted on AVS voltage regulator */
|
||||
static struct regulator_ops avs_ops = {
|
||||
static const struct regulator_ops avs_ops = {
|
||||
.set_voltage_sel = bd9571mwv_avs_set_voltage_sel_regmap,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = bd9571mwv_avs_get_voltage_sel_regmap,
|
||||
@ -108,7 +108,7 @@ static struct regulator_ops avs_ops = {
|
||||
};
|
||||
|
||||
/* Operations permitted on voltage regulators */
|
||||
static struct regulator_ops reg_ops = {
|
||||
static const struct regulator_ops reg_ops = {
|
||||
.set_voltage_sel = bd9571mwv_reg_set_voltage_sel_regmap,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
@ -116,13 +116,13 @@ static struct regulator_ops reg_ops = {
|
||||
};
|
||||
|
||||
/* Operations permitted on voltage monitors */
|
||||
static struct regulator_ops vid_ops = {
|
||||
static const struct regulator_ops vid_ops = {
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
};
|
||||
|
||||
static struct regulator_desc regulators[] = {
|
||||
static const struct regulator_desc regulators[] = {
|
||||
BD9571MWV_REG("VD09", "vd09", VD09, avs_ops, 0, 0x7f,
|
||||
0x80, 600000, 10000, 0x3c),
|
||||
BD9571MWV_REG("VD18", "vd18", VD18, vid_ops, BD9571MWV_VD18_VID, 0xf,
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regmap.h>
|
||||
@ -82,7 +81,6 @@ struct regulator_enable_gpio {
|
||||
struct gpio_desc *gpiod;
|
||||
u32 enable_count; /* a number of enabled shared GPIO */
|
||||
u32 request_count; /* a number of requested shared GPIO */
|
||||
unsigned int ena_gpio_invert:1;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -145,14 +143,6 @@ static bool regulator_ops_is_valid(struct regulator_dev *rdev, int ops)
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline struct regulator_dev *rdev_get_supply(struct regulator_dev *rdev)
|
||||
{
|
||||
if (rdev && rdev->supply)
|
||||
return rdev->supply->rdev;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* regulator_lock_nested - lock a single regulator
|
||||
* @rdev: regulator source
|
||||
@ -326,7 +316,7 @@ err_unlock:
|
||||
* @rdev: regulator source
|
||||
* @ww_ctx: w/w mutex acquire context
|
||||
*
|
||||
* Unlock all regulators related with rdev by coupling or suppling.
|
||||
* Unlock all regulators related with rdev by coupling or supplying.
|
||||
*/
|
||||
static void regulator_unlock_dependent(struct regulator_dev *rdev,
|
||||
struct ww_acquire_ctx *ww_ctx)
|
||||
@ -341,7 +331,7 @@ static void regulator_unlock_dependent(struct regulator_dev *rdev,
|
||||
* @ww_ctx: w/w mutex acquire context
|
||||
*
|
||||
* This function as a wrapper on regulator_lock_recursive(), which locks
|
||||
* all regulators related with rdev by coupling or suppling.
|
||||
* all regulators related with rdev by coupling or supplying.
|
||||
*/
|
||||
static void regulator_lock_dependent(struct regulator_dev *rdev,
|
||||
struct ww_acquire_ctx *ww_ctx)
|
||||
@ -924,14 +914,14 @@ static int drms_uA_update(struct regulator_dev *rdev)
|
||||
int current_uA = 0, output_uV, input_uV, err;
|
||||
unsigned int mode;
|
||||
|
||||
lockdep_assert_held_once(&rdev->mutex.base);
|
||||
|
||||
/*
|
||||
* first check to see if we can set modes at all, otherwise just
|
||||
* tell the consumer everything is OK.
|
||||
*/
|
||||
if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_DRMS))
|
||||
if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_DRMS)) {
|
||||
rdev_dbg(rdev, "DRMS operation not allowed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!rdev->desc->ops->get_optimum_mode &&
|
||||
!rdev->desc->ops->set_load)
|
||||
@ -1003,7 +993,7 @@ static int suspend_set_state(struct regulator_dev *rdev,
|
||||
if (rstate == NULL)
|
||||
return 0;
|
||||
|
||||
/* If we have no suspend mode configration don't set anything;
|
||||
/* If we have no suspend mode configuration don't set anything;
|
||||
* only warn if the driver implements set_suspend_voltage or
|
||||
* set_suspend_mode callback.
|
||||
*/
|
||||
@ -1131,7 +1121,7 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
|
||||
int current_uV = _regulator_get_voltage(rdev);
|
||||
|
||||
if (current_uV == -ENOTRECOVERABLE) {
|
||||
/* This regulator can't be read and must be initted */
|
||||
/* This regulator can't be read and must be initialized */
|
||||
rdev_info(rdev, "Setting %d-%duV\n",
|
||||
rdev->constraints->min_uV,
|
||||
rdev->constraints->max_uV);
|
||||
@ -1782,7 +1772,7 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
|
||||
struct device *dev = rdev->dev.parent;
|
||||
int ret;
|
||||
|
||||
/* No supply to resovle? */
|
||||
/* No supply to resolve? */
|
||||
if (!rdev->supply_name)
|
||||
return 0;
|
||||
|
||||
@ -2231,38 +2221,21 @@ static int regulator_ena_gpio_request(struct regulator_dev *rdev,
|
||||
{
|
||||
struct regulator_enable_gpio *pin;
|
||||
struct gpio_desc *gpiod;
|
||||
int ret;
|
||||
|
||||
if (config->ena_gpiod)
|
||||
gpiod = config->ena_gpiod;
|
||||
else
|
||||
gpiod = gpio_to_desc(config->ena_gpio);
|
||||
gpiod = config->ena_gpiod;
|
||||
|
||||
list_for_each_entry(pin, ®ulator_ena_gpio_list, list) {
|
||||
if (pin->gpiod == gpiod) {
|
||||
rdev_dbg(rdev, "GPIO %d is already used\n",
|
||||
config->ena_gpio);
|
||||
rdev_dbg(rdev, "GPIO is already used\n");
|
||||
goto update_ena_gpio_to_rdev;
|
||||
}
|
||||
}
|
||||
|
||||
if (!config->ena_gpiod) {
|
||||
ret = gpio_request_one(config->ena_gpio,
|
||||
GPIOF_DIR_OUT | config->ena_gpio_flags,
|
||||
rdev_get_name(rdev));
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
pin = kzalloc(sizeof(struct regulator_enable_gpio), GFP_KERNEL);
|
||||
if (pin == NULL) {
|
||||
if (!config->ena_gpiod)
|
||||
gpio_free(config->ena_gpio);
|
||||
if (pin == NULL)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pin->gpiod = gpiod;
|
||||
pin->ena_gpio_invert = config->ena_gpio_invert;
|
||||
list_add(&pin->list, ®ulator_ena_gpio_list);
|
||||
|
||||
update_ena_gpio_to_rdev:
|
||||
@ -2283,7 +2256,6 @@ static void regulator_ena_gpio_free(struct regulator_dev *rdev)
|
||||
if (pin->gpiod == rdev->ena_pin->gpiod) {
|
||||
if (pin->request_count <= 1) {
|
||||
pin->request_count = 0;
|
||||
gpiod_put(pin->gpiod);
|
||||
list_del(&pin->list);
|
||||
kfree(pin);
|
||||
rdev->ena_pin = NULL;
|
||||
@ -2313,8 +2285,7 @@ static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable)
|
||||
if (enable) {
|
||||
/* Enable GPIO at initial use */
|
||||
if (pin->enable_count == 0)
|
||||
gpiod_set_value_cansleep(pin->gpiod,
|
||||
!pin->ena_gpio_invert);
|
||||
gpiod_set_value_cansleep(pin->gpiod, 1);
|
||||
|
||||
pin->enable_count++;
|
||||
} else {
|
||||
@ -2325,8 +2296,7 @@ static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable)
|
||||
|
||||
/* Disable GPIO if not used */
|
||||
if (pin->enable_count <= 1) {
|
||||
gpiod_set_value_cansleep(pin->gpiod,
|
||||
pin->ena_gpio_invert);
|
||||
gpiod_set_value_cansleep(pin->gpiod, 0);
|
||||
pin->enable_count = 0;
|
||||
}
|
||||
}
|
||||
@ -2403,7 +2373,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
|
||||
* timer wrapping.
|
||||
* in case of multiple timer wrapping, either it can be
|
||||
* detected by out-of-range remaining, or it cannot be
|
||||
* detected and we gets a panelty of
|
||||
* detected and we get a penalty of
|
||||
* _regulator_enable_delay().
|
||||
*/
|
||||
remaining = intended - start_jiffy;
|
||||
@ -2803,7 +2773,7 @@ static void regulator_disable_work(struct work_struct *work)
|
||||
/**
|
||||
* regulator_disable_deferred - disable regulator output with delay
|
||||
* @regulator: regulator source
|
||||
* @ms: miliseconds until the regulator is disabled
|
||||
* @ms: milliseconds until the regulator is disabled
|
||||
*
|
||||
* Execute regulator_disable() on the regulator after a delay. This
|
||||
* is intended for use with devices that require some time to quiesce.
|
||||
@ -4937,7 +4907,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
|
||||
* device tree until we have handled it over to the core. If the
|
||||
* config that was passed in to this function DOES NOT contain
|
||||
* a descriptor, and the config after this call DOES contain
|
||||
* a descriptor, we definately got one from parsing the device
|
||||
* a descriptor, we definitely got one from parsing the device
|
||||
* tree.
|
||||
*/
|
||||
if (!cfg->ena_gpiod && config->ena_gpiod)
|
||||
@ -4969,15 +4939,13 @@ regulator_register(const struct regulator_desc *regulator_desc,
|
||||
goto clean;
|
||||
}
|
||||
|
||||
if (config->ena_gpiod ||
|
||||
((config->ena_gpio || config->ena_gpio_initialized) &&
|
||||
gpio_is_valid(config->ena_gpio))) {
|
||||
if (config->ena_gpiod) {
|
||||
mutex_lock(®ulator_list_mutex);
|
||||
ret = regulator_ena_gpio_request(rdev, config);
|
||||
mutex_unlock(®ulator_list_mutex);
|
||||
if (ret != 0) {
|
||||
rdev_err(rdev, "Failed to request enable GPIO%d: %d\n",
|
||||
config->ena_gpio, ret);
|
||||
rdev_err(rdev, "Failed to request enable GPIO: %d\n",
|
||||
ret);
|
||||
goto clean;
|
||||
}
|
||||
/* The regulator core took over the GPIO descriptor */
|
||||
@ -5245,6 +5213,12 @@ struct device *rdev_get_dev(struct regulator_dev *rdev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rdev_get_dev);
|
||||
|
||||
struct regmap *rdev_get_regmap(struct regulator_dev *rdev)
|
||||
{
|
||||
return rdev->regmap;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rdev_get_regmap);
|
||||
|
||||
void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data)
|
||||
{
|
||||
return reg_init_data->driver_data;
|
||||
|
@ -100,12 +100,11 @@ struct cpcap_regulator {
|
||||
struct regulator_desc rdesc;
|
||||
const u16 assign_reg;
|
||||
const u16 assign_mask;
|
||||
const u16 vsel_shift;
|
||||
};
|
||||
|
||||
#define CPCAP_REG(_ID, reg, assignment_reg, assignment_mask, val_tbl, \
|
||||
mode_mask, volt_mask, volt_shft, \
|
||||
mode_val, off_val, volt_trans_time) { \
|
||||
mode_mask, volt_mask, mode_val, off_val, \
|
||||
volt_trans_time) { \
|
||||
.rdesc = { \
|
||||
.name = #_ID, \
|
||||
.of_match = of_match_ptr(#_ID), \
|
||||
@ -127,7 +126,6 @@ struct cpcap_regulator {
|
||||
}, \
|
||||
.assign_reg = (assignment_reg), \
|
||||
.assign_mask = (assignment_mask), \
|
||||
.vsel_shift = (volt_shft), \
|
||||
}
|
||||
|
||||
struct cpcap_ddata {
|
||||
@ -336,155 +334,155 @@ static const unsigned int vaudio_val_tbl[] = { 0, 2775000, };
|
||||
* SW1 to SW4 and SW6 seems to be unused for mapphone. Note that VSIM and
|
||||
* VSIMCARD have a shared resource assignment bit.
|
||||
*/
|
||||
static struct cpcap_regulator omap4_regulators[] = {
|
||||
static const struct cpcap_regulator omap4_regulators[] = {
|
||||
CPCAP_REG(SW1, CPCAP_REG_S1C1, CPCAP_REG_ASSIGN2,
|
||||
CPCAP_BIT_SW1_SEL, unknown_val_tbl,
|
||||
0, 0, 0, 0, 0, 0),
|
||||
0, 0, 0, 0, 0),
|
||||
CPCAP_REG(SW2, CPCAP_REG_S2C1, CPCAP_REG_ASSIGN2,
|
||||
CPCAP_BIT_SW2_SEL, unknown_val_tbl,
|
||||
0, 0, 0, 0, 0, 0),
|
||||
0, 0, 0, 0, 0),
|
||||
CPCAP_REG(SW3, CPCAP_REG_S3C, CPCAP_REG_ASSIGN2,
|
||||
CPCAP_BIT_SW3_SEL, unknown_val_tbl,
|
||||
0, 0, 0, 0, 0, 0),
|
||||
0, 0, 0, 0, 0),
|
||||
CPCAP_REG(SW4, CPCAP_REG_S4C1, CPCAP_REG_ASSIGN2,
|
||||
CPCAP_BIT_SW4_SEL, unknown_val_tbl,
|
||||
0, 0, 0, 0, 0, 0),
|
||||
0, 0, 0, 0, 0),
|
||||
CPCAP_REG(SW5, CPCAP_REG_S5C, CPCAP_REG_ASSIGN2,
|
||||
CPCAP_BIT_SW5_SEL, sw5_val_tbl,
|
||||
0x28, 0, 0, 0x20 | CPCAP_REG_OFF_MODE_SEC, 0, 0),
|
||||
0x28, 0, 0x20 | CPCAP_REG_OFF_MODE_SEC, 0, 0),
|
||||
CPCAP_REG(SW6, CPCAP_REG_S6C, CPCAP_REG_ASSIGN2,
|
||||
CPCAP_BIT_SW6_SEL, unknown_val_tbl,
|
||||
0, 0, 0, 0, 0, 0),
|
||||
0, 0, 0, 0, 0),
|
||||
CPCAP_REG(VCAM, CPCAP_REG_VCAMC, CPCAP_REG_ASSIGN2,
|
||||
CPCAP_BIT_VCAM_SEL, vcam_val_tbl,
|
||||
0x87, 0x30, 4, 0x3, 0, 420),
|
||||
0x87, 0x30, 0x3, 0, 420),
|
||||
CPCAP_REG(VCSI, CPCAP_REG_VCSIC, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VCSI_SEL, vcsi_val_tbl,
|
||||
0x47, 0x10, 4, 0x43, 0x41, 350),
|
||||
0x47, 0x10, 0x43, 0x41, 350),
|
||||
CPCAP_REG(VDAC, CPCAP_REG_VDACC, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VDAC_SEL, vdac_val_tbl,
|
||||
0x87, 0x30, 4, 0x3, 0, 420),
|
||||
0x87, 0x30, 0x3, 0, 420),
|
||||
CPCAP_REG(VDIG, CPCAP_REG_VDIGC, CPCAP_REG_ASSIGN2,
|
||||
CPCAP_BIT_VDIG_SEL, vdig_val_tbl,
|
||||
0x87, 0x30, 4, 0x82, 0, 420),
|
||||
0x87, 0x30, 0x82, 0, 420),
|
||||
CPCAP_REG(VFUSE, CPCAP_REG_VFUSEC, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VFUSE_SEL, vfuse_val_tbl,
|
||||
0x80, 0xf, 0, 0x80, 0, 420),
|
||||
0x80, 0xf, 0x80, 0, 420),
|
||||
CPCAP_REG(VHVIO, CPCAP_REG_VHVIOC, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VHVIO_SEL, vhvio_val_tbl,
|
||||
0x17, 0, 0, 0, 0x12, 0),
|
||||
0x17, 0, 0, 0x12, 0),
|
||||
CPCAP_REG(VSDIO, CPCAP_REG_VSDIOC, CPCAP_REG_ASSIGN2,
|
||||
CPCAP_BIT_VSDIO_SEL, vsdio_val_tbl,
|
||||
0x87, 0x38, 3, 0x82, 0, 420),
|
||||
0x87, 0x38, 0x82, 0, 420),
|
||||
CPCAP_REG(VPLL, CPCAP_REG_VPLLC, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VPLL_SEL, vpll_val_tbl,
|
||||
0x43, 0x18, 3, 0x2, 0, 420),
|
||||
0x43, 0x18, 0x2, 0, 420),
|
||||
CPCAP_REG(VRF1, CPCAP_REG_VRF1C, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VRF1_SEL, vrf1_val_tbl,
|
||||
0xac, 0x2, 1, 0x4, 0, 10),
|
||||
0xac, 0x2, 0x4, 0, 10),
|
||||
CPCAP_REG(VRF2, CPCAP_REG_VRF2C, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VRF2_SEL, vrf2_val_tbl,
|
||||
0x23, 0x8, 3, 0, 0, 10),
|
||||
0x23, 0x8, 0, 0, 10),
|
||||
CPCAP_REG(VRFREF, CPCAP_REG_VRFREFC, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VRFREF_SEL, vrfref_val_tbl,
|
||||
0x23, 0x8, 3, 0, 0, 420),
|
||||
0x23, 0x8, 0, 0, 420),
|
||||
CPCAP_REG(VWLAN1, CPCAP_REG_VWLAN1C, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VWLAN1_SEL, vwlan1_val_tbl,
|
||||
0x47, 0x10, 4, 0, 0, 420),
|
||||
0x47, 0x10, 0, 0, 420),
|
||||
CPCAP_REG(VWLAN2, CPCAP_REG_VWLAN2C, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VWLAN2_SEL, vwlan2_val_tbl,
|
||||
0x20c, 0xc0, 6, 0x20c, 0, 420),
|
||||
0x20c, 0xc0, 0x20c, 0, 420),
|
||||
CPCAP_REG(VSIM, CPCAP_REG_VSIMC, CPCAP_REG_ASSIGN3,
|
||||
0xffff, vsim_val_tbl,
|
||||
0x23, 0x8, 3, 0x3, 0, 420),
|
||||
0x23, 0x8, 0x3, 0, 420),
|
||||
CPCAP_REG(VSIMCARD, CPCAP_REG_VSIMC, CPCAP_REG_ASSIGN3,
|
||||
0xffff, vsimcard_val_tbl,
|
||||
0x1e80, 0x8, 3, 0x1e00, 0, 420),
|
||||
0x1e80, 0x8, 0x1e00, 0, 420),
|
||||
CPCAP_REG(VVIB, CPCAP_REG_VVIBC, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VVIB_SEL, vvib_val_tbl,
|
||||
0x1, 0xc, 2, 0x1, 0, 500),
|
||||
0x1, 0xc, 0x1, 0, 500),
|
||||
CPCAP_REG(VUSB, CPCAP_REG_VUSBC, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VUSB_SEL, vusb_val_tbl,
|
||||
0x11c, 0x40, 6, 0xc, 0, 0),
|
||||
0x11c, 0x40, 0xc, 0, 0),
|
||||
CPCAP_REG(VAUDIO, CPCAP_REG_VAUDIOC, CPCAP_REG_ASSIGN4,
|
||||
CPCAP_BIT_VAUDIO_SEL, vaudio_val_tbl,
|
||||
0x16, 0x1, 0, 0x4, 0, 0),
|
||||
0x16, 0x1, 0x4, 0, 0),
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
static struct cpcap_regulator xoom_regulators[] = {
|
||||
static const struct cpcap_regulator xoom_regulators[] = {
|
||||
CPCAP_REG(SW1, CPCAP_REG_S1C1, CPCAP_REG_ASSIGN2,
|
||||
CPCAP_BIT_SW1_SEL, unknown_val_tbl,
|
||||
0, 0, 0, 0, 0, 0),
|
||||
0, 0, 0, 0, 0),
|
||||
CPCAP_REG(SW2, CPCAP_REG_S2C1, CPCAP_REG_ASSIGN2,
|
||||
CPCAP_BIT_SW2_SEL, sw2_sw4_val_tbl,
|
||||
0xf00, 0x7f, 0, 0x800, 0, 120),
|
||||
0xf00, 0x7f, 0x800, 0, 120),
|
||||
CPCAP_REG(SW3, CPCAP_REG_S3C, CPCAP_REG_ASSIGN2,
|
||||
CPCAP_BIT_SW3_SEL, unknown_val_tbl,
|
||||
0, 0, 0, 0, 0, 0),
|
||||
0, 0, 0, 0, 0),
|
||||
CPCAP_REG(SW4, CPCAP_REG_S4C1, CPCAP_REG_ASSIGN2,
|
||||
CPCAP_BIT_SW4_SEL, sw2_sw4_val_tbl,
|
||||
0xf00, 0x7f, 0, 0x900, 0, 100),
|
||||
0xf00, 0x7f, 0x900, 0, 100),
|
||||
CPCAP_REG(SW5, CPCAP_REG_S5C, CPCAP_REG_ASSIGN2,
|
||||
CPCAP_BIT_SW5_SEL, sw5_val_tbl,
|
||||
0x2a, 0, 0, 0x22, 0, 0),
|
||||
0x2a, 0, 0x22, 0, 0),
|
||||
CPCAP_REG(SW6, CPCAP_REG_S6C, CPCAP_REG_ASSIGN2,
|
||||
CPCAP_BIT_SW6_SEL, unknown_val_tbl,
|
||||
0, 0, 0, 0, 0, 0),
|
||||
0, 0, 0, 0, 0),
|
||||
CPCAP_REG(VCAM, CPCAP_REG_VCAMC, CPCAP_REG_ASSIGN2,
|
||||
CPCAP_BIT_VCAM_SEL, vcam_val_tbl,
|
||||
0x87, 0x30, 4, 0x7, 0, 420),
|
||||
0x87, 0x30, 0x7, 0, 420),
|
||||
CPCAP_REG(VCSI, CPCAP_REG_VCSIC, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VCSI_SEL, vcsi_val_tbl,
|
||||
0x47, 0x10, 4, 0x7, 0, 350),
|
||||
0x47, 0x10, 0x7, 0, 350),
|
||||
CPCAP_REG(VDAC, CPCAP_REG_VDACC, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VDAC_SEL, vdac_val_tbl,
|
||||
0x87, 0x30, 4, 0x3, 0, 420),
|
||||
0x87, 0x30, 0x3, 0, 420),
|
||||
CPCAP_REG(VDIG, CPCAP_REG_VDIGC, CPCAP_REG_ASSIGN2,
|
||||
CPCAP_BIT_VDIG_SEL, vdig_val_tbl,
|
||||
0x87, 0x30, 4, 0x5, 0, 420),
|
||||
0x87, 0x30, 0x5, 0, 420),
|
||||
CPCAP_REG(VFUSE, CPCAP_REG_VFUSEC, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VFUSE_SEL, vfuse_val_tbl,
|
||||
0x80, 0xf, 0, 0x80, 0, 420),
|
||||
0x80, 0xf, 0x80, 0, 420),
|
||||
CPCAP_REG(VHVIO, CPCAP_REG_VHVIOC, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VHVIO_SEL, vhvio_val_tbl,
|
||||
0x17, 0, 0, 0x2, 0, 0),
|
||||
0x17, 0, 0x2, 0, 0),
|
||||
CPCAP_REG(VSDIO, CPCAP_REG_VSDIOC, CPCAP_REG_ASSIGN2,
|
||||
CPCAP_BIT_VSDIO_SEL, vsdio_val_tbl,
|
||||
0x87, 0x38, 3, 0x2, 0, 420),
|
||||
0x87, 0x38, 0x2, 0, 420),
|
||||
CPCAP_REG(VPLL, CPCAP_REG_VPLLC, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VPLL_SEL, vpll_val_tbl,
|
||||
0x43, 0x18, 3, 0x1, 0, 420),
|
||||
0x43, 0x18, 0x1, 0, 420),
|
||||
CPCAP_REG(VRF1, CPCAP_REG_VRF1C, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VRF1_SEL, vrf1_val_tbl,
|
||||
0xac, 0x2, 1, 0xc, 0, 10),
|
||||
0xac, 0x2, 0xc, 0, 10),
|
||||
CPCAP_REG(VRF2, CPCAP_REG_VRF2C, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VRF2_SEL, vrf2_val_tbl,
|
||||
0x23, 0x8, 3, 0x3, 0, 10),
|
||||
0x23, 0x8, 0x3, 0, 10),
|
||||
CPCAP_REG(VRFREF, CPCAP_REG_VRFREFC, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VRFREF_SEL, vrfref_val_tbl,
|
||||
0x23, 0x8, 3, 0x3, 0, 420),
|
||||
0x23, 0x8, 0x3, 0, 420),
|
||||
CPCAP_REG(VWLAN1, CPCAP_REG_VWLAN1C, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VWLAN1_SEL, vwlan1_val_tbl,
|
||||
0x47, 0x10, 4, 0x5, 0, 420),
|
||||
0x47, 0x10, 0x5, 0, 420),
|
||||
CPCAP_REG(VWLAN2, CPCAP_REG_VWLAN2C, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VWLAN2_SEL, vwlan2_val_tbl,
|
||||
0x20c, 0xc0, 6, 0x8, 0, 420),
|
||||
0x20c, 0xc0, 0x8, 0, 420),
|
||||
CPCAP_REG(VSIM, CPCAP_REG_VSIMC, CPCAP_REG_ASSIGN3,
|
||||
0xffff, vsim_val_tbl,
|
||||
0x23, 0x8, 3, 0x3, 0, 420),
|
||||
0x23, 0x8, 0x3, 0, 420),
|
||||
CPCAP_REG(VSIMCARD, CPCAP_REG_VSIMC, CPCAP_REG_ASSIGN3,
|
||||
0xffff, vsimcard_val_tbl,
|
||||
0x1e80, 0x8, 3, 0x1e00, 0, 420),
|
||||
0x1e80, 0x8, 0x1e00, 0, 420),
|
||||
CPCAP_REG(VVIB, CPCAP_REG_VVIBC, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VVIB_SEL, vvib_val_tbl,
|
||||
0x1, 0xc, 2, 0, 0x1, 500),
|
||||
0x1, 0xc, 0, 0x1, 500),
|
||||
CPCAP_REG(VUSB, CPCAP_REG_VUSBC, CPCAP_REG_ASSIGN3,
|
||||
CPCAP_BIT_VUSB_SEL, vusb_val_tbl,
|
||||
0x11c, 0x40, 6, 0xc, 0, 0),
|
||||
0x11c, 0x40, 0xc, 0, 0),
|
||||
CPCAP_REG(VAUDIO, CPCAP_REG_VAUDIOC, CPCAP_REG_ASSIGN4,
|
||||
CPCAP_BIT_VAUDIO_SEL, vaudio_val_tbl,
|
||||
0x16, 0x1, 0, 0x4, 0, 0),
|
||||
0x16, 0x1, 0x4, 0, 0),
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
|
@ -48,7 +48,9 @@
|
||||
#define DA9055_ID_LDO6 7
|
||||
|
||||
/* DA9055 BUCK current limit */
|
||||
static const int da9055_current_limits[] = { 500000, 600000, 700000, 800000 };
|
||||
static const unsigned int da9055_current_limits[] = {
|
||||
500000, 600000, 700000, 800000
|
||||
};
|
||||
|
||||
struct da9055_conf_reg {
|
||||
int reg;
|
||||
@ -169,39 +171,6 @@ static int da9055_ldo_set_mode(struct regulator_dev *rdev, unsigned int mode)
|
||||
val << volt.sl_shift);
|
||||
}
|
||||
|
||||
static int da9055_buck_get_current_limit(struct regulator_dev *rdev)
|
||||
{
|
||||
struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
|
||||
struct da9055_regulator_info *info = regulator->info;
|
||||
int ret;
|
||||
|
||||
ret = da9055_reg_read(regulator->da9055, DA9055_REG_BUCK_LIM);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret &= info->mode.mask;
|
||||
return da9055_current_limits[ret >> info->mode.shift];
|
||||
}
|
||||
|
||||
static int da9055_buck_set_current_limit(struct regulator_dev *rdev, int min_uA,
|
||||
int max_uA)
|
||||
{
|
||||
struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
|
||||
struct da9055_regulator_info *info = regulator->info;
|
||||
int i;
|
||||
|
||||
for (i = ARRAY_SIZE(da9055_current_limits) - 1; i >= 0; i--) {
|
||||
if ((min_uA <= da9055_current_limits[i]) &&
|
||||
(da9055_current_limits[i] <= max_uA))
|
||||
return da9055_reg_update(regulator->da9055,
|
||||
DA9055_REG_BUCK_LIM,
|
||||
info->mode.mask,
|
||||
i << info->mode.shift);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int da9055_regulator_get_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
|
||||
@ -329,8 +298,8 @@ static const struct regulator_ops da9055_buck_ops = {
|
||||
.get_mode = da9055_buck_get_mode,
|
||||
.set_mode = da9055_buck_set_mode,
|
||||
|
||||
.get_current_limit = da9055_buck_get_current_limit,
|
||||
.set_current_limit = da9055_buck_set_current_limit,
|
||||
.get_current_limit = regulator_get_current_limit_regmap,
|
||||
.set_current_limit = regulator_set_current_limit_regmap,
|
||||
|
||||
.get_voltage_sel = da9055_regulator_get_voltage_sel,
|
||||
.set_voltage_sel = da9055_regulator_set_voltage_sel,
|
||||
@ -407,6 +376,10 @@ static const struct regulator_ops da9055_ldo_ops = {
|
||||
.uV_step = (step) * 1000,\
|
||||
.linear_min_sel = (voffset),\
|
||||
.owner = THIS_MODULE,\
|
||||
.curr_table = da9055_current_limits,\
|
||||
.n_current_limits = ARRAY_SIZE(da9055_current_limits),\
|
||||
.csel_reg = DA9055_REG_BUCK_LIM,\
|
||||
.csel_mask = (mbits),\
|
||||
},\
|
||||
.conf = {\
|
||||
.reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \
|
||||
@ -457,7 +430,6 @@ static int da9055_gpio_init(struct da9055_regulator *regulator,
|
||||
int gpio_mux = pdata->gpio_ren[id];
|
||||
|
||||
config->ena_gpiod = pdata->ena_gpiods[id];
|
||||
config->ena_gpio_invert = 1;
|
||||
|
||||
/*
|
||||
* GPI pin is muxed with regulator to control the
|
||||
|
@ -126,7 +126,7 @@ static int da9062_set_current_limit(struct regulator_dev *rdev,
|
||||
const struct da9062_regulator_info *rinfo = regl->info;
|
||||
int n, tval;
|
||||
|
||||
for (n = 0; n < rinfo->n_current_limits; n++) {
|
||||
for (n = rinfo->n_current_limits - 1; n >= 0; n--) {
|
||||
tval = rinfo->current_limits[n];
|
||||
if (tval >= min_ua && tval <= max_ua)
|
||||
return regmap_field_write(regl->ilimit, n);
|
||||
@ -992,7 +992,6 @@ static int da9062_regulator_probe(struct platform_device *pdev)
|
||||
struct regulator_config config = { };
|
||||
const struct da9062_regulator_info *rinfo;
|
||||
int irq, n, ret;
|
||||
size_t size;
|
||||
int max_regulators;
|
||||
|
||||
switch (chip->chip_type) {
|
||||
@ -1010,9 +1009,8 @@ static int da9062_regulator_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
/* Allocate memory required by usable regulators */
|
||||
size = sizeof(struct da9062_regulators) +
|
||||
max_regulators * sizeof(struct da9062_regulator);
|
||||
regulators = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
|
||||
regulators = devm_kzalloc(&pdev->dev, struct_size(regulators, regulator,
|
||||
max_regulators), GFP_KERNEL);
|
||||
if (!regulators)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1029,31 +1027,50 @@ static int da9062_regulator_probe(struct platform_device *pdev)
|
||||
regl->desc.type = REGULATOR_VOLTAGE;
|
||||
regl->desc.owner = THIS_MODULE;
|
||||
|
||||
if (regl->info->mode.reg)
|
||||
if (regl->info->mode.reg) {
|
||||
regl->mode = devm_regmap_field_alloc(
|
||||
&pdev->dev,
|
||||
chip->regmap,
|
||||
regl->info->mode);
|
||||
if (regl->info->suspend.reg)
|
||||
if (IS_ERR(regl->mode))
|
||||
return PTR_ERR(regl->mode);
|
||||
}
|
||||
|
||||
if (regl->info->suspend.reg) {
|
||||
regl->suspend = devm_regmap_field_alloc(
|
||||
&pdev->dev,
|
||||
chip->regmap,
|
||||
regl->info->suspend);
|
||||
if (regl->info->sleep.reg)
|
||||
if (IS_ERR(regl->suspend))
|
||||
return PTR_ERR(regl->suspend);
|
||||
}
|
||||
|
||||
if (regl->info->sleep.reg) {
|
||||
regl->sleep = devm_regmap_field_alloc(
|
||||
&pdev->dev,
|
||||
chip->regmap,
|
||||
regl->info->sleep);
|
||||
if (regl->info->suspend_sleep.reg)
|
||||
if (IS_ERR(regl->sleep))
|
||||
return PTR_ERR(regl->sleep);
|
||||
}
|
||||
|
||||
if (regl->info->suspend_sleep.reg) {
|
||||
regl->suspend_sleep = devm_regmap_field_alloc(
|
||||
&pdev->dev,
|
||||
chip->regmap,
|
||||
regl->info->suspend_sleep);
|
||||
if (regl->info->ilimit.reg)
|
||||
if (IS_ERR(regl->suspend_sleep))
|
||||
return PTR_ERR(regl->suspend_sleep);
|
||||
}
|
||||
|
||||
if (regl->info->ilimit.reg) {
|
||||
regl->ilimit = devm_regmap_field_alloc(
|
||||
&pdev->dev,
|
||||
chip->regmap,
|
||||
regl->info->ilimit);
|
||||
if (IS_ERR(regl->ilimit))
|
||||
return PTR_ERR(regl->ilimit);
|
||||
}
|
||||
|
||||
/* Register regulator */
|
||||
memset(&config, 0, sizeof(config));
|
||||
|
@ -167,7 +167,7 @@ static int da9063_set_current_limit(struct regulator_dev *rdev,
|
||||
const struct da9063_regulator_info *rinfo = regl->info;
|
||||
int n, tval;
|
||||
|
||||
for (n = 0; n < rinfo->n_current_limits; n++) {
|
||||
for (n = rinfo->n_current_limits - 1; n >= 0; n--) {
|
||||
tval = rinfo->current_limits[n];
|
||||
if (tval >= min_uA && tval <= max_uA)
|
||||
return regmap_field_write(regl->ilimit, n);
|
||||
@ -739,7 +739,6 @@ static int da9063_regulator_probe(struct platform_device *pdev)
|
||||
struct regulator_config config;
|
||||
bool bcores_merged, bmem_bio_merged;
|
||||
int id, irq, n, n_regulators, ret, val;
|
||||
size_t size;
|
||||
|
||||
regl_pdata = da9063_pdata ? da9063_pdata->regulators_pdata : NULL;
|
||||
|
||||
@ -784,9 +783,8 @@ static int da9063_regulator_probe(struct platform_device *pdev)
|
||||
n_regulators--; /* remove BMEM_BIO_MERGED */
|
||||
|
||||
/* Allocate memory required by usable regulators */
|
||||
size = sizeof(struct da9063_regulators) +
|
||||
n_regulators * sizeof(struct da9063_regulator);
|
||||
regulators = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
|
||||
regulators = devm_kzalloc(&pdev->dev, struct_size(regulators,
|
||||
regulator, n_regulators), GFP_KERNEL);
|
||||
if (!regulators)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -835,21 +833,40 @@ static int da9063_regulator_probe(struct platform_device *pdev)
|
||||
regl->desc.type = REGULATOR_VOLTAGE;
|
||||
regl->desc.owner = THIS_MODULE;
|
||||
|
||||
if (regl->info->mode.reg)
|
||||
if (regl->info->mode.reg) {
|
||||
regl->mode = devm_regmap_field_alloc(&pdev->dev,
|
||||
da9063->regmap, regl->info->mode);
|
||||
if (regl->info->suspend.reg)
|
||||
if (IS_ERR(regl->mode))
|
||||
return PTR_ERR(regl->mode);
|
||||
}
|
||||
|
||||
if (regl->info->suspend.reg) {
|
||||
regl->suspend = devm_regmap_field_alloc(&pdev->dev,
|
||||
da9063->regmap, regl->info->suspend);
|
||||
if (regl->info->sleep.reg)
|
||||
if (IS_ERR(regl->suspend))
|
||||
return PTR_ERR(regl->suspend);
|
||||
}
|
||||
|
||||
if (regl->info->sleep.reg) {
|
||||
regl->sleep = devm_regmap_field_alloc(&pdev->dev,
|
||||
da9063->regmap, regl->info->sleep);
|
||||
if (regl->info->suspend_sleep.reg)
|
||||
if (IS_ERR(regl->sleep))
|
||||
return PTR_ERR(regl->sleep);
|
||||
}
|
||||
|
||||
if (regl->info->suspend_sleep.reg) {
|
||||
regl->suspend_sleep = devm_regmap_field_alloc(&pdev->dev,
|
||||
da9063->regmap, regl->info->suspend_sleep);
|
||||
if (regl->info->ilimit.reg)
|
||||
if (IS_ERR(regl->suspend_sleep))
|
||||
return PTR_ERR(regl->suspend_sleep);
|
||||
}
|
||||
|
||||
if (regl->info->ilimit.reg) {
|
||||
regl->ilimit = devm_regmap_field_alloc(&pdev->dev,
|
||||
da9063->regmap, regl->info->ilimit);
|
||||
if (IS_ERR(regl->ilimit))
|
||||
return PTR_ERR(regl->ilimit);
|
||||
}
|
||||
|
||||
/* Register regulator */
|
||||
memset(&config, 0, sizeof(config));
|
||||
|
@ -41,10 +41,6 @@ static const struct regmap_config da9210_regmap_config = {
|
||||
.val_bits = 8,
|
||||
};
|
||||
|
||||
static int da9210_set_current_limit(struct regulator_dev *rdev, int min_uA,
|
||||
int max_uA);
|
||||
static int da9210_get_current_limit(struct regulator_dev *rdev);
|
||||
|
||||
static const struct regulator_ops da9210_buck_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
@ -52,8 +48,8 @@ static const struct regulator_ops da9210_buck_ops = {
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.set_current_limit = da9210_set_current_limit,
|
||||
.get_current_limit = da9210_get_current_limit,
|
||||
.set_current_limit = regulator_set_current_limit_regmap,
|
||||
.get_current_limit = regulator_get_current_limit_regmap,
|
||||
};
|
||||
|
||||
/* Default limits measured in millivolts and milliamps */
|
||||
@ -62,7 +58,7 @@ static const struct regulator_ops da9210_buck_ops = {
|
||||
#define DA9210_STEP_MV 10
|
||||
|
||||
/* Current limits for buck (uA) indices corresponds with register values */
|
||||
static const int da9210_buck_limits[] = {
|
||||
static const unsigned int da9210_buck_limits[] = {
|
||||
1600000, 1800000, 2000000, 2200000, 2400000, 2600000, 2800000, 3000000,
|
||||
3200000, 3400000, 3600000, 3800000, 4000000, 4200000, 4400000, 4600000
|
||||
};
|
||||
@ -80,47 +76,12 @@ static const struct regulator_desc da9210_reg = {
|
||||
.enable_reg = DA9210_REG_BUCK_CONT,
|
||||
.enable_mask = DA9210_BUCK_EN,
|
||||
.owner = THIS_MODULE,
|
||||
.curr_table = da9210_buck_limits,
|
||||
.n_current_limits = ARRAY_SIZE(da9210_buck_limits),
|
||||
.csel_reg = DA9210_REG_BUCK_ILIM,
|
||||
.csel_mask = DA9210_BUCK_ILIM_MASK,
|
||||
};
|
||||
|
||||
static int da9210_set_current_limit(struct regulator_dev *rdev, int min_uA,
|
||||
int max_uA)
|
||||
{
|
||||
struct da9210 *chip = rdev_get_drvdata(rdev);
|
||||
unsigned int sel;
|
||||
int i;
|
||||
|
||||
/* search for closest to maximum */
|
||||
for (i = ARRAY_SIZE(da9210_buck_limits)-1; i >= 0; i--) {
|
||||
if (min_uA <= da9210_buck_limits[i] &&
|
||||
max_uA >= da9210_buck_limits[i]) {
|
||||
sel = i;
|
||||
sel = sel << DA9210_BUCK_ILIM_SHIFT;
|
||||
return regmap_update_bits(chip->regmap,
|
||||
DA9210_REG_BUCK_ILIM,
|
||||
DA9210_BUCK_ILIM_MASK, sel);
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int da9210_get_current_limit(struct regulator_dev *rdev)
|
||||
{
|
||||
struct da9210 *chip = rdev_get_drvdata(rdev);
|
||||
unsigned int data;
|
||||
unsigned int sel;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(chip->regmap, DA9210_REG_BUCK_ILIM, &data);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* select one of 16 values: 0000 (1600mA) to 1111 (4600mA) */
|
||||
sel = (data & DA9210_BUCK_ILIM_MASK) >> DA9210_BUCK_ILIM_SHIFT;
|
||||
|
||||
return da9210_buck_limits[sel];
|
||||
}
|
||||
|
||||
static irqreturn_t da9210_irq_handler(int irq, void *data)
|
||||
{
|
||||
struct da9210 *chip = data;
|
||||
|
@ -40,7 +40,6 @@
|
||||
/* VSEL bit definitions */
|
||||
#define VSEL_BUCK_EN (1 << 7)
|
||||
#define VSEL_MODE (1 << 6)
|
||||
#define VSEL_NSEL_MASK 0x3F
|
||||
/* Chip ID and Verison */
|
||||
#define DIE_ID 0x0F /* ID1 */
|
||||
#define DIE_REV 0x0F /* ID2 */
|
||||
@ -49,14 +48,26 @@
|
||||
#define CTL_SLEW_MASK (0x7 << 4)
|
||||
#define CTL_SLEW_SHIFT 4
|
||||
#define CTL_RESET (1 << 2)
|
||||
#define CTL_MODE_VSEL0_MODE BIT(0)
|
||||
#define CTL_MODE_VSEL1_MODE BIT(1)
|
||||
|
||||
#define FAN53555_NVOLTAGES 64 /* Numbers of voltages */
|
||||
#define FAN53526_NVOLTAGES 128
|
||||
|
||||
enum fan53555_vendor {
|
||||
FAN53555_VENDOR_FAIRCHILD = 0,
|
||||
FAN53526_VENDOR_FAIRCHILD = 0,
|
||||
FAN53555_VENDOR_FAIRCHILD,
|
||||
FAN53555_VENDOR_SILERGY,
|
||||
};
|
||||
|
||||
enum {
|
||||
FAN53526_CHIP_ID_01 = 1,
|
||||
};
|
||||
|
||||
enum {
|
||||
FAN53526_CHIP_REV_08 = 8,
|
||||
};
|
||||
|
||||
/* IC Type */
|
||||
enum {
|
||||
FAN53555_CHIP_ID_00 = 0,
|
||||
@ -94,8 +105,12 @@ struct fan53555_device_info {
|
||||
/* Voltage range and step(linear) */
|
||||
unsigned int vsel_min;
|
||||
unsigned int vsel_step;
|
||||
unsigned int vsel_count;
|
||||
/* Voltage slew rate limiting */
|
||||
unsigned int slew_rate;
|
||||
/* Mode */
|
||||
unsigned int mode_reg;
|
||||
unsigned int mode_mask;
|
||||
/* Sleep voltage cache */
|
||||
unsigned int sleep_vol_cache;
|
||||
};
|
||||
@ -111,7 +126,7 @@ static int fan53555_set_suspend_voltage(struct regulator_dev *rdev, int uV)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = regmap_update_bits(di->regmap, di->sleep_reg,
|
||||
VSEL_NSEL_MASK, ret);
|
||||
di->desc.vsel_mask, ret);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/* Cache the sleep voltage setting.
|
||||
@ -143,11 +158,11 @@ static int fan53555_set_mode(struct regulator_dev *rdev, unsigned int mode)
|
||||
|
||||
switch (mode) {
|
||||
case REGULATOR_MODE_FAST:
|
||||
regmap_update_bits(di->regmap, di->vol_reg,
|
||||
VSEL_MODE, VSEL_MODE);
|
||||
regmap_update_bits(di->regmap, di->mode_reg,
|
||||
di->mode_mask, di->mode_mask);
|
||||
break;
|
||||
case REGULATOR_MODE_NORMAL:
|
||||
regmap_update_bits(di->regmap, di->vol_reg, VSEL_MODE, 0);
|
||||
regmap_update_bits(di->regmap, di->vol_reg, di->mode_mask, 0);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
@ -161,10 +176,10 @@ static unsigned int fan53555_get_mode(struct regulator_dev *rdev)
|
||||
unsigned int val;
|
||||
int ret = 0;
|
||||
|
||||
ret = regmap_read(di->regmap, di->vol_reg, &val);
|
||||
ret = regmap_read(di->regmap, di->mode_reg, &val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (val & VSEL_MODE)
|
||||
if (val & di->mode_mask)
|
||||
return REGULATOR_MODE_FAST;
|
||||
else
|
||||
return REGULATOR_MODE_NORMAL;
|
||||
@ -219,6 +234,34 @@ static const struct regulator_ops fan53555_regulator_ops = {
|
||||
.set_suspend_disable = fan53555_set_suspend_disable,
|
||||
};
|
||||
|
||||
static int fan53526_voltages_setup_fairchild(struct fan53555_device_info *di)
|
||||
{
|
||||
/* Init voltage range and step */
|
||||
switch (di->chip_id) {
|
||||
case FAN53526_CHIP_ID_01:
|
||||
switch (di->chip_rev) {
|
||||
case FAN53526_CHIP_REV_08:
|
||||
di->vsel_min = 600000;
|
||||
di->vsel_step = 6250;
|
||||
break;
|
||||
default:
|
||||
dev_err(di->dev,
|
||||
"Chip ID %d with rev %d not supported!\n",
|
||||
di->chip_id, di->chip_rev);
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dev_err(di->dev,
|
||||
"Chip ID %d not supported!\n", di->chip_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
di->vsel_count = FAN53526_NVOLTAGES;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fan53555_voltages_setup_fairchild(struct fan53555_device_info *di)
|
||||
{
|
||||
/* Init voltage range and step */
|
||||
@ -257,6 +300,8 @@ static int fan53555_voltages_setup_fairchild(struct fan53555_device_info *di)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
di->vsel_count = FAN53555_NVOLTAGES;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -274,6 +319,8 @@ static int fan53555_voltages_setup_silergy(struct fan53555_device_info *di)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
di->vsel_count = FAN53555_NVOLTAGES;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -302,7 +349,35 @@ static int fan53555_device_setup(struct fan53555_device_info *di,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Setup mode control register */
|
||||
switch (di->vendor) {
|
||||
case FAN53526_VENDOR_FAIRCHILD:
|
||||
di->mode_reg = FAN53555_CONTROL;
|
||||
|
||||
switch (pdata->sleep_vsel_id) {
|
||||
case FAN53555_VSEL_ID_0:
|
||||
di->mode_mask = CTL_MODE_VSEL1_MODE;
|
||||
break;
|
||||
case FAN53555_VSEL_ID_1:
|
||||
di->mode_mask = CTL_MODE_VSEL0_MODE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FAN53555_VENDOR_FAIRCHILD:
|
||||
case FAN53555_VENDOR_SILERGY:
|
||||
di->mode_reg = di->vol_reg;
|
||||
di->mode_mask = VSEL_MODE;
|
||||
break;
|
||||
default:
|
||||
dev_err(di->dev, "vendor %d not supported!\n", di->vendor);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Setup voltage range */
|
||||
switch (di->vendor) {
|
||||
case FAN53526_VENDOR_FAIRCHILD:
|
||||
ret = fan53526_voltages_setup_fairchild(di);
|
||||
break;
|
||||
case FAN53555_VENDOR_FAIRCHILD:
|
||||
ret = fan53555_voltages_setup_fairchild(di);
|
||||
break;
|
||||
@ -326,13 +401,13 @@ static int fan53555_regulator_register(struct fan53555_device_info *di,
|
||||
rdesc->supply_name = "vin";
|
||||
rdesc->ops = &fan53555_regulator_ops;
|
||||
rdesc->type = REGULATOR_VOLTAGE;
|
||||
rdesc->n_voltages = FAN53555_NVOLTAGES;
|
||||
rdesc->n_voltages = di->vsel_count;
|
||||
rdesc->enable_reg = di->vol_reg;
|
||||
rdesc->enable_mask = VSEL_BUCK_EN;
|
||||
rdesc->min_uV = di->vsel_min;
|
||||
rdesc->uV_step = di->vsel_step;
|
||||
rdesc->vsel_reg = di->vol_reg;
|
||||
rdesc->vsel_mask = VSEL_NSEL_MASK;
|
||||
rdesc->vsel_mask = di->vsel_count - 1;
|
||||
rdesc->owner = THIS_MODULE;
|
||||
|
||||
di->rdev = devm_regulator_register(di->dev, &di->desc, config);
|
||||
@ -368,6 +443,9 @@ static struct fan53555_platform_data *fan53555_parse_dt(struct device *dev,
|
||||
|
||||
static const struct of_device_id fan53555_dt_ids[] = {
|
||||
{
|
||||
.compatible = "fcs,fan53526",
|
||||
.data = (void *)FAN53526_VENDOR_FAIRCHILD,
|
||||
}, {
|
||||
.compatible = "fcs,fan53555",
|
||||
.data = (void *)FAN53555_VENDOR_FAIRCHILD
|
||||
}, {
|
||||
@ -412,11 +490,13 @@ static int fan53555_regulator_probe(struct i2c_client *client,
|
||||
} else {
|
||||
/* if no ramp constraint set, get the pdata ramp_delay */
|
||||
if (!di->regulator->constraints.ramp_delay) {
|
||||
int slew_idx = (pdata->slew_rate & 0x7)
|
||||
? pdata->slew_rate : 0;
|
||||
if (pdata->slew_rate >= ARRAY_SIZE(slew_rates)) {
|
||||
dev_err(&client->dev, "Invalid slew_rate\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
di->regulator->constraints.ramp_delay
|
||||
= slew_rates[slew_idx];
|
||||
= slew_rates[pdata->slew_rate];
|
||||
}
|
||||
|
||||
di->vendor = id->driver_data;
|
||||
@ -467,6 +547,9 @@ static int fan53555_regulator_probe(struct i2c_client *client,
|
||||
|
||||
static const struct i2c_device_id fan53555_id[] = {
|
||||
{
|
||||
.name = "fan53526",
|
||||
.driver_data = FAN53526_VENDOR_FAIRCHILD
|
||||
}, {
|
||||
.name = "fan53555",
|
||||
.driver_data = FAN53555_VENDOR_FAIRCHILD
|
||||
}, {
|
||||
|
@ -79,15 +79,6 @@ of_get_fixed_voltage_config(struct device *dev,
|
||||
|
||||
of_property_read_u32(np, "startup-delay-us", &config->startup_delay);
|
||||
|
||||
/*
|
||||
* FIXME: we pulled active low/high and open drain handling into
|
||||
* gpiolib so it will be handled there. Delete this in the second
|
||||
* step when we also remove the custom inversion handling for all
|
||||
* legacy boardfiles.
|
||||
*/
|
||||
config->enable_high = 1;
|
||||
config->gpio_is_open_drain = 0;
|
||||
|
||||
if (of_find_property(np, "vin-supply", NULL))
|
||||
config->input_supply = "vin";
|
||||
|
||||
@ -151,24 +142,14 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
|
||||
|
||||
drvdata->desc.fixed_uV = config->microvolts;
|
||||
|
||||
cfg.ena_gpio_invert = !config->enable_high;
|
||||
if (config->enabled_at_boot) {
|
||||
if (config->enable_high)
|
||||
gflags = GPIOD_OUT_HIGH;
|
||||
else
|
||||
gflags = GPIOD_OUT_LOW;
|
||||
} else {
|
||||
if (config->enable_high)
|
||||
gflags = GPIOD_OUT_LOW;
|
||||
else
|
||||
gflags = GPIOD_OUT_HIGH;
|
||||
}
|
||||
if (config->gpio_is_open_drain) {
|
||||
if (gflags == GPIOD_OUT_HIGH)
|
||||
gflags = GPIOD_OUT_HIGH_OPEN_DRAIN;
|
||||
else
|
||||
gflags = GPIOD_OUT_LOW_OPEN_DRAIN;
|
||||
}
|
||||
/*
|
||||
* The signal will be inverted by the GPIO core if flagged so in the
|
||||
* decriptor.
|
||||
*/
|
||||
if (config->enabled_at_boot)
|
||||
gflags = GPIOD_OUT_HIGH;
|
||||
else
|
||||
gflags = GPIOD_OUT_LOW;
|
||||
|
||||
/*
|
||||
* Some fixed regulators share the enable line between two
|
||||
|
@ -30,16 +30,15 @@
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/regulator/gpio-regulator.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
|
||||
struct gpio_regulator_data {
|
||||
struct regulator_desc desc;
|
||||
struct regulator_dev *dev;
|
||||
|
||||
struct gpio *gpios;
|
||||
struct gpio_desc **gpiods;
|
||||
int nr_gpios;
|
||||
|
||||
struct gpio_regulator_state *states;
|
||||
@ -82,7 +81,7 @@ static int gpio_regulator_set_voltage(struct regulator_dev *dev,
|
||||
|
||||
for (ptr = 0; ptr < data->nr_gpios; ptr++) {
|
||||
state = (target & (1 << ptr)) >> ptr;
|
||||
gpio_set_value_cansleep(data->gpios[ptr].gpio, state);
|
||||
gpiod_set_value_cansleep(data->gpiods[ptr], state);
|
||||
}
|
||||
data->state = target;
|
||||
|
||||
@ -119,7 +118,7 @@ static int gpio_regulator_set_current_limit(struct regulator_dev *dev,
|
||||
|
||||
for (ptr = 0; ptr < data->nr_gpios; ptr++) {
|
||||
state = (target & (1 << ptr)) >> ptr;
|
||||
gpio_set_value_cansleep(data->gpios[ptr].gpio, state);
|
||||
gpiod_set_value_cansleep(data->gpiods[ptr], state);
|
||||
}
|
||||
data->state = target;
|
||||
|
||||
@ -138,7 +137,8 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np,
|
||||
{
|
||||
struct gpio_regulator_config *config;
|
||||
const char *regtype;
|
||||
int proplen, gpio, i;
|
||||
int proplen, i;
|
||||
int ngpios;
|
||||
int ret;
|
||||
|
||||
config = devm_kzalloc(dev,
|
||||
@ -153,59 +153,36 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np,
|
||||
|
||||
config->supply_name = config->init_data->constraints.name;
|
||||
|
||||
if (of_property_read_bool(np, "enable-active-high"))
|
||||
config->enable_high = true;
|
||||
|
||||
if (of_property_read_bool(np, "enable-at-boot"))
|
||||
config->enabled_at_boot = true;
|
||||
|
||||
of_property_read_u32(np, "startup-delay-us", &config->startup_delay);
|
||||
|
||||
config->enable_gpio = of_get_named_gpio(np, "enable-gpio", 0);
|
||||
if (config->enable_gpio < 0 && config->enable_gpio != -ENOENT)
|
||||
return ERR_PTR(config->enable_gpio);
|
||||
|
||||
/* Fetch GPIOs. - optional property*/
|
||||
ret = of_gpio_count(np);
|
||||
if ((ret < 0) && (ret != -ENOENT))
|
||||
return ERR_PTR(ret);
|
||||
|
||||
if (ret > 0) {
|
||||
config->nr_gpios = ret;
|
||||
config->gpios = devm_kcalloc(dev,
|
||||
config->nr_gpios, sizeof(struct gpio),
|
||||
GFP_KERNEL);
|
||||
if (!config->gpios)
|
||||
/* Fetch GPIO init levels */
|
||||
ngpios = gpiod_count(dev, NULL);
|
||||
if (ngpios > 0) {
|
||||
config->gflags = devm_kzalloc(dev,
|
||||
sizeof(enum gpiod_flags)
|
||||
* ngpios,
|
||||
GFP_KERNEL);
|
||||
if (!config->gflags)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
proplen = of_property_count_u32_elems(np, "gpios-states");
|
||||
/* optional property */
|
||||
if (proplen < 0)
|
||||
proplen = 0;
|
||||
for (i = 0; i < ngpios; i++) {
|
||||
u32 val;
|
||||
|
||||
if (proplen > 0 && proplen != config->nr_gpios) {
|
||||
dev_warn(dev, "gpios <-> gpios-states mismatch\n");
|
||||
proplen = 0;
|
||||
}
|
||||
ret = of_property_read_u32_index(np, "gpios-states", i,
|
||||
&val);
|
||||
|
||||
for (i = 0; i < config->nr_gpios; i++) {
|
||||
gpio = of_get_named_gpio(np, "gpios", i);
|
||||
if (gpio < 0) {
|
||||
if (gpio != -ENOENT)
|
||||
return ERR_PTR(gpio);
|
||||
break;
|
||||
}
|
||||
config->gpios[i].gpio = gpio;
|
||||
config->gpios[i].label = config->supply_name;
|
||||
if (proplen > 0) {
|
||||
of_property_read_u32_index(np, "gpios-states",
|
||||
i, &ret);
|
||||
if (ret)
|
||||
config->gpios[i].flags =
|
||||
GPIOF_OUT_INIT_HIGH;
|
||||
}
|
||||
/* Default to high per specification */
|
||||
if (ret)
|
||||
config->gflags[i] = GPIOD_OUT_HIGH;
|
||||
else
|
||||
config->gflags[i] =
|
||||
val ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW;
|
||||
}
|
||||
}
|
||||
config->ngpios = ngpios;
|
||||
|
||||
/* Fetch states. */
|
||||
proplen = of_property_count_u32_elems(np, "states");
|
||||
@ -251,59 +228,56 @@ static struct regulator_ops gpio_regulator_current_ops = {
|
||||
|
||||
static int gpio_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct gpio_regulator_config *config = dev_get_platdata(&pdev->dev);
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct gpio_regulator_config *config = dev_get_platdata(dev);
|
||||
struct device_node *np = dev->of_node;
|
||||
struct gpio_regulator_data *drvdata;
|
||||
struct regulator_config cfg = { };
|
||||
int ptr, ret, state;
|
||||
enum gpiod_flags gflags;
|
||||
int ptr, ret, state, i;
|
||||
|
||||
drvdata = devm_kzalloc(&pdev->dev, sizeof(struct gpio_regulator_data),
|
||||
drvdata = devm_kzalloc(dev, sizeof(struct gpio_regulator_data),
|
||||
GFP_KERNEL);
|
||||
if (drvdata == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
if (np) {
|
||||
config = of_get_gpio_regulator_config(&pdev->dev, np,
|
||||
config = of_get_gpio_regulator_config(dev, np,
|
||||
&drvdata->desc);
|
||||
if (IS_ERR(config))
|
||||
return PTR_ERR(config);
|
||||
}
|
||||
|
||||
drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL);
|
||||
drvdata->desc.name = devm_kstrdup(dev, config->supply_name, GFP_KERNEL);
|
||||
if (drvdata->desc.name == NULL) {
|
||||
dev_err(&pdev->dev, "Failed to allocate supply name\n");
|
||||
dev_err(dev, "Failed to allocate supply name\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (config->nr_gpios != 0) {
|
||||
drvdata->gpios = kmemdup(config->gpios,
|
||||
config->nr_gpios * sizeof(struct gpio),
|
||||
GFP_KERNEL);
|
||||
if (drvdata->gpios == NULL) {
|
||||
dev_err(&pdev->dev, "Failed to allocate gpio data\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_name;
|
||||
}
|
||||
|
||||
drvdata->nr_gpios = config->nr_gpios;
|
||||
ret = gpio_request_array(drvdata->gpios, drvdata->nr_gpios);
|
||||
if (ret) {
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(&pdev->dev,
|
||||
"Could not obtain regulator setting GPIOs: %d\n",
|
||||
ret);
|
||||
goto err_memgpio;
|
||||
}
|
||||
drvdata->gpiods = devm_kzalloc(dev, sizeof(struct gpio_desc *),
|
||||
GFP_KERNEL);
|
||||
if (!drvdata->gpiods)
|
||||
return -ENOMEM;
|
||||
for (i = 0; i < config->ngpios; i++) {
|
||||
drvdata->gpiods[i] = devm_gpiod_get_index(dev,
|
||||
NULL,
|
||||
i,
|
||||
config->gflags[i]);
|
||||
if (IS_ERR(drvdata->gpiods[i]))
|
||||
return PTR_ERR(drvdata->gpiods[i]);
|
||||
/* This is good to know */
|
||||
gpiod_set_consumer_name(drvdata->gpiods[i], drvdata->desc.name);
|
||||
}
|
||||
drvdata->nr_gpios = config->ngpios;
|
||||
|
||||
drvdata->states = kmemdup(config->states,
|
||||
config->nr_states *
|
||||
sizeof(struct gpio_regulator_state),
|
||||
GFP_KERNEL);
|
||||
drvdata->states = devm_kmemdup(dev,
|
||||
config->states,
|
||||
config->nr_states *
|
||||
sizeof(struct gpio_regulator_state),
|
||||
GFP_KERNEL);
|
||||
if (drvdata->states == NULL) {
|
||||
dev_err(&pdev->dev, "Failed to allocate state data\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_stategpio;
|
||||
dev_err(dev, "Failed to allocate state data\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
drvdata->nr_states = config->nr_states;
|
||||
|
||||
@ -322,61 +296,46 @@ static int gpio_regulator_probe(struct platform_device *pdev)
|
||||
drvdata->desc.ops = &gpio_regulator_current_ops;
|
||||
break;
|
||||
default:
|
||||
dev_err(&pdev->dev, "No regulator type set\n");
|
||||
ret = -EINVAL;
|
||||
goto err_memstate;
|
||||
dev_err(dev, "No regulator type set\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* build initial state from gpio init data. */
|
||||
state = 0;
|
||||
for (ptr = 0; ptr < drvdata->nr_gpios; ptr++) {
|
||||
if (config->gpios[ptr].flags & GPIOF_OUT_INIT_HIGH)
|
||||
if (config->gflags[ptr] == GPIOD_OUT_HIGH)
|
||||
state |= (1 << ptr);
|
||||
}
|
||||
drvdata->state = state;
|
||||
|
||||
cfg.dev = &pdev->dev;
|
||||
cfg.dev = dev;
|
||||
cfg.init_data = config->init_data;
|
||||
cfg.driver_data = drvdata;
|
||||
cfg.of_node = np;
|
||||
|
||||
if (gpio_is_valid(config->enable_gpio)) {
|
||||
cfg.ena_gpio = config->enable_gpio;
|
||||
cfg.ena_gpio_initialized = true;
|
||||
}
|
||||
cfg.ena_gpio_invert = !config->enable_high;
|
||||
if (config->enabled_at_boot) {
|
||||
if (config->enable_high)
|
||||
cfg.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH;
|
||||
else
|
||||
cfg.ena_gpio_flags |= GPIOF_OUT_INIT_LOW;
|
||||
} else {
|
||||
if (config->enable_high)
|
||||
cfg.ena_gpio_flags |= GPIOF_OUT_INIT_LOW;
|
||||
else
|
||||
cfg.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH;
|
||||
}
|
||||
/*
|
||||
* The signal will be inverted by the GPIO core if flagged so in the
|
||||
* decriptor.
|
||||
*/
|
||||
if (config->enabled_at_boot)
|
||||
gflags = GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_NONEXCLUSIVE;
|
||||
else
|
||||
gflags = GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_NONEXCLUSIVE;
|
||||
|
||||
cfg.ena_gpiod = gpiod_get_optional(dev, "enable", gflags);
|
||||
if (IS_ERR(cfg.ena_gpiod))
|
||||
return PTR_ERR(cfg.ena_gpiod);
|
||||
|
||||
drvdata->dev = regulator_register(&drvdata->desc, &cfg);
|
||||
if (IS_ERR(drvdata->dev)) {
|
||||
ret = PTR_ERR(drvdata->dev);
|
||||
dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret);
|
||||
goto err_memstate;
|
||||
dev_err(dev, "Failed to register regulator: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, drvdata);
|
||||
|
||||
return 0;
|
||||
|
||||
err_memstate:
|
||||
kfree(drvdata->states);
|
||||
err_stategpio:
|
||||
gpio_free_array(drvdata->gpios, drvdata->nr_gpios);
|
||||
err_memgpio:
|
||||
kfree(drvdata->gpios);
|
||||
err_name:
|
||||
kfree(drvdata->desc.name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int gpio_regulator_remove(struct platform_device *pdev)
|
||||
@ -385,13 +344,6 @@ static int gpio_regulator_remove(struct platform_device *pdev)
|
||||
|
||||
regulator_unregister(drvdata->dev);
|
||||
|
||||
gpio_free_array(drvdata->gpios, drvdata->nr_gpios);
|
||||
|
||||
kfree(drvdata->states);
|
||||
kfree(drvdata->gpios);
|
||||
|
||||
kfree(drvdata->desc.name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -593,6 +593,45 @@ int regulator_list_voltage_pickable_linear_range(struct regulator_dev *rdev,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_list_voltage_pickable_linear_range);
|
||||
|
||||
/**
|
||||
* regulator_desc_list_voltage_linear_range - List voltages for linear ranges
|
||||
*
|
||||
* @desc: Regulator desc for regulator which volatges are to be listed
|
||||
* @selector: Selector to convert into a voltage
|
||||
*
|
||||
* Regulators with a series of simple linear mappings between voltages
|
||||
* and selectors who have set linear_ranges in the regulator descriptor
|
||||
* can use this function prior regulator registration to list voltages.
|
||||
* This is useful when voltages need to be listed during device-tree
|
||||
* parsing.
|
||||
*/
|
||||
int regulator_desc_list_voltage_linear_range(const struct regulator_desc *desc,
|
||||
unsigned int selector)
|
||||
{
|
||||
const struct regulator_linear_range *range;
|
||||
int i;
|
||||
|
||||
if (!desc->n_linear_ranges) {
|
||||
BUG_ON(!desc->n_linear_ranges);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < desc->n_linear_ranges; i++) {
|
||||
range = &desc->linear_ranges[i];
|
||||
|
||||
if (!(selector >= range->min_sel &&
|
||||
selector <= range->max_sel))
|
||||
continue;
|
||||
|
||||
selector -= range->min_sel;
|
||||
|
||||
return range->min_uV + (range->uV_step * selector);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_desc_list_voltage_linear_range);
|
||||
|
||||
/**
|
||||
* regulator_list_voltage_linear_range - List voltages for linear ranges
|
||||
*
|
||||
@ -606,27 +645,7 @@ EXPORT_SYMBOL_GPL(regulator_list_voltage_pickable_linear_range);
|
||||
int regulator_list_voltage_linear_range(struct regulator_dev *rdev,
|
||||
unsigned int selector)
|
||||
{
|
||||
const struct regulator_linear_range *range;
|
||||
int i;
|
||||
|
||||
if (!rdev->desc->n_linear_ranges) {
|
||||
BUG_ON(!rdev->desc->n_linear_ranges);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
|
||||
range = &rdev->desc->linear_ranges[i];
|
||||
|
||||
if (!(selector >= range->min_sel &&
|
||||
selector <= range->max_sel))
|
||||
continue;
|
||||
|
||||
selector -= range->min_sel;
|
||||
|
||||
return range->min_uV + (range->uV_step * selector);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
return regulator_desc_list_voltage_linear_range(rdev->desc, selector);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_list_voltage_linear_range);
|
||||
|
||||
@ -761,3 +780,89 @@ int regulator_set_active_discharge_regmap(struct regulator_dev *rdev,
|
||||
rdev->desc->active_discharge_mask, val);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_set_active_discharge_regmap);
|
||||
|
||||
/**
|
||||
* regulator_set_current_limit_regmap - set_current_limit for regmap users
|
||||
*
|
||||
* @rdev: regulator to operate on
|
||||
* @min_uA: Lower bound for current limit
|
||||
* @max_uA: Upper bound for current limit
|
||||
*
|
||||
* Regulators that use regmap for their register I/O can set curr_table,
|
||||
* csel_reg and csel_mask fields in their descriptor and then use this
|
||||
* as their set_current_limit operation, saving some code.
|
||||
*/
|
||||
int regulator_set_current_limit_regmap(struct regulator_dev *rdev,
|
||||
int min_uA, int max_uA)
|
||||
{
|
||||
unsigned int n_currents = rdev->desc->n_current_limits;
|
||||
int i, sel = -1;
|
||||
|
||||
if (n_currents == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (rdev->desc->curr_table) {
|
||||
const unsigned int *curr_table = rdev->desc->curr_table;
|
||||
bool ascend = curr_table[n_currents - 1] > curr_table[0];
|
||||
|
||||
/* search for closest to maximum */
|
||||
if (ascend) {
|
||||
for (i = n_currents - 1; i >= 0; i--) {
|
||||
if (min_uA <= curr_table[i] &&
|
||||
curr_table[i] <= max_uA) {
|
||||
sel = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < n_currents; i++) {
|
||||
if (min_uA <= curr_table[i] &&
|
||||
curr_table[i] <= max_uA) {
|
||||
sel = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sel < 0)
|
||||
return -EINVAL;
|
||||
|
||||
sel <<= ffs(rdev->desc->csel_mask) - 1;
|
||||
|
||||
return regmap_update_bits(rdev->regmap, rdev->desc->csel_reg,
|
||||
rdev->desc->csel_mask, sel);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_set_current_limit_regmap);
|
||||
|
||||
/**
|
||||
* regulator_get_current_limit_regmap - get_current_limit for regmap users
|
||||
*
|
||||
* @rdev: regulator to operate on
|
||||
*
|
||||
* Regulators that use regmap for their register I/O can set the
|
||||
* csel_reg and csel_mask fields in their descriptor and then use this
|
||||
* as their get_current_limit operation, saving some code.
|
||||
*/
|
||||
int regulator_get_current_limit_regmap(struct regulator_dev *rdev)
|
||||
{
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(rdev->regmap, rdev->desc->csel_reg, &val);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
val &= rdev->desc->csel_mask;
|
||||
val >>= ffs(rdev->desc->csel_mask) - 1;
|
||||
|
||||
if (rdev->desc->curr_table) {
|
||||
if (val >= rdev->desc->n_current_limits)
|
||||
return -EINVAL;
|
||||
|
||||
return rdev->desc->curr_table[val];
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_get_current_limit_regmap);
|
||||
|
@ -28,7 +28,6 @@
|
||||
struct hi655x_regulator {
|
||||
unsigned int disable_reg;
|
||||
unsigned int status_reg;
|
||||
unsigned int ctrl_regs;
|
||||
unsigned int ctrl_mask;
|
||||
struct regulator_desc rdesc;
|
||||
};
|
||||
|
@ -31,7 +31,6 @@
|
||||
/* PMIC details */
|
||||
struct isl_pmic {
|
||||
struct i2c_client *client;
|
||||
struct regulator_dev *rdev[3];
|
||||
struct mutex mtx;
|
||||
};
|
||||
|
||||
@ -66,14 +65,14 @@ static int isl6271a_set_voltage_sel(struct regulator_dev *dev,
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct regulator_ops isl_core_ops = {
|
||||
static const struct regulator_ops isl_core_ops = {
|
||||
.get_voltage_sel = isl6271a_get_voltage_sel,
|
||||
.set_voltage_sel = isl6271a_set_voltage_sel,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
};
|
||||
|
||||
static struct regulator_ops isl_fixed_ops = {
|
||||
static const struct regulator_ops isl_fixed_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
};
|
||||
|
||||
@ -109,6 +108,7 @@ static const struct regulator_desc isl_rd[] = {
|
||||
static int isl6271a_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct regulator_dev *rdev;
|
||||
struct regulator_config config = { };
|
||||
struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev);
|
||||
struct isl_pmic *pmic;
|
||||
@ -133,11 +133,10 @@ static int isl6271a_probe(struct i2c_client *i2c,
|
||||
config.init_data = NULL;
|
||||
config.driver_data = pmic;
|
||||
|
||||
pmic->rdev[i] = devm_regulator_register(&i2c->dev, &isl_rd[i],
|
||||
&config);
|
||||
if (IS_ERR(pmic->rdev[i])) {
|
||||
rdev = devm_regulator_register(&i2c->dev, &isl_rd[i], &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(&i2c->dev, "failed to register %s\n", id->name);
|
||||
return PTR_ERR(pmic->rdev[i]);
|
||||
return PTR_ERR(rdev);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -258,6 +258,9 @@ static int lm363x_regulator_probe(struct platform_device *pdev)
|
||||
* Register update is required if the pin is used.
|
||||
*/
|
||||
gpiod = lm363x_regulator_of_get_enable_gpio(dev, id);
|
||||
if (IS_ERR(gpiod))
|
||||
return PTR_ERR(gpiod);
|
||||
|
||||
if (gpiod) {
|
||||
cfg.ena_gpiod = gpiod;
|
||||
|
||||
@ -265,8 +268,7 @@ static int lm363x_regulator_probe(struct platform_device *pdev)
|
||||
LM3632_EXT_EN_MASK,
|
||||
LM3632_EXT_EN_MASK);
|
||||
if (ret) {
|
||||
if (gpiod)
|
||||
gpiod_put(gpiod);
|
||||
gpiod_put(gpiod);
|
||||
dev_err(dev, "External pin err: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -232,8 +232,9 @@ static const struct of_device_id lochnagar_of_match[] = {
|
||||
.compatible = "cirrus,lochnagar2-vddcore",
|
||||
.data = &lochnagar_regulators[LOCHNAGAR_VDDCORE],
|
||||
},
|
||||
{},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, lochnagar_of_match);
|
||||
|
||||
static int lochnagar_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
|
@ -159,7 +159,7 @@ static int lp3971_ldo_set_voltage_sel(struct regulator_dev *dev,
|
||||
selector << LDO_VOL_CONTR_SHIFT(ldo));
|
||||
}
|
||||
|
||||
static struct regulator_ops lp3971_ldo_ops = {
|
||||
static const struct regulator_ops lp3971_ldo_ops = {
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
.map_voltage = regulator_map_voltage_ascend,
|
||||
.is_enabled = lp3971_ldo_is_enabled,
|
||||
@ -233,7 +233,7 @@ static int lp3971_dcdc_set_voltage_sel(struct regulator_dev *dev,
|
||||
0 << BUCK_VOL_CHANGE_SHIFT(buck));
|
||||
}
|
||||
|
||||
static struct regulator_ops lp3971_dcdc_ops = {
|
||||
static const struct regulator_ops lp3971_dcdc_ops = {
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
.map_voltage = regulator_map_voltage_ascend,
|
||||
.is_enabled = lp3971_dcdc_is_enabled,
|
||||
|
@ -305,7 +305,7 @@ static int lp3972_ldo_set_voltage_sel(struct regulator_dev *dev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct regulator_ops lp3972_ldo_ops = {
|
||||
static const struct regulator_ops lp3972_ldo_ops = {
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
.map_voltage = regulator_map_voltage_ascend,
|
||||
.is_enabled = lp3972_ldo_is_enabled,
|
||||
@ -386,7 +386,7 @@ static int lp3972_dcdc_set_voltage_sel(struct regulator_dev *dev,
|
||||
LP3972_VOL_CHANGE_FLAG_MASK, 0);
|
||||
}
|
||||
|
||||
static struct regulator_ops lp3972_dcdc_ops = {
|
||||
static const struct regulator_ops lp3972_dcdc_ops = {
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
.map_voltage = regulator_map_voltage_ascend,
|
||||
.is_enabled = lp3972_dcdc_is_enabled,
|
||||
|
@ -353,64 +353,6 @@ static int lp872x_buck_get_voltage_sel(struct regulator_dev *rdev)
|
||||
return val & LP872X_VOUT_M;
|
||||
}
|
||||
|
||||
static int lp8725_buck_set_current_limit(struct regulator_dev *rdev,
|
||||
int min_uA, int max_uA)
|
||||
{
|
||||
struct lp872x *lp = rdev_get_drvdata(rdev);
|
||||
enum lp872x_regulator_id buck = rdev_get_id(rdev);
|
||||
int i;
|
||||
u8 addr;
|
||||
|
||||
switch (buck) {
|
||||
case LP8725_ID_BUCK1:
|
||||
addr = LP8725_BUCK1_VOUT2;
|
||||
break;
|
||||
case LP8725_ID_BUCK2:
|
||||
addr = LP8725_BUCK2_VOUT2;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = ARRAY_SIZE(lp8725_buck_uA) - 1; i >= 0; i--) {
|
||||
if (lp8725_buck_uA[i] >= min_uA &&
|
||||
lp8725_buck_uA[i] <= max_uA)
|
||||
return lp872x_update_bits(lp, addr,
|
||||
LP8725_BUCK_CL_M,
|
||||
i << LP8725_BUCK_CL_S);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int lp8725_buck_get_current_limit(struct regulator_dev *rdev)
|
||||
{
|
||||
struct lp872x *lp = rdev_get_drvdata(rdev);
|
||||
enum lp872x_regulator_id buck = rdev_get_id(rdev);
|
||||
u8 addr, val;
|
||||
int ret;
|
||||
|
||||
switch (buck) {
|
||||
case LP8725_ID_BUCK1:
|
||||
addr = LP8725_BUCK1_VOUT2;
|
||||
break;
|
||||
case LP8725_ID_BUCK2:
|
||||
addr = LP8725_BUCK2_VOUT2;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = lp872x_read_byte(lp, addr, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
val = (val & LP8725_BUCK_CL_M) >> LP8725_BUCK_CL_S;
|
||||
|
||||
return (val < ARRAY_SIZE(lp8725_buck_uA)) ?
|
||||
lp8725_buck_uA[val] : -EINVAL;
|
||||
}
|
||||
|
||||
static int lp872x_buck_set_mode(struct regulator_dev *rdev, unsigned int mode)
|
||||
{
|
||||
struct lp872x *lp = rdev_get_drvdata(rdev);
|
||||
@ -478,7 +420,7 @@ static unsigned int lp872x_buck_get_mode(struct regulator_dev *rdev)
|
||||
return val & mask ? REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
|
||||
}
|
||||
|
||||
static struct regulator_ops lp872x_ldo_ops = {
|
||||
static const struct regulator_ops lp872x_ldo_ops = {
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
.map_voltage = regulator_map_voltage_ascend,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
@ -489,7 +431,7 @@ static struct regulator_ops lp872x_ldo_ops = {
|
||||
.enable_time = lp872x_regulator_enable_time,
|
||||
};
|
||||
|
||||
static struct regulator_ops lp8720_buck_ops = {
|
||||
static const struct regulator_ops lp8720_buck_ops = {
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
.map_voltage = regulator_map_voltage_ascend,
|
||||
.set_voltage_sel = lp872x_buck_set_voltage_sel,
|
||||
@ -502,7 +444,7 @@ static struct regulator_ops lp8720_buck_ops = {
|
||||
.get_mode = lp872x_buck_get_mode,
|
||||
};
|
||||
|
||||
static struct regulator_ops lp8725_buck_ops = {
|
||||
static const struct regulator_ops lp8725_buck_ops = {
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
.map_voltage = regulator_map_voltage_ascend,
|
||||
.set_voltage_sel = lp872x_buck_set_voltage_sel,
|
||||
@ -513,11 +455,11 @@ static struct regulator_ops lp8725_buck_ops = {
|
||||
.enable_time = lp872x_regulator_enable_time,
|
||||
.set_mode = lp872x_buck_set_mode,
|
||||
.get_mode = lp872x_buck_get_mode,
|
||||
.set_current_limit = lp8725_buck_set_current_limit,
|
||||
.get_current_limit = lp8725_buck_get_current_limit,
|
||||
.set_current_limit = regulator_set_current_limit_regmap,
|
||||
.get_current_limit = regulator_get_current_limit_regmap,
|
||||
};
|
||||
|
||||
static struct regulator_desc lp8720_regulator_desc[] = {
|
||||
static const struct regulator_desc lp8720_regulator_desc[] = {
|
||||
{
|
||||
.name = "ldo1",
|
||||
.of_match = of_match_ptr("ldo1"),
|
||||
@ -602,7 +544,7 @@ static struct regulator_desc lp8720_regulator_desc[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct regulator_desc lp8725_regulator_desc[] = {
|
||||
static const struct regulator_desc lp8725_regulator_desc[] = {
|
||||
{
|
||||
.name = "ldo1",
|
||||
.of_match = of_match_ptr("ldo1"),
|
||||
@ -712,6 +654,10 @@ static struct regulator_desc lp8725_regulator_desc[] = {
|
||||
.owner = THIS_MODULE,
|
||||
.enable_reg = LP872X_GENERAL_CFG,
|
||||
.enable_mask = LP8725_BUCK1_EN_M,
|
||||
.curr_table = lp8725_buck_uA,
|
||||
.n_current_limits = ARRAY_SIZE(lp8725_buck_uA),
|
||||
.csel_reg = LP8725_BUCK1_VOUT2,
|
||||
.csel_mask = LP8725_BUCK_CL_M,
|
||||
},
|
||||
{
|
||||
.name = "buck2",
|
||||
@ -724,6 +670,10 @@ static struct regulator_desc lp8725_regulator_desc[] = {
|
||||
.owner = THIS_MODULE,
|
||||
.enable_reg = LP872X_GENERAL_CFG,
|
||||
.enable_mask = LP8725_BUCK2_EN_M,
|
||||
.curr_table = lp8725_buck_uA,
|
||||
.n_current_limits = ARRAY_SIZE(lp8725_buck_uA),
|
||||
.csel_reg = LP8725_BUCK2_VOUT2,
|
||||
.csel_mask = LP8725_BUCK_CL_M,
|
||||
},
|
||||
};
|
||||
|
||||
@ -820,7 +770,7 @@ static struct regulator_init_data
|
||||
|
||||
static int lp872x_regulator_register(struct lp872x *lp)
|
||||
{
|
||||
struct regulator_desc *desc;
|
||||
const struct regulator_desc *desc;
|
||||
struct regulator_config cfg = { };
|
||||
struct regulator_dev *rdev;
|
||||
int i;
|
||||
|
@ -39,6 +39,10 @@
|
||||
.ramp_delay = _delay, \
|
||||
.linear_ranges = _lr, \
|
||||
.n_linear_ranges = ARRAY_SIZE(_lr), \
|
||||
.curr_table = lp873x_buck_uA, \
|
||||
.n_current_limits = ARRAY_SIZE(lp873x_buck_uA), \
|
||||
.csel_reg = (_cr), \
|
||||
.csel_mask = LP873X_BUCK0_CTRL_2_BUCK0_ILIM,\
|
||||
}, \
|
||||
.ctrl2_reg = _cr, \
|
||||
}
|
||||
@ -61,7 +65,7 @@ static const struct regulator_linear_range ldo0_ldo1_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(800000, 0x0, 0x19, 100000),
|
||||
};
|
||||
|
||||
static unsigned int lp873x_buck_ramp_delay[] = {
|
||||
static const unsigned int lp873x_buck_ramp_delay[] = {
|
||||
30000, 15000, 10000, 7500, 3800, 1900, 940, 470
|
||||
};
|
||||
|
||||
@ -108,45 +112,8 @@ static int lp873x_buck_set_ramp_delay(struct regulator_dev *rdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lp873x_buck_set_current_limit(struct regulator_dev *rdev,
|
||||
int min_uA, int max_uA)
|
||||
{
|
||||
int id = rdev_get_id(rdev);
|
||||
struct lp873x *lp873 = rdev_get_drvdata(rdev);
|
||||
int i;
|
||||
|
||||
for (i = ARRAY_SIZE(lp873x_buck_uA) - 1; i >= 0; i--) {
|
||||
if (lp873x_buck_uA[i] >= min_uA &&
|
||||
lp873x_buck_uA[i] <= max_uA)
|
||||
return regmap_update_bits(lp873->regmap,
|
||||
regulators[id].ctrl2_reg,
|
||||
LP873X_BUCK0_CTRL_2_BUCK0_ILIM,
|
||||
i << __ffs(LP873X_BUCK0_CTRL_2_BUCK0_ILIM));
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int lp873x_buck_get_current_limit(struct regulator_dev *rdev)
|
||||
{
|
||||
int id = rdev_get_id(rdev);
|
||||
struct lp873x *lp873 = rdev_get_drvdata(rdev);
|
||||
int ret;
|
||||
unsigned int val;
|
||||
|
||||
ret = regmap_read(lp873->regmap, regulators[id].ctrl2_reg, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
val = (val & LP873X_BUCK0_CTRL_2_BUCK0_ILIM) >>
|
||||
__ffs(LP873X_BUCK0_CTRL_2_BUCK0_ILIM);
|
||||
|
||||
return (val < ARRAY_SIZE(lp873x_buck_uA)) ?
|
||||
lp873x_buck_uA[val] : -EINVAL;
|
||||
}
|
||||
|
||||
/* Operations permitted on BUCK0, BUCK1 */
|
||||
static struct regulator_ops lp873x_buck01_ops = {
|
||||
static const struct regulator_ops lp873x_buck01_ops = {
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
@ -156,12 +123,12 @@ static struct regulator_ops lp873x_buck01_ops = {
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
.set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||
.set_ramp_delay = lp873x_buck_set_ramp_delay,
|
||||
.set_current_limit = lp873x_buck_set_current_limit,
|
||||
.get_current_limit = lp873x_buck_get_current_limit,
|
||||
.set_current_limit = regulator_set_current_limit_regmap,
|
||||
.get_current_limit = regulator_get_current_limit_regmap,
|
||||
};
|
||||
|
||||
/* Operations permitted on LDO0 and LDO1 */
|
||||
static struct regulator_ops lp873x_ldo01_ops = {
|
||||
static const struct regulator_ops lp873x_ldo01_ops = {
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
|
@ -315,7 +315,7 @@ out_i2c_error:
|
||||
.vsel_mask = LP8755_BUCK_VOUT_M,\
|
||||
}
|
||||
|
||||
static struct regulator_desc lp8755_regulators[] = {
|
||||
static const struct regulator_desc lp8755_regulators[] = {
|
||||
lp8755_buck_desc(0),
|
||||
lp8755_buck_desc(1),
|
||||
lp8755_buck_desc(2),
|
||||
@ -386,7 +386,7 @@ static irqreturn_t lp8755_irq_handler(int irq, void *data)
|
||||
if (ret < 0)
|
||||
goto err_i2c;
|
||||
|
||||
/* send OCP event to all regualtor devices */
|
||||
/* send OCP event to all regulator devices */
|
||||
if ((flag1 & 0x01) && (pchip->irqmask & 0x01))
|
||||
for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++)
|
||||
if (pchip->rdev[icnt] != NULL)
|
||||
@ -394,7 +394,7 @@ static irqreturn_t lp8755_irq_handler(int irq, void *data)
|
||||
LP8755_EVENT_OCP,
|
||||
NULL);
|
||||
|
||||
/* send OVP event to all regualtor devices */
|
||||
/* send OVP event to all regulator devices */
|
||||
if ((flag1 & 0x02) && (pchip->irqmask & 0x02))
|
||||
for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++)
|
||||
if (pchip->rdev[icnt] != NULL)
|
||||
|
@ -51,7 +51,7 @@ static const struct regulator_linear_range buck0_1_2_3_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1420000, 0x9e, 0xff, 20000),
|
||||
};
|
||||
|
||||
static unsigned int lp87565_buck_ramp_delay[] = {
|
||||
static const unsigned int lp87565_buck_ramp_delay[] = {
|
||||
30000, 15000, 10000, 7500, 3800, 1900, 940, 470
|
||||
};
|
||||
|
||||
@ -140,7 +140,7 @@ static int lp87565_buck_get_current_limit(struct regulator_dev *rdev)
|
||||
}
|
||||
|
||||
/* Operations permitted on BUCK0, BUCK1 */
|
||||
static struct regulator_ops lp87565_buck_ops = {
|
||||
static const struct regulator_ops lp87565_buck_ops = {
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
|
@ -95,12 +95,10 @@ struct lp8788_buck {
|
||||
void *dvs;
|
||||
};
|
||||
|
||||
/* BUCK 1 ~ 4 voltage table */
|
||||
static const int lp8788_buck_vtbl[] = {
|
||||
500000, 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000,
|
||||
1150000, 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000,
|
||||
1550000, 1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000,
|
||||
1950000, 2000000,
|
||||
/* BUCK 1 ~ 4 voltage ranges */
|
||||
static const struct regulator_linear_range buck_volt_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 0, 0, 0),
|
||||
REGULATOR_LINEAR_RANGE(800000, 1, 25, 50000),
|
||||
};
|
||||
|
||||
static void lp8788_buck1_set_dvs(struct lp8788_buck *buck)
|
||||
@ -345,8 +343,8 @@ static unsigned int lp8788_buck_get_mode(struct regulator_dev *rdev)
|
||||
}
|
||||
|
||||
static const struct regulator_ops lp8788_buck12_ops = {
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
.map_voltage = regulator_map_voltage_ascend,
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
.set_voltage_sel = lp8788_buck12_set_voltage_sel,
|
||||
.get_voltage_sel = lp8788_buck12_get_voltage_sel,
|
||||
.enable = regulator_enable_regmap,
|
||||
@ -358,8 +356,8 @@ static const struct regulator_ops lp8788_buck12_ops = {
|
||||
};
|
||||
|
||||
static const struct regulator_ops lp8788_buck34_ops = {
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
.map_voltage = regulator_map_voltage_ascend,
|
||||
.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,
|
||||
.enable = regulator_enable_regmap,
|
||||
@ -370,13 +368,14 @@ static const struct regulator_ops lp8788_buck34_ops = {
|
||||
.get_mode = lp8788_buck_get_mode,
|
||||
};
|
||||
|
||||
static struct regulator_desc lp8788_buck_desc[] = {
|
||||
static const struct regulator_desc lp8788_buck_desc[] = {
|
||||
{
|
||||
.name = "buck1",
|
||||
.id = BUCK1,
|
||||
.ops = &lp8788_buck12_ops,
|
||||
.n_voltages = ARRAY_SIZE(lp8788_buck_vtbl),
|
||||
.volt_table = lp8788_buck_vtbl,
|
||||
.n_voltages = 26,
|
||||
.linear_ranges = buck_volt_ranges,
|
||||
.n_linear_ranges = ARRAY_SIZE(buck_volt_ranges),
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.enable_reg = LP8788_EN_BUCK,
|
||||
@ -386,8 +385,9 @@ static struct regulator_desc lp8788_buck_desc[] = {
|
||||
.name = "buck2",
|
||||
.id = BUCK2,
|
||||
.ops = &lp8788_buck12_ops,
|
||||
.n_voltages = ARRAY_SIZE(lp8788_buck_vtbl),
|
||||
.volt_table = lp8788_buck_vtbl,
|
||||
.n_voltages = 26,
|
||||
.linear_ranges = buck_volt_ranges,
|
||||
.n_linear_ranges = ARRAY_SIZE(buck_volt_ranges),
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.enable_reg = LP8788_EN_BUCK,
|
||||
@ -397,8 +397,9 @@ static struct regulator_desc lp8788_buck_desc[] = {
|
||||
.name = "buck3",
|
||||
.id = BUCK3,
|
||||
.ops = &lp8788_buck34_ops,
|
||||
.n_voltages = ARRAY_SIZE(lp8788_buck_vtbl),
|
||||
.volt_table = lp8788_buck_vtbl,
|
||||
.n_voltages = 26,
|
||||
.linear_ranges = buck_volt_ranges,
|
||||
.n_linear_ranges = ARRAY_SIZE(buck_volt_ranges),
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.vsel_reg = LP8788_BUCK3_VOUT,
|
||||
@ -410,8 +411,9 @@ static struct regulator_desc lp8788_buck_desc[] = {
|
||||
.name = "buck4",
|
||||
.id = BUCK4,
|
||||
.ops = &lp8788_buck34_ops,
|
||||
.n_voltages = ARRAY_SIZE(lp8788_buck_vtbl),
|
||||
.volt_table = lp8788_buck_vtbl,
|
||||
.n_voltages = 26,
|
||||
.linear_ranges = buck_volt_ranges,
|
||||
.n_linear_ranges = ARRAY_SIZE(buck_volt_ranges),
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.vsel_reg = LP8788_BUCK4_VOUT,
|
||||
|
@ -186,7 +186,7 @@ static const struct regulator_ops lp8788_ldo_voltage_fixed_ops = {
|
||||
.enable_time = lp8788_ldo_enable_time,
|
||||
};
|
||||
|
||||
static struct regulator_desc lp8788_dldo_desc[] = {
|
||||
static const struct regulator_desc lp8788_dldo_desc[] = {
|
||||
{
|
||||
.name = "dldo1",
|
||||
.id = DLDO1,
|
||||
@ -343,7 +343,7 @@ static struct regulator_desc lp8788_dldo_desc[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct regulator_desc lp8788_aldo_desc[] = {
|
||||
static const struct regulator_desc lp8788_aldo_desc[] = {
|
||||
{
|
||||
.name = "aldo1",
|
||||
.id = ALDO1,
|
||||
|
@ -241,61 +241,10 @@ static struct regulator_desc ltc3676_regulators[LTC3676_NUM_REGULATORS] = {
|
||||
LTC3676_FIXED_REG(LDO4, ldo4, LDOB, 2),
|
||||
};
|
||||
|
||||
static bool ltc3676_writeable_reg(struct device *dev, unsigned int reg)
|
||||
static bool ltc3676_readable_writeable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case LTC3676_IRQSTAT:
|
||||
case LTC3676_BUCK1:
|
||||
case LTC3676_BUCK2:
|
||||
case LTC3676_BUCK3:
|
||||
case LTC3676_BUCK4:
|
||||
case LTC3676_LDOA:
|
||||
case LTC3676_LDOB:
|
||||
case LTC3676_SQD1:
|
||||
case LTC3676_SQD2:
|
||||
case LTC3676_CNTRL:
|
||||
case LTC3676_DVB1A:
|
||||
case LTC3676_DVB1B:
|
||||
case LTC3676_DVB2A:
|
||||
case LTC3676_DVB2B:
|
||||
case LTC3676_DVB3A:
|
||||
case LTC3676_DVB3B:
|
||||
case LTC3676_DVB4A:
|
||||
case LTC3676_DVB4B:
|
||||
case LTC3676_MSKIRQ:
|
||||
case LTC3676_MSKPG:
|
||||
case LTC3676_USER:
|
||||
case LTC3676_HRST:
|
||||
case LTC3676_CLIRQ:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ltc3676_readable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case LTC3676_IRQSTAT:
|
||||
case LTC3676_BUCK1:
|
||||
case LTC3676_BUCK2:
|
||||
case LTC3676_BUCK3:
|
||||
case LTC3676_BUCK4:
|
||||
case LTC3676_LDOA:
|
||||
case LTC3676_LDOB:
|
||||
case LTC3676_SQD1:
|
||||
case LTC3676_SQD2:
|
||||
case LTC3676_CNTRL:
|
||||
case LTC3676_DVB1A:
|
||||
case LTC3676_DVB1B:
|
||||
case LTC3676_DVB2A:
|
||||
case LTC3676_DVB2B:
|
||||
case LTC3676_DVB3A:
|
||||
case LTC3676_DVB3B:
|
||||
case LTC3676_DVB4A:
|
||||
case LTC3676_DVB4B:
|
||||
case LTC3676_MSKIRQ:
|
||||
case LTC3676_MSKPG:
|
||||
case LTC3676_USER:
|
||||
case LTC3676_BUCK1 ... LTC3676_IRQSTAT:
|
||||
case LTC3676_HRST:
|
||||
case LTC3676_CLIRQ:
|
||||
return true;
|
||||
@ -306,9 +255,7 @@ static bool ltc3676_readable_reg(struct device *dev, unsigned int reg)
|
||||
static bool ltc3676_volatile_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case LTC3676_IRQSTAT:
|
||||
case LTC3676_PGSTATL:
|
||||
case LTC3676_PGSTATRT:
|
||||
case LTC3676_IRQSTAT ... LTC3676_PGSTATRT:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -317,8 +264,8 @@ static bool ltc3676_volatile_reg(struct device *dev, unsigned int reg)
|
||||
static const struct regmap_config ltc3676_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.writeable_reg = ltc3676_writeable_reg,
|
||||
.readable_reg = ltc3676_readable_reg,
|
||||
.writeable_reg = ltc3676_readable_writeable_reg,
|
||||
.readable_reg = ltc3676_readable_writeable_reg,
|
||||
.volatile_reg = ltc3676_volatile_reg,
|
||||
.max_register = LTC3676_CLIRQ,
|
||||
.use_single_read = true,
|
||||
@ -442,5 +389,5 @@ static struct i2c_driver ltc3676_driver = {
|
||||
module_i2c_driver(ltc3676_driver);
|
||||
|
||||
MODULE_AUTHOR("Tim Harvey <tharvey@gateworks.com>");
|
||||
MODULE_DESCRIPTION("Regulator driver for Linear Technology LTC1376");
|
||||
MODULE_DESCRIPTION("Regulator driver for Linear Technology LTC3676");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@ -324,4 +324,3 @@ module_exit(max14577_regulator_exit);
|
||||
MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>");
|
||||
MODULE_DESCRIPTION("Maxim 14577/77836 regulator driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:max14577-regulator");
|
||||
|
@ -690,6 +690,7 @@ static const struct regulator_ops max77620_regulator_ops = {
|
||||
.active_discharge_mask = MAX77620_SD_CFG1_ADE_MASK, \
|
||||
.active_discharge_reg = MAX77620_REG_##_id##_CFG, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
}, \
|
||||
}
|
||||
|
||||
@ -721,6 +722,7 @@ static const struct regulator_ops max77620_regulator_ops = {
|
||||
.active_discharge_mask = MAX77620_LDO_CFG2_ADE_MASK, \
|
||||
.active_discharge_reg = MAX77620_REG_##_id##_CFG2, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
}, \
|
||||
}
|
||||
|
||||
|
498
drivers/regulator/max77650-regulator.c
Normal file
498
drivers/regulator/max77650-regulator.c
Normal file
@ -0,0 +1,498 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Copyright (C) 2018 BayLibre SAS
|
||||
// Author: Bartosz Golaszewski <bgolaszewski@baylibre.com>
|
||||
//
|
||||
// Regulator driver for MAXIM 77650/77651 charger/power-supply.
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/mfd/max77650.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
|
||||
#define MAX77650_REGULATOR_EN_CTRL_MASK GENMASK(3, 0)
|
||||
#define MAX77650_REGULATOR_EN_CTRL_BITS(_reg) \
|
||||
((_reg) & MAX77650_REGULATOR_EN_CTRL_MASK)
|
||||
#define MAX77650_REGULATOR_ENABLED GENMASK(2, 1)
|
||||
#define MAX77650_REGULATOR_DISABLED BIT(2)
|
||||
|
||||
#define MAX77650_REGULATOR_V_LDO_MASK GENMASK(6, 0)
|
||||
#define MAX77650_REGULATOR_V_SBB_MASK GENMASK(5, 0)
|
||||
|
||||
#define MAX77650_REGULATOR_AD_MASK BIT(3)
|
||||
#define MAX77650_REGULATOR_AD_DISABLED 0x00
|
||||
#define MAX77650_REGULATOR_AD_ENABLED BIT(3)
|
||||
|
||||
#define MAX77650_REGULATOR_CURR_LIM_MASK GENMASK(7, 6)
|
||||
|
||||
enum {
|
||||
MAX77650_REGULATOR_ID_LDO = 0,
|
||||
MAX77650_REGULATOR_ID_SBB0,
|
||||
MAX77650_REGULATOR_ID_SBB1,
|
||||
MAX77650_REGULATOR_ID_SBB2,
|
||||
MAX77650_REGULATOR_NUM_REGULATORS,
|
||||
};
|
||||
|
||||
struct max77650_regulator_desc {
|
||||
struct regulator_desc desc;
|
||||
unsigned int regA;
|
||||
unsigned int regB;
|
||||
};
|
||||
|
||||
static const u32 max77651_sbb1_regulator_volt_table[] = {
|
||||
2400000, 3200000, 4000000, 4800000,
|
||||
2450000, 3250000, 4050000, 4850000,
|
||||
2500000, 3300000, 4100000, 4900000,
|
||||
2550000, 3350000, 4150000, 4950000,
|
||||
2600000, 3400000, 4200000, 5000000,
|
||||
2650000, 3450000, 4250000, 5050000,
|
||||
2700000, 3500000, 4300000, 5100000,
|
||||
2750000, 3550000, 4350000, 5150000,
|
||||
2800000, 3600000, 4400000, 5200000,
|
||||
2850000, 3650000, 4450000, 5250000,
|
||||
2900000, 3700000, 4500000, 0,
|
||||
2950000, 3750000, 4550000, 0,
|
||||
3000000, 3800000, 4600000, 0,
|
||||
3050000, 3850000, 4650000, 0,
|
||||
3100000, 3900000, 4700000, 0,
|
||||
3150000, 3950000, 4750000, 0,
|
||||
};
|
||||
|
||||
#define MAX77651_REGULATOR_SBB1_SEL_DEC(_val) \
|
||||
(((_val & 0x3c) >> 2) | ((_val & 0x03) << 4))
|
||||
#define MAX77651_REGULATOR_SBB1_SEL_ENC(_val) \
|
||||
(((_val & 0x30) >> 4) | ((_val & 0x0f) << 2))
|
||||
|
||||
#define MAX77650_REGULATOR_SBB1_SEL_DECR(_val) \
|
||||
do { \
|
||||
_val = MAX77651_REGULATOR_SBB1_SEL_DEC(_val); \
|
||||
_val--; \
|
||||
_val = MAX77651_REGULATOR_SBB1_SEL_ENC(_val); \
|
||||
} while (0)
|
||||
|
||||
#define MAX77650_REGULATOR_SBB1_SEL_INCR(_val) \
|
||||
do { \
|
||||
_val = MAX77651_REGULATOR_SBB1_SEL_DEC(_val); \
|
||||
_val++; \
|
||||
_val = MAX77651_REGULATOR_SBB1_SEL_ENC(_val); \
|
||||
} while (0)
|
||||
|
||||
static const unsigned int max77650_current_limit_table[] = {
|
||||
1000000, 866000, 707000, 500000,
|
||||
};
|
||||
|
||||
static int max77650_regulator_is_enabled(struct regulator_dev *rdev)
|
||||
{
|
||||
struct max77650_regulator_desc *rdesc;
|
||||
struct regmap *map;
|
||||
int val, rv, en;
|
||||
|
||||
rdesc = rdev_get_drvdata(rdev);
|
||||
map = rdev_get_regmap(rdev);
|
||||
|
||||
rv = regmap_read(map, rdesc->regB, &val);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
en = MAX77650_REGULATOR_EN_CTRL_BITS(val);
|
||||
|
||||
return en != MAX77650_REGULATOR_DISABLED;
|
||||
}
|
||||
|
||||
static int max77650_regulator_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct max77650_regulator_desc *rdesc;
|
||||
struct regmap *map;
|
||||
|
||||
rdesc = rdev_get_drvdata(rdev);
|
||||
map = rdev_get_regmap(rdev);
|
||||
|
||||
return regmap_update_bits(map, rdesc->regB,
|
||||
MAX77650_REGULATOR_EN_CTRL_MASK,
|
||||
MAX77650_REGULATOR_ENABLED);
|
||||
}
|
||||
|
||||
static int max77650_regulator_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct max77650_regulator_desc *rdesc;
|
||||
struct regmap *map;
|
||||
|
||||
rdesc = rdev_get_drvdata(rdev);
|
||||
map = rdev_get_regmap(rdev);
|
||||
|
||||
return regmap_update_bits(map, rdesc->regB,
|
||||
MAX77650_REGULATOR_EN_CTRL_MASK,
|
||||
MAX77650_REGULATOR_DISABLED);
|
||||
}
|
||||
|
||||
static int max77650_regulator_set_voltage_sel(struct regulator_dev *rdev,
|
||||
unsigned int sel)
|
||||
{
|
||||
int rv = 0, curr, diff;
|
||||
bool ascending;
|
||||
|
||||
/*
|
||||
* If the regulator is disabled, we can program the desired
|
||||
* voltage right away.
|
||||
*/
|
||||
if (!max77650_regulator_is_enabled(rdev))
|
||||
return regulator_set_voltage_sel_regmap(rdev, sel);
|
||||
|
||||
/*
|
||||
* Otherwise we need to manually ramp the output voltage up/down
|
||||
* one step at a time.
|
||||
*/
|
||||
|
||||
curr = regulator_get_voltage_sel_regmap(rdev);
|
||||
if (curr < 0)
|
||||
return curr;
|
||||
|
||||
diff = curr - sel;
|
||||
if (diff == 0)
|
||||
return 0; /* Already there. */
|
||||
else if (diff > 0)
|
||||
ascending = false;
|
||||
else
|
||||
ascending = true;
|
||||
|
||||
/*
|
||||
* Make sure we'll get to the right voltage and break the loop even if
|
||||
* the selector equals 0.
|
||||
*/
|
||||
for (ascending ? curr++ : curr--;; ascending ? curr++ : curr--) {
|
||||
rv = regulator_set_voltage_sel_regmap(rdev, curr);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
if (curr == sel)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Special case: non-linear voltage table for max77651 SBB1 - software
|
||||
* must ensure the voltage is ramped in 50mV increments.
|
||||
*/
|
||||
static int max77651_regulator_sbb1_set_voltage_sel(struct regulator_dev *rdev,
|
||||
unsigned int sel)
|
||||
{
|
||||
int rv = 0, curr, vcurr, vdest, vdiff;
|
||||
|
||||
/*
|
||||
* If the regulator is disabled, we can program the desired
|
||||
* voltage right away.
|
||||
*/
|
||||
if (!max77650_regulator_is_enabled(rdev))
|
||||
return regulator_set_voltage_sel_regmap(rdev, sel);
|
||||
|
||||
curr = regulator_get_voltage_sel_regmap(rdev);
|
||||
if (curr < 0)
|
||||
return curr;
|
||||
|
||||
if (curr == sel)
|
||||
return 0; /* Already there. */
|
||||
|
||||
vcurr = max77651_sbb1_regulator_volt_table[curr];
|
||||
vdest = max77651_sbb1_regulator_volt_table[sel];
|
||||
vdiff = vcurr - vdest;
|
||||
|
||||
for (;;) {
|
||||
if (vdiff > 0)
|
||||
MAX77650_REGULATOR_SBB1_SEL_DECR(curr);
|
||||
else
|
||||
MAX77650_REGULATOR_SBB1_SEL_INCR(curr);
|
||||
|
||||
rv = regulator_set_voltage_sel_regmap(rdev, curr);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
if (curr == sel)
|
||||
break;
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct regulator_ops max77650_regulator_LDO_ops = {
|
||||
.is_enabled = max77650_regulator_is_enabled,
|
||||
.enable = max77650_regulator_enable,
|
||||
.disable = max77650_regulator_disable,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = max77650_regulator_set_voltage_sel,
|
||||
.set_active_discharge = regulator_set_active_discharge_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_ops max77650_regulator_SBB_ops = {
|
||||
.is_enabled = max77650_regulator_is_enabled,
|
||||
.enable = max77650_regulator_enable,
|
||||
.disable = max77650_regulator_disable,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = max77650_regulator_set_voltage_sel,
|
||||
.get_current_limit = regulator_get_current_limit_regmap,
|
||||
.set_current_limit = regulator_set_current_limit_regmap,
|
||||
.set_active_discharge = regulator_set_active_discharge_regmap,
|
||||
};
|
||||
|
||||
/* Special case for max77651 SBB1 - non-linear voltage mapping. */
|
||||
static const struct regulator_ops max77651_SBB1_regulator_ops = {
|
||||
.is_enabled = max77650_regulator_is_enabled,
|
||||
.enable = max77650_regulator_enable,
|
||||
.disable = max77650_regulator_disable,
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = max77651_regulator_sbb1_set_voltage_sel,
|
||||
.get_current_limit = regulator_get_current_limit_regmap,
|
||||
.set_current_limit = regulator_set_current_limit_regmap,
|
||||
.set_active_discharge = regulator_set_active_discharge_regmap,
|
||||
};
|
||||
|
||||
static struct max77650_regulator_desc max77650_LDO_desc = {
|
||||
.desc = {
|
||||
.name = "ldo",
|
||||
.of_match = of_match_ptr("ldo"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.supply_name = "in-ldo",
|
||||
.id = MAX77650_REGULATOR_ID_LDO,
|
||||
.ops = &max77650_regulator_LDO_ops,
|
||||
.min_uV = 1350000,
|
||||
.uV_step = 12500,
|
||||
.n_voltages = 128,
|
||||
.vsel_mask = MAX77650_REGULATOR_V_LDO_MASK,
|
||||
.vsel_reg = MAX77650_REG_CNFG_LDO_A,
|
||||
.active_discharge_off = MAX77650_REGULATOR_AD_DISABLED,
|
||||
.active_discharge_on = MAX77650_REGULATOR_AD_ENABLED,
|
||||
.active_discharge_mask = MAX77650_REGULATOR_AD_MASK,
|
||||
.active_discharge_reg = MAX77650_REG_CNFG_LDO_B,
|
||||
.enable_time = 100,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.regA = MAX77650_REG_CNFG_LDO_A,
|
||||
.regB = MAX77650_REG_CNFG_LDO_B,
|
||||
};
|
||||
|
||||
static struct max77650_regulator_desc max77650_SBB0_desc = {
|
||||
.desc = {
|
||||
.name = "sbb0",
|
||||
.of_match = of_match_ptr("sbb0"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.supply_name = "in-sbb0",
|
||||
.id = MAX77650_REGULATOR_ID_SBB0,
|
||||
.ops = &max77650_regulator_SBB_ops,
|
||||
.min_uV = 800000,
|
||||
.uV_step = 25000,
|
||||
.n_voltages = 64,
|
||||
.vsel_mask = MAX77650_REGULATOR_V_SBB_MASK,
|
||||
.vsel_reg = MAX77650_REG_CNFG_SBB0_A,
|
||||
.active_discharge_off = MAX77650_REGULATOR_AD_DISABLED,
|
||||
.active_discharge_on = MAX77650_REGULATOR_AD_ENABLED,
|
||||
.active_discharge_mask = MAX77650_REGULATOR_AD_MASK,
|
||||
.active_discharge_reg = MAX77650_REG_CNFG_SBB0_B,
|
||||
.enable_time = 100,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.csel_reg = MAX77650_REG_CNFG_SBB0_A,
|
||||
.csel_mask = MAX77650_REGULATOR_CURR_LIM_MASK,
|
||||
.curr_table = max77650_current_limit_table,
|
||||
.n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
|
||||
},
|
||||
.regA = MAX77650_REG_CNFG_SBB0_A,
|
||||
.regB = MAX77650_REG_CNFG_SBB0_B,
|
||||
};
|
||||
|
||||
static struct max77650_regulator_desc max77650_SBB1_desc = {
|
||||
.desc = {
|
||||
.name = "sbb1",
|
||||
.of_match = of_match_ptr("sbb1"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.supply_name = "in-sbb1",
|
||||
.id = MAX77650_REGULATOR_ID_SBB1,
|
||||
.ops = &max77650_regulator_SBB_ops,
|
||||
.min_uV = 800000,
|
||||
.uV_step = 12500,
|
||||
.n_voltages = 64,
|
||||
.vsel_mask = MAX77650_REGULATOR_V_SBB_MASK,
|
||||
.vsel_reg = MAX77650_REG_CNFG_SBB1_A,
|
||||
.active_discharge_off = MAX77650_REGULATOR_AD_DISABLED,
|
||||
.active_discharge_on = MAX77650_REGULATOR_AD_ENABLED,
|
||||
.active_discharge_mask = MAX77650_REGULATOR_AD_MASK,
|
||||
.active_discharge_reg = MAX77650_REG_CNFG_SBB1_B,
|
||||
.enable_time = 100,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.csel_reg = MAX77650_REG_CNFG_SBB1_A,
|
||||
.csel_mask = MAX77650_REGULATOR_CURR_LIM_MASK,
|
||||
.curr_table = max77650_current_limit_table,
|
||||
.n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
|
||||
},
|
||||
.regA = MAX77650_REG_CNFG_SBB1_A,
|
||||
.regB = MAX77650_REG_CNFG_SBB1_B,
|
||||
};
|
||||
|
||||
static struct max77650_regulator_desc max77651_SBB1_desc = {
|
||||
.desc = {
|
||||
.name = "sbb1",
|
||||
.of_match = of_match_ptr("sbb1"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.supply_name = "in-sbb1",
|
||||
.id = MAX77650_REGULATOR_ID_SBB1,
|
||||
.ops = &max77651_SBB1_regulator_ops,
|
||||
.volt_table = max77651_sbb1_regulator_volt_table,
|
||||
.n_voltages = ARRAY_SIZE(max77651_sbb1_regulator_volt_table),
|
||||
.vsel_mask = MAX77650_REGULATOR_V_SBB_MASK,
|
||||
.vsel_reg = MAX77650_REG_CNFG_SBB1_A,
|
||||
.active_discharge_off = MAX77650_REGULATOR_AD_DISABLED,
|
||||
.active_discharge_on = MAX77650_REGULATOR_AD_ENABLED,
|
||||
.active_discharge_mask = MAX77650_REGULATOR_AD_MASK,
|
||||
.active_discharge_reg = MAX77650_REG_CNFG_SBB1_B,
|
||||
.enable_time = 100,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.csel_reg = MAX77650_REG_CNFG_SBB1_A,
|
||||
.csel_mask = MAX77650_REGULATOR_CURR_LIM_MASK,
|
||||
.curr_table = max77650_current_limit_table,
|
||||
.n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
|
||||
},
|
||||
.regA = MAX77650_REG_CNFG_SBB1_A,
|
||||
.regB = MAX77650_REG_CNFG_SBB1_B,
|
||||
};
|
||||
|
||||
static struct max77650_regulator_desc max77650_SBB2_desc = {
|
||||
.desc = {
|
||||
.name = "sbb2",
|
||||
.of_match = of_match_ptr("sbb2"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.supply_name = "in-sbb0",
|
||||
.id = MAX77650_REGULATOR_ID_SBB2,
|
||||
.ops = &max77650_regulator_SBB_ops,
|
||||
.min_uV = 800000,
|
||||
.uV_step = 50000,
|
||||
.n_voltages = 64,
|
||||
.vsel_mask = MAX77650_REGULATOR_V_SBB_MASK,
|
||||
.vsel_reg = MAX77650_REG_CNFG_SBB2_A,
|
||||
.active_discharge_off = MAX77650_REGULATOR_AD_DISABLED,
|
||||
.active_discharge_on = MAX77650_REGULATOR_AD_ENABLED,
|
||||
.active_discharge_mask = MAX77650_REGULATOR_AD_MASK,
|
||||
.active_discharge_reg = MAX77650_REG_CNFG_SBB2_B,
|
||||
.enable_time = 100,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.csel_reg = MAX77650_REG_CNFG_SBB2_A,
|
||||
.csel_mask = MAX77650_REGULATOR_CURR_LIM_MASK,
|
||||
.curr_table = max77650_current_limit_table,
|
||||
.n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
|
||||
},
|
||||
.regA = MAX77650_REG_CNFG_SBB2_A,
|
||||
.regB = MAX77650_REG_CNFG_SBB2_B,
|
||||
};
|
||||
|
||||
static struct max77650_regulator_desc max77651_SBB2_desc = {
|
||||
.desc = {
|
||||
.name = "sbb2",
|
||||
.of_match = of_match_ptr("sbb2"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.supply_name = "in-sbb0",
|
||||
.id = MAX77650_REGULATOR_ID_SBB2,
|
||||
.ops = &max77650_regulator_SBB_ops,
|
||||
.min_uV = 2400000,
|
||||
.uV_step = 50000,
|
||||
.n_voltages = 64,
|
||||
.vsel_mask = MAX77650_REGULATOR_V_SBB_MASK,
|
||||
.vsel_reg = MAX77650_REG_CNFG_SBB2_A,
|
||||
.active_discharge_off = MAX77650_REGULATOR_AD_DISABLED,
|
||||
.active_discharge_on = MAX77650_REGULATOR_AD_ENABLED,
|
||||
.active_discharge_mask = MAX77650_REGULATOR_AD_MASK,
|
||||
.active_discharge_reg = MAX77650_REG_CNFG_SBB2_B,
|
||||
.enable_time = 100,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
.csel_reg = MAX77650_REG_CNFG_SBB2_A,
|
||||
.csel_mask = MAX77650_REGULATOR_CURR_LIM_MASK,
|
||||
.curr_table = max77650_current_limit_table,
|
||||
.n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
|
||||
},
|
||||
.regA = MAX77650_REG_CNFG_SBB2_A,
|
||||
.regB = MAX77650_REG_CNFG_SBB2_B,
|
||||
};
|
||||
|
||||
static int max77650_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct max77650_regulator_desc **rdescs;
|
||||
struct max77650_regulator_desc *rdesc;
|
||||
struct regulator_config config = { };
|
||||
struct device *dev, *parent;
|
||||
struct regulator_dev *rdev;
|
||||
struct regmap *map;
|
||||
unsigned int val;
|
||||
int i, rv;
|
||||
|
||||
dev = &pdev->dev;
|
||||
parent = dev->parent;
|
||||
|
||||
if (!dev->of_node)
|
||||
dev->of_node = parent->of_node;
|
||||
|
||||
rdescs = devm_kcalloc(dev, MAX77650_REGULATOR_NUM_REGULATORS,
|
||||
sizeof(*rdescs), GFP_KERNEL);
|
||||
if (!rdescs)
|
||||
return -ENOMEM;
|
||||
|
||||
map = dev_get_regmap(parent, NULL);
|
||||
if (!map)
|
||||
return -ENODEV;
|
||||
|
||||
rv = regmap_read(map, MAX77650_REG_CID, &val);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
rdescs[MAX77650_REGULATOR_ID_LDO] = &max77650_LDO_desc;
|
||||
rdescs[MAX77650_REGULATOR_ID_SBB0] = &max77650_SBB0_desc;
|
||||
|
||||
switch (MAX77650_CID_BITS(val)) {
|
||||
case MAX77650_CID_77650A:
|
||||
case MAX77650_CID_77650C:
|
||||
rdescs[MAX77650_REGULATOR_ID_SBB1] = &max77650_SBB1_desc;
|
||||
rdescs[MAX77650_REGULATOR_ID_SBB2] = &max77650_SBB2_desc;
|
||||
break;
|
||||
case MAX77650_CID_77651A:
|
||||
case MAX77650_CID_77651B:
|
||||
rdescs[MAX77650_REGULATOR_ID_SBB1] = &max77651_SBB1_desc;
|
||||
rdescs[MAX77650_REGULATOR_ID_SBB2] = &max77651_SBB2_desc;
|
||||
break;
|
||||
default:
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
config.dev = parent;
|
||||
|
||||
for (i = 0; i < MAX77650_REGULATOR_NUM_REGULATORS; i++) {
|
||||
rdesc = rdescs[i];
|
||||
config.driver_data = rdesc;
|
||||
|
||||
rdev = devm_regulator_register(dev, &rdesc->desc, &config);
|
||||
if (IS_ERR(rdev))
|
||||
return PTR_ERR(rdev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver max77650_regulator_driver = {
|
||||
.driver = {
|
||||
.name = "max77650-regulator",
|
||||
},
|
||||
.probe = max77650_regulator_probe,
|
||||
};
|
||||
module_platform_driver(max77650_regulator_driver);
|
||||
|
||||
MODULE_DESCRIPTION("MAXIM 77650/77651 regulator driver");
|
||||
MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -248,9 +248,9 @@ static int max77802_set_ramp_delay_2bit(struct regulator_dev *rdev,
|
||||
unsigned int ramp_value;
|
||||
|
||||
if (id > MAX77802_BUCK4) {
|
||||
dev_warn(&rdev->dev,
|
||||
"%s: regulator: ramp delay not supported\n",
|
||||
rdev->desc->name);
|
||||
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,
|
||||
|
@ -226,7 +226,7 @@ static const unsigned int mc13783_pwgtdrv_val[] = {
|
||||
5500000,
|
||||
};
|
||||
|
||||
static struct regulator_ops mc13783_gpo_regulator_ops;
|
||||
static const struct regulator_ops mc13783_gpo_regulator_ops;
|
||||
|
||||
#define MC13783_DEFINE(prefix, name, node, reg, vsel_reg, voltages) \
|
||||
MC13xxx_DEFINE(MC13783_REG_, name, node, reg, vsel_reg, voltages, \
|
||||
@ -380,7 +380,7 @@ static int mc13783_gpo_regulator_is_enabled(struct regulator_dev *rdev)
|
||||
return (val & mc13xxx_regulators[id].enable_bit) != 0;
|
||||
}
|
||||
|
||||
static struct regulator_ops mc13783_gpo_regulator_ops = {
|
||||
static const struct regulator_ops mc13783_gpo_regulator_ops = {
|
||||
.enable = mc13783_gpo_regulator_enable,
|
||||
.disable = mc13783_gpo_regulator_disable,
|
||||
.is_enabled = mc13783_gpo_regulator_is_enabled,
|
||||
|
@ -242,8 +242,8 @@ static const unsigned int mc13892_pwgtdrv[] = {
|
||||
5000000,
|
||||
};
|
||||
|
||||
static struct regulator_ops mc13892_gpo_regulator_ops;
|
||||
static struct regulator_ops mc13892_sw_regulator_ops;
|
||||
static const struct regulator_ops mc13892_gpo_regulator_ops;
|
||||
static const struct regulator_ops mc13892_sw_regulator_ops;
|
||||
|
||||
|
||||
#define MC13892_FIXED_DEFINE(name, node, reg, voltages) \
|
||||
@ -387,7 +387,7 @@ static int mc13892_gpo_regulator_is_enabled(struct regulator_dev *rdev)
|
||||
}
|
||||
|
||||
|
||||
static struct regulator_ops mc13892_gpo_regulator_ops = {
|
||||
static const struct regulator_ops mc13892_gpo_regulator_ops = {
|
||||
.enable = mc13892_gpo_regulator_enable,
|
||||
.disable = mc13892_gpo_regulator_disable,
|
||||
.is_enabled = mc13892_gpo_regulator_is_enabled,
|
||||
@ -479,7 +479,7 @@ static int mc13892_sw_regulator_set_voltage_sel(struct regulator_dev *rdev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct regulator_ops mc13892_sw_regulator_ops = {
|
||||
static const struct regulator_ops mc13892_sw_regulator_ops = {
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
.map_voltage = regulator_map_voltage_ascend,
|
||||
.set_voltage_sel = mc13892_sw_regulator_set_voltage_sel,
|
||||
|
@ -99,7 +99,7 @@ static int mc13xxx_regulator_get_voltage(struct regulator_dev *rdev)
|
||||
return rdev->desc->volt_table[val];
|
||||
}
|
||||
|
||||
struct regulator_ops mc13xxx_regulator_ops = {
|
||||
const struct regulator_ops mc13xxx_regulator_ops = {
|
||||
.enable = mc13xxx_regulator_enable,
|
||||
.disable = mc13xxx_regulator_disable,
|
||||
.is_enabled = mc13xxx_regulator_is_enabled,
|
||||
@ -127,7 +127,7 @@ int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev, int min_uV,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_set_voltage);
|
||||
|
||||
struct regulator_ops mc13xxx_fixed_regulator_ops = {
|
||||
const struct regulator_ops mc13xxx_fixed_regulator_ops = {
|
||||
.enable = mc13xxx_regulator_enable,
|
||||
.disable = mc13xxx_regulator_disable,
|
||||
.is_enabled = mc13xxx_regulator_is_enabled,
|
||||
|
@ -53,8 +53,8 @@ static inline struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt(
|
||||
}
|
||||
#endif
|
||||
|
||||
extern struct regulator_ops mc13xxx_regulator_ops;
|
||||
extern struct regulator_ops mc13xxx_fixed_regulator_ops;
|
||||
extern const struct regulator_ops mc13xxx_regulator_ops;
|
||||
extern const struct regulator_ops mc13xxx_fixed_regulator_ops;
|
||||
|
||||
#define MC13xxx_DEFINE(prefix, _name, _node, _reg, _vsel_reg, _voltages, _ops) \
|
||||
[prefix ## _name] = { \
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
|
||||
#define VDD_LOW_SEL 0x0D
|
||||
#define VDD_HIGH_SEL 0x3F
|
||||
@ -546,7 +547,6 @@ static struct i2c_driver mcp16502_drv = {
|
||||
|
||||
module_i2c_driver(mcp16502_drv);
|
||||
|
||||
MODULE_VERSION("1.0");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("MCP16502 PMIC driver");
|
||||
MODULE_AUTHOR("Andrei Stefanescu andrei.stefanescu@microchip.com");
|
||||
|
@ -38,13 +38,9 @@ static const struct regmap_config mt6311_regmap_config = {
|
||||
#define MT6311_MAX_UV 1393750
|
||||
#define MT6311_STEP_UV 6250
|
||||
|
||||
static const struct regulator_linear_range buck_volt_range[] = {
|
||||
REGULATOR_LINEAR_RANGE(MT6311_MIN_UV, 0, 0x7f, MT6311_STEP_UV),
|
||||
};
|
||||
|
||||
static const struct regulator_ops mt6311_buck_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.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,
|
||||
@ -71,8 +67,6 @@ static const struct regulator_ops mt6311_ldo_ops = {
|
||||
.min_uV = MT6311_MIN_UV,\
|
||||
.uV_step = MT6311_STEP_UV,\
|
||||
.owner = THIS_MODULE,\
|
||||
.linear_ranges = buck_volt_range, \
|
||||
.n_linear_ranges = ARRAY_SIZE(buck_volt_range), \
|
||||
.enable_reg = MT6311_VDVFS11_CON9,\
|
||||
.enable_mask = MT6311_PMIC_VDVFS11_EN_MASK,\
|
||||
.vsel_reg = MT6311_VDVFS11_CON12,\
|
||||
|
@ -255,7 +255,7 @@ static void of_get_regulation_constraints(struct device_node *np,
|
||||
* @desc: regulator description
|
||||
*
|
||||
* Populates regulator_init_data structure by extracting data from device
|
||||
* tree node, returns a pointer to the populated struture or NULL if memory
|
||||
* tree node, returns a pointer to the populated structure or NULL if memory
|
||||
* alloc fails.
|
||||
*/
|
||||
struct regulator_init_data *of_get_regulator_init_data(struct device *dev,
|
||||
@ -547,7 +547,7 @@ bool of_check_coupling_data(struct regulator_dev *rdev)
|
||||
NULL);
|
||||
|
||||
if (c_n_phandles != n_phandles) {
|
||||
dev_err(&rdev->dev, "number of couped reg phandles mismatch\n");
|
||||
dev_err(&rdev->dev, "number of coupled reg phandles mismatch\n");
|
||||
ret = false;
|
||||
goto clean;
|
||||
}
|
||||
|
@ -382,7 +382,7 @@ static struct palmas_sleep_requestor_info tps65917_sleep_req_info[] = {
|
||||
EXTERNAL_REQUESTOR_TPS65917(LDO5, 2, 4),
|
||||
};
|
||||
|
||||
static unsigned int palmas_smps_ramp_delay[4] = {0, 10000, 5000, 2500};
|
||||
static const unsigned int palmas_smps_ramp_delay[4] = {0, 10000, 5000, 2500};
|
||||
|
||||
#define SMPS_CTRL_MODE_OFF 0x00
|
||||
#define SMPS_CTRL_MODE_ON 0x01
|
||||
|
@ -53,10 +53,6 @@ enum {
|
||||
|
||||
struct pv88060_regulator {
|
||||
struct regulator_desc desc;
|
||||
/* Current limiting */
|
||||
unsigned n_current_limits;
|
||||
const int *current_limits;
|
||||
unsigned int limit_mask;
|
||||
unsigned int conf; /* buck configuration register */
|
||||
};
|
||||
|
||||
@ -75,7 +71,7 @@ static const struct regmap_config pv88060_regmap_config = {
|
||||
* Entry indexes corresponds to register values.
|
||||
*/
|
||||
|
||||
static const int pv88060_buck1_limits[] = {
|
||||
static const unsigned int pv88060_buck1_limits[] = {
|
||||
1496000, 2393000, 3291000, 4189000
|
||||
};
|
||||
|
||||
@ -128,40 +124,6 @@ static int pv88060_buck_set_mode(struct regulator_dev *rdev,
|
||||
PV88060_BUCK_MODE_MASK, val);
|
||||
}
|
||||
|
||||
static int pv88060_set_current_limit(struct regulator_dev *rdev, int min,
|
||||
int max)
|
||||
{
|
||||
struct pv88060_regulator *info = rdev_get_drvdata(rdev);
|
||||
int i;
|
||||
|
||||
/* search for closest to maximum */
|
||||
for (i = info->n_current_limits - 1; i >= 0; i--) {
|
||||
if (min <= info->current_limits[i]
|
||||
&& max >= info->current_limits[i]) {
|
||||
return regmap_update_bits(rdev->regmap,
|
||||
info->conf,
|
||||
info->limit_mask,
|
||||
i << PV88060_BUCK_ILIM_SHIFT);
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int pv88060_get_current_limit(struct regulator_dev *rdev)
|
||||
{
|
||||
struct pv88060_regulator *info = rdev_get_drvdata(rdev);
|
||||
unsigned int data;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(rdev->regmap, info->conf, &data);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
data = (data & info->limit_mask) >> PV88060_BUCK_ILIM_SHIFT;
|
||||
return info->current_limits[data];
|
||||
}
|
||||
|
||||
static const struct regulator_ops pv88060_buck_ops = {
|
||||
.get_mode = pv88060_buck_get_mode,
|
||||
.set_mode = pv88060_buck_set_mode,
|
||||
@ -171,8 +133,8 @@ static const struct regulator_ops pv88060_buck_ops = {
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.set_current_limit = pv88060_set_current_limit,
|
||||
.get_current_limit = pv88060_get_current_limit,
|
||||
.set_current_limit = regulator_set_current_limit_regmap,
|
||||
.get_current_limit = regulator_get_current_limit_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_ops pv88060_ldo_ops = {
|
||||
@ -184,6 +146,12 @@ static const struct regulator_ops pv88060_ldo_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
};
|
||||
|
||||
static const struct regulator_ops pv88060_sw_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
};
|
||||
|
||||
#define PV88060_BUCK(chip, regl_name, min, step, max, limits_array) \
|
||||
{\
|
||||
.desc = {\
|
||||
@ -201,10 +169,11 @@ static const struct regulator_ops pv88060_ldo_ops = {
|
||||
.enable_mask = PV88060_BUCK_EN, \
|
||||
.vsel_reg = PV88060_REG_##regl_name##_CONF0,\
|
||||
.vsel_mask = PV88060_VBUCK_MASK,\
|
||||
.curr_table = limits_array,\
|
||||
.n_current_limits = ARRAY_SIZE(limits_array),\
|
||||
.csel_reg = PV88060_REG_##regl_name##_CONF1,\
|
||||
.csel_mask = PV88060_BUCK_ILIM_MASK,\
|
||||
},\
|
||||
.current_limits = limits_array,\
|
||||
.n_current_limits = ARRAY_SIZE(limits_array),\
|
||||
.limit_mask = PV88060_BUCK_ILIM_MASK, \
|
||||
.conf = PV88060_REG_##regl_name##_CONF1,\
|
||||
}
|
||||
|
||||
@ -237,9 +206,8 @@ static const struct regulator_ops pv88060_ldo_ops = {
|
||||
.regulators_node = of_match_ptr("regulators"),\
|
||||
.type = REGULATOR_VOLTAGE,\
|
||||
.owner = THIS_MODULE,\
|
||||
.ops = &pv88060_ldo_ops,\
|
||||
.min_uV = max,\
|
||||
.uV_step = 0,\
|
||||
.ops = &pv88060_sw_ops,\
|
||||
.fixed_uV = max,\
|
||||
.n_voltages = 1,\
|
||||
.enable_reg = PV88060_REG_##regl_name##_CONF,\
|
||||
.enable_mask = PV88060_SW_EN,\
|
||||
|
@ -45,12 +45,7 @@ enum pv88080_types {
|
||||
|
||||
struct pv88080_regulator {
|
||||
struct regulator_desc desc;
|
||||
/* Current limiting */
|
||||
unsigned int n_current_limits;
|
||||
const int *current_limits;
|
||||
unsigned int limit_mask;
|
||||
unsigned int mode_reg;
|
||||
unsigned int limit_reg;
|
||||
unsigned int conf2;
|
||||
unsigned int conf5;
|
||||
};
|
||||
@ -102,11 +97,11 @@ static const struct regmap_config pv88080_regmap_config = {
|
||||
* Entry indexes corresponds to register values.
|
||||
*/
|
||||
|
||||
static const int pv88080_buck1_limits[] = {
|
||||
static const unsigned int pv88080_buck1_limits[] = {
|
||||
3230000, 5130000, 6960000, 8790000
|
||||
};
|
||||
|
||||
static const int pv88080_buck23_limits[] = {
|
||||
static const unsigned int pv88080_buck23_limits[] = {
|
||||
1496000, 2393000, 3291000, 4189000
|
||||
};
|
||||
|
||||
@ -272,40 +267,6 @@ static int pv88080_buck_set_mode(struct regulator_dev *rdev,
|
||||
PV88080_BUCK1_MODE_MASK, val);
|
||||
}
|
||||
|
||||
static int pv88080_set_current_limit(struct regulator_dev *rdev, int min,
|
||||
int max)
|
||||
{
|
||||
struct pv88080_regulator *info = rdev_get_drvdata(rdev);
|
||||
int i;
|
||||
|
||||
/* search for closest to maximum */
|
||||
for (i = info->n_current_limits - 1; i >= 0; i--) {
|
||||
if (min <= info->current_limits[i]
|
||||
&& max >= info->current_limits[i]) {
|
||||
return regmap_update_bits(rdev->regmap,
|
||||
info->limit_reg,
|
||||
info->limit_mask,
|
||||
i << PV88080_BUCK1_ILIM_SHIFT);
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int pv88080_get_current_limit(struct regulator_dev *rdev)
|
||||
{
|
||||
struct pv88080_regulator *info = rdev_get_drvdata(rdev);
|
||||
unsigned int data;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(rdev->regmap, info->limit_reg, &data);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
data = (data & info->limit_mask) >> PV88080_BUCK1_ILIM_SHIFT;
|
||||
return info->current_limits[data];
|
||||
}
|
||||
|
||||
static const struct regulator_ops pv88080_buck_ops = {
|
||||
.get_mode = pv88080_buck_get_mode,
|
||||
.set_mode = pv88080_buck_set_mode,
|
||||
@ -315,8 +276,8 @@ static const struct regulator_ops pv88080_buck_ops = {
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.set_current_limit = pv88080_set_current_limit,
|
||||
.get_current_limit = pv88080_get_current_limit,
|
||||
.set_current_limit = regulator_set_current_limit_regmap,
|
||||
.get_current_limit = regulator_get_current_limit_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_ops pv88080_hvbuck_ops = {
|
||||
@ -341,9 +302,9 @@ static const struct regulator_ops pv88080_hvbuck_ops = {
|
||||
.min_uV = min, \
|
||||
.uV_step = step, \
|
||||
.n_voltages = ((max) - (min))/(step) + 1, \
|
||||
.curr_table = limits_array, \
|
||||
.n_current_limits = ARRAY_SIZE(limits_array), \
|
||||
},\
|
||||
.current_limits = limits_array, \
|
||||
.n_current_limits = ARRAY_SIZE(limits_array), \
|
||||
}
|
||||
|
||||
#define PV88080_HVBUCK(chip, regl_name, min, step, max) \
|
||||
@ -521,9 +482,9 @@ static int pv88080_i2c_probe(struct i2c_client *i2c,
|
||||
if (init_data)
|
||||
config.init_data = &init_data[i];
|
||||
|
||||
pv88080_regulator_info[i].limit_reg
|
||||
pv88080_regulator_info[i].desc.csel_reg
|
||||
= regmap_config->buck_regmap[i].buck_limit_reg;
|
||||
pv88080_regulator_info[i].limit_mask
|
||||
pv88080_regulator_info[i].desc.csel_mask
|
||||
= regmap_config->buck_regmap[i].buck_limit_mask;
|
||||
pv88080_regulator_info[i].mode_reg
|
||||
= regmap_config->buck_regmap[i].buck_mode_reg;
|
||||
|
@ -42,10 +42,6 @@ enum {
|
||||
|
||||
struct pv88090_regulator {
|
||||
struct regulator_desc desc;
|
||||
/* Current limiting */
|
||||
unsigned int n_current_limits;
|
||||
const int *current_limits;
|
||||
unsigned int limit_mask;
|
||||
unsigned int conf;
|
||||
unsigned int conf2;
|
||||
};
|
||||
@ -71,14 +67,14 @@ static const struct regmap_config pv88090_regmap_config = {
|
||||
* Entry indexes corresponds to register values.
|
||||
*/
|
||||
|
||||
static const int pv88090_buck1_limits[] = {
|
||||
static const unsigned int pv88090_buck1_limits[] = {
|
||||
220000, 440000, 660000, 880000, 1100000, 1320000, 1540000, 1760000,
|
||||
1980000, 2200000, 2420000, 2640000, 2860000, 3080000, 3300000, 3520000,
|
||||
3740000, 3960000, 4180000, 4400000, 4620000, 4840000, 5060000, 5280000,
|
||||
5500000, 5720000, 5940000, 6160000, 6380000, 6600000, 6820000, 7040000
|
||||
};
|
||||
|
||||
static const int pv88090_buck23_limits[] = {
|
||||
static const unsigned int pv88090_buck23_limits[] = {
|
||||
1496000, 2393000, 3291000, 4189000
|
||||
};
|
||||
|
||||
@ -150,40 +146,6 @@ static int pv88090_buck_set_mode(struct regulator_dev *rdev,
|
||||
PV88090_BUCK1_MODE_MASK, val);
|
||||
}
|
||||
|
||||
static int pv88090_set_current_limit(struct regulator_dev *rdev, int min,
|
||||
int max)
|
||||
{
|
||||
struct pv88090_regulator *info = rdev_get_drvdata(rdev);
|
||||
int i;
|
||||
|
||||
/* search for closest to maximum */
|
||||
for (i = info->n_current_limits - 1; i >= 0; i--) {
|
||||
if (min <= info->current_limits[i]
|
||||
&& max >= info->current_limits[i]) {
|
||||
return regmap_update_bits(rdev->regmap,
|
||||
info->conf,
|
||||
info->limit_mask,
|
||||
i << PV88090_BUCK1_ILIM_SHIFT);
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int pv88090_get_current_limit(struct regulator_dev *rdev)
|
||||
{
|
||||
struct pv88090_regulator *info = rdev_get_drvdata(rdev);
|
||||
unsigned int data;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(rdev->regmap, info->conf, &data);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
data = (data & info->limit_mask) >> PV88090_BUCK1_ILIM_SHIFT;
|
||||
return info->current_limits[data];
|
||||
}
|
||||
|
||||
static const struct regulator_ops pv88090_buck_ops = {
|
||||
.get_mode = pv88090_buck_get_mode,
|
||||
.set_mode = pv88090_buck_set_mode,
|
||||
@ -193,8 +155,8 @@ static const struct regulator_ops pv88090_buck_ops = {
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.set_current_limit = pv88090_set_current_limit,
|
||||
.get_current_limit = pv88090_get_current_limit,
|
||||
.set_current_limit = regulator_set_current_limit_regmap,
|
||||
.get_current_limit = regulator_get_current_limit_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_ops pv88090_ldo_ops = {
|
||||
@ -223,10 +185,11 @@ static const struct regulator_ops pv88090_ldo_ops = {
|
||||
.enable_mask = PV88090_##regl_name##_EN, \
|
||||
.vsel_reg = PV88090_REG_##regl_name##_CONF0, \
|
||||
.vsel_mask = PV88090_V##regl_name##_MASK, \
|
||||
.curr_table = limits_array, \
|
||||
.n_current_limits = ARRAY_SIZE(limits_array), \
|
||||
.csel_reg = PV88090_REG_##regl_name##_CONF1, \
|
||||
.csel_mask = PV88090_##regl_name##_ILIM_MASK, \
|
||||
},\
|
||||
.current_limits = limits_array, \
|
||||
.n_current_limits = ARRAY_SIZE(limits_array), \
|
||||
.limit_mask = PV88090_##regl_name##_ILIM_MASK, \
|
||||
.conf = PV88090_REG_##regl_name##_CONF1, \
|
||||
.conf2 = PV88090_REG_##regl_name##_CONF2, \
|
||||
}
|
||||
|
@ -40,9 +40,6 @@ struct pwm_regulator_data {
|
||||
/* regulator descriptor */
|
||||
struct regulator_desc desc;
|
||||
|
||||
/* Regulator ops */
|
||||
struct regulator_ops ops;
|
||||
|
||||
int state;
|
||||
|
||||
/* Enable GPIO */
|
||||
@ -231,7 +228,7 @@ static int pwm_regulator_set_voltage(struct regulator_dev *rdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct regulator_ops pwm_regulator_voltage_table_ops = {
|
||||
static const struct regulator_ops pwm_regulator_voltage_table_ops = {
|
||||
.set_voltage_sel = pwm_regulator_set_voltage_sel,
|
||||
.get_voltage_sel = pwm_regulator_get_voltage_sel,
|
||||
.list_voltage = pwm_regulator_list_voltage,
|
||||
@ -241,7 +238,7 @@ static struct regulator_ops pwm_regulator_voltage_table_ops = {
|
||||
.is_enabled = pwm_regulator_is_enabled,
|
||||
};
|
||||
|
||||
static struct regulator_ops pwm_regulator_voltage_continuous_ops = {
|
||||
static const struct regulator_ops pwm_regulator_voltage_continuous_ops = {
|
||||
.get_voltage = pwm_regulator_get_voltage,
|
||||
.set_voltage = pwm_regulator_set_voltage,
|
||||
.enable = pwm_regulator_enable,
|
||||
@ -249,7 +246,7 @@ static struct regulator_ops pwm_regulator_voltage_continuous_ops = {
|
||||
.is_enabled = pwm_regulator_is_enabled,
|
||||
};
|
||||
|
||||
static struct regulator_desc pwm_regulator_desc = {
|
||||
static const struct regulator_desc pwm_regulator_desc = {
|
||||
.name = "pwm-regulator",
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
@ -287,9 +284,7 @@ static int pwm_regulator_init_table(struct platform_device *pdev,
|
||||
|
||||
drvdata->state = -EINVAL;
|
||||
drvdata->duty_cycle_table = duty_cycle_table;
|
||||
memcpy(&drvdata->ops, &pwm_regulator_voltage_table_ops,
|
||||
sizeof(drvdata->ops));
|
||||
drvdata->desc.ops = &drvdata->ops;
|
||||
drvdata->desc.ops = &pwm_regulator_voltage_table_ops;
|
||||
drvdata->desc.n_voltages = length / sizeof(*duty_cycle_table);
|
||||
|
||||
return 0;
|
||||
@ -301,9 +296,7 @@ static int pwm_regulator_init_continuous(struct platform_device *pdev,
|
||||
u32 dutycycle_range[2] = { 0, 100 };
|
||||
u32 dutycycle_unit = 100;
|
||||
|
||||
memcpy(&drvdata->ops, &pwm_regulator_voltage_continuous_ops,
|
||||
sizeof(drvdata->ops));
|
||||
drvdata->desc.ops = &drvdata->ops;
|
||||
drvdata->desc.ops = &pwm_regulator_voltage_continuous_ops;
|
||||
drvdata->desc.continuous_voltage_range = true;
|
||||
|
||||
of_property_read_u32_array(pdev->dev.of_node,
|
||||
|
@ -31,6 +31,11 @@ struct qcom_rpm_reg {
|
||||
|
||||
int is_enabled;
|
||||
int uV;
|
||||
u32 load;
|
||||
|
||||
unsigned int enabled_updated:1;
|
||||
unsigned int uv_updated:1;
|
||||
unsigned int load_updated:1;
|
||||
};
|
||||
|
||||
struct rpm_regulator_req {
|
||||
@ -43,30 +48,59 @@ struct rpm_regulator_req {
|
||||
#define RPM_KEY_UV 0x00007675 /* "uv" */
|
||||
#define RPM_KEY_MA 0x0000616d /* "ma" */
|
||||
|
||||
static int rpm_reg_write_active(struct qcom_rpm_reg *vreg,
|
||||
struct rpm_regulator_req *req,
|
||||
size_t size)
|
||||
static int rpm_reg_write_active(struct qcom_rpm_reg *vreg)
|
||||
{
|
||||
return qcom_rpm_smd_write(vreg->rpm,
|
||||
QCOM_SMD_RPM_ACTIVE_STATE,
|
||||
vreg->type,
|
||||
vreg->id,
|
||||
req, size);
|
||||
struct rpm_regulator_req req[3];
|
||||
int reqlen = 0;
|
||||
int ret;
|
||||
|
||||
if (vreg->enabled_updated) {
|
||||
req[reqlen].key = cpu_to_le32(RPM_KEY_SWEN);
|
||||
req[reqlen].nbytes = cpu_to_le32(sizeof(u32));
|
||||
req[reqlen].value = cpu_to_le32(vreg->is_enabled);
|
||||
reqlen++;
|
||||
}
|
||||
|
||||
if (vreg->uv_updated && vreg->is_enabled) {
|
||||
req[reqlen].key = cpu_to_le32(RPM_KEY_UV);
|
||||
req[reqlen].nbytes = cpu_to_le32(sizeof(u32));
|
||||
req[reqlen].value = cpu_to_le32(vreg->uV);
|
||||
reqlen++;
|
||||
}
|
||||
|
||||
if (vreg->load_updated && vreg->is_enabled) {
|
||||
req[reqlen].key = cpu_to_le32(RPM_KEY_MA);
|
||||
req[reqlen].nbytes = cpu_to_le32(sizeof(u32));
|
||||
req[reqlen].value = cpu_to_le32(vreg->load / 1000);
|
||||
reqlen++;
|
||||
}
|
||||
|
||||
if (!reqlen)
|
||||
return 0;
|
||||
|
||||
ret = qcom_rpm_smd_write(vreg->rpm, QCOM_SMD_RPM_ACTIVE_STATE,
|
||||
vreg->type, vreg->id,
|
||||
req, sizeof(req[0]) * reqlen);
|
||||
if (!ret) {
|
||||
vreg->enabled_updated = 0;
|
||||
vreg->uv_updated = 0;
|
||||
vreg->load_updated = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rpm_reg_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
|
||||
struct rpm_regulator_req req;
|
||||
int ret;
|
||||
|
||||
req.key = cpu_to_le32(RPM_KEY_SWEN);
|
||||
req.nbytes = cpu_to_le32(sizeof(u32));
|
||||
req.value = cpu_to_le32(1);
|
||||
vreg->is_enabled = 1;
|
||||
vreg->enabled_updated = 1;
|
||||
|
||||
ret = rpm_reg_write_active(vreg, &req, sizeof(req));
|
||||
if (!ret)
|
||||
vreg->is_enabled = 1;
|
||||
ret = rpm_reg_write_active(vreg);
|
||||
if (ret)
|
||||
vreg->is_enabled = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -81,16 +115,14 @@ static int rpm_reg_is_enabled(struct regulator_dev *rdev)
|
||||
static int rpm_reg_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
|
||||
struct rpm_regulator_req req;
|
||||
int ret;
|
||||
|
||||
req.key = cpu_to_le32(RPM_KEY_SWEN);
|
||||
req.nbytes = cpu_to_le32(sizeof(u32));
|
||||
req.value = 0;
|
||||
vreg->is_enabled = 0;
|
||||
vreg->enabled_updated = 1;
|
||||
|
||||
ret = rpm_reg_write_active(vreg, &req, sizeof(req));
|
||||
if (!ret)
|
||||
vreg->is_enabled = 0;
|
||||
ret = rpm_reg_write_active(vreg);
|
||||
if (ret)
|
||||
vreg->is_enabled = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -108,16 +140,15 @@ static int rpm_reg_set_voltage(struct regulator_dev *rdev,
|
||||
unsigned *selector)
|
||||
{
|
||||
struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
|
||||
struct rpm_regulator_req req;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
int old_uV = vreg->uV;
|
||||
|
||||
req.key = cpu_to_le32(RPM_KEY_UV);
|
||||
req.nbytes = cpu_to_le32(sizeof(u32));
|
||||
req.value = cpu_to_le32(min_uV);
|
||||
vreg->uV = min_uV;
|
||||
vreg->uv_updated = 1;
|
||||
|
||||
ret = rpm_reg_write_active(vreg, &req, sizeof(req));
|
||||
if (!ret)
|
||||
vreg->uV = min_uV;
|
||||
ret = rpm_reg_write_active(vreg);
|
||||
if (ret)
|
||||
vreg->uV = old_uV;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -125,13 +156,16 @@ static int rpm_reg_set_voltage(struct regulator_dev *rdev,
|
||||
static int rpm_reg_set_load(struct regulator_dev *rdev, int load_uA)
|
||||
{
|
||||
struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev);
|
||||
struct rpm_regulator_req req;
|
||||
u32 old_load = vreg->load;
|
||||
int ret;
|
||||
|
||||
req.key = cpu_to_le32(RPM_KEY_MA);
|
||||
req.nbytes = cpu_to_le32(sizeof(u32));
|
||||
req.value = cpu_to_le32(load_uA / 1000);
|
||||
vreg->load = load_uA;
|
||||
vreg->load_updated = 1;
|
||||
ret = rpm_reg_write_active(vreg);
|
||||
if (ret)
|
||||
vreg->load = old_load;
|
||||
|
||||
return rpm_reg_write_active(vreg, &req, sizeof(req));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct regulator_ops rpm_smps_ldo_ops = {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Regulator driver for Rockchip RK808/RK818
|
||||
* Regulator driver for Rockchip RK805/RK808/RK818
|
||||
*
|
||||
* Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
|
||||
*
|
||||
@ -363,28 +363,28 @@ static int rk808_set_suspend_disable(struct regulator_dev *rdev)
|
||||
rdev->desc->enable_mask);
|
||||
}
|
||||
|
||||
static struct regulator_ops rk805_reg_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.set_suspend_voltage = rk808_set_suspend_voltage,
|
||||
.set_suspend_enable = rk805_set_suspend_enable,
|
||||
.set_suspend_disable = rk805_set_suspend_disable,
|
||||
static const struct regulator_ops rk805_reg_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.set_suspend_voltage = rk808_set_suspend_voltage,
|
||||
.set_suspend_enable = rk805_set_suspend_enable,
|
||||
.set_suspend_disable = rk805_set_suspend_disable,
|
||||
};
|
||||
|
||||
static struct regulator_ops rk805_switch_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.set_suspend_enable = rk805_set_suspend_enable,
|
||||
.set_suspend_disable = rk805_set_suspend_disable,
|
||||
static const struct regulator_ops rk805_switch_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.set_suspend_enable = rk805_set_suspend_enable,
|
||||
.set_suspend_disable = rk805_set_suspend_disable,
|
||||
};
|
||||
|
||||
static struct regulator_ops rk808_buck1_2_ops = {
|
||||
static const struct regulator_ops rk808_buck1_2_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = rk808_buck1_2_get_voltage_sel_regmap,
|
||||
@ -399,7 +399,7 @@ static struct regulator_ops rk808_buck1_2_ops = {
|
||||
.set_suspend_disable = rk808_set_suspend_disable,
|
||||
};
|
||||
|
||||
static struct regulator_ops rk808_reg_ops = {
|
||||
static const struct regulator_ops rk808_reg_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
@ -412,7 +412,7 @@ static struct regulator_ops rk808_reg_ops = {
|
||||
.set_suspend_disable = rk808_set_suspend_disable,
|
||||
};
|
||||
|
||||
static struct regulator_ops rk808_reg_ops_ranges = {
|
||||
static const struct regulator_ops rk808_reg_ops_ranges = {
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
@ -425,7 +425,7 @@ static struct regulator_ops rk808_reg_ops_ranges = {
|
||||
.set_suspend_disable = rk808_set_suspend_disable,
|
||||
};
|
||||
|
||||
static struct regulator_ops rk808_switch_ops = {
|
||||
static const struct regulator_ops rk808_switch_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
@ -433,6 +433,12 @@ static struct regulator_ops rk808_switch_ops = {
|
||||
.set_suspend_disable = rk808_set_suspend_disable,
|
||||
};
|
||||
|
||||
static const struct regulator_linear_range rk805_buck_1_2_voltage_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(712500, 0, 59, 12500),
|
||||
REGULATOR_LINEAR_RANGE(1800000, 60, 62, 200000),
|
||||
REGULATOR_LINEAR_RANGE(2300000, 63, 63, 0),
|
||||
};
|
||||
|
||||
static const struct regulator_desc rk805_reg[] = {
|
||||
{
|
||||
.name = "DCDC_REG1",
|
||||
@ -440,11 +446,11 @@ static const struct regulator_desc rk805_reg[] = {
|
||||
.of_match = of_match_ptr("DCDC_REG1"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = RK805_ID_DCDC1,
|
||||
.ops = &rk805_reg_ops,
|
||||
.ops = &rk808_reg_ops_ranges,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.min_uV = 712500,
|
||||
.uV_step = 12500,
|
||||
.n_voltages = 64,
|
||||
.linear_ranges = rk805_buck_1_2_voltage_ranges,
|
||||
.n_linear_ranges = ARRAY_SIZE(rk805_buck_1_2_voltage_ranges),
|
||||
.vsel_reg = RK805_BUCK1_ON_VSEL_REG,
|
||||
.vsel_mask = RK818_BUCK_VSEL_MASK,
|
||||
.enable_reg = RK805_DCDC_EN_REG,
|
||||
@ -456,11 +462,11 @@ static const struct regulator_desc rk805_reg[] = {
|
||||
.of_match = of_match_ptr("DCDC_REG2"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = RK805_ID_DCDC2,
|
||||
.ops = &rk805_reg_ops,
|
||||
.ops = &rk808_reg_ops_ranges,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.min_uV = 712500,
|
||||
.uV_step = 12500,
|
||||
.n_voltages = 64,
|
||||
.linear_ranges = rk805_buck_1_2_voltage_ranges,
|
||||
.n_linear_ranges = ARRAY_SIZE(rk805_buck_1_2_voltage_ranges),
|
||||
.vsel_reg = RK805_BUCK2_ON_VSEL_REG,
|
||||
.vsel_mask = RK818_BUCK_VSEL_MASK,
|
||||
.enable_reg = RK805_DCDC_EN_REG,
|
||||
@ -796,7 +802,7 @@ static struct platform_driver rk808_regulator_driver = {
|
||||
|
||||
module_platform_driver(rk808_regulator_driver);
|
||||
|
||||
MODULE_DESCRIPTION("regulator driver for the RK808/RK818 series PMICs");
|
||||
MODULE_DESCRIPTION("regulator driver for the RK805/RK808/RK818 series PMICs");
|
||||
MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
|
||||
MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
|
||||
MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
|
||||
|
@ -16,14 +16,14 @@
|
||||
#include <linux/mfd/rt5033-private.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
|
||||
static struct regulator_ops rt5033_safe_ldo_ops = {
|
||||
static const struct regulator_ops rt5033_safe_ldo_ops = {
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
};
|
||||
|
||||
static struct regulator_ops rt5033_buck_ops = {
|
||||
static const struct regulator_ops rt5033_buck_ops = {
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
|
@ -115,7 +115,7 @@ static const struct sec_voltage_desc *reg_voltage_map[] = {
|
||||
[S5M8767_BUCK9] = &buck_voltage_val3,
|
||||
};
|
||||
|
||||
static unsigned int s5m8767_opmode_reg[][4] = {
|
||||
static const unsigned int s5m8767_opmode_reg[][4] = {
|
||||
/* {OFF, ON, LOWPOWER, SUSPEND} */
|
||||
/* LDO1 ... LDO28 */
|
||||
{0x0, 0x3, 0x2, 0x1}, /* LDO1 */
|
||||
@ -339,13 +339,9 @@ static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev,
|
||||
unsigned int new_sel)
|
||||
{
|
||||
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
|
||||
const struct sec_voltage_desc *desc;
|
||||
int reg_id = rdev_get_id(rdev);
|
||||
|
||||
desc = reg_voltage_map[reg_id];
|
||||
|
||||
if ((old_sel < new_sel) && s5m8767->ramp_delay)
|
||||
return DIV_ROUND_UP(desc->step * (new_sel - old_sel),
|
||||
return DIV_ROUND_UP(rdev->desc->uV_step * (new_sel - old_sel),
|
||||
s5m8767->ramp_delay * 1000);
|
||||
return 0;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
/* STM32 VREFBUF registers */
|
||||
#define STM32_VREFBUF_CSR 0x00
|
||||
@ -25,9 +26,12 @@
|
||||
#define STM32_HIZ BIT(1)
|
||||
#define STM32_ENVR BIT(0)
|
||||
|
||||
#define STM32_VREFBUF_AUTO_SUSPEND_DELAY_MS 10
|
||||
|
||||
struct stm32_vrefbuf {
|
||||
void __iomem *base;
|
||||
struct clk *clk;
|
||||
struct device *dev;
|
||||
};
|
||||
|
||||
static const unsigned int stm32_vrefbuf_voltages[] = {
|
||||
@ -38,9 +42,16 @@ static const unsigned int stm32_vrefbuf_voltages[] = {
|
||||
static int stm32_vrefbuf_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
|
||||
u32 val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_get_sync(priv->dev);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put_noidle(priv->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
|
||||
val = (val & ~STM32_HIZ) | STM32_ENVR;
|
||||
writel_relaxed(val, priv->base + STM32_VREFBUF_CSR);
|
||||
|
||||
@ -59,45 +70,95 @@ static int stm32_vrefbuf_enable(struct regulator_dev *rdev)
|
||||
writel_relaxed(val, priv->base + STM32_VREFBUF_CSR);
|
||||
}
|
||||
|
||||
pm_runtime_mark_last_busy(priv->dev);
|
||||
pm_runtime_put_autosuspend(priv->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int stm32_vrefbuf_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
|
||||
u32 val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_get_sync(priv->dev);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put_noidle(priv->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
|
||||
val = (val & ~STM32_ENVR) | STM32_HIZ;
|
||||
writel_relaxed(val, priv->base + STM32_VREFBUF_CSR);
|
||||
|
||||
pm_runtime_mark_last_busy(priv->dev);
|
||||
pm_runtime_put_autosuspend(priv->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32_vrefbuf_is_enabled(struct regulator_dev *rdev)
|
||||
{
|
||||
struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
|
||||
int ret;
|
||||
|
||||
return readl_relaxed(priv->base + STM32_VREFBUF_CSR) & STM32_ENVR;
|
||||
ret = pm_runtime_get_sync(priv->dev);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put_noidle(priv->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = readl_relaxed(priv->base + STM32_VREFBUF_CSR) & STM32_ENVR;
|
||||
|
||||
pm_runtime_mark_last_busy(priv->dev);
|
||||
pm_runtime_put_autosuspend(priv->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int stm32_vrefbuf_set_voltage_sel(struct regulator_dev *rdev,
|
||||
unsigned sel)
|
||||
{
|
||||
struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
|
||||
u32 val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_get_sync(priv->dev);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put_noidle(priv->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
|
||||
val = (val & ~STM32_VRS) | FIELD_PREP(STM32_VRS, sel);
|
||||
writel_relaxed(val, priv->base + STM32_VREFBUF_CSR);
|
||||
|
||||
pm_runtime_mark_last_busy(priv->dev);
|
||||
pm_runtime_put_autosuspend(priv->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32_vrefbuf_get_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
|
||||
u32 val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
return FIELD_GET(STM32_VRS, val);
|
||||
ret = pm_runtime_get_sync(priv->dev);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put_noidle(priv->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
val = readl_relaxed(priv->base + STM32_VREFBUF_CSR);
|
||||
ret = FIELD_GET(STM32_VRS, val);
|
||||
|
||||
pm_runtime_mark_last_busy(priv->dev);
|
||||
pm_runtime_put_autosuspend(priv->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct regulator_ops stm32_vrefbuf_volt_ops = {
|
||||
@ -130,6 +191,7 @@ static int stm32_vrefbuf_probe(struct platform_device *pdev)
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
priv->dev = &pdev->dev;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
priv->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
@ -140,10 +202,17 @@ static int stm32_vrefbuf_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(priv->clk))
|
||||
return PTR_ERR(priv->clk);
|
||||
|
||||
pm_runtime_get_noresume(&pdev->dev);
|
||||
pm_runtime_set_active(&pdev->dev);
|
||||
pm_runtime_set_autosuspend_delay(&pdev->dev,
|
||||
STM32_VREFBUF_AUTO_SUSPEND_DELAY_MS);
|
||||
pm_runtime_use_autosuspend(&pdev->dev);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
ret = clk_prepare_enable(priv->clk);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "clk prepare failed with error %d\n", ret);
|
||||
return ret;
|
||||
goto err_pm_stop;
|
||||
}
|
||||
|
||||
config.dev = &pdev->dev;
|
||||
@ -161,10 +230,17 @@ static int stm32_vrefbuf_probe(struct platform_device *pdev)
|
||||
}
|
||||
platform_set_drvdata(pdev, rdev);
|
||||
|
||||
pm_runtime_mark_last_busy(&pdev->dev);
|
||||
pm_runtime_put_autosuspend(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_clk_dis:
|
||||
clk_disable_unprepare(priv->clk);
|
||||
err_pm_stop:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
pm_runtime_set_suspended(&pdev->dev);
|
||||
pm_runtime_put_noidle(&pdev->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -174,10 +250,40 @@ static int stm32_vrefbuf_remove(struct platform_device *pdev)
|
||||
struct regulator_dev *rdev = platform_get_drvdata(pdev);
|
||||
struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
|
||||
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
regulator_unregister(rdev);
|
||||
clk_disable_unprepare(priv->clk);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
pm_runtime_set_suspended(&pdev->dev);
|
||||
pm_runtime_put_noidle(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
static int __maybe_unused stm32_vrefbuf_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct regulator_dev *rdev = dev_get_drvdata(dev);
|
||||
struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
|
||||
|
||||
clk_disable_unprepare(priv->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused stm32_vrefbuf_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct regulator_dev *rdev = dev_get_drvdata(dev);
|
||||
struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev);
|
||||
|
||||
return clk_prepare_enable(priv->clk);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops stm32_vrefbuf_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
|
||||
pm_runtime_force_resume)
|
||||
SET_RUNTIME_PM_OPS(stm32_vrefbuf_runtime_suspend,
|
||||
stm32_vrefbuf_runtime_resume,
|
||||
NULL)
|
||||
};
|
||||
|
||||
static const struct of_device_id stm32_vrefbuf_of_match[] = {
|
||||
@ -192,6 +298,7 @@ static struct platform_driver stm32_vrefbuf_driver = {
|
||||
.driver = {
|
||||
.name = "stm32-vrefbuf",
|
||||
.of_match_table = of_match_ptr(stm32_vrefbuf_of_match),
|
||||
.pm = &stm32_vrefbuf_pm_ops,
|
||||
},
|
||||
};
|
||||
module_platform_driver(stm32_vrefbuf_driver);
|
||||
|
@ -12,8 +12,10 @@
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
|
||||
#include <dt-bindings/mfd/st,stpmic1.h>
|
||||
|
||||
/**
|
||||
* stpmic1 regulator description
|
||||
* stpmic1 regulator description: this structure is used as driver data
|
||||
* @desc: regulator framework description
|
||||
* @mask_reset_reg: mask reset register address
|
||||
* @mask_reset_mask: mask rank and mask reset register mask
|
||||
@ -28,28 +30,9 @@ struct stpmic1_regulator_cfg {
|
||||
u8 icc_mask;
|
||||
};
|
||||
|
||||
/**
|
||||
* stpmic1 regulator data: this structure is used as driver data
|
||||
* @regul_id: regulator id
|
||||
* @reg_node: DT node of regulator (unused on non-DT platforms)
|
||||
* @cfg: stpmic specific regulator description
|
||||
* @mask_reset: mask_reset bit value
|
||||
* @irq_curlim: current limit interrupt number
|
||||
* @regmap: point to parent regmap structure
|
||||
*/
|
||||
struct stpmic1_regulator {
|
||||
unsigned int regul_id;
|
||||
struct device_node *reg_node;
|
||||
struct stpmic1_regulator_cfg *cfg;
|
||||
u8 mask_reset;
|
||||
int irq_curlim;
|
||||
struct regmap *regmap;
|
||||
};
|
||||
|
||||
static int stpmic1_set_mode(struct regulator_dev *rdev, unsigned int mode);
|
||||
static unsigned int stpmic1_get_mode(struct regulator_dev *rdev);
|
||||
static int stpmic1_set_icc(struct regulator_dev *rdev);
|
||||
static int stpmic1_regulator_parse_dt(void *driver_data);
|
||||
static unsigned int stpmic1_map_mode(unsigned int mode);
|
||||
|
||||
enum {
|
||||
@ -72,16 +55,13 @@ enum {
|
||||
/* Enable time worst case is 5000mV/(2250uV/uS) */
|
||||
#define PMIC_ENABLE_TIME_US 2200
|
||||
|
||||
#define STPMIC1_BUCK_MODE_NORMAL 0
|
||||
#define STPMIC1_BUCK_MODE_LP BUCK_HPLP_ENABLE_MASK
|
||||
|
||||
static const struct regulator_linear_range buck1_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(725000, 0, 4, 0),
|
||||
REGULATOR_LINEAR_RANGE(725000, 5, 36, 25000),
|
||||
REGULATOR_LINEAR_RANGE(1500000, 37, 63, 0),
|
||||
};
|
||||
|
||||
struct regulator_linear_range buck2_ranges[] = {
|
||||
static const struct regulator_linear_range buck2_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1000000, 0, 17, 0),
|
||||
REGULATOR_LINEAR_RANGE(1050000, 18, 19, 0),
|
||||
REGULATOR_LINEAR_RANGE(1100000, 20, 21, 0),
|
||||
@ -95,7 +75,7 @@ struct regulator_linear_range buck2_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1500000, 36, 63, 0),
|
||||
};
|
||||
|
||||
struct regulator_linear_range buck3_ranges[] = {
|
||||
static const struct regulator_linear_range buck3_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1000000, 0, 19, 0),
|
||||
REGULATOR_LINEAR_RANGE(1100000, 20, 23, 0),
|
||||
REGULATOR_LINEAR_RANGE(1200000, 24, 27, 0),
|
||||
@ -103,10 +83,9 @@ struct regulator_linear_range buck3_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1400000, 32, 35, 0),
|
||||
REGULATOR_LINEAR_RANGE(1500000, 36, 55, 100000),
|
||||
REGULATOR_LINEAR_RANGE(3400000, 56, 63, 0),
|
||||
|
||||
};
|
||||
|
||||
struct regulator_linear_range buck4_ranges[] = {
|
||||
static const struct regulator_linear_range buck4_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(600000, 0, 27, 25000),
|
||||
REGULATOR_LINEAR_RANGE(1300000, 28, 29, 0),
|
||||
REGULATOR_LINEAR_RANGE(1350000, 30, 31, 0),
|
||||
@ -114,24 +93,21 @@ struct regulator_linear_range buck4_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1450000, 34, 35, 0),
|
||||
REGULATOR_LINEAR_RANGE(1500000, 36, 60, 100000),
|
||||
REGULATOR_LINEAR_RANGE(3900000, 61, 63, 0),
|
||||
|
||||
};
|
||||
|
||||
struct regulator_linear_range ldo1_ranges[] = {
|
||||
static const struct regulator_linear_range ldo1_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0),
|
||||
REGULATOR_LINEAR_RANGE(1700000, 8, 24, 100000),
|
||||
REGULATOR_LINEAR_RANGE(3300000, 25, 31, 0),
|
||||
|
||||
};
|
||||
|
||||
struct regulator_linear_range ldo2_ranges[] = {
|
||||
static const struct regulator_linear_range ldo2_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0),
|
||||
REGULATOR_LINEAR_RANGE(1700000, 8, 24, 100000),
|
||||
REGULATOR_LINEAR_RANGE(3300000, 25, 30, 0),
|
||||
|
||||
};
|
||||
|
||||
struct regulator_linear_range ldo3_ranges[] = {
|
||||
static const struct regulator_linear_range ldo3_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0),
|
||||
REGULATOR_LINEAR_RANGE(1700000, 8, 24, 100000),
|
||||
REGULATOR_LINEAR_RANGE(3300000, 25, 30, 0),
|
||||
@ -139,18 +115,18 @@ struct regulator_linear_range ldo3_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 31, 31, 0),
|
||||
};
|
||||
|
||||
struct regulator_linear_range ldo5_ranges[] = {
|
||||
static const struct regulator_linear_range ldo5_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0),
|
||||
REGULATOR_LINEAR_RANGE(1700000, 8, 30, 100000),
|
||||
REGULATOR_LINEAR_RANGE(3900000, 31, 31, 0),
|
||||
};
|
||||
|
||||
struct regulator_linear_range ldo6_ranges[] = {
|
||||
static const struct regulator_linear_range ldo6_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(900000, 0, 24, 100000),
|
||||
REGULATOR_LINEAR_RANGE(3300000, 25, 31, 0),
|
||||
};
|
||||
|
||||
static struct regulator_ops stpmic1_ldo_ops = {
|
||||
static const struct regulator_ops stpmic1_ldo_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
@ -158,11 +134,10 @@ static struct regulator_ops stpmic1_ldo_ops = {
|
||||
.disable = regulator_disable_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.set_pull_down = regulator_set_pull_down_regmap,
|
||||
.set_over_current_protection = stpmic1_set_icc,
|
||||
};
|
||||
|
||||
static struct regulator_ops stpmic1_ldo3_ops = {
|
||||
static const struct regulator_ops stpmic1_ldo3_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.map_voltage = regulator_map_voltage_iterate,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
@ -170,21 +145,19 @@ static struct regulator_ops stpmic1_ldo3_ops = {
|
||||
.disable = regulator_disable_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.set_pull_down = regulator_set_pull_down_regmap,
|
||||
.get_bypass = regulator_get_bypass_regmap,
|
||||
.set_bypass = regulator_set_bypass_regmap,
|
||||
.set_over_current_protection = stpmic1_set_icc,
|
||||
};
|
||||
|
||||
static struct regulator_ops stpmic1_ldo4_fixed_regul_ops = {
|
||||
static const struct regulator_ops stpmic1_ldo4_fixed_regul_ops = {
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.set_pull_down = regulator_set_pull_down_regmap,
|
||||
.set_over_current_protection = stpmic1_set_icc,
|
||||
};
|
||||
|
||||
static struct regulator_ops stpmic1_buck_ops = {
|
||||
static const struct regulator_ops stpmic1_buck_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
@ -198,20 +171,27 @@ static struct regulator_ops stpmic1_buck_ops = {
|
||||
.set_over_current_protection = stpmic1_set_icc,
|
||||
};
|
||||
|
||||
static struct regulator_ops stpmic1_vref_ddr_ops = {
|
||||
static const struct regulator_ops stpmic1_vref_ddr_ops = {
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.set_pull_down = regulator_set_pull_down_regmap,
|
||||
};
|
||||
|
||||
static struct regulator_ops stpmic1_switch_regul_ops = {
|
||||
static const struct regulator_ops stpmic1_boost_regul_ops = {
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.set_over_current_protection = stpmic1_set_icc,
|
||||
};
|
||||
|
||||
static const struct regulator_ops stpmic1_switch_regul_ops = {
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.set_over_current_protection = stpmic1_set_icc,
|
||||
.set_active_discharge = regulator_set_active_discharge_regmap,
|
||||
};
|
||||
|
||||
#define REG_LDO(ids, base) { \
|
||||
.name = #ids, \
|
||||
.id = STPMIC1_##ids, \
|
||||
@ -228,8 +208,6 @@ static struct regulator_ops stpmic1_switch_regul_ops = {
|
||||
.enable_val = 1, \
|
||||
.disable_val = 0, \
|
||||
.enable_time = PMIC_ENABLE_TIME_US, \
|
||||
.pull_down_reg = ids##_PULL_DOWN_REG, \
|
||||
.pull_down_mask = ids##_PULL_DOWN_MASK, \
|
||||
.supply_name = #base, \
|
||||
}
|
||||
|
||||
@ -253,8 +231,6 @@ static struct regulator_ops stpmic1_switch_regul_ops = {
|
||||
.bypass_mask = LDO_BYPASS_MASK, \
|
||||
.bypass_val_on = LDO_BYPASS_MASK, \
|
||||
.bypass_val_off = 0, \
|
||||
.pull_down_reg = ids##_PULL_DOWN_REG, \
|
||||
.pull_down_mask = ids##_PULL_DOWN_MASK, \
|
||||
.supply_name = #base, \
|
||||
}
|
||||
|
||||
@ -272,8 +248,6 @@ static struct regulator_ops stpmic1_switch_regul_ops = {
|
||||
.enable_val = 1, \
|
||||
.disable_val = 0, \
|
||||
.enable_time = PMIC_ENABLE_TIME_US, \
|
||||
.pull_down_reg = ids##_PULL_DOWN_REG, \
|
||||
.pull_down_mask = ids##_PULL_DOWN_MASK, \
|
||||
.supply_name = #base, \
|
||||
}
|
||||
|
||||
@ -313,12 +287,27 @@ static struct regulator_ops stpmic1_switch_regul_ops = {
|
||||
.enable_val = 1, \
|
||||
.disable_val = 0, \
|
||||
.enable_time = PMIC_ENABLE_TIME_US, \
|
||||
.pull_down_reg = ids##_PULL_DOWN_REG, \
|
||||
.pull_down_mask = ids##_PULL_DOWN_MASK, \
|
||||
.supply_name = #base, \
|
||||
}
|
||||
|
||||
#define REG_SWITCH(ids, base, reg, mask, val) { \
|
||||
#define REG_BOOST(ids, base) { \
|
||||
.name = #ids, \
|
||||
.id = STPMIC1_##ids, \
|
||||
.n_voltages = 1, \
|
||||
.ops = &stpmic1_boost_regul_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
.min_uV = 0, \
|
||||
.fixed_uV = 5000000, \
|
||||
.enable_reg = BST_SW_CR, \
|
||||
.enable_mask = BOOST_ENABLED, \
|
||||
.enable_val = BOOST_ENABLED, \
|
||||
.disable_val = 0, \
|
||||
.enable_time = PMIC_ENABLE_TIME_US, \
|
||||
.supply_name = #base, \
|
||||
}
|
||||
|
||||
#define REG_VBUS_OTG(ids, base) { \
|
||||
.name = #ids, \
|
||||
.id = STPMIC1_##ids, \
|
||||
.n_voltages = 1, \
|
||||
@ -327,15 +316,38 @@ static struct regulator_ops stpmic1_switch_regul_ops = {
|
||||
.owner = THIS_MODULE, \
|
||||
.min_uV = 0, \
|
||||
.fixed_uV = 5000000, \
|
||||
.enable_reg = (reg), \
|
||||
.enable_mask = (mask), \
|
||||
.enable_val = (val), \
|
||||
.enable_reg = BST_SW_CR, \
|
||||
.enable_mask = USBSW_OTG_SWITCH_ENABLED, \
|
||||
.enable_val = USBSW_OTG_SWITCH_ENABLED, \
|
||||
.disable_val = 0, \
|
||||
.enable_time = PMIC_ENABLE_TIME_US, \
|
||||
.supply_name = #base, \
|
||||
.active_discharge_reg = BST_SW_CR, \
|
||||
.active_discharge_mask = VBUS_OTG_DISCHARGE, \
|
||||
.active_discharge_on = VBUS_OTG_DISCHARGE, \
|
||||
}
|
||||
|
||||
struct stpmic1_regulator_cfg stpmic1_regulator_cfgs[] = {
|
||||
#define REG_SW_OUT(ids, base) { \
|
||||
.name = #ids, \
|
||||
.id = STPMIC1_##ids, \
|
||||
.n_voltages = 1, \
|
||||
.ops = &stpmic1_switch_regul_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
.min_uV = 0, \
|
||||
.fixed_uV = 5000000, \
|
||||
.enable_reg = BST_SW_CR, \
|
||||
.enable_mask = SWIN_SWOUT_ENABLED, \
|
||||
.enable_val = SWIN_SWOUT_ENABLED, \
|
||||
.disable_val = 0, \
|
||||
.enable_time = PMIC_ENABLE_TIME_US, \
|
||||
.supply_name = #base, \
|
||||
.active_discharge_reg = BST_SW_CR, \
|
||||
.active_discharge_mask = SW_OUT_DISCHARGE, \
|
||||
.active_discharge_on = SW_OUT_DISCHARGE, \
|
||||
}
|
||||
|
||||
static const struct stpmic1_regulator_cfg stpmic1_regulator_cfgs[] = {
|
||||
[STPMIC1_BUCK1] = {
|
||||
.desc = REG_BUCK(BUCK1, buck1),
|
||||
.icc_reg = BUCKS_ICCTO_CR,
|
||||
@ -412,23 +424,17 @@ struct stpmic1_regulator_cfg stpmic1_regulator_cfgs[] = {
|
||||
.mask_reset_mask = BIT(6),
|
||||
},
|
||||
[STPMIC1_BOOST] = {
|
||||
.desc = REG_SWITCH(BOOST, boost, BST_SW_CR,
|
||||
BOOST_ENABLED,
|
||||
BOOST_ENABLED),
|
||||
.desc = REG_BOOST(BOOST, boost),
|
||||
.icc_reg = BUCKS_ICCTO_CR,
|
||||
.icc_mask = BIT(6),
|
||||
},
|
||||
[STPMIC1_VBUS_OTG] = {
|
||||
.desc = REG_SWITCH(VBUS_OTG, pwr_sw1, BST_SW_CR,
|
||||
USBSW_OTG_SWITCH_ENABLED,
|
||||
USBSW_OTG_SWITCH_ENABLED),
|
||||
.desc = REG_VBUS_OTG(VBUS_OTG, pwr_sw1),
|
||||
.icc_reg = BUCKS_ICCTO_CR,
|
||||
.icc_mask = BIT(4),
|
||||
},
|
||||
[STPMIC1_SW_OUT] = {
|
||||
.desc = REG_SWITCH(SW_OUT, pwr_sw2, BST_SW_CR,
|
||||
SWIN_SWOUT_ENABLED,
|
||||
SWIN_SWOUT_ENABLED),
|
||||
.desc = REG_SW_OUT(SW_OUT, pwr_sw2),
|
||||
.icc_reg = BUCKS_ICCTO_CR,
|
||||
.icc_mask = BIT(5),
|
||||
},
|
||||
@ -449,8 +455,9 @@ static unsigned int stpmic1_map_mode(unsigned int mode)
|
||||
static unsigned int stpmic1_get_mode(struct regulator_dev *rdev)
|
||||
{
|
||||
int value;
|
||||
struct regmap *regmap = rdev_get_regmap(rdev);
|
||||
|
||||
regmap_read(rdev->regmap, rdev->desc->enable_reg, &value);
|
||||
regmap_read(regmap, rdev->desc->enable_reg, &value);
|
||||
|
||||
if (value & STPMIC1_BUCK_MODE_LP)
|
||||
return REGULATOR_MODE_STANDBY;
|
||||
@ -461,6 +468,7 @@ static unsigned int stpmic1_get_mode(struct regulator_dev *rdev)
|
||||
static int stpmic1_set_mode(struct regulator_dev *rdev, unsigned int mode)
|
||||
{
|
||||
int value;
|
||||
struct regmap *regmap = rdev_get_regmap(rdev);
|
||||
|
||||
switch (mode) {
|
||||
case REGULATOR_MODE_NORMAL:
|
||||
@ -473,17 +481,18 @@ static int stpmic1_set_mode(struct regulator_dev *rdev, unsigned int mode)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
|
||||
return regmap_update_bits(regmap, rdev->desc->enable_reg,
|
||||
STPMIC1_BUCK_MODE_LP, value);
|
||||
}
|
||||
|
||||
static int stpmic1_set_icc(struct regulator_dev *rdev)
|
||||
{
|
||||
struct stpmic1_regulator *regul = rdev_get_drvdata(rdev);
|
||||
struct stpmic1_regulator_cfg *cfg = rdev_get_drvdata(rdev);
|
||||
struct regmap *regmap = rdev_get_regmap(rdev);
|
||||
|
||||
/* enable switch off in case of over current */
|
||||
return regmap_update_bits(regul->regmap, regul->cfg->icc_reg,
|
||||
regul->cfg->icc_mask, regul->cfg->icc_mask);
|
||||
return regmap_update_bits(regmap, cfg->icc_reg, cfg->icc_mask,
|
||||
cfg->icc_mask);
|
||||
}
|
||||
|
||||
static irqreturn_t stpmic1_curlim_irq_handler(int irq, void *data)
|
||||
@ -502,46 +511,13 @@ static irqreturn_t stpmic1_curlim_irq_handler(int irq, void *data)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int stpmic1_regulator_init(struct platform_device *pdev,
|
||||
struct regulator_dev *rdev)
|
||||
{
|
||||
struct stpmic1_regulator *regul = rdev_get_drvdata(rdev);
|
||||
int ret = 0;
|
||||
|
||||
/* set mask reset */
|
||||
if (regul->mask_reset && regul->cfg->mask_reset_reg != 0) {
|
||||
ret = regmap_update_bits(regul->regmap,
|
||||
regul->cfg->mask_reset_reg,
|
||||
regul->cfg->mask_reset_mask,
|
||||
regul->cfg->mask_reset_mask);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "set mask reset failed\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* setup an irq handler for over-current detection */
|
||||
if (regul->irq_curlim > 0) {
|
||||
ret = devm_request_threaded_irq(&pdev->dev,
|
||||
regul->irq_curlim, NULL,
|
||||
stpmic1_curlim_irq_handler,
|
||||
IRQF_ONESHOT | IRQF_SHARED,
|
||||
pdev->name, rdev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Request IRQ failed\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MATCH(_name, _id) \
|
||||
[STPMIC1_##_id] = { \
|
||||
.name = #_name, \
|
||||
.desc = &stpmic1_regulator_cfgs[STPMIC1_##_id].desc, \
|
||||
}
|
||||
|
||||
static struct of_regulator_match stpmic1_regulators_matches[] = {
|
||||
static struct of_regulator_match stpmic1_matches[] = {
|
||||
MATCH(buck1, BUCK1),
|
||||
MATCH(buck2, BUCK2),
|
||||
MATCH(buck3, BUCK3),
|
||||
@ -558,94 +534,75 @@ static struct of_regulator_match stpmic1_regulators_matches[] = {
|
||||
MATCH(pwr_sw2, SW_OUT),
|
||||
};
|
||||
|
||||
static int stpmic1_regulator_parse_dt(void *driver_data)
|
||||
{
|
||||
struct stpmic1_regulator *regul =
|
||||
(struct stpmic1_regulator *)driver_data;
|
||||
|
||||
if (!regul)
|
||||
return -EINVAL;
|
||||
|
||||
if (of_get_property(regul->reg_node, "st,mask-reset", NULL))
|
||||
regul->mask_reset = 1;
|
||||
|
||||
regul->irq_curlim = of_irq_get(regul->reg_node, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct
|
||||
regulator_dev *stpmic1_regulator_register(struct platform_device *pdev, int id,
|
||||
struct regulator_init_data *init_data,
|
||||
struct stpmic1_regulator *regul)
|
||||
static int stpmic1_regulator_register(struct platform_device *pdev, int id,
|
||||
struct of_regulator_match *match,
|
||||
const struct stpmic1_regulator_cfg *cfg)
|
||||
{
|
||||
struct stpmic1 *pmic_dev = dev_get_drvdata(pdev->dev.parent);
|
||||
struct regulator_dev *rdev;
|
||||
struct regulator_config config = {};
|
||||
int ret = 0;
|
||||
int irq;
|
||||
|
||||
config.dev = &pdev->dev;
|
||||
config.init_data = init_data;
|
||||
config.of_node = stpmic1_regulators_matches[id].of_node;
|
||||
config.init_data = match->init_data;
|
||||
config.of_node = match->of_node;
|
||||
config.regmap = pmic_dev->regmap;
|
||||
config.driver_data = regul;
|
||||
config.driver_data = (void *)cfg;
|
||||
|
||||
regul->regul_id = id;
|
||||
regul->reg_node = config.of_node;
|
||||
regul->cfg = &stpmic1_regulator_cfgs[id];
|
||||
regul->regmap = pmic_dev->regmap;
|
||||
|
||||
rdev = devm_regulator_register(&pdev->dev, ®ul->cfg->desc, &config);
|
||||
rdev = devm_regulator_register(&pdev->dev, &cfg->desc, &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(&pdev->dev, "failed to register %s regulator\n",
|
||||
regul->cfg->desc.name);
|
||||
cfg->desc.name);
|
||||
return PTR_ERR(rdev);
|
||||
}
|
||||
|
||||
return rdev;
|
||||
/* set mask reset */
|
||||
if (of_get_property(config.of_node, "st,mask-reset", NULL) &&
|
||||
cfg->mask_reset_reg != 0) {
|
||||
ret = regmap_update_bits(pmic_dev->regmap,
|
||||
cfg->mask_reset_reg,
|
||||
cfg->mask_reset_mask,
|
||||
cfg->mask_reset_mask);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "set mask reset failed\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* setup an irq handler for over-current detection */
|
||||
irq = of_irq_get(config.of_node, 0);
|
||||
if (irq > 0) {
|
||||
ret = devm_request_threaded_irq(&pdev->dev,
|
||||
irq, NULL,
|
||||
stpmic1_curlim_irq_handler,
|
||||
IRQF_ONESHOT | IRQF_SHARED,
|
||||
pdev->name, rdev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Request IRQ failed\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stpmic1_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct regulator_dev *rdev;
|
||||
struct stpmic1_regulator *regul;
|
||||
struct regulator_init_data *init_data;
|
||||
struct device_node *np;
|
||||
int i, ret;
|
||||
|
||||
np = pdev->dev.of_node;
|
||||
|
||||
ret = of_regulator_match(&pdev->dev, np,
|
||||
stpmic1_regulators_matches,
|
||||
ARRAY_SIZE(stpmic1_regulators_matches));
|
||||
ret = of_regulator_match(&pdev->dev, pdev->dev.of_node, stpmic1_matches,
|
||||
ARRAY_SIZE(stpmic1_matches));
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev,
|
||||
"Error in PMIC regulator device tree node");
|
||||
return ret;
|
||||
}
|
||||
|
||||
regul = devm_kzalloc(&pdev->dev, ARRAY_SIZE(stpmic1_regulator_cfgs) *
|
||||
sizeof(struct stpmic1_regulator),
|
||||
GFP_KERNEL);
|
||||
if (!regul)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(stpmic1_regulator_cfgs); i++) {
|
||||
/* Parse DT & find regulators to register */
|
||||
init_data = stpmic1_regulators_matches[i].init_data;
|
||||
if (init_data)
|
||||
init_data->regulator_init = &stpmic1_regulator_parse_dt;
|
||||
|
||||
rdev = stpmic1_regulator_register(pdev, i, init_data, regul);
|
||||
if (IS_ERR(rdev))
|
||||
return PTR_ERR(rdev);
|
||||
|
||||
ret = stpmic1_regulator_init(pdev, rdev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"failed to initialize regulator %d\n", ret);
|
||||
ret = stpmic1_regulator_register(pdev, i, &stpmic1_matches[i],
|
||||
&stpmic1_regulator_cfgs[i]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
regul++;
|
||||
}
|
||||
|
||||
dev_dbg(&pdev->dev, "stpmic1_regulator driver probed\n");
|
||||
|
@ -205,7 +205,8 @@ static int tps65218_pmic_set_input_current_lim(struct regulator_dev *dev,
|
||||
return -EINVAL;
|
||||
|
||||
return tps65218_set_bits(tps, dev->desc->csel_reg, dev->desc->csel_mask,
|
||||
index << 2, TPS65218_PROTECT_L1);
|
||||
index << __builtin_ctz(dev->desc->csel_mask),
|
||||
TPS65218_PROTECT_L1);
|
||||
}
|
||||
|
||||
static int tps65218_pmic_set_current_limit(struct regulator_dev *dev,
|
||||
@ -224,7 +225,8 @@ static int tps65218_pmic_set_current_limit(struct regulator_dev *dev,
|
||||
return -EINVAL;
|
||||
|
||||
return tps65218_set_bits(tps, dev->desc->csel_reg, dev->desc->csel_mask,
|
||||
index << 2, TPS65218_PROTECT_L1);
|
||||
index << __builtin_ctz(dev->desc->csel_mask),
|
||||
TPS65218_PROTECT_L1);
|
||||
}
|
||||
|
||||
static int tps65218_pmic_get_current_limit(struct regulator_dev *dev)
|
||||
@ -237,12 +239,13 @@ static int tps65218_pmic_get_current_limit(struct regulator_dev *dev)
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
|
||||
index = (index & dev->desc->csel_mask) >> 2;
|
||||
index = (index & dev->desc->csel_mask) >>
|
||||
__builtin_ctz(dev->desc->csel_mask);
|
||||
|
||||
return ls3_currents[index];
|
||||
}
|
||||
|
||||
static struct regulator_ops tps65218_ls3_ops = {
|
||||
static struct regulator_ops tps65218_ls23_ops = {
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = tps65218_pmic_enable,
|
||||
.disable = tps65218_pmic_disable,
|
||||
@ -304,8 +307,13 @@ static const struct regulator_desc regulators[] = {
|
||||
TPS65218_ENABLE2_LDO1_EN, 0, 0, ldo1_dcdc3_ranges,
|
||||
2, 0, 0, TPS65218_REG_SEQ6,
|
||||
TPS65218_SEQ6_LDO1_SEQ_MASK),
|
||||
TPS65218_REGULATOR("LS2", "regulator-ls2", TPS65218_LS_2,
|
||||
REGULATOR_CURRENT, tps65218_ls23_ops, 0, 0, 0,
|
||||
TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LS2_EN,
|
||||
TPS65218_REG_CONFIG2, TPS65218_CONFIG2_LS2ILIM_MASK,
|
||||
NULL, 0, 0, 0, 0, 0),
|
||||
TPS65218_REGULATOR("LS3", "regulator-ls3", TPS65218_LS_3,
|
||||
REGULATOR_CURRENT, tps65218_ls3_ops, 0, 0, 0,
|
||||
REGULATOR_CURRENT, tps65218_ls23_ops, 0, 0, 0,
|
||||
TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LS3_EN,
|
||||
TPS65218_REG_CONFIG2, TPS65218_CONFIG2_LS3ILIM_MASK,
|
||||
NULL, 0, 0, 0, 0, 0),
|
||||
|
@ -576,14 +576,9 @@ static int twlreg_probe(struct platform_device *pdev)
|
||||
struct regulator_init_data *initdata;
|
||||
struct regulation_constraints *c;
|
||||
struct regulator_dev *rdev;
|
||||
const struct of_device_id *match;
|
||||
struct regulator_config config = { };
|
||||
|
||||
match = of_match_device(twl_of_match, &pdev->dev);
|
||||
if (!match)
|
||||
return -ENODEV;
|
||||
|
||||
template = match->data;
|
||||
template = of_device_get_match_data(&pdev->dev);
|
||||
if (!template)
|
||||
return -ENODEV;
|
||||
|
||||
|
@ -31,9 +31,6 @@ struct twlreg_info {
|
||||
/* twl resource ID, for resource control state machine */
|
||||
u8 id;
|
||||
|
||||
/* chip constraints on regulator behavior */
|
||||
u16 min_mV;
|
||||
|
||||
u8 flags;
|
||||
|
||||
/* used by regulator core */
|
||||
@ -247,32 +244,11 @@ static int twl6030coresmps_get_voltage(struct regulator_dev *rdev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static struct regulator_ops twl6030coresmps_ops = {
|
||||
static const struct regulator_ops twl6030coresmps_ops = {
|
||||
.set_voltage = twl6030coresmps_set_voltage,
|
||||
.get_voltage = twl6030coresmps_get_voltage,
|
||||
};
|
||||
|
||||
static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned sel)
|
||||
{
|
||||
struct twlreg_info *info = rdev_get_drvdata(rdev);
|
||||
|
||||
switch (sel) {
|
||||
case 0:
|
||||
return 0;
|
||||
case 1 ... 24:
|
||||
/* Linear mapping from 00000001 to 00011000:
|
||||
* Absolute voltage value = 1.0 V + 0.1 V × (sel – 00000001)
|
||||
*/
|
||||
return (info->min_mV + 100 * (sel - 1)) * 1000;
|
||||
case 25 ... 30:
|
||||
return -EINVAL;
|
||||
case 31:
|
||||
return 2750000;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
twl6030ldo_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
|
||||
{
|
||||
@ -290,8 +266,8 @@ static int twl6030ldo_get_voltage_sel(struct regulator_dev *rdev)
|
||||
return vsel;
|
||||
}
|
||||
|
||||
static struct regulator_ops twl6030ldo_ops = {
|
||||
.list_voltage = twl6030ldo_list_voltage,
|
||||
static const struct regulator_ops twl6030ldo_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
|
||||
.set_voltage_sel = twl6030ldo_set_voltage_sel,
|
||||
.get_voltage_sel = twl6030ldo_get_voltage_sel,
|
||||
@ -305,7 +281,7 @@ static struct regulator_ops twl6030ldo_ops = {
|
||||
.get_status = twl6030reg_get_status,
|
||||
};
|
||||
|
||||
static struct regulator_ops twl6030fixed_ops = {
|
||||
static const struct regulator_ops twl6030fixed_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
|
||||
.enable = twl6030reg_enable,
|
||||
@ -496,7 +472,7 @@ static int twl6030smps_get_voltage_sel(struct regulator_dev *rdev)
|
||||
return twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS);
|
||||
}
|
||||
|
||||
static struct regulator_ops twlsmps_ops = {
|
||||
static const struct regulator_ops twlsmps_ops = {
|
||||
.list_voltage = twl6030smps_list_voltage,
|
||||
.map_voltage = twl6030smps_map_voltage,
|
||||
|
||||
@ -513,6 +489,11 @@ static struct regulator_ops twlsmps_ops = {
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
static const struct regulator_linear_range twl6030ldo_linear_range[] = {
|
||||
REGULATOR_LINEAR_RANGE(0, 0, 0, 0),
|
||||
REGULATOR_LINEAR_RANGE(1000000, 1, 24, 100000),
|
||||
REGULATOR_LINEAR_RANGE(2750000, 31, 31, 0),
|
||||
};
|
||||
|
||||
#define TWL6030_ADJUSTABLE_SMPS(label) \
|
||||
static const struct twlreg_info TWL6030_INFO_##label = { \
|
||||
@ -525,28 +506,30 @@ static const struct twlreg_info TWL6030_INFO_##label = { \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts) \
|
||||
#define TWL6030_ADJUSTABLE_LDO(label, offset) \
|
||||
static const struct twlreg_info TWL6030_INFO_##label = { \
|
||||
.base = offset, \
|
||||
.min_mV = min_mVolts, \
|
||||
.desc = { \
|
||||
.name = #label, \
|
||||
.id = TWL6030_REG_##label, \
|
||||
.n_voltages = 32, \
|
||||
.linear_ranges = twl6030ldo_linear_range, \
|
||||
.n_linear_ranges = ARRAY_SIZE(twl6030ldo_linear_range), \
|
||||
.ops = &twl6030ldo_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define TWL6032_ADJUSTABLE_LDO(label, offset, min_mVolts) \
|
||||
#define TWL6032_ADJUSTABLE_LDO(label, offset) \
|
||||
static const struct twlreg_info TWL6032_INFO_##label = { \
|
||||
.base = offset, \
|
||||
.min_mV = min_mVolts, \
|
||||
.desc = { \
|
||||
.name = #label, \
|
||||
.id = TWL6032_REG_##label, \
|
||||
.n_voltages = 32, \
|
||||
.linear_ranges = twl6030ldo_linear_range, \
|
||||
.n_linear_ranges = ARRAY_SIZE(twl6030ldo_linear_range), \
|
||||
.ops = &twl6030ldo_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
@ -557,7 +540,6 @@ static const struct twlreg_info TWL6032_INFO_##label = { \
|
||||
static const struct twlreg_info TWLFIXED_INFO_##label = { \
|
||||
.base = offset, \
|
||||
.id = 0, \
|
||||
.min_mV = mVolts, \
|
||||
.desc = { \
|
||||
.name = #label, \
|
||||
.id = TWL6030##_REG_##label, \
|
||||
@ -574,7 +556,6 @@ static const struct twlreg_info TWLFIXED_INFO_##label = { \
|
||||
#define TWL6032_ADJUSTABLE_SMPS(label, offset) \
|
||||
static const struct twlreg_info TWLSMPS_INFO_##label = { \
|
||||
.base = offset, \
|
||||
.min_mV = 600, \
|
||||
.desc = { \
|
||||
.name = #label, \
|
||||
.id = TWL6032_REG_##label, \
|
||||
@ -592,22 +573,22 @@ static const struct twlreg_info TWLSMPS_INFO_##label = { \
|
||||
TWL6030_ADJUSTABLE_SMPS(VDD1);
|
||||
TWL6030_ADJUSTABLE_SMPS(VDD2);
|
||||
TWL6030_ADJUSTABLE_SMPS(VDD3);
|
||||
TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000);
|
||||
TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000);
|
||||
TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000);
|
||||
TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000);
|
||||
TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000);
|
||||
TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000);
|
||||
TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54);
|
||||
TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58);
|
||||
TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c);
|
||||
TWL6030_ADJUSTABLE_LDO(VMMC, 0x68);
|
||||
TWL6030_ADJUSTABLE_LDO(VPP, 0x6c);
|
||||
TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74);
|
||||
/* 6025 are renamed compared to 6030 versions */
|
||||
TWL6032_ADJUSTABLE_LDO(LDO2, 0x54, 1000);
|
||||
TWL6032_ADJUSTABLE_LDO(LDO4, 0x58, 1000);
|
||||
TWL6032_ADJUSTABLE_LDO(LDO3, 0x5c, 1000);
|
||||
TWL6032_ADJUSTABLE_LDO(LDO5, 0x68, 1000);
|
||||
TWL6032_ADJUSTABLE_LDO(LDO1, 0x6c, 1000);
|
||||
TWL6032_ADJUSTABLE_LDO(LDO7, 0x74, 1000);
|
||||
TWL6032_ADJUSTABLE_LDO(LDO6, 0x60, 1000);
|
||||
TWL6032_ADJUSTABLE_LDO(LDOLN, 0x64, 1000);
|
||||
TWL6032_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000);
|
||||
TWL6032_ADJUSTABLE_LDO(LDO2, 0x54);
|
||||
TWL6032_ADJUSTABLE_LDO(LDO4, 0x58);
|
||||
TWL6032_ADJUSTABLE_LDO(LDO3, 0x5c);
|
||||
TWL6032_ADJUSTABLE_LDO(LDO5, 0x68);
|
||||
TWL6032_ADJUSTABLE_LDO(LDO1, 0x6c);
|
||||
TWL6032_ADJUSTABLE_LDO(LDO7, 0x74);
|
||||
TWL6032_ADJUSTABLE_LDO(LDO6, 0x60);
|
||||
TWL6032_ADJUSTABLE_LDO(LDOLN, 0x64);
|
||||
TWL6032_ADJUSTABLE_LDO(LDOUSB, 0x70);
|
||||
TWL6030_FIXED_LDO(VANA, 0x50, 2100, 0);
|
||||
TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 0);
|
||||
TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 0);
|
||||
@ -687,14 +668,9 @@ static int twlreg_probe(struct platform_device *pdev)
|
||||
struct regulator_init_data *initdata;
|
||||
struct regulation_constraints *c;
|
||||
struct regulator_dev *rdev;
|
||||
const struct of_device_id *match;
|
||||
struct regulator_config config = { };
|
||||
|
||||
match = of_match_device(twl_of_match, &pdev->dev);
|
||||
if (!match)
|
||||
return -ENODEV;
|
||||
|
||||
template = match->data;
|
||||
template = of_device_get_match_data(&pdev->dev);
|
||||
if (!template)
|
||||
return -ENODEV;
|
||||
|
||||
|
@ -205,33 +205,10 @@ static irqreturn_t wm831x_dcdc_oc_irq(int irq, void *data)
|
||||
* BUCKV specifics
|
||||
*/
|
||||
|
||||
static int wm831x_buckv_list_voltage(struct regulator_dev *rdev,
|
||||
unsigned selector)
|
||||
{
|
||||
if (selector <= 0x8)
|
||||
return 600000;
|
||||
if (selector <= WM831X_BUCKV_MAX_SELECTOR)
|
||||
return 600000 + ((selector - 0x8) * 12500);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int wm831x_buckv_map_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV)
|
||||
{
|
||||
u16 vsel;
|
||||
|
||||
if (min_uV < 600000)
|
||||
vsel = 0;
|
||||
else if (min_uV <= 1800000)
|
||||
vsel = DIV_ROUND_UP(min_uV - 600000, 12500) + 8;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
if (wm831x_buckv_list_voltage(rdev, vsel) > max_uV)
|
||||
return -EINVAL;
|
||||
|
||||
return vsel;
|
||||
}
|
||||
static const struct regulator_linear_range wm831x_buckv_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(600000, 0, 0x7, 0),
|
||||
REGULATOR_LINEAR_RANGE(600000, 0x8, 0x68, 12500),
|
||||
};
|
||||
|
||||
static int wm831x_buckv_set_dvs(struct regulator_dev *rdev, int state)
|
||||
{
|
||||
@ -309,7 +286,7 @@ static int wm831x_buckv_set_suspend_voltage(struct regulator_dev *rdev,
|
||||
u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL;
|
||||
int vsel;
|
||||
|
||||
vsel = wm831x_buckv_map_voltage(rdev, uV, uV);
|
||||
vsel = regulator_map_voltage_linear_range(rdev, uV, uV);
|
||||
if (vsel < 0)
|
||||
return vsel;
|
||||
|
||||
@ -331,48 +308,14 @@ static const unsigned int wm831x_dcdc_ilim[] = {
|
||||
125000, 250000, 375000, 500000, 625000, 750000, 875000, 1000000
|
||||
};
|
||||
|
||||
static int wm831x_buckv_set_current_limit(struct regulator_dev *rdev,
|
||||
int min_uA, int max_uA)
|
||||
{
|
||||
struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
|
||||
struct wm831x *wm831x = dcdc->wm831x;
|
||||
u16 reg = dcdc->base + WM831X_DCDC_CONTROL_2;
|
||||
int i;
|
||||
|
||||
for (i = ARRAY_SIZE(wm831x_dcdc_ilim) - 1; i >= 0; i--) {
|
||||
if ((min_uA <= wm831x_dcdc_ilim[i]) &&
|
||||
(wm831x_dcdc_ilim[i] <= max_uA))
|
||||
return wm831x_set_bits(wm831x, reg,
|
||||
WM831X_DC1_HC_THR_MASK,
|
||||
i << WM831X_DC1_HC_THR_SHIFT);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int wm831x_buckv_get_current_limit(struct regulator_dev *rdev)
|
||||
{
|
||||
struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
|
||||
struct wm831x *wm831x = dcdc->wm831x;
|
||||
u16 reg = dcdc->base + WM831X_DCDC_CONTROL_2;
|
||||
int val;
|
||||
|
||||
val = wm831x_reg_read(wm831x, reg);
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
val = (val & WM831X_DC1_HC_THR_MASK) >> WM831X_DC1_HC_THR_SHIFT;
|
||||
return wm831x_dcdc_ilim[val];
|
||||
}
|
||||
|
||||
static const struct regulator_ops wm831x_buckv_ops = {
|
||||
.set_voltage_sel = wm831x_buckv_set_voltage_sel,
|
||||
.get_voltage_sel = wm831x_buckv_get_voltage_sel,
|
||||
.list_voltage = wm831x_buckv_list_voltage,
|
||||
.map_voltage = wm831x_buckv_map_voltage,
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
.set_suspend_voltage = wm831x_buckv_set_suspend_voltage,
|
||||
.set_current_limit = wm831x_buckv_set_current_limit,
|
||||
.get_current_limit = wm831x_buckv_get_current_limit,
|
||||
.set_current_limit = regulator_set_current_limit_regmap,
|
||||
.get_current_limit = regulator_get_current_limit_regmap,
|
||||
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
@ -492,10 +435,16 @@ static int wm831x_buckv_probe(struct platform_device *pdev)
|
||||
dcdc->desc.id = id;
|
||||
dcdc->desc.type = REGULATOR_VOLTAGE;
|
||||
dcdc->desc.n_voltages = WM831X_BUCKV_MAX_SELECTOR + 1;
|
||||
dcdc->desc.linear_ranges = wm831x_buckv_ranges;
|
||||
dcdc->desc.n_linear_ranges = ARRAY_SIZE(wm831x_buckv_ranges);
|
||||
dcdc->desc.ops = &wm831x_buckv_ops;
|
||||
dcdc->desc.owner = THIS_MODULE;
|
||||
dcdc->desc.enable_reg = WM831X_DCDC_ENABLE;
|
||||
dcdc->desc.enable_mask = 1 << id;
|
||||
dcdc->desc.csel_reg = dcdc->base + WM831X_DCDC_CONTROL_2;
|
||||
dcdc->desc.csel_mask = WM831X_DC1_HC_THR_MASK;
|
||||
dcdc->desc.n_current_limits = ARRAY_SIZE(wm831x_dcdc_ilim);
|
||||
dcdc->desc.curr_table = wm831x_dcdc_ilim;
|
||||
|
||||
ret = wm831x_reg_read(wm831x, dcdc->base + WM831X_DCDC_ON_CONFIG);
|
||||
if (ret < 0) {
|
||||
|
@ -208,6 +208,7 @@ enum tps65218_regulator_id {
|
||||
/* LDOs */
|
||||
TPS65218_LDO_1,
|
||||
/* LS's */
|
||||
TPS65218_LS_2,
|
||||
TPS65218_LS_3,
|
||||
};
|
||||
|
||||
@ -218,7 +219,7 @@ enum tps65218_regulator_id {
|
||||
/* Number of LDO voltage regulators available */
|
||||
#define TPS65218_NUM_LDO 1
|
||||
/* Number of total LS current regulators available */
|
||||
#define TPS65218_NUM_LS 1
|
||||
#define TPS65218_NUM_LS 2
|
||||
/* Number of total regulators available */
|
||||
#define TPS65218_NUM_REGULATOR (TPS65218_NUM_DCDC + TPS65218_NUM_LDO \
|
||||
+ TPS65218_NUM_LS)
|
||||
|
@ -264,6 +264,7 @@ enum regulator_type {
|
||||
* @continuous_voltage_range: Indicates if the regulator can set any
|
||||
* voltage within constrains range.
|
||||
* @n_voltages: Number of selectors available for ops.list_voltage().
|
||||
* @n_current_limits: Number of selectors available for current limits
|
||||
*
|
||||
* @min_uV: Voltage given by the lowest selector (if linear mapping)
|
||||
* @uV_step: Voltage increase with each selector (if linear mapping)
|
||||
@ -278,14 +279,15 @@ enum regulator_type {
|
||||
* @n_linear_ranges: Number of entries in the @linear_ranges (and in
|
||||
* linear_range_selectors if used) table(s).
|
||||
* @volt_table: Voltage mapping table (if table based mapping)
|
||||
* @curr_table: Current limit mapping table (if table based mapping)
|
||||
*
|
||||
* @vsel_range_reg: Register for range selector when using pickable ranges
|
||||
* and regulator_regmap_X_voltage_X_pickable functions.
|
||||
* @vsel_range_mask: Mask for register bitfield used for range selector
|
||||
* @vsel_reg: Register for selector when using regulator_regmap_X_voltage_
|
||||
* @vsel_mask: Mask for register bitfield used for selector
|
||||
* @csel_reg: Register for TPS65218 LS3 current regulator
|
||||
* @csel_mask: Mask for TPS65218 LS3 current regulator
|
||||
* @csel_reg: Register for current limit selector using regmap set_current_limit
|
||||
* @csel_mask: Mask for register bitfield used for current limit selector
|
||||
* @apply_reg: Register for initiate voltage change on the output when
|
||||
* using regulator_set_voltage_sel_regmap
|
||||
* @apply_bit: Register bitfield used for initiate voltage change on the
|
||||
@ -333,6 +335,7 @@ struct regulator_desc {
|
||||
int id;
|
||||
unsigned int continuous_voltage_range:1;
|
||||
unsigned n_voltages;
|
||||
unsigned int n_current_limits;
|
||||
const struct regulator_ops *ops;
|
||||
int irq;
|
||||
enum regulator_type type;
|
||||
@ -351,6 +354,7 @@ struct regulator_desc {
|
||||
int n_linear_ranges;
|
||||
|
||||
const unsigned int *volt_table;
|
||||
const unsigned int *curr_table;
|
||||
|
||||
unsigned int vsel_range_reg;
|
||||
unsigned int vsel_range_mask;
|
||||
@ -401,13 +405,7 @@ struct regulator_desc {
|
||||
* NULL).
|
||||
* @regmap: regmap to use for core regmap helpers if dev_get_regmap() is
|
||||
* insufficient.
|
||||
* @ena_gpio_initialized: GPIO controlling regulator enable was properly
|
||||
* initialized, meaning that >= 0 is a valid gpio
|
||||
* identifier and < 0 is a non existent gpio.
|
||||
* @ena_gpio: GPIO controlling regulator enable.
|
||||
* @ena_gpiod: GPIO descriptor controlling regulator enable.
|
||||
* @ena_gpio_invert: Sense for GPIO enable control.
|
||||
* @ena_gpio_flags: Flags to use when calling gpio_request_one()
|
||||
* @ena_gpiod: GPIO controlling regulator enable.
|
||||
*/
|
||||
struct regulator_config {
|
||||
struct device *dev;
|
||||
@ -416,11 +414,7 @@ struct regulator_config {
|
||||
struct device_node *of_node;
|
||||
struct regmap *regmap;
|
||||
|
||||
bool ena_gpio_initialized;
|
||||
int ena_gpio;
|
||||
struct gpio_desc *ena_gpiod;
|
||||
unsigned int ena_gpio_invert:1;
|
||||
unsigned int ena_gpio_flags;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -503,6 +497,7 @@ int regulator_notifier_call_chain(struct regulator_dev *rdev,
|
||||
|
||||
void *rdev_get_drvdata(struct regulator_dev *rdev);
|
||||
struct device *rdev_get_dev(struct regulator_dev *rdev);
|
||||
struct regmap *rdev_get_regmap(struct regulator_dev *rdev);
|
||||
int rdev_get_id(struct regulator_dev *rdev);
|
||||
|
||||
int regulator_mode_to_status(unsigned int);
|
||||
@ -543,9 +538,18 @@ int regulator_set_pull_down_regmap(struct regulator_dev *rdev);
|
||||
|
||||
int regulator_set_active_discharge_regmap(struct regulator_dev *rdev,
|
||||
bool enable);
|
||||
int regulator_set_current_limit_regmap(struct regulator_dev *rdev,
|
||||
int min_uA, int max_uA);
|
||||
int regulator_get_current_limit_regmap(struct regulator_dev *rdev);
|
||||
void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data);
|
||||
|
||||
void regulator_lock(struct regulator_dev *rdev);
|
||||
void regulator_unlock(struct regulator_dev *rdev);
|
||||
|
||||
/*
|
||||
* Helper functions intended to be used by regulator drivers prior registering
|
||||
* their regulators.
|
||||
*/
|
||||
int regulator_desc_list_voltage_linear_range(const struct regulator_desc *desc,
|
||||
unsigned int selector);
|
||||
#endif
|
||||
|
@ -25,14 +25,6 @@ struct regulator_init_data;
|
||||
* @input_supply: Name of the input regulator supply
|
||||
* @microvolts: Output voltage of regulator
|
||||
* @startup_delay: Start-up time in microseconds
|
||||
* @gpio_is_open_drain: Gpio pin is open drain or normal type.
|
||||
* If it is open drain type then HIGH will be set
|
||||
* through PULL-UP with setting gpio as input
|
||||
* and low will be set as gpio-output with driven
|
||||
* to low. For non-open-drain case, the gpio will
|
||||
* will be in output and drive to low/high accordingly.
|
||||
* @enable_high: Polarity of enable GPIO
|
||||
* 1 = Active high, 0 = Active low
|
||||
* @enabled_at_boot: Whether regulator has been enabled at
|
||||
* boot or not. 1 = Yes, 0 = No
|
||||
* This is used to keep the regulator at
|
||||
@ -48,8 +40,6 @@ struct fixed_voltage_config {
|
||||
const char *input_supply;
|
||||
int microvolts;
|
||||
unsigned startup_delay;
|
||||
unsigned gpio_is_open_drain:1;
|
||||
unsigned enable_high:1;
|
||||
unsigned enabled_at_boot:1;
|
||||
struct regulator_init_data *init_data;
|
||||
};
|
||||
|
@ -21,6 +21,8 @@
|
||||
#ifndef __REGULATOR_GPIO_H
|
||||
#define __REGULATOR_GPIO_H
|
||||
|
||||
#include <linux/gpio/consumer.h>
|
||||
|
||||
struct regulator_init_data;
|
||||
|
||||
enum regulator_type;
|
||||
@ -44,18 +46,14 @@ struct gpio_regulator_state {
|
||||
/**
|
||||
* struct gpio_regulator_config - config structure
|
||||
* @supply_name: Name of the regulator supply
|
||||
* @enable_gpio: GPIO to use for enable control
|
||||
* set to -EINVAL if not used
|
||||
* @enable_high: Polarity of enable GPIO
|
||||
* 1 = Active high, 0 = Active low
|
||||
* @enabled_at_boot: Whether regulator has been enabled at
|
||||
* boot or not. 1 = Yes, 0 = No
|
||||
* This is used to keep the regulator at
|
||||
* the default state
|
||||
* @startup_delay: Start-up time in microseconds
|
||||
* @gpios: Array containing the gpios needed to control
|
||||
* the setting of the regulator
|
||||
* @nr_gpios: Number of gpios
|
||||
* @gflags: Array of GPIO configuration flags for initial
|
||||
* states
|
||||
* @ngpios: Number of GPIOs and configurations available
|
||||
* @states: Array of gpio_regulator_state entries describing
|
||||
* the gpio state for specific voltages
|
||||
* @nr_states: Number of states available
|
||||
@ -69,13 +67,11 @@ struct gpio_regulator_state {
|
||||
struct gpio_regulator_config {
|
||||
const char *supply_name;
|
||||
|
||||
int enable_gpio;
|
||||
unsigned enable_high:1;
|
||||
unsigned enabled_at_boot:1;
|
||||
unsigned startup_delay;
|
||||
|
||||
struct gpio *gpios;
|
||||
int nr_gpios;
|
||||
enum gpiod_flags *gflags;
|
||||
int ngpios;
|
||||
|
||||
struct gpio_regulator_state *states;
|
||||
int nr_states;
|
||||
|
Loading…
Reference in New Issue
Block a user