mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 04:33:26 +02:00
Merge tag 'regulator-v6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator
Pull regulator updates from Mark Brown: "This release is almost all drivers, there's some small improvements in the core but otherwise everything is updates to drivers, mostly the addition of new ones. There's also a bunch of changes pulled in from the MFD subsystem as dependencies, Rockchip and TI core MFD code that the regulator drivers depend on. I've also yet again managed to put a SPI commit in the regulator tree, I don't know what it is about those two trees (this for spi-geni-qcom). Summary: - Support for Renesas RAA215300, Rockchip RK808, Texas Instruments TPS6594 and TPS6287x, and X-Powers AXP15060 and AXP313a" * tag 'regulator-v6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (43 commits) regulator: Add Renesas PMIC RAA215300 driver regulator: dt-bindings: Add Renesas RAA215300 PMIC bindings regulator: ltc3676: Use maple tree register cache regulator: ltc3589: Use maple tree register cache regulator: helper: Document ramp_delay parameter of regulator_set_ramp_delay_regmap() regulator: mt6358: Use linear voltage helpers for single range regulators regulator: mt6358: Const-ify mt6358_regulator_info data structures regulator: mt6358: Drop *_SSHUB regulators regulator: mt6358: Merge VCN33_* regulators regulator: dt-bindings: mt6358: Drop *_sshub regulators regulator: dt-bindings: mt6358: Merge ldo_vcn33_* regulators regulator: dt-bindings: pwm-regulator: Add missing type for "pwm-dutycycle-unit" regulator: Switch two more i2c drivers back to use .probe() spi: spi-geni-qcom: Do not do DMA map/unmap inside driver, use framework instead soc: qcom: geni-se: Add interfaces geni_se_tx_init_dma() and geni_se_rx_init_dma() regulator: tps6594-regulator: Add driver for TI TPS6594 regulators regulator: axp20x: Add AXP15060 support regulator: axp20x: Add support for AXP313a variant dt-bindings: pfuze100.yaml: Add an entry for interrupts regulator: stm32-pwr: Fix regulator disabling ...
This commit is contained in:
406
Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml
Normal file
406
Documentation/devicetree/bindings/mfd/rockchip,rk806.yaml
Normal file
@@ -0,0 +1,406 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mfd/rockchip,rk806.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: RK806 Power Management Integrated Circuit
|
||||
|
||||
maintainers:
|
||||
- Sebastian Reichel <sebastian.reichel@collabora.com>
|
||||
|
||||
description:
|
||||
Rockchip RK806 series PMIC. This device consists of an spi or
|
||||
i2c controlled MFD that includes multiple switchable regulators.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- rockchip,rk806
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
gpio-controller: true
|
||||
|
||||
'#gpio-cells':
|
||||
const: 2
|
||||
|
||||
vcc1-supply:
|
||||
description:
|
||||
The input supply for dcdc-reg1.
|
||||
|
||||
vcc2-supply:
|
||||
description:
|
||||
The input supply for dcdc-reg2.
|
||||
|
||||
vcc3-supply:
|
||||
description:
|
||||
The input supply for dcdc-reg3.
|
||||
|
||||
vcc4-supply:
|
||||
description:
|
||||
The input supply for dcdc-reg4.
|
||||
|
||||
vcc5-supply:
|
||||
description:
|
||||
The input supply for dcdc-reg5.
|
||||
|
||||
vcc6-supply:
|
||||
description:
|
||||
The input supply for dcdc-reg6.
|
||||
|
||||
vcc7-supply:
|
||||
description:
|
||||
The input supply for dcdc-reg7.
|
||||
|
||||
vcc8-supply:
|
||||
description:
|
||||
The input supply for dcdc-reg8.
|
||||
|
||||
vcc9-supply:
|
||||
description:
|
||||
The input supply for dcdc-reg9.
|
||||
|
||||
vcc10-supply:
|
||||
description:
|
||||
The input supply for dcdc-reg10.
|
||||
|
||||
vcc11-supply:
|
||||
description:
|
||||
The input supply for pldo-reg1, pldo-reg2 and pldo-reg3.
|
||||
|
||||
vcc12-supply:
|
||||
description:
|
||||
The input supply for pldo-reg4 and pldo-reg5.
|
||||
|
||||
vcc13-supply:
|
||||
description:
|
||||
The input supply for nldo-reg1, nldo-reg2 and nldo-reg3.
|
||||
|
||||
vcc14-supply:
|
||||
description:
|
||||
The input supply for nldo-reg4 and nldo-reg5.
|
||||
|
||||
vcca-supply:
|
||||
description:
|
||||
The input supply for pldo-reg6.
|
||||
|
||||
regulators:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
patternProperties:
|
||||
"^(dcdc-reg([1-9]|10)|pldo-reg[1-6]|nldo-reg[1-5])$":
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
patternProperties:
|
||||
'-pins$':
|
||||
type: object
|
||||
additionalProperties: false
|
||||
$ref: /schemas/pinctrl/pinmux-node.yaml
|
||||
|
||||
properties:
|
||||
function:
|
||||
enum: [pin_fun0, pin_fun1, pin_fun2, pin_fun3, pin_fun4, pin_fun5]
|
||||
|
||||
pins:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
enum: [gpio_pwrctrl1, gpio_pwrctrl2, gpio_pwrctrl3]
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/pinctrl/rockchip.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pmic@0 {
|
||||
compatible = "rockchip,rk806";
|
||||
reg = <0x0>;
|
||||
|
||||
interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
|
||||
|
||||
vcc1-supply = <&vcc5v0_sys>;
|
||||
vcc2-supply = <&vcc5v0_sys>;
|
||||
vcc3-supply = <&vcc5v0_sys>;
|
||||
vcc4-supply = <&vcc5v0_sys>;
|
||||
vcc5-supply = <&vcc5v0_sys>;
|
||||
vcc6-supply = <&vcc5v0_sys>;
|
||||
vcc7-supply = <&vcc5v0_sys>;
|
||||
vcc8-supply = <&vcc5v0_sys>;
|
||||
vcc9-supply = <&vcc5v0_sys>;
|
||||
vcc10-supply = <&vcc5v0_sys>;
|
||||
vcc11-supply = <&vcc_2v0_pldo_s3>;
|
||||
vcc12-supply = <&vcc5v0_sys>;
|
||||
vcc13-supply = <&vcc5v0_sys>;
|
||||
vcc14-supply = <&vcc_1v1_nldo_s3>;
|
||||
vcca-supply = <&vcc5v0_sys>;
|
||||
|
||||
regulators {
|
||||
vdd_gpu_s0: dcdc-reg1 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <550000>;
|
||||
regulator-max-microvolt = <950000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
regulator-name = "vdd_gpu_s0";
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
vdd_npu_s0: dcdc-reg2 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <550000>;
|
||||
regulator-max-microvolt = <950000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
regulator-name = "vdd_npu_s0";
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
vdd_log_s0: dcdc-reg3 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <750000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
regulator-name = "vdd_log_s0";
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <750000>;
|
||||
};
|
||||
};
|
||||
|
||||
vdd_vdenc_s0: dcdc-reg4 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <550000>;
|
||||
regulator-max-microvolt = <950000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
regulator-name = "vdd_vdenc_s0";
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
vdd_gpu_mem_s0: dcdc-reg5 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <675000>;
|
||||
regulator-max-microvolt = <950000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
regulator-name = "vdd_gpu_mem_s0";
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
vdd_npu_mem_s0: dcdc-reg6 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <675000>;
|
||||
regulator-max-microvolt = <950000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
regulator-name = "vdd_npu_mem_s0";
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
vcc_2v0_pldo_s3: dcdc-reg7 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <2000000>;
|
||||
regulator-max-microvolt = <2000000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
regulator-name = "vdd_2v0_pldo_s3";
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <2000000>;
|
||||
};
|
||||
};
|
||||
|
||||
vdd_vdenc_mem_s0: dcdc-reg8 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <675000>;
|
||||
regulator-max-microvolt = <950000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
regulator-name = "vdd_vdenc_mem_s0";
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
vdd2_ddr_s3: dcdc-reg9 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-name = "vdd2_ddr_s3";
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
vcc_1v1_nldo_s3: dcdc-reg10 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <1100000>;
|
||||
regulator-max-microvolt = <1100000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
regulator-name = "vcc_1v1_nldo_s3";
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <1100000>;
|
||||
};
|
||||
};
|
||||
|
||||
avcc_1v8_s0: pldo-reg1 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
regulator-name = "avcc_1v8_s0";
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
vdd1_1v8_ddr_s3: pldo-reg2 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
regulator-name = "vdd1_1v8_ddr_s3";
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <1800000>;
|
||||
};
|
||||
};
|
||||
|
||||
vcc_1v8_s3: pldo-reg3 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
regulator-name = "vcc_1v8_s3";
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <1800000>;
|
||||
};
|
||||
};
|
||||
|
||||
vcc_3v3_s0: pldo-reg4 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
regulator-name = "vcc_3v3_s0";
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
vccio_sd_s0: pldo-reg5 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
regulator-name = "vccio_sd_s0";
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
master_pldo6_s3: pldo-reg6 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-name = "master_pldo6_s3";
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <1800000>;
|
||||
};
|
||||
};
|
||||
|
||||
vdd_0v75_s3: nldo-reg1 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <750000>;
|
||||
regulator-ramp-delay = <12500>;
|
||||
regulator-name = "vdd_0v75_s3";
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <750000>;
|
||||
};
|
||||
};
|
||||
|
||||
vdd2l_0v9_ddr_s3: nldo-reg2 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <900000>;
|
||||
regulator-max-microvolt = <900000>;
|
||||
regulator-name = "vdd2l_0v9_ddr_s3";
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <900000>;
|
||||
};
|
||||
};
|
||||
|
||||
master_nldo3: nldo-reg3 {
|
||||
regulator-name = "master_nldo3";
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
avdd_0v75_s0: nldo-reg4 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <750000>;
|
||||
regulator-name = "avdd_0v75_s0";
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
vdd_0v85_s0: nldo-reg5 {
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <850000>;
|
||||
regulator-max-microvolt = <850000>;
|
||||
regulator-name = "vdd_0v85_s0";
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
@@ -8,15 +8,14 @@ Documentation/devicetree/bindings/regulator/regulator.txt.
|
||||
|
||||
The valid names for regulators are::
|
||||
BUCK:
|
||||
buck_vdram1, buck_vcore, buck_vcore_sshub, buck_vpa, buck_vproc11,
|
||||
buck_vproc12, buck_vgpu, buck_vs2, buck_vmodem, buck_vs1
|
||||
buck_vdram1, buck_vcore, buck_vpa, buck_vproc11, buck_vproc12, buck_vgpu,
|
||||
buck_vs2, buck_vmodem, buck_vs1
|
||||
LDO:
|
||||
ldo_vdram2, ldo_vsim1, ldo_vibr, ldo_vrf12, ldo_vio18, ldo_vusb, ldo_vcamio,
|
||||
ldo_vcamd, ldo_vcn18, ldo_vfe28, ldo_vsram_proc11, ldo_vcn28, ldo_vsram_others,
|
||||
ldo_vsram_others_sshub, ldo_vsram_gpu, ldo_vxo22, ldo_vefuse, ldo_vaux18,
|
||||
ldo_vmch, ldo_vbif28, ldo_vsram_proc12, ldo_vcama1, ldo_vemc, ldo_vio28, ldo_va12,
|
||||
ldo_vrf18, ldo_vcn33_bt, ldo_vcn33_wifi, ldo_vcama2, ldo_vmc, ldo_vldo28, ldo_vaud28,
|
||||
ldo_vsim2
|
||||
ldo_vsram_gpu, ldo_vxo22, ldo_vefuse, ldo_vaux18, ldo_vmch, ldo_vbif28,
|
||||
ldo_vsram_proc12, ldo_vcama1, ldo_vemc, ldo_vio28, ldo_va12, ldo_vrf18,
|
||||
ldo_vcn33, ldo_vcama2, ldo_vmc, ldo_vldo28, ldo_vaud28, ldo_vsim2
|
||||
|
||||
Example:
|
||||
|
||||
@@ -305,15 +304,8 @@ Example:
|
||||
regulator-enable-ramp-delay = <120>;
|
||||
};
|
||||
|
||||
mt6358_vcn33_bt_reg: ldo_vcn33_bt {
|
||||
regulator-name = "vcn33_bt";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3500000>;
|
||||
regulator-enable-ramp-delay = <270>;
|
||||
};
|
||||
|
||||
mt6358_vcn33_wifi_reg: ldo_vcn33_wifi {
|
||||
regulator-name = "vcn33_wifi";
|
||||
mt6358_vcn33_reg: ldo_vcn33 {
|
||||
regulator-name = "vcn33";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3500000>;
|
||||
regulator-enable-ramp-delay = <270>;
|
||||
@@ -354,17 +346,5 @@ Example:
|
||||
regulator-max-microvolt = <3100000>;
|
||||
regulator-enable-ramp-delay = <540>;
|
||||
};
|
||||
|
||||
mt6358_vcore_sshub_reg: buck_vcore_sshub {
|
||||
regulator-name = "vcore_sshub";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <1293750>;
|
||||
};
|
||||
|
||||
mt6358_vsram_others_sshub_reg: ldo_vsram_others_sshub {
|
||||
regulator-name = "vsram_others_sshub";
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <1293750>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@@ -36,6 +36,9 @@ properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
fsl,pfuze-support-disable-sw:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description: |
|
||||
|
@@ -64,6 +64,7 @@ properties:
|
||||
defined, <100> is assumed, meaning that
|
||||
pwm-dutycycle-range contains values expressed in
|
||||
percent.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
default: 100
|
||||
|
||||
pwm-dutycycle-range:
|
||||
|
@@ -0,0 +1,85 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/regulator/renesas,raa215300.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Renesas RAA215300 Power Management Integrated Circuit (PMIC)
|
||||
|
||||
maintainers:
|
||||
- Biju Das <biju.das.jz@bp.renesas.com>
|
||||
|
||||
description: |
|
||||
The RAA215300 is a high-performance, low-cost 9-channel PMIC designed for
|
||||
32-bit and 64-bit MCU and MPU applications. It supports DDR3, DDR3L, DDR4,
|
||||
and LPDDR4 memory power requirements. The internally compensated regulators,
|
||||
built-in Real-Time Clock (RTC), 32kHz crystal oscillator, and coin cell
|
||||
battery charger provide a highly integrated, small footprint power solution
|
||||
ideal for System-On-Module (SOM) applications. A spread spectrum feature
|
||||
provides an ease-of-use solution for noise-sensitive audio or RF applications.
|
||||
|
||||
This device exposes two devices via I2C. One for the integrated RTC IP, and
|
||||
one for everything else.
|
||||
|
||||
Link to datasheet:
|
||||
https://www.renesas.com/in/en/products/power-power-management/multi-channel-power-management-ics-pmics/ssdsoc-power-management-ics-pmic-and-pmus/raa215300-high-performance-9-channel-pmic-supporting-ddr-memory-built-charger-and-rtc
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- renesas,raa215300
|
||||
|
||||
reg:
|
||||
maxItems: 2
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: main
|
||||
- const: rtc
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
description: |
|
||||
The clocks are optional. The RTC is disabled, if no clocks are
|
||||
provided(either xin or clkin).
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
description: |
|
||||
Use xin, if connected to an external crystal.
|
||||
Use clkin, if connected to an external clock signal.
|
||||
enum:
|
||||
- xin
|
||||
- clkin
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
/* 32.768kHz crystal */
|
||||
x2: x2-clock {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <32768>;
|
||||
};
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
raa215300: pmic@12 {
|
||||
compatible = "renesas,raa215300";
|
||||
reg = <0x12>, <0x6f>;
|
||||
reg-names = "main", "rtc";
|
||||
|
||||
clocks = <&x2>;
|
||||
clock-names = "xin";
|
||||
};
|
||||
};
|
52
Documentation/devicetree/bindings/regulator/ti,tps62870.yaml
Normal file
52
Documentation/devicetree/bindings/regulator/ti,tps62870.yaml
Normal file
@@ -0,0 +1,52 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/regulator/ti,tps62870.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: TI TPS62870/TPS62871/TPS62872/TPS62873 voltage regulator
|
||||
|
||||
maintainers:
|
||||
- Mårten Lindahl <marten.lindahl@axis.com>
|
||||
|
||||
allOf:
|
||||
- $ref: regulator.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- ti,tps62870
|
||||
- ti,tps62871
|
||||
- ti,tps62872
|
||||
- ti,tps62873
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
regulator-initial-mode:
|
||||
enum: [ 1, 2 ]
|
||||
description: 1 - Forced PWM mode, 2 - Low power mode
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
regulator@41 {
|
||||
compatible = "ti,tps62873";
|
||||
reg = <0x41>;
|
||||
regulator-name = "+0.75V";
|
||||
regulator-min-microvolt = <400000>;
|
||||
regulator-max-microvolt = <1675000>;
|
||||
regulator-initial-mode = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
...
|
@@ -82,7 +82,7 @@ config COMMON_CLK_MAX9485
|
||||
|
||||
config COMMON_CLK_RK808
|
||||
tristate "Clock driver for RK805/RK808/RK809/RK817/RK818"
|
||||
depends on MFD_RK808
|
||||
depends on MFD_RK8XX
|
||||
help
|
||||
This driver supports RK805, RK809 and RK817, RK808 and RK818 crystal oscillator clock.
|
||||
These multi-function devices have two fixed-rate oscillators, clocked at 32KHz each.
|
||||
|
@@ -12,10 +12,9 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mfd/rk808.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
struct rk808_clkout {
|
||||
struct rk808 *rk808;
|
||||
struct regmap *regmap;
|
||||
struct clk_hw clkout1_hw;
|
||||
struct clk_hw clkout2_hw;
|
||||
};
|
||||
@@ -31,9 +30,8 @@ static int rk808_clkout2_enable(struct clk_hw *hw, bool enable)
|
||||
struct rk808_clkout *rk808_clkout = container_of(hw,
|
||||
struct rk808_clkout,
|
||||
clkout2_hw);
|
||||
struct rk808 *rk808 = rk808_clkout->rk808;
|
||||
|
||||
return regmap_update_bits(rk808->regmap, RK808_CLK32OUT_REG,
|
||||
return regmap_update_bits(rk808_clkout->regmap, RK808_CLK32OUT_REG,
|
||||
CLK32KOUT2_EN, enable ? CLK32KOUT2_EN : 0);
|
||||
}
|
||||
|
||||
@@ -52,10 +50,9 @@ static int rk808_clkout2_is_prepared(struct clk_hw *hw)
|
||||
struct rk808_clkout *rk808_clkout = container_of(hw,
|
||||
struct rk808_clkout,
|
||||
clkout2_hw);
|
||||
struct rk808 *rk808 = rk808_clkout->rk808;
|
||||
uint32_t val;
|
||||
|
||||
int ret = regmap_read(rk808->regmap, RK808_CLK32OUT_REG, &val);
|
||||
int ret = regmap_read(rk808_clkout->regmap, RK808_CLK32OUT_REG, &val);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@@ -93,9 +90,8 @@ static int rk817_clkout2_enable(struct clk_hw *hw, bool enable)
|
||||
struct rk808_clkout *rk808_clkout = container_of(hw,
|
||||
struct rk808_clkout,
|
||||
clkout2_hw);
|
||||
struct rk808 *rk808 = rk808_clkout->rk808;
|
||||
|
||||
return regmap_update_bits(rk808->regmap, RK817_SYS_CFG(1),
|
||||
return regmap_update_bits(rk808_clkout->regmap, RK817_SYS_CFG(1),
|
||||
RK817_CLK32KOUT2_EN,
|
||||
enable ? RK817_CLK32KOUT2_EN : 0);
|
||||
}
|
||||
@@ -115,10 +111,9 @@ static int rk817_clkout2_is_prepared(struct clk_hw *hw)
|
||||
struct rk808_clkout *rk808_clkout = container_of(hw,
|
||||
struct rk808_clkout,
|
||||
clkout2_hw);
|
||||
struct rk808 *rk808 = rk808_clkout->rk808;
|
||||
unsigned int val;
|
||||
|
||||
int ret = regmap_read(rk808->regmap, RK817_SYS_CFG(1), &val);
|
||||
int ret = regmap_read(rk808_clkout->regmap, RK817_SYS_CFG(1), &val);
|
||||
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
@@ -153,18 +148,21 @@ static const struct clk_ops *rkpmic_get_ops(long variant)
|
||||
static int rk808_clkout_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
|
||||
struct i2c_client *client = rk808->i2c;
|
||||
struct device_node *node = client->dev.of_node;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct clk_init_data init = {};
|
||||
struct rk808_clkout *rk808_clkout;
|
||||
int ret;
|
||||
|
||||
rk808_clkout = devm_kzalloc(&client->dev,
|
||||
dev->of_node = pdev->dev.parent->of_node;
|
||||
|
||||
rk808_clkout = devm_kzalloc(dev,
|
||||
sizeof(*rk808_clkout), GFP_KERNEL);
|
||||
if (!rk808_clkout)
|
||||
return -ENOMEM;
|
||||
|
||||
rk808_clkout->rk808 = rk808;
|
||||
rk808_clkout->regmap = dev_get_regmap(pdev->dev.parent, NULL);
|
||||
if (!rk808_clkout->regmap)
|
||||
return -ENODEV;
|
||||
|
||||
init.parent_names = NULL;
|
||||
init.num_parents = 0;
|
||||
@@ -173,10 +171,10 @@ static int rk808_clkout_probe(struct platform_device *pdev)
|
||||
rk808_clkout->clkout1_hw.init = &init;
|
||||
|
||||
/* optional override of the clockname */
|
||||
of_property_read_string_index(node, "clock-output-names",
|
||||
of_property_read_string_index(dev->of_node, "clock-output-names",
|
||||
0, &init.name);
|
||||
|
||||
ret = devm_clk_hw_register(&client->dev, &rk808_clkout->clkout1_hw);
|
||||
ret = devm_clk_hw_register(dev, &rk808_clkout->clkout1_hw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -185,10 +183,10 @@ static int rk808_clkout_probe(struct platform_device *pdev)
|
||||
rk808_clkout->clkout2_hw.init = &init;
|
||||
|
||||
/* optional override of the clockname */
|
||||
of_property_read_string_index(node, "clock-output-names",
|
||||
of_property_read_string_index(dev->of_node, "clock-output-names",
|
||||
1, &init.name);
|
||||
|
||||
ret = devm_clk_hw_register(&client->dev, &rk808_clkout->clkout2_hw);
|
||||
ret = devm_clk_hw_register(dev, &rk808_clkout->clkout2_hw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@@ -609,7 +609,7 @@ config INPUT_PWM_VIBRA
|
||||
|
||||
config INPUT_RK805_PWRKEY
|
||||
tristate "Rockchip RK805 PMIC power key support"
|
||||
depends on MFD_RK808
|
||||
depends on MFD_RK8XX
|
||||
help
|
||||
Select this option to enable power key driver for RK805.
|
||||
|
||||
|
@@ -1183,12 +1183,17 @@ config MFD_RC5T583
|
||||
Additional drivers must be enabled in order to use the
|
||||
different functionality of the device.
|
||||
|
||||
config MFD_RK808
|
||||
config MFD_RK8XX
|
||||
bool
|
||||
select MFD_CORE
|
||||
|
||||
config MFD_RK8XX_I2C
|
||||
tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power Management Chip"
|
||||
depends on I2C && OF
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
select REGMAP_IRQ
|
||||
select MFD_RK8XX
|
||||
help
|
||||
If you say yes here you get support for the RK805, RK808, RK809,
|
||||
RK817 and RK818 Power Management chips.
|
||||
@@ -1196,6 +1201,20 @@ config MFD_RK808
|
||||
through I2C interface. The device supports multiple sub-devices
|
||||
including interrupts, RTC, LDO & DCDC regulators, and onkey.
|
||||
|
||||
config MFD_RK8XX_SPI
|
||||
tristate "Rockchip RK806 Power Management Chip"
|
||||
depends on SPI && OF
|
||||
select MFD_CORE
|
||||
select REGMAP_SPI
|
||||
select REGMAP_IRQ
|
||||
select MFD_RK8XX
|
||||
help
|
||||
If you say yes here you get support for the RK806 Power Management
|
||||
chip.
|
||||
This driver provides common support for accessing the device
|
||||
through an SPI interface. The device supports multiple sub-devices
|
||||
including interrupts, LDO & DCDC regulators, and power on-key.
|
||||
|
||||
config MFD_RN5T618
|
||||
tristate "Ricoh RN5T567/618 PMIC"
|
||||
depends on I2C
|
||||
@@ -1679,6 +1698,38 @@ config MFD_TPS65912_SPI
|
||||
If you say yes here you get support for the TPS65912 series of
|
||||
PM chips with SPI interface.
|
||||
|
||||
config MFD_TPS6594
|
||||
tristate
|
||||
select MFD_CORE
|
||||
select REGMAP
|
||||
select REGMAP_IRQ
|
||||
|
||||
config MFD_TPS6594_I2C
|
||||
tristate "TI TPS6594 Power Management chip with I2C"
|
||||
select MFD_TPS6594
|
||||
select REGMAP_I2C
|
||||
select CRC8
|
||||
depends on I2C
|
||||
help
|
||||
If you say yes here you get support for the TPS6594 series of
|
||||
PM chips with I2C interface.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called tps6594-i2c.
|
||||
|
||||
config MFD_TPS6594_SPI
|
||||
tristate "TI TPS6594 Power Management chip with SPI"
|
||||
select MFD_TPS6594
|
||||
select REGMAP_SPI
|
||||
select CRC8
|
||||
depends on SPI_MASTER
|
||||
help
|
||||
If you say yes here you get support for the TPS6594 series of
|
||||
PM chips with SPI interface.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called tps6594-spi.
|
||||
|
||||
config TWL4030_CORE
|
||||
bool "TI TWL4030/TWL5030/TWL6030/TPS659x0 Support"
|
||||
depends on I2C=y
|
||||
|
@@ -96,6 +96,9 @@ obj-$(CONFIG_MFD_TPS65910) += tps65910.o
|
||||
obj-$(CONFIG_MFD_TPS65912) += tps65912-core.o
|
||||
obj-$(CONFIG_MFD_TPS65912_I2C) += tps65912-i2c.o
|
||||
obj-$(CONFIG_MFD_TPS65912_SPI) += tps65912-spi.o
|
||||
obj-$(CONFIG_MFD_TPS6594) += tps6594-core.o
|
||||
obj-$(CONFIG_MFD_TPS6594_I2C) += tps6594-i2c.o
|
||||
obj-$(CONFIG_MFD_TPS6594_SPI) += tps6594-spi.o
|
||||
obj-$(CONFIG_MENELAUS) += menelaus.o
|
||||
|
||||
obj-$(CONFIG_TWL4030_CORE) += twl-core.o twl4030-irq.o twl6030-irq.o
|
||||
@@ -214,7 +217,9 @@ obj-$(CONFIG_MFD_PALMAS) += palmas.o
|
||||
obj-$(CONFIG_MFD_VIPERBOARD) += viperboard.o
|
||||
obj-$(CONFIG_MFD_NTXEC) += ntxec.o
|
||||
obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o
|
||||
obj-$(CONFIG_MFD_RK808) += rk808.o
|
||||
obj-$(CONFIG_MFD_RK8XX) += rk8xx-core.o
|
||||
obj-$(CONFIG_MFD_RK8XX_I2C) += rk8xx-i2c.o
|
||||
obj-$(CONFIG_MFD_RK8XX_SPI) += rk8xx-spi.o
|
||||
obj-$(CONFIG_MFD_RN5T618) += rn5t618.o
|
||||
obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o sec-irq.o
|
||||
obj-$(CONFIG_MFD_SYSCON) += syscon.o
|
||||
|
@@ -63,6 +63,7 @@ static const struct of_device_id axp20x_i2c_of_match[] = {
|
||||
{ .compatible = "x-powers,axp209", .data = (void *)AXP209_ID },
|
||||
{ .compatible = "x-powers,axp221", .data = (void *)AXP221_ID },
|
||||
{ .compatible = "x-powers,axp223", .data = (void *)AXP223_ID },
|
||||
{ .compatible = "x-powers,axp313a", .data = (void *)AXP313A_ID },
|
||||
{ .compatible = "x-powers,axp803", .data = (void *)AXP803_ID },
|
||||
{ .compatible = "x-powers,axp806", .data = (void *)AXP806_ID },
|
||||
{ .compatible = "x-powers,axp15060", .data = (void *)AXP15060_ID },
|
||||
@@ -77,6 +78,7 @@ static const struct i2c_device_id axp20x_i2c_id[] = {
|
||||
{ "axp209", 0 },
|
||||
{ "axp221", 0 },
|
||||
{ "axp223", 0 },
|
||||
{ "axp313a", 0 },
|
||||
{ "axp803", 0 },
|
||||
{ "axp806", 0 },
|
||||
{ "axp15060", 0 },
|
||||
|
@@ -39,6 +39,7 @@ static const char * const axp20x_model_names[] = {
|
||||
"AXP221",
|
||||
"AXP223",
|
||||
"AXP288",
|
||||
"AXP313a",
|
||||
"AXP803",
|
||||
"AXP806",
|
||||
"AXP809",
|
||||
@@ -156,6 +157,25 @@ static const struct regmap_range axp806_writeable_ranges[] = {
|
||||
regmap_reg_range(AXP806_REG_ADDR_EXT, AXP806_REG_ADDR_EXT),
|
||||
};
|
||||
|
||||
static const struct regmap_range axp313a_writeable_ranges[] = {
|
||||
regmap_reg_range(AXP313A_ON_INDICATE, AXP313A_IRQ_STATE),
|
||||
};
|
||||
|
||||
static const struct regmap_range axp313a_volatile_ranges[] = {
|
||||
regmap_reg_range(AXP313A_SHUTDOWN_CTRL, AXP313A_SHUTDOWN_CTRL),
|
||||
regmap_reg_range(AXP313A_IRQ_STATE, AXP313A_IRQ_STATE),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table axp313a_writeable_table = {
|
||||
.yes_ranges = axp313a_writeable_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(axp313a_writeable_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table axp313a_volatile_table = {
|
||||
.yes_ranges = axp313a_volatile_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(axp313a_volatile_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_range axp806_volatile_ranges[] = {
|
||||
regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE),
|
||||
};
|
||||
@@ -248,6 +268,11 @@ static const struct resource axp288_fuel_gauge_resources[] = {
|
||||
DEFINE_RES_IRQ(AXP288_IRQ_WL1),
|
||||
};
|
||||
|
||||
static const struct resource axp313a_pek_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(AXP313A_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
|
||||
DEFINE_RES_IRQ_NAMED(AXP313A_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
|
||||
};
|
||||
|
||||
static const struct resource axp803_pek_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
|
||||
DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
|
||||
@@ -304,6 +329,15 @@ static const struct regmap_config axp288_regmap_config = {
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
static const struct regmap_config axp313a_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.wr_table = &axp313a_writeable_table,
|
||||
.volatile_table = &axp313a_volatile_table,
|
||||
.max_register = AXP313A_IRQ_STATE,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
static const struct regmap_config axp806_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
@@ -456,6 +490,16 @@ static const struct regmap_irq axp288_regmap_irqs[] = {
|
||||
INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG, 5, 1),
|
||||
};
|
||||
|
||||
static const struct regmap_irq axp313a_regmap_irqs[] = {
|
||||
INIT_REGMAP_IRQ(AXP313A, PEK_RIS_EDGE, 0, 7),
|
||||
INIT_REGMAP_IRQ(AXP313A, PEK_FAL_EDGE, 0, 6),
|
||||
INIT_REGMAP_IRQ(AXP313A, PEK_SHORT, 0, 5),
|
||||
INIT_REGMAP_IRQ(AXP313A, PEK_LONG, 0, 4),
|
||||
INIT_REGMAP_IRQ(AXP313A, DCDC3_V_LOW, 0, 3),
|
||||
INIT_REGMAP_IRQ(AXP313A, DCDC2_V_LOW, 0, 2),
|
||||
INIT_REGMAP_IRQ(AXP313A, DIE_TEMP_HIGH, 0, 0),
|
||||
};
|
||||
|
||||
static const struct regmap_irq axp803_regmap_irqs[] = {
|
||||
INIT_REGMAP_IRQ(AXP803, ACIN_OVER_V, 0, 7),
|
||||
INIT_REGMAP_IRQ(AXP803, ACIN_PLUGIN, 0, 6),
|
||||
@@ -606,6 +650,17 @@ static const struct regmap_irq_chip axp288_regmap_irq_chip = {
|
||||
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip axp313a_regmap_irq_chip = {
|
||||
.name = "axp313a_irq_chip",
|
||||
.status_base = AXP313A_IRQ_STATE,
|
||||
.ack_base = AXP313A_IRQ_STATE,
|
||||
.unmask_base = AXP313A_IRQ_EN,
|
||||
.init_ack_masked = true,
|
||||
.irqs = axp313a_regmap_irqs,
|
||||
.num_irqs = ARRAY_SIZE(axp313a_regmap_irqs),
|
||||
.num_regs = 1,
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip axp803_regmap_irq_chip = {
|
||||
.name = "axp803",
|
||||
.status_base = AXP20X_IRQ1_STATE,
|
||||
@@ -745,6 +800,11 @@ static const struct mfd_cell axp152_cells[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct mfd_cell axp313a_cells[] = {
|
||||
MFD_CELL_NAME("axp20x-regulator"),
|
||||
MFD_CELL_RES("axp313a-pek", axp313a_pek_resources),
|
||||
};
|
||||
|
||||
static const struct resource axp288_adc_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(AXP288_IRQ_GPADC, "GPADC"),
|
||||
};
|
||||
@@ -914,8 +974,18 @@ static const struct mfd_cell axp_regulator_only_cells[] = {
|
||||
static int axp20x_power_off(struct sys_off_data *data)
|
||||
{
|
||||
struct axp20x_dev *axp20x = data->cb_data;
|
||||
unsigned int shutdown_reg;
|
||||
|
||||
regmap_write(axp20x->regmap, AXP20X_OFF_CTRL, AXP20X_OFF);
|
||||
switch (axp20x->variant) {
|
||||
case AXP313A_ID:
|
||||
shutdown_reg = AXP313A_SHUTDOWN_CTRL;
|
||||
break;
|
||||
default:
|
||||
shutdown_reg = AXP20X_OFF_CTRL;
|
||||
break;
|
||||
}
|
||||
|
||||
regmap_write(axp20x->regmap, shutdown_reg, AXP20X_OFF);
|
||||
|
||||
/* Give capacitors etc. time to drain to avoid kernel panic msg. */
|
||||
mdelay(500);
|
||||
@@ -978,6 +1048,12 @@ int axp20x_match_device(struct axp20x_dev *axp20x)
|
||||
axp20x->regmap_irq_chip = &axp288_regmap_irq_chip;
|
||||
axp20x->irq_flags = IRQF_TRIGGER_LOW;
|
||||
break;
|
||||
case AXP313A_ID:
|
||||
axp20x->nr_cells = ARRAY_SIZE(axp313a_cells);
|
||||
axp20x->cells = axp313a_cells;
|
||||
axp20x->regmap_cfg = &axp313a_regmap_config;
|
||||
axp20x->regmap_irq_chip = &axp313a_regmap_irq_chip;
|
||||
break;
|
||||
case AXP803_ID:
|
||||
axp20x->nr_cells = ARRAY_SIZE(axp803_cells);
|
||||
axp20x->cells = axp803_cells;
|
||||
|
@@ -1,18 +1,15 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* MFD core driver for Rockchip RK808/RK818
|
||||
* MFD core driver for Rockchip RK8XX
|
||||
*
|
||||
* Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
|
||||
* Copyright (C) 2016 PHYTEC Messtechnik GmbH
|
||||
*
|
||||
* Author: Chris Zhong <zyw@rock-chips.com>
|
||||
* Author: Zhang Qing <zhangqing@rock-chips.com>
|
||||
*
|
||||
* Copyright (C) 2016 PHYTEC Messtechnik GmbH
|
||||
*
|
||||
* Author: Wadim Egorov <w.egorov@phytec.de>
|
||||
*/
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mfd/rk808.h>
|
||||
#include <linux/mfd/core.h>
|
||||
@@ -27,92 +24,6 @@ struct rk808_reg_data {
|
||||
int value;
|
||||
};
|
||||
|
||||
static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
/*
|
||||
* Notes:
|
||||
* - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
|
||||
* we don't use that feature. It's better to cache.
|
||||
* - It's unlikely we care that RK808_DEVCTRL_REG is volatile since
|
||||
* bits are cleared in case when we shutoff anyway, but better safe.
|
||||
*/
|
||||
|
||||
switch (reg) {
|
||||
case RK808_SECONDS_REG ... RK808_WEEKS_REG:
|
||||
case RK808_RTC_STATUS_REG:
|
||||
case RK808_VB_MON_REG:
|
||||
case RK808_THERMAL_REG:
|
||||
case RK808_DCDC_UV_STS_REG:
|
||||
case RK808_LDO_UV_STS_REG:
|
||||
case RK808_DCDC_PG_REG:
|
||||
case RK808_LDO_PG_REG:
|
||||
case RK808_DEVCTRL_REG:
|
||||
case RK808_INT_STS_REG1:
|
||||
case RK808_INT_STS_REG2:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool rk817_is_volatile_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
/*
|
||||
* Notes:
|
||||
* - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
|
||||
* we don't use that feature. It's better to cache.
|
||||
*/
|
||||
|
||||
switch (reg) {
|
||||
case RK817_SECONDS_REG ... RK817_WEEKS_REG:
|
||||
case RK817_RTC_STATUS_REG:
|
||||
case RK817_CODEC_DTOP_LPT_SRST:
|
||||
case RK817_GAS_GAUGE_ADC_CONFIG0 ... RK817_GAS_GAUGE_CUR_ADC_K0:
|
||||
case RK817_PMIC_CHRG_STS:
|
||||
case RK817_PMIC_CHRG_OUT:
|
||||
case RK817_PMIC_CHRG_IN:
|
||||
case RK817_INT_STS_REG0:
|
||||
case RK817_INT_STS_REG1:
|
||||
case RK817_INT_STS_REG2:
|
||||
case RK817_SYS_STS:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static const struct regmap_config rk818_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = RK818_USB_CTRL_REG,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.volatile_reg = rk808_is_volatile_reg,
|
||||
};
|
||||
|
||||
static const struct regmap_config rk805_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = RK805_OFF_SOURCE_REG,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.volatile_reg = rk808_is_volatile_reg,
|
||||
};
|
||||
|
||||
static const struct regmap_config rk808_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = RK808_IO_POL_REG,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.volatile_reg = rk808_is_volatile_reg,
|
||||
};
|
||||
|
||||
static const struct regmap_config rk817_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = RK817_GPIO_INT_CFG,
|
||||
.cache_type = REGCACHE_NONE,
|
||||
.volatile_reg = rk817_is_volatile_reg,
|
||||
};
|
||||
|
||||
static const struct resource rtc_resources[] = {
|
||||
DEFINE_RES_IRQ(RK808_IRQ_RTC_ALARM),
|
||||
};
|
||||
@@ -126,6 +37,11 @@ static const struct resource rk805_key_resources[] = {
|
||||
DEFINE_RES_IRQ(RK805_IRQ_PWRON_FALL),
|
||||
};
|
||||
|
||||
static struct resource rk806_pwrkey_resources[] = {
|
||||
DEFINE_RES_IRQ(RK806_IRQ_PWRON_FALL),
|
||||
DEFINE_RES_IRQ(RK806_IRQ_PWRON_RISE),
|
||||
};
|
||||
|
||||
static const struct resource rk817_pwrkey_resources[] = {
|
||||
DEFINE_RES_IRQ(RK817_IRQ_PWRON_RISE),
|
||||
DEFINE_RES_IRQ(RK817_IRQ_PWRON_FALL),
|
||||
@@ -153,6 +69,17 @@ static const struct mfd_cell rk805s[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct mfd_cell rk806s[] = {
|
||||
{ .name = "rk805-pinctrl", .id = PLATFORM_DEVID_AUTO, },
|
||||
{ .name = "rk808-regulator", .id = PLATFORM_DEVID_AUTO, },
|
||||
{
|
||||
.name = "rk805-pwrkey",
|
||||
.resources = rk806_pwrkey_resources,
|
||||
.num_resources = ARRAY_SIZE(rk806_pwrkey_resources),
|
||||
.id = PLATFORM_DEVID_AUTO,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct mfd_cell rk808s[] = {
|
||||
{ .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, },
|
||||
{ .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, },
|
||||
@@ -212,6 +139,12 @@ static const struct rk808_reg_data rk805_pre_init_reg[] = {
|
||||
{RK805_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP115C},
|
||||
};
|
||||
|
||||
static const struct rk808_reg_data rk806_pre_init_reg[] = {
|
||||
{ RK806_GPIO_INT_CONFIG, RK806_INT_POL_MSK, RK806_INT_POL_L },
|
||||
{ RK806_SYS_CFG3, RK806_SLAVE_RESTART_FUN_MSK, RK806_SLAVE_RESTART_FUN_EN },
|
||||
{ RK806_SYS_OPTION, RK806_SYS_ENB2_2M_MSK, RK806_SYS_ENB2_2M_EN },
|
||||
};
|
||||
|
||||
static const struct rk808_reg_data rk808_pre_init_reg[] = {
|
||||
{ RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_150MA },
|
||||
{ RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_200MA },
|
||||
@@ -362,6 +295,27 @@ static const struct regmap_irq rk805_irqs[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct regmap_irq rk806_irqs[] = {
|
||||
/* INT_STS0 IRQs */
|
||||
REGMAP_IRQ_REG(RK806_IRQ_PWRON_FALL, 0, RK806_INT_STS_PWRON_FALL),
|
||||
REGMAP_IRQ_REG(RK806_IRQ_PWRON_RISE, 0, RK806_INT_STS_PWRON_RISE),
|
||||
REGMAP_IRQ_REG(RK806_IRQ_PWRON, 0, RK806_INT_STS_PWRON),
|
||||
REGMAP_IRQ_REG(RK806_IRQ_PWRON_LP, 0, RK806_INT_STS_PWRON_LP),
|
||||
REGMAP_IRQ_REG(RK806_IRQ_HOTDIE, 0, RK806_INT_STS_HOTDIE),
|
||||
REGMAP_IRQ_REG(RK806_IRQ_VDC_RISE, 0, RK806_INT_STS_VDC_RISE),
|
||||
REGMAP_IRQ_REG(RK806_IRQ_VDC_FALL, 0, RK806_INT_STS_VDC_FALL),
|
||||
REGMAP_IRQ_REG(RK806_IRQ_VB_LO, 0, RK806_INT_STS_VB_LO),
|
||||
/* INT_STS1 IRQs */
|
||||
REGMAP_IRQ_REG(RK806_IRQ_REV0, 1, RK806_INT_STS_REV0),
|
||||
REGMAP_IRQ_REG(RK806_IRQ_REV1, 1, RK806_INT_STS_REV1),
|
||||
REGMAP_IRQ_REG(RK806_IRQ_REV2, 1, RK806_INT_STS_REV2),
|
||||
REGMAP_IRQ_REG(RK806_IRQ_CRC_ERROR, 1, RK806_INT_STS_CRC_ERROR),
|
||||
REGMAP_IRQ_REG(RK806_IRQ_SLP3_GPIO, 1, RK806_INT_STS_SLP3_GPIO),
|
||||
REGMAP_IRQ_REG(RK806_IRQ_SLP2_GPIO, 1, RK806_INT_STS_SLP2_GPIO),
|
||||
REGMAP_IRQ_REG(RK806_IRQ_SLP1_GPIO, 1, RK806_INT_STS_SLP1_GPIO),
|
||||
REGMAP_IRQ_REG(RK806_IRQ_WDT, 1, RK806_INT_STS_WDT),
|
||||
};
|
||||
|
||||
static const struct regmap_irq rk808_irqs[] = {
|
||||
/* INT_STS */
|
||||
[RK808_IRQ_VOUT_LO] = {
|
||||
@@ -512,6 +466,18 @@ static struct regmap_irq_chip rk805_irq_chip = {
|
||||
.init_ack_masked = true,
|
||||
};
|
||||
|
||||
static struct regmap_irq_chip rk806_irq_chip = {
|
||||
.name = "rk806",
|
||||
.irqs = rk806_irqs,
|
||||
.num_irqs = ARRAY_SIZE(rk806_irqs),
|
||||
.num_regs = 2,
|
||||
.irq_reg_stride = 2,
|
||||
.mask_base = RK806_INT_MSK0,
|
||||
.status_base = RK806_INT_STS0,
|
||||
.ack_base = RK806_INT_STS0,
|
||||
.init_ack_masked = true,
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip rk808_irq_chip = {
|
||||
.name = "rk808",
|
||||
.irqs = rk808_irqs,
|
||||
@@ -548,13 +514,11 @@ static const struct regmap_irq_chip rk818_irq_chip = {
|
||||
.init_ack_masked = true,
|
||||
};
|
||||
|
||||
static struct i2c_client *rk808_i2c_client;
|
||||
|
||||
static void rk808_pm_power_off(void)
|
||||
static int rk808_power_off(struct sys_off_data *data)
|
||||
{
|
||||
struct rk808 *rk808 = data->cb_data;
|
||||
int ret;
|
||||
unsigned int reg, bit;
|
||||
struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
|
||||
|
||||
switch (rk808->variant) {
|
||||
case RK805_ID:
|
||||
@@ -575,16 +539,18 @@ static void rk808_pm_power_off(void)
|
||||
bit = DEV_OFF;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
|
||||
if (ret)
|
||||
dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n");
|
||||
dev_err(rk808->dev, "Failed to shutdown device!\n");
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static int rk808_restart_notify(struct notifier_block *this, unsigned long mode, void *cmd)
|
||||
static int rk808_restart(struct sys_off_data *data)
|
||||
{
|
||||
struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
|
||||
struct rk808 *rk808 = data->cb_data;
|
||||
unsigned int reg, bit;
|
||||
int ret;
|
||||
|
||||
@@ -600,19 +566,14 @@ static int rk808_restart_notify(struct notifier_block *this, unsigned long mode,
|
||||
}
|
||||
ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
|
||||
if (ret)
|
||||
dev_err(&rk808_i2c_client->dev, "Failed to restart device!\n");
|
||||
dev_err(rk808->dev, "Failed to restart device!\n");
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static struct notifier_block rk808_restart_handler = {
|
||||
.notifier_call = rk808_restart_notify,
|
||||
.priority = 192,
|
||||
};
|
||||
|
||||
static void rk8xx_shutdown(struct i2c_client *client)
|
||||
void rk8xx_shutdown(struct device *dev)
|
||||
{
|
||||
struct rk808 *rk808 = i2c_get_clientdata(client);
|
||||
struct rk808 *rk808 = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
switch (rk808->variant) {
|
||||
@@ -633,75 +594,47 @@ static void rk8xx_shutdown(struct i2c_client *client)
|
||||
return;
|
||||
}
|
||||
if (ret)
|
||||
dev_warn(&client->dev,
|
||||
dev_warn(dev,
|
||||
"Cannot switch to power down function\n");
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rk8xx_shutdown);
|
||||
|
||||
static const struct of_device_id rk808_of_match[] = {
|
||||
{ .compatible = "rockchip,rk805" },
|
||||
{ .compatible = "rockchip,rk808" },
|
||||
{ .compatible = "rockchip,rk809" },
|
||||
{ .compatible = "rockchip,rk817" },
|
||||
{ .compatible = "rockchip,rk818" },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rk808_of_match);
|
||||
|
||||
static int rk808_probe(struct i2c_client *client)
|
||||
int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap *regmap)
|
||||
{
|
||||
struct device_node *np = client->dev.of_node;
|
||||
struct rk808 *rk808;
|
||||
const struct rk808_reg_data *pre_init_reg;
|
||||
const struct mfd_cell *cells;
|
||||
int dual_support = 0;
|
||||
int nr_pre_init_regs;
|
||||
int nr_cells;
|
||||
int msb, lsb;
|
||||
unsigned char pmic_id_msb, pmic_id_lsb;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
rk808 = devm_kzalloc(&client->dev, sizeof(*rk808), GFP_KERNEL);
|
||||
rk808 = devm_kzalloc(dev, sizeof(*rk808), GFP_KERNEL);
|
||||
if (!rk808)
|
||||
return -ENOMEM;
|
||||
|
||||
if (of_device_is_compatible(np, "rockchip,rk817") ||
|
||||
of_device_is_compatible(np, "rockchip,rk809")) {
|
||||
pmic_id_msb = RK817_ID_MSB;
|
||||
pmic_id_lsb = RK817_ID_LSB;
|
||||
} else {
|
||||
pmic_id_msb = RK808_ID_MSB;
|
||||
pmic_id_lsb = RK808_ID_LSB;
|
||||
}
|
||||
|
||||
/* Read chip variant */
|
||||
msb = i2c_smbus_read_byte_data(client, pmic_id_msb);
|
||||
if (msb < 0) {
|
||||
dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
|
||||
RK808_ID_MSB);
|
||||
return msb;
|
||||
}
|
||||
|
||||
lsb = i2c_smbus_read_byte_data(client, pmic_id_lsb);
|
||||
if (lsb < 0) {
|
||||
dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
|
||||
RK808_ID_LSB);
|
||||
return lsb;
|
||||
}
|
||||
|
||||
rk808->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
|
||||
dev_info(&client->dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
|
||||
rk808->dev = dev;
|
||||
rk808->variant = variant;
|
||||
rk808->regmap = regmap;
|
||||
dev_set_drvdata(dev, rk808);
|
||||
|
||||
switch (rk808->variant) {
|
||||
case RK805_ID:
|
||||
rk808->regmap_cfg = &rk805_regmap_config;
|
||||
rk808->regmap_irq_chip = &rk805_irq_chip;
|
||||
pre_init_reg = rk805_pre_init_reg;
|
||||
nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg);
|
||||
cells = rk805s;
|
||||
nr_cells = ARRAY_SIZE(rk805s);
|
||||
break;
|
||||
case RK806_ID:
|
||||
rk808->regmap_irq_chip = &rk806_irq_chip;
|
||||
pre_init_reg = rk806_pre_init_reg;
|
||||
nr_pre_init_regs = ARRAY_SIZE(rk806_pre_init_reg);
|
||||
cells = rk806s;
|
||||
nr_cells = ARRAY_SIZE(rk806s);
|
||||
dual_support = IRQF_SHARED;
|
||||
break;
|
||||
case RK808_ID:
|
||||
rk808->regmap_cfg = &rk808_regmap_config;
|
||||
rk808->regmap_irq_chip = &rk808_irq_chip;
|
||||
pre_init_reg = rk808_pre_init_reg;
|
||||
nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg);
|
||||
@@ -709,7 +642,6 @@ static int rk808_probe(struct i2c_client *client)
|
||||
nr_cells = ARRAY_SIZE(rk808s);
|
||||
break;
|
||||
case RK818_ID:
|
||||
rk808->regmap_cfg = &rk818_regmap_config;
|
||||
rk808->regmap_irq_chip = &rk818_irq_chip;
|
||||
pre_init_reg = rk818_pre_init_reg;
|
||||
nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg);
|
||||
@@ -718,7 +650,6 @@ static int rk808_probe(struct i2c_client *client)
|
||||
break;
|
||||
case RK809_ID:
|
||||
case RK817_ID:
|
||||
rk808->regmap_cfg = &rk817_regmap_config;
|
||||
rk808->regmap_irq_chip = &rk817_irq_chip;
|
||||
pre_init_reg = rk817_pre_init_reg;
|
||||
nr_pre_init_regs = ARRAY_SIZE(rk817_pre_init_reg);
|
||||
@@ -726,97 +657,64 @@ static int rk808_probe(struct i2c_client *client)
|
||||
nr_cells = ARRAY_SIZE(rk817s);
|
||||
break;
|
||||
default:
|
||||
dev_err(&client->dev, "Unsupported RK8XX ID %lu\n",
|
||||
rk808->variant);
|
||||
dev_err(dev, "Unsupported RK8XX ID %lu\n", rk808->variant);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rk808->i2c = client;
|
||||
i2c_set_clientdata(client, rk808);
|
||||
if (!irq)
|
||||
return dev_err_probe(dev, -EINVAL, "No interrupt support, no core IRQ\n");
|
||||
|
||||
rk808->regmap = devm_regmap_init_i2c(client, rk808->regmap_cfg);
|
||||
if (IS_ERR(rk808->regmap)) {
|
||||
dev_err(&client->dev, "regmap initialization failed\n");
|
||||
return PTR_ERR(rk808->regmap);
|
||||
}
|
||||
|
||||
if (!client->irq) {
|
||||
dev_err(&client->dev, "No interrupt support, no core IRQ\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = regmap_add_irq_chip(rk808->regmap, client->irq,
|
||||
IRQF_ONESHOT, -1,
|
||||
rk808->regmap_irq_chip, &rk808->irq_data);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "Failed to add irq_chip %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = devm_regmap_add_irq_chip(dev, rk808->regmap, irq,
|
||||
IRQF_ONESHOT | dual_support, -1,
|
||||
rk808->regmap_irq_chip, &rk808->irq_data);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to add irq_chip\n");
|
||||
|
||||
for (i = 0; i < nr_pre_init_regs; i++) {
|
||||
ret = regmap_update_bits(rk808->regmap,
|
||||
pre_init_reg[i].addr,
|
||||
pre_init_reg[i].mask,
|
||||
pre_init_reg[i].value);
|
||||
if (ret) {
|
||||
dev_err(&client->dev,
|
||||
"0x%x write err\n",
|
||||
pre_init_reg[i].addr);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "0x%x write err\n",
|
||||
pre_init_reg[i].addr);
|
||||
}
|
||||
|
||||
ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
|
||||
cells, nr_cells, NULL, 0,
|
||||
ret = devm_mfd_add_devices(dev, 0, cells, nr_cells, NULL, 0,
|
||||
regmap_irq_get_domain(rk808->irq_data));
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to add MFD devices %d\n", ret);
|
||||
goto err_irq;
|
||||
}
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to add MFD devices\n");
|
||||
|
||||
if (of_property_read_bool(np, "rockchip,system-power-controller")) {
|
||||
rk808_i2c_client = client;
|
||||
pm_power_off = rk808_pm_power_off;
|
||||
if (device_property_read_bool(dev, "rockchip,system-power-controller")) {
|
||||
ret = devm_register_sys_off_handler(dev,
|
||||
SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_PRIO_HIGH,
|
||||
&rk808_power_off, rk808);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"failed to register poweroff handler\n");
|
||||
|
||||
switch (rk808->variant) {
|
||||
case RK809_ID:
|
||||
case RK817_ID:
|
||||
ret = register_restart_handler(&rk808_restart_handler);
|
||||
ret = devm_register_sys_off_handler(dev,
|
||||
SYS_OFF_MODE_RESTART, SYS_OFF_PRIO_HIGH,
|
||||
&rk808_restart, rk808);
|
||||
if (ret)
|
||||
dev_warn(&client->dev, "failed to register rst handler, %d\n", ret);
|
||||
dev_warn(dev, "failed to register rst handler, %d\n", ret);
|
||||
break;
|
||||
default:
|
||||
dev_dbg(&client->dev, "pmic controlled board reset not supported\n");
|
||||
dev_dbg(dev, "pmic controlled board reset not supported\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_irq:
|
||||
regmap_del_irq_chip(client->irq, rk808->irq_data);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rk8xx_probe);
|
||||
|
||||
static void rk808_remove(struct i2c_client *client)
|
||||
int rk8xx_suspend(struct device *dev)
|
||||
{
|
||||
struct rk808 *rk808 = i2c_get_clientdata(client);
|
||||
|
||||
regmap_del_irq_chip(client->irq, rk808->irq_data);
|
||||
|
||||
/**
|
||||
* pm_power_off may points to a function from another module.
|
||||
* Check if the pointer is set by us and only then overwrite it.
|
||||
*/
|
||||
if (pm_power_off == rk808_pm_power_off)
|
||||
pm_power_off = NULL;
|
||||
|
||||
unregister_restart_handler(&rk808_restart_handler);
|
||||
}
|
||||
|
||||
static int __maybe_unused rk8xx_suspend(struct device *dev)
|
||||
{
|
||||
struct rk808 *rk808 = i2c_get_clientdata(to_i2c_client(dev));
|
||||
struct rk808 *rk808 = dev_get_drvdata(dev);
|
||||
int ret = 0;
|
||||
|
||||
switch (rk808->variant) {
|
||||
@@ -839,10 +737,11 @@ static int __maybe_unused rk8xx_suspend(struct device *dev)
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rk8xx_suspend);
|
||||
|
||||
static int __maybe_unused rk8xx_resume(struct device *dev)
|
||||
int rk8xx_resume(struct device *dev)
|
||||
{
|
||||
struct rk808 *rk808 = i2c_get_clientdata(to_i2c_client(dev));
|
||||
struct rk808 *rk808 = dev_get_drvdata(dev);
|
||||
int ret = 0;
|
||||
|
||||
switch (rk808->variant) {
|
||||
@@ -859,23 +758,10 @@ static int __maybe_unused rk8xx_resume(struct device *dev)
|
||||
|
||||
return ret;
|
||||
}
|
||||
static SIMPLE_DEV_PM_OPS(rk8xx_pm_ops, rk8xx_suspend, rk8xx_resume);
|
||||
|
||||
static struct i2c_driver rk808_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "rk808",
|
||||
.of_match_table = rk808_of_match,
|
||||
.pm = &rk8xx_pm_ops,
|
||||
},
|
||||
.probe_new = rk808_probe,
|
||||
.remove = rk808_remove,
|
||||
.shutdown = rk8xx_shutdown,
|
||||
};
|
||||
|
||||
module_i2c_driver(rk808_i2c_driver);
|
||||
EXPORT_SYMBOL_GPL(rk8xx_resume);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
|
||||
MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
|
||||
MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
|
||||
MODULE_DESCRIPTION("RK808/RK818 PMIC driver");
|
||||
MODULE_DESCRIPTION("RK8xx PMIC core");
|
185
drivers/mfd/rk8xx-i2c.c
Normal file
185
drivers/mfd/rk8xx-i2c.c
Normal file
@@ -0,0 +1,185 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Rockchip RK808/RK818 Core (I2C) driver
|
||||
*
|
||||
* Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
|
||||
* Copyright (C) 2016 PHYTEC Messtechnik GmbH
|
||||
*
|
||||
* Author: Chris Zhong <zyw@rock-chips.com>
|
||||
* Author: Zhang Qing <zhangqing@rock-chips.com>
|
||||
* Author: Wadim Egorov <w.egorov@phytec.de>
|
||||
*/
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/mfd/rk808.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
struct rk8xx_i2c_platform_data {
|
||||
const struct regmap_config *regmap_cfg;
|
||||
int variant;
|
||||
};
|
||||
|
||||
static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
/*
|
||||
* Notes:
|
||||
* - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
|
||||
* we don't use that feature. It's better to cache.
|
||||
* - It's unlikely we care that RK808_DEVCTRL_REG is volatile since
|
||||
* bits are cleared in case when we shutoff anyway, but better safe.
|
||||
*/
|
||||
|
||||
switch (reg) {
|
||||
case RK808_SECONDS_REG ... RK808_WEEKS_REG:
|
||||
case RK808_RTC_STATUS_REG:
|
||||
case RK808_VB_MON_REG:
|
||||
case RK808_THERMAL_REG:
|
||||
case RK808_DCDC_UV_STS_REG:
|
||||
case RK808_LDO_UV_STS_REG:
|
||||
case RK808_DCDC_PG_REG:
|
||||
case RK808_LDO_PG_REG:
|
||||
case RK808_DEVCTRL_REG:
|
||||
case RK808_INT_STS_REG1:
|
||||
case RK808_INT_STS_REG2:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool rk817_is_volatile_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
/*
|
||||
* Notes:
|
||||
* - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but
|
||||
* we don't use that feature. It's better to cache.
|
||||
*/
|
||||
|
||||
switch (reg) {
|
||||
case RK817_SECONDS_REG ... RK817_WEEKS_REG:
|
||||
case RK817_RTC_STATUS_REG:
|
||||
case RK817_CODEC_DTOP_LPT_SRST:
|
||||
case RK817_GAS_GAUGE_ADC_CONFIG0 ... RK817_GAS_GAUGE_CUR_ADC_K0:
|
||||
case RK817_PMIC_CHRG_STS:
|
||||
case RK817_PMIC_CHRG_OUT:
|
||||
case RK817_PMIC_CHRG_IN:
|
||||
case RK817_INT_STS_REG0:
|
||||
case RK817_INT_STS_REG1:
|
||||
case RK817_INT_STS_REG2:
|
||||
case RK817_SYS_STS:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static const struct regmap_config rk818_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = RK818_USB_CTRL_REG,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.volatile_reg = rk808_is_volatile_reg,
|
||||
};
|
||||
|
||||
static const struct regmap_config rk805_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = RK805_OFF_SOURCE_REG,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.volatile_reg = rk808_is_volatile_reg,
|
||||
};
|
||||
|
||||
static const struct regmap_config rk808_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = RK808_IO_POL_REG,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.volatile_reg = rk808_is_volatile_reg,
|
||||
};
|
||||
|
||||
static const struct regmap_config rk817_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = RK817_GPIO_INT_CFG,
|
||||
.cache_type = REGCACHE_NONE,
|
||||
.volatile_reg = rk817_is_volatile_reg,
|
||||
};
|
||||
|
||||
static const struct rk8xx_i2c_platform_data rk805_data = {
|
||||
.regmap_cfg = &rk805_regmap_config,
|
||||
.variant = RK805_ID,
|
||||
};
|
||||
|
||||
static const struct rk8xx_i2c_platform_data rk808_data = {
|
||||
.regmap_cfg = &rk808_regmap_config,
|
||||
.variant = RK808_ID,
|
||||
};
|
||||
|
||||
static const struct rk8xx_i2c_platform_data rk809_data = {
|
||||
.regmap_cfg = &rk817_regmap_config,
|
||||
.variant = RK809_ID,
|
||||
};
|
||||
|
||||
static const struct rk8xx_i2c_platform_data rk817_data = {
|
||||
.regmap_cfg = &rk817_regmap_config,
|
||||
.variant = RK817_ID,
|
||||
};
|
||||
|
||||
static const struct rk8xx_i2c_platform_data rk818_data = {
|
||||
.regmap_cfg = &rk818_regmap_config,
|
||||
.variant = RK818_ID,
|
||||
};
|
||||
|
||||
static int rk8xx_i2c_probe(struct i2c_client *client)
|
||||
{
|
||||
const struct rk8xx_i2c_platform_data *data;
|
||||
struct regmap *regmap;
|
||||
|
||||
data = device_get_match_data(&client->dev);
|
||||
if (!data)
|
||||
return -ENODEV;
|
||||
|
||||
regmap = devm_regmap_init_i2c(client, data->regmap_cfg);
|
||||
if (IS_ERR(regmap))
|
||||
return dev_err_probe(&client->dev, PTR_ERR(regmap),
|
||||
"regmap initialization failed\n");
|
||||
|
||||
return rk8xx_probe(&client->dev, data->variant, client->irq, regmap);
|
||||
}
|
||||
|
||||
static void rk8xx_i2c_shutdown(struct i2c_client *client)
|
||||
{
|
||||
rk8xx_shutdown(&client->dev);
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(rk8xx_i2c_pm_ops, rk8xx_suspend, rk8xx_resume);
|
||||
|
||||
static const struct of_device_id rk8xx_i2c_of_match[] = {
|
||||
{ .compatible = "rockchip,rk805", .data = &rk805_data },
|
||||
{ .compatible = "rockchip,rk808", .data = &rk808_data },
|
||||
{ .compatible = "rockchip,rk809", .data = &rk809_data },
|
||||
{ .compatible = "rockchip,rk817", .data = &rk817_data },
|
||||
{ .compatible = "rockchip,rk818", .data = &rk818_data },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rk8xx_i2c_of_match);
|
||||
|
||||
static struct i2c_driver rk8xx_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "rk8xx-i2c",
|
||||
.of_match_table = rk8xx_i2c_of_match,
|
||||
.pm = &rk8xx_i2c_pm_ops,
|
||||
},
|
||||
.probe_new = rk8xx_i2c_probe,
|
||||
.shutdown = rk8xx_i2c_shutdown,
|
||||
};
|
||||
module_i2c_driver(rk8xx_i2c_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
|
||||
MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
|
||||
MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
|
||||
MODULE_DESCRIPTION("RK8xx I2C PMIC driver");
|
124
drivers/mfd/rk8xx-spi.c
Normal file
124
drivers/mfd/rk8xx-spi.c
Normal file
@@ -0,0 +1,124 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Rockchip RK806 Core (SPI) driver
|
||||
*
|
||||
* Copyright (c) 2021 Rockchip Electronics Co., Ltd.
|
||||
* Copyright (c) 2023 Collabora Ltd.
|
||||
*
|
||||
* Author: Xu Shengfei <xsf@rock-chips.com>
|
||||
* Author: Sebastian Reichel <sebastian.reichel@collabora.com>
|
||||
*/
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/rk808.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
#define RK806_ADDR_SIZE 2
|
||||
#define RK806_CMD_WITH_SIZE(CMD, VALUE_BYTES) \
|
||||
(RK806_CMD_##CMD | RK806_CMD_CRC_DIS | (VALUE_BYTES - 1))
|
||||
|
||||
static const struct regmap_range rk806_volatile_ranges[] = {
|
||||
regmap_reg_range(RK806_POWER_EN0, RK806_POWER_EN5),
|
||||
regmap_reg_range(RK806_DVS_START_CTRL, RK806_INT_MSK1),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table rk806_volatile_table = {
|
||||
.yes_ranges = rk806_volatile_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(rk806_volatile_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_config rk806_regmap_config_spi = {
|
||||
.reg_bits = 16,
|
||||
.val_bits = 8,
|
||||
.max_register = RK806_BUCK_RSERVE_REG5,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.volatile_table = &rk806_volatile_table,
|
||||
};
|
||||
|
||||
static int rk806_spi_bus_write(void *context, const void *vdata, size_t count)
|
||||
{
|
||||
struct device *dev = context;
|
||||
struct spi_device *spi = to_spi_device(dev);
|
||||
struct spi_transfer xfer[2] = { 0 };
|
||||
/* data and thus count includes the register address */
|
||||
size_t val_size = count - RK806_ADDR_SIZE;
|
||||
char cmd;
|
||||
|
||||
if (val_size < 1 || val_size > (RK806_CMD_LEN_MSK + 1))
|
||||
return -EINVAL;
|
||||
|
||||
cmd = RK806_CMD_WITH_SIZE(WRITE, val_size);
|
||||
|
||||
xfer[0].tx_buf = &cmd;
|
||||
xfer[0].len = sizeof(cmd);
|
||||
xfer[1].tx_buf = vdata;
|
||||
xfer[1].len = count;
|
||||
|
||||
return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
|
||||
}
|
||||
|
||||
static int rk806_spi_bus_read(void *context, const void *vreg, size_t reg_size,
|
||||
void *val, size_t val_size)
|
||||
{
|
||||
struct device *dev = context;
|
||||
struct spi_device *spi = to_spi_device(dev);
|
||||
char txbuf[3] = { 0 };
|
||||
|
||||
if (reg_size != RK806_ADDR_SIZE ||
|
||||
val_size < 1 || val_size > (RK806_CMD_LEN_MSK + 1))
|
||||
return -EINVAL;
|
||||
|
||||
/* TX buffer contains command byte followed by two address bytes */
|
||||
txbuf[0] = RK806_CMD_WITH_SIZE(READ, val_size);
|
||||
memcpy(txbuf+1, vreg, reg_size);
|
||||
|
||||
return spi_write_then_read(spi, txbuf, sizeof(txbuf), val, val_size);
|
||||
}
|
||||
|
||||
static const struct regmap_bus rk806_regmap_bus_spi = {
|
||||
.write = rk806_spi_bus_write,
|
||||
.read = rk806_spi_bus_read,
|
||||
.reg_format_endian_default = REGMAP_ENDIAN_LITTLE,
|
||||
};
|
||||
|
||||
static int rk8xx_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
struct regmap *regmap;
|
||||
|
||||
regmap = devm_regmap_init(&spi->dev, &rk806_regmap_bus_spi,
|
||||
&spi->dev, &rk806_regmap_config_spi);
|
||||
if (IS_ERR(regmap))
|
||||
return dev_err_probe(&spi->dev, PTR_ERR(regmap),
|
||||
"Failed to init regmap\n");
|
||||
|
||||
return rk8xx_probe(&spi->dev, RK806_ID, spi->irq, regmap);
|
||||
}
|
||||
|
||||
static const struct of_device_id rk8xx_spi_of_match[] = {
|
||||
{ .compatible = "rockchip,rk806", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rk8xx_spi_of_match);
|
||||
|
||||
static const struct spi_device_id rk8xx_spi_id_table[] = {
|
||||
{ "rk806", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, rk8xx_spi_id_table);
|
||||
|
||||
static struct spi_driver rk8xx_spi_driver = {
|
||||
.driver = {
|
||||
.name = "rk8xx-spi",
|
||||
.of_match_table = rk8xx_spi_of_match,
|
||||
},
|
||||
.probe = rk8xx_spi_probe,
|
||||
.id_table = rk8xx_spi_id_table,
|
||||
};
|
||||
module_spi_driver(rk8xx_spi_driver);
|
||||
|
||||
MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");
|
||||
MODULE_DESCRIPTION("RK8xx SPI PMIC driver");
|
||||
MODULE_LICENSE("GPL");
|
462
drivers/mfd/tps6594-core.c
Normal file
462
drivers/mfd/tps6594-core.c
Normal file
@@ -0,0 +1,462 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Core functions for TI TPS6594/TPS6593/LP8764 PMICs
|
||||
*
|
||||
* Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
|
||||
*/
|
||||
|
||||
#include <linux/completion.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/tps6594.h>
|
||||
|
||||
#define TPS6594_CRC_SYNC_TIMEOUT_MS 150
|
||||
|
||||
/* Completion to synchronize CRC feature enabling on all PMICs */
|
||||
static DECLARE_COMPLETION(tps6594_crc_comp);
|
||||
|
||||
static const struct resource tps6594_regulator_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK1_OV, TPS6594_IRQ_NAME_BUCK1_OV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK1_UV, TPS6594_IRQ_NAME_BUCK1_UV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK1_SC, TPS6594_IRQ_NAME_BUCK1_SC),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK1_ILIM, TPS6594_IRQ_NAME_BUCK1_ILIM),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK2_OV, TPS6594_IRQ_NAME_BUCK2_OV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK2_UV, TPS6594_IRQ_NAME_BUCK2_UV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK2_SC, TPS6594_IRQ_NAME_BUCK2_SC),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK2_ILIM, TPS6594_IRQ_NAME_BUCK2_ILIM),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK3_OV, TPS6594_IRQ_NAME_BUCK3_OV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK3_UV, TPS6594_IRQ_NAME_BUCK3_UV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK3_SC, TPS6594_IRQ_NAME_BUCK3_SC),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK3_ILIM, TPS6594_IRQ_NAME_BUCK3_ILIM),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK4_OV, TPS6594_IRQ_NAME_BUCK4_OV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK4_UV, TPS6594_IRQ_NAME_BUCK4_UV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK4_SC, TPS6594_IRQ_NAME_BUCK4_SC),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK4_ILIM, TPS6594_IRQ_NAME_BUCK4_ILIM),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK5_OV, TPS6594_IRQ_NAME_BUCK5_OV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK5_UV, TPS6594_IRQ_NAME_BUCK5_UV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK5_SC, TPS6594_IRQ_NAME_BUCK5_SC),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BUCK5_ILIM, TPS6594_IRQ_NAME_BUCK5_ILIM),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO1_OV, TPS6594_IRQ_NAME_LDO1_OV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO1_UV, TPS6594_IRQ_NAME_LDO1_UV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO1_SC, TPS6594_IRQ_NAME_LDO1_SC),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO1_ILIM, TPS6594_IRQ_NAME_LDO1_ILIM),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO2_OV, TPS6594_IRQ_NAME_LDO2_OV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO2_UV, TPS6594_IRQ_NAME_LDO2_UV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO2_SC, TPS6594_IRQ_NAME_LDO2_SC),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO2_ILIM, TPS6594_IRQ_NAME_LDO2_ILIM),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO3_OV, TPS6594_IRQ_NAME_LDO3_OV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO3_UV, TPS6594_IRQ_NAME_LDO3_UV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO3_SC, TPS6594_IRQ_NAME_LDO3_SC),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO3_ILIM, TPS6594_IRQ_NAME_LDO3_ILIM),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO4_OV, TPS6594_IRQ_NAME_LDO4_OV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO4_UV, TPS6594_IRQ_NAME_LDO4_UV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO4_SC, TPS6594_IRQ_NAME_LDO4_SC),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_LDO4_ILIM, TPS6594_IRQ_NAME_LDO4_ILIM),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_VCCA_OV, TPS6594_IRQ_NAME_VCCA_OV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_VCCA_UV, TPS6594_IRQ_NAME_VCCA_UV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_VMON1_OV, TPS6594_IRQ_NAME_VMON1_OV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_VMON1_UV, TPS6594_IRQ_NAME_VMON1_UV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_VMON1_RV, TPS6594_IRQ_NAME_VMON1_RV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_VMON2_OV, TPS6594_IRQ_NAME_VMON2_OV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_VMON2_UV, TPS6594_IRQ_NAME_VMON2_UV),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_VMON2_RV, TPS6594_IRQ_NAME_VMON2_RV),
|
||||
};
|
||||
|
||||
static const struct resource tps6594_pinctrl_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_GPIO9, TPS6594_IRQ_NAME_GPIO9),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_GPIO10, TPS6594_IRQ_NAME_GPIO10),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_GPIO11, TPS6594_IRQ_NAME_GPIO11),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_GPIO1, TPS6594_IRQ_NAME_GPIO1),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_GPIO2, TPS6594_IRQ_NAME_GPIO2),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_GPIO3, TPS6594_IRQ_NAME_GPIO3),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_GPIO4, TPS6594_IRQ_NAME_GPIO4),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_GPIO5, TPS6594_IRQ_NAME_GPIO5),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_GPIO6, TPS6594_IRQ_NAME_GPIO6),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_GPIO7, TPS6594_IRQ_NAME_GPIO7),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_GPIO8, TPS6594_IRQ_NAME_GPIO8),
|
||||
};
|
||||
|
||||
static const struct resource tps6594_pfsm_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_NPWRON_START, TPS6594_IRQ_NAME_NPWRON_START),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_ENABLE, TPS6594_IRQ_NAME_ENABLE),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_FSD, TPS6594_IRQ_NAME_FSD),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_SOFT_REBOOT, TPS6594_IRQ_NAME_SOFT_REBOOT),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BIST_PASS, TPS6594_IRQ_NAME_BIST_PASS),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_EXT_CLK, TPS6594_IRQ_NAME_EXT_CLK),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_TWARN, TPS6594_IRQ_NAME_TWARN),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_TSD_ORD, TPS6594_IRQ_NAME_TSD_ORD),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_BIST_FAIL, TPS6594_IRQ_NAME_BIST_FAIL),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_REG_CRC_ERR, TPS6594_IRQ_NAME_REG_CRC_ERR),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_RECOV_CNT, TPS6594_IRQ_NAME_RECOV_CNT),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_SPMI_ERR, TPS6594_IRQ_NAME_SPMI_ERR),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_NPWRON_LONG, TPS6594_IRQ_NAME_NPWRON_LONG),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_NINT_READBACK, TPS6594_IRQ_NAME_NINT_READBACK),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_NRSTOUT_READBACK, TPS6594_IRQ_NAME_NRSTOUT_READBACK),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_TSD_IMM, TPS6594_IRQ_NAME_TSD_IMM),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_VCCA_OVP, TPS6594_IRQ_NAME_VCCA_OVP),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_PFSM_ERR, TPS6594_IRQ_NAME_PFSM_ERR),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_IMM_SHUTDOWN, TPS6594_IRQ_NAME_IMM_SHUTDOWN),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_ORD_SHUTDOWN, TPS6594_IRQ_NAME_ORD_SHUTDOWN),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_MCU_PWR_ERR, TPS6594_IRQ_NAME_MCU_PWR_ERR),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_SOC_PWR_ERR, TPS6594_IRQ_NAME_SOC_PWR_ERR),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_COMM_FRM_ERR, TPS6594_IRQ_NAME_COMM_FRM_ERR),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_COMM_CRC_ERR, TPS6594_IRQ_NAME_COMM_CRC_ERR),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_COMM_ADR_ERR, TPS6594_IRQ_NAME_COMM_ADR_ERR),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_EN_DRV_READBACK, TPS6594_IRQ_NAME_EN_DRV_READBACK),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_NRSTOUT_SOC_READBACK,
|
||||
TPS6594_IRQ_NAME_NRSTOUT_SOC_READBACK),
|
||||
};
|
||||
|
||||
static const struct resource tps6594_esm_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_ESM_SOC_PIN, TPS6594_IRQ_NAME_ESM_SOC_PIN),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_ESM_SOC_FAIL, TPS6594_IRQ_NAME_ESM_SOC_FAIL),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_ESM_SOC_RST, TPS6594_IRQ_NAME_ESM_SOC_RST),
|
||||
};
|
||||
|
||||
static const struct resource tps6594_rtc_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_TIMER, TPS6594_IRQ_NAME_TIMER),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_ALARM, TPS6594_IRQ_NAME_ALARM),
|
||||
DEFINE_RES_IRQ_NAMED(TPS6594_IRQ_POWER_UP, TPS6594_IRQ_NAME_POWERUP),
|
||||
};
|
||||
|
||||
static const struct mfd_cell tps6594_common_cells[] = {
|
||||
MFD_CELL_RES("tps6594-regulator", tps6594_regulator_resources),
|
||||
MFD_CELL_RES("tps6594-pinctrl", tps6594_pinctrl_resources),
|
||||
MFD_CELL_RES("tps6594-pfsm", tps6594_pfsm_resources),
|
||||
MFD_CELL_RES("tps6594-esm", tps6594_esm_resources),
|
||||
};
|
||||
|
||||
static const struct mfd_cell tps6594_rtc_cells[] = {
|
||||
MFD_CELL_RES("tps6594-rtc", tps6594_rtc_resources),
|
||||
};
|
||||
|
||||
static const struct regmap_irq tps6594_irqs[] = {
|
||||
/* INT_BUCK1_2 register */
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_BUCK1_OV, 0, TPS6594_BIT_BUCKX_OV_INT(0)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_BUCK1_UV, 0, TPS6594_BIT_BUCKX_UV_INT(0)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_BUCK1_SC, 0, TPS6594_BIT_BUCKX_SC_INT(0)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_BUCK1_ILIM, 0, TPS6594_BIT_BUCKX_ILIM_INT(0)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_BUCK2_OV, 0, TPS6594_BIT_BUCKX_OV_INT(1)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_BUCK2_UV, 0, TPS6594_BIT_BUCKX_UV_INT(1)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_BUCK2_SC, 0, TPS6594_BIT_BUCKX_SC_INT(1)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_BUCK2_ILIM, 0, TPS6594_BIT_BUCKX_ILIM_INT(1)),
|
||||
|
||||
/* INT_BUCK3_4 register */
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_BUCK3_OV, 1, TPS6594_BIT_BUCKX_OV_INT(2)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_BUCK3_UV, 1, TPS6594_BIT_BUCKX_UV_INT(2)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_BUCK3_SC, 1, TPS6594_BIT_BUCKX_SC_INT(2)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_BUCK3_ILIM, 1, TPS6594_BIT_BUCKX_ILIM_INT(2)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_BUCK4_OV, 1, TPS6594_BIT_BUCKX_OV_INT(3)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_BUCK4_UV, 1, TPS6594_BIT_BUCKX_UV_INT(3)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_BUCK4_SC, 1, TPS6594_BIT_BUCKX_SC_INT(3)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_BUCK4_ILIM, 1, TPS6594_BIT_BUCKX_ILIM_INT(3)),
|
||||
|
||||
/* INT_BUCK5 register */
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_BUCK5_OV, 2, TPS6594_BIT_BUCKX_OV_INT(4)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_BUCK5_UV, 2, TPS6594_BIT_BUCKX_UV_INT(4)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_BUCK5_SC, 2, TPS6594_BIT_BUCKX_SC_INT(4)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_BUCK5_ILIM, 2, TPS6594_BIT_BUCKX_ILIM_INT(4)),
|
||||
|
||||
/* INT_LDO1_2 register */
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_LDO1_OV, 3, TPS6594_BIT_LDOX_OV_INT(0)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_LDO1_UV, 3, TPS6594_BIT_LDOX_UV_INT(0)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_LDO1_SC, 3, TPS6594_BIT_LDOX_SC_INT(0)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_LDO1_ILIM, 3, TPS6594_BIT_LDOX_ILIM_INT(0)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_LDO2_OV, 3, TPS6594_BIT_LDOX_OV_INT(1)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_LDO2_UV, 3, TPS6594_BIT_LDOX_UV_INT(1)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_LDO2_SC, 3, TPS6594_BIT_LDOX_SC_INT(1)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_LDO2_ILIM, 3, TPS6594_BIT_LDOX_ILIM_INT(1)),
|
||||
|
||||
/* INT_LDO3_4 register */
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_LDO3_OV, 4, TPS6594_BIT_LDOX_OV_INT(2)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_LDO3_UV, 4, TPS6594_BIT_LDOX_UV_INT(2)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_LDO3_SC, 4, TPS6594_BIT_LDOX_SC_INT(2)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_LDO3_ILIM, 4, TPS6594_BIT_LDOX_ILIM_INT(2)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_LDO4_OV, 4, TPS6594_BIT_LDOX_OV_INT(3)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_LDO4_UV, 4, TPS6594_BIT_LDOX_UV_INT(3)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_LDO4_SC, 4, TPS6594_BIT_LDOX_SC_INT(3)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_LDO4_ILIM, 4, TPS6594_BIT_LDOX_ILIM_INT(3)),
|
||||
|
||||
/* INT_VMON register */
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_VCCA_OV, 5, TPS6594_BIT_VCCA_OV_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_VCCA_UV, 5, TPS6594_BIT_VCCA_UV_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_VMON1_OV, 5, TPS6594_BIT_VMON1_OV_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_VMON1_UV, 5, TPS6594_BIT_VMON1_UV_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_VMON1_RV, 5, TPS6594_BIT_VMON1_RV_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_VMON2_OV, 5, TPS6594_BIT_VMON2_OV_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_VMON2_UV, 5, TPS6594_BIT_VMON2_UV_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_VMON2_RV, 5, TPS6594_BIT_VMON2_RV_INT),
|
||||
|
||||
/* INT_GPIO register */
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_GPIO9, 6, TPS6594_BIT_GPIO9_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_GPIO10, 6, TPS6594_BIT_GPIO10_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_GPIO11, 6, TPS6594_BIT_GPIO11_INT),
|
||||
|
||||
/* INT_GPIO1_8 register */
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_GPIO1, 7, TPS6594_BIT_GPIOX_INT(0)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_GPIO2, 7, TPS6594_BIT_GPIOX_INT(1)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_GPIO3, 7, TPS6594_BIT_GPIOX_INT(2)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_GPIO4, 7, TPS6594_BIT_GPIOX_INT(3)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_GPIO5, 7, TPS6594_BIT_GPIOX_INT(4)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_GPIO6, 7, TPS6594_BIT_GPIOX_INT(5)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_GPIO7, 7, TPS6594_BIT_GPIOX_INT(6)),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_GPIO8, 7, TPS6594_BIT_GPIOX_INT(7)),
|
||||
|
||||
/* INT_STARTUP register */
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_NPWRON_START, 8, TPS6594_BIT_NPWRON_START_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_ENABLE, 8, TPS6594_BIT_ENABLE_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_FSD, 8, TPS6594_BIT_FSD_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_SOFT_REBOOT, 8, TPS6594_BIT_SOFT_REBOOT_INT),
|
||||
|
||||
/* INT_MISC register */
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_BIST_PASS, 9, TPS6594_BIT_BIST_PASS_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_EXT_CLK, 9, TPS6594_BIT_EXT_CLK_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_TWARN, 9, TPS6594_BIT_TWARN_INT),
|
||||
|
||||
/* INT_MODERATE_ERR register */
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_TSD_ORD, 10, TPS6594_BIT_TSD_ORD_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_BIST_FAIL, 10, TPS6594_BIT_BIST_FAIL_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_REG_CRC_ERR, 10, TPS6594_BIT_REG_CRC_ERR_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_RECOV_CNT, 10, TPS6594_BIT_RECOV_CNT_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_SPMI_ERR, 10, TPS6594_BIT_SPMI_ERR_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_NPWRON_LONG, 10, TPS6594_BIT_NPWRON_LONG_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_NINT_READBACK, 10, TPS6594_BIT_NINT_READBACK_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_NRSTOUT_READBACK, 10, TPS6594_BIT_NRSTOUT_READBACK_INT),
|
||||
|
||||
/* INT_SEVERE_ERR register */
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_TSD_IMM, 11, TPS6594_BIT_TSD_IMM_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_VCCA_OVP, 11, TPS6594_BIT_VCCA_OVP_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_PFSM_ERR, 11, TPS6594_BIT_PFSM_ERR_INT),
|
||||
|
||||
/* INT_FSM_ERR register */
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_IMM_SHUTDOWN, 12, TPS6594_BIT_IMM_SHUTDOWN_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_ORD_SHUTDOWN, 12, TPS6594_BIT_ORD_SHUTDOWN_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_MCU_PWR_ERR, 12, TPS6594_BIT_MCU_PWR_ERR_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_SOC_PWR_ERR, 12, TPS6594_BIT_SOC_PWR_ERR_INT),
|
||||
|
||||
/* INT_COMM_ERR register */
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_COMM_FRM_ERR, 13, TPS6594_BIT_COMM_FRM_ERR_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_COMM_CRC_ERR, 13, TPS6594_BIT_COMM_CRC_ERR_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_COMM_ADR_ERR, 13, TPS6594_BIT_COMM_ADR_ERR_INT),
|
||||
|
||||
/* INT_READBACK_ERR register */
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_EN_DRV_READBACK, 14, TPS6594_BIT_EN_DRV_READBACK_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_NRSTOUT_SOC_READBACK, 14, TPS6594_BIT_NRSTOUT_SOC_READBACK_INT),
|
||||
|
||||
/* INT_ESM register */
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_ESM_SOC_PIN, 15, TPS6594_BIT_ESM_SOC_PIN_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_ESM_SOC_FAIL, 15, TPS6594_BIT_ESM_SOC_FAIL_INT),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_ESM_SOC_RST, 15, TPS6594_BIT_ESM_SOC_RST_INT),
|
||||
|
||||
/* RTC_STATUS register */
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_TIMER, 16, TPS6594_BIT_TIMER),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_ALARM, 16, TPS6594_BIT_ALARM),
|
||||
REGMAP_IRQ_REG(TPS6594_IRQ_POWER_UP, 16, TPS6594_BIT_POWER_UP),
|
||||
};
|
||||
|
||||
static const unsigned int tps6594_irq_reg[] = {
|
||||
TPS6594_REG_INT_BUCK1_2,
|
||||
TPS6594_REG_INT_BUCK3_4,
|
||||
TPS6594_REG_INT_BUCK5,
|
||||
TPS6594_REG_INT_LDO1_2,
|
||||
TPS6594_REG_INT_LDO3_4,
|
||||
TPS6594_REG_INT_VMON,
|
||||
TPS6594_REG_INT_GPIO,
|
||||
TPS6594_REG_INT_GPIO1_8,
|
||||
TPS6594_REG_INT_STARTUP,
|
||||
TPS6594_REG_INT_MISC,
|
||||
TPS6594_REG_INT_MODERATE_ERR,
|
||||
TPS6594_REG_INT_SEVERE_ERR,
|
||||
TPS6594_REG_INT_FSM_ERR,
|
||||
TPS6594_REG_INT_COMM_ERR,
|
||||
TPS6594_REG_INT_READBACK_ERR,
|
||||
TPS6594_REG_INT_ESM,
|
||||
TPS6594_REG_RTC_STATUS,
|
||||
};
|
||||
|
||||
static inline unsigned int tps6594_get_irq_reg(struct regmap_irq_chip_data *data,
|
||||
unsigned int base, int index)
|
||||
{
|
||||
return tps6594_irq_reg[index];
|
||||
};
|
||||
|
||||
static int tps6594_handle_post_irq(void *irq_drv_data)
|
||||
{
|
||||
struct tps6594 *tps = irq_drv_data;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* When CRC is enabled, writing to a read-only bit triggers an error,
|
||||
* and COMM_ADR_ERR_INT bit is set. Besides, bits indicating interrupts
|
||||
* (that must be cleared) and read-only bits are sometimes grouped in
|
||||
* the same register.
|
||||
* Since regmap clears interrupts by doing a write per register, clearing
|
||||
* an interrupt bit in a register containing also a read-only bit makes
|
||||
* COMM_ADR_ERR_INT bit set. Clear immediately this bit to avoid raising
|
||||
* a new interrupt.
|
||||
*/
|
||||
if (tps->use_crc)
|
||||
ret = regmap_write_bits(tps->regmap, TPS6594_REG_INT_COMM_ERR,
|
||||
TPS6594_BIT_COMM_ADR_ERR_INT,
|
||||
TPS6594_BIT_COMM_ADR_ERR_INT);
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
static struct regmap_irq_chip tps6594_irq_chip = {
|
||||
.ack_base = TPS6594_REG_INT_BUCK1_2,
|
||||
.ack_invert = 1,
|
||||
.clear_ack = 1,
|
||||
.init_ack_masked = 1,
|
||||
.num_regs = ARRAY_SIZE(tps6594_irq_reg),
|
||||
.irqs = tps6594_irqs,
|
||||
.num_irqs = ARRAY_SIZE(tps6594_irqs),
|
||||
.get_irq_reg = tps6594_get_irq_reg,
|
||||
.handle_post_irq = tps6594_handle_post_irq,
|
||||
};
|
||||
|
||||
bool tps6594_is_volatile_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
return (reg >= TPS6594_REG_INT_TOP && reg <= TPS6594_REG_STAT_READBACK_ERR) ||
|
||||
reg == TPS6594_REG_RTC_STATUS;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tps6594_is_volatile_reg);
|
||||
|
||||
static int tps6594_check_crc_mode(struct tps6594 *tps, bool primary_pmic)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Check if CRC is enabled.
|
||||
* Once CRC is enabled, it can't be disabled until next power cycle.
|
||||
*/
|
||||
tps->use_crc = true;
|
||||
ret = regmap_test_bits(tps->regmap, TPS6594_REG_SERIAL_IF_CONFIG,
|
||||
TPS6594_BIT_I2C1_SPI_CRC_EN);
|
||||
if (ret == 0) {
|
||||
ret = -EIO;
|
||||
} else if (ret > 0) {
|
||||
dev_info(tps->dev, "CRC feature enabled on %s PMIC",
|
||||
primary_pmic ? "primary" : "secondary");
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tps6594_set_crc_feature(struct tps6594 *tps)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = tps6594_check_crc_mode(tps, true);
|
||||
if (ret) {
|
||||
/*
|
||||
* If CRC is not already enabled, force PFSM I2C_2 trigger to enable it
|
||||
* on primary PMIC.
|
||||
*/
|
||||
tps->use_crc = false;
|
||||
ret = regmap_write_bits(tps->regmap, TPS6594_REG_FSM_I2C_TRIGGERS,
|
||||
TPS6594_BIT_TRIGGER_I2C(2), TPS6594_BIT_TRIGGER_I2C(2));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Wait for PFSM to process trigger.
|
||||
* The datasheet indicates 2 ms, and clock specification is +/-5%.
|
||||
* 4 ms should provide sufficient margin.
|
||||
*/
|
||||
usleep_range(4000, 5000);
|
||||
|
||||
ret = tps6594_check_crc_mode(tps, true);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tps6594_enable_crc(struct tps6594 *tps)
|
||||
{
|
||||
struct device *dev = tps->dev;
|
||||
unsigned int is_primary;
|
||||
unsigned long timeout = msecs_to_jiffies(TPS6594_CRC_SYNC_TIMEOUT_MS);
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* CRC mode can be used with I2C or SPI protocols.
|
||||
* If this mode is specified for primary PMIC, it will also be applied to secondary PMICs
|
||||
* through SPMI serial interface.
|
||||
* In this multi-PMIC synchronization scheme, the primary PMIC is the controller device
|
||||
* on the SPMI bus, and the secondary PMICs are the target devices on the SPMI bus.
|
||||
*/
|
||||
is_primary = of_property_read_bool(dev->of_node, "ti,primary-pmic");
|
||||
if (is_primary) {
|
||||
/* Enable CRC feature on primary PMIC */
|
||||
ret = tps6594_set_crc_feature(tps);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Notify secondary PMICs that CRC feature is enabled */
|
||||
complete_all(&tps6594_crc_comp);
|
||||
} else {
|
||||
/* Wait for CRC feature enabling event from primary PMIC */
|
||||
ret = wait_for_completion_interruptible_timeout(&tps6594_crc_comp, timeout);
|
||||
if (ret == 0)
|
||||
ret = -ETIMEDOUT;
|
||||
else if (ret > 0)
|
||||
ret = tps6594_check_crc_mode(tps, false);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tps6594_device_init(struct tps6594 *tps, bool enable_crc)
|
||||
{
|
||||
struct device *dev = tps->dev;
|
||||
int ret;
|
||||
|
||||
if (enable_crc) {
|
||||
ret = tps6594_enable_crc(tps);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to enable CRC\n");
|
||||
}
|
||||
|
||||
/* Keep PMIC in ACTIVE state */
|
||||
ret = regmap_set_bits(tps->regmap, TPS6594_REG_FSM_NSLEEP_TRIGGERS,
|
||||
TPS6594_BIT_NSLEEP1B | TPS6594_BIT_NSLEEP2B);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to set PMIC state\n");
|
||||
|
||||
tps6594_irq_chip.irq_drv_data = tps;
|
||||
tps6594_irq_chip.name = devm_kasprintf(dev, GFP_KERNEL, "%s-%ld-0x%02x",
|
||||
dev->driver->name, tps->chip_id, tps->reg);
|
||||
|
||||
ret = devm_regmap_add_irq_chip(dev, tps->regmap, tps->irq, IRQF_SHARED | IRQF_ONESHOT,
|
||||
0, &tps6594_irq_chip, &tps->irq_data);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to add regmap IRQ\n");
|
||||
|
||||
ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, tps6594_common_cells,
|
||||
ARRAY_SIZE(tps6594_common_cells), NULL, 0,
|
||||
regmap_irq_get_domain(tps->irq_data));
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to add common child devices\n");
|
||||
|
||||
/* No RTC for LP8764 */
|
||||
if (tps->chip_id != LP8764) {
|
||||
ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, tps6594_rtc_cells,
|
||||
ARRAY_SIZE(tps6594_rtc_cells), NULL, 0,
|
||||
regmap_irq_get_domain(tps->irq_data));
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to add RTC child device\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tps6594_device_init);
|
||||
|
||||
MODULE_AUTHOR("Julien Panis <jpanis@baylibre.com>");
|
||||
MODULE_DESCRIPTION("TPS6594 Driver");
|
||||
MODULE_LICENSE("GPL");
|
244
drivers/mfd/tps6594-i2c.c
Normal file
244
drivers/mfd/tps6594-i2c.c
Normal file
@@ -0,0 +1,244 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* I2C access driver for TI TPS6594/TPS6593/LP8764 PMICs
|
||||
*
|
||||
* Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
|
||||
*/
|
||||
|
||||
#include <linux/crc8.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <linux/mfd/tps6594.h>
|
||||
|
||||
static bool enable_crc;
|
||||
module_param(enable_crc, bool, 0444);
|
||||
MODULE_PARM_DESC(enable_crc, "Enable CRC feature for I2C interface");
|
||||
|
||||
DECLARE_CRC8_TABLE(tps6594_i2c_crc_table);
|
||||
|
||||
static int tps6594_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
|
||||
{
|
||||
int ret = i2c_transfer(adap, msgs, num);
|
||||
|
||||
if (ret == num)
|
||||
return 0;
|
||||
else if (ret < 0)
|
||||
return ret;
|
||||
else
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static int tps6594_i2c_reg_read_with_crc(struct i2c_client *client, u8 page, u8 reg, u8 *val)
|
||||
{
|
||||
struct i2c_msg msgs[2];
|
||||
u8 buf_rx[] = { 0, 0 };
|
||||
/* I2C address = I2C base address + Page index */
|
||||
const u8 addr = client->addr + page;
|
||||
/*
|
||||
* CRC is calculated from every bit included in the protocol
|
||||
* except the ACK bits from the target. Byte stream is:
|
||||
* - B0: (I2C_addr_7bits << 1) | WR_bit, with WR_bit = 0
|
||||
* - B1: reg
|
||||
* - B2: (I2C_addr_7bits << 1) | RD_bit, with RD_bit = 1
|
||||
* - B3: val
|
||||
* - B4: CRC from B0-B1-B2-B3
|
||||
*/
|
||||
u8 crc_data[] = { addr << 1, reg, addr << 1 | 1, 0 };
|
||||
int ret;
|
||||
|
||||
/* Write register */
|
||||
msgs[0].addr = addr;
|
||||
msgs[0].flags = 0;
|
||||
msgs[0].len = 1;
|
||||
msgs[0].buf = ®
|
||||
|
||||
/* Read data and CRC */
|
||||
msgs[1].addr = msgs[0].addr;
|
||||
msgs[1].flags = I2C_M_RD;
|
||||
msgs[1].len = 2;
|
||||
msgs[1].buf = buf_rx;
|
||||
|
||||
ret = tps6594_i2c_transfer(client->adapter, msgs, 2);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
crc_data[sizeof(crc_data) - 1] = *val = buf_rx[0];
|
||||
if (buf_rx[1] != crc8(tps6594_i2c_crc_table, crc_data, sizeof(crc_data), CRC8_INIT_VALUE))
|
||||
return -EIO;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tps6594_i2c_reg_write_with_crc(struct i2c_client *client, u8 page, u8 reg, u8 val)
|
||||
{
|
||||
struct i2c_msg msg;
|
||||
u8 buf[] = { reg, val, 0 };
|
||||
/* I2C address = I2C base address + Page index */
|
||||
const u8 addr = client->addr + page;
|
||||
/*
|
||||
* CRC is calculated from every bit included in the protocol
|
||||
* except the ACK bits from the target. Byte stream is:
|
||||
* - B0: (I2C_addr_7bits << 1) | WR_bit, with WR_bit = 0
|
||||
* - B1: reg
|
||||
* - B2: val
|
||||
* - B3: CRC from B0-B1-B2
|
||||
*/
|
||||
const u8 crc_data[] = { addr << 1, reg, val };
|
||||
|
||||
/* Write register, data and CRC */
|
||||
msg.addr = addr;
|
||||
msg.flags = client->flags & I2C_M_TEN;
|
||||
msg.len = sizeof(buf);
|
||||
msg.buf = buf;
|
||||
|
||||
buf[msg.len - 1] = crc8(tps6594_i2c_crc_table, crc_data, sizeof(crc_data), CRC8_INIT_VALUE);
|
||||
|
||||
return tps6594_i2c_transfer(client->adapter, &msg, 1);
|
||||
}
|
||||
|
||||
static int tps6594_i2c_read(void *context, const void *reg_buf, size_t reg_size,
|
||||
void *val_buf, size_t val_size)
|
||||
{
|
||||
struct i2c_client *client = context;
|
||||
struct tps6594 *tps = i2c_get_clientdata(client);
|
||||
struct i2c_msg msgs[2];
|
||||
const u8 *reg_bytes = reg_buf;
|
||||
u8 *val_bytes = val_buf;
|
||||
const u8 page = reg_bytes[1];
|
||||
u8 reg = reg_bytes[0];
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
if (tps->use_crc) {
|
||||
/*
|
||||
* Auto-increment feature does not support CRC protocol.
|
||||
* Converts the bulk read operation into a series of single read operations.
|
||||
*/
|
||||
for (i = 0 ; ret == 0 && i < val_size ; i++)
|
||||
ret = tps6594_i2c_reg_read_with_crc(client, page, reg + i, val_bytes + i);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Write register: I2C address = I2C base address + Page index */
|
||||
msgs[0].addr = client->addr + page;
|
||||
msgs[0].flags = 0;
|
||||
msgs[0].len = 1;
|
||||
msgs[0].buf = ®
|
||||
|
||||
/* Read data */
|
||||
msgs[1].addr = msgs[0].addr;
|
||||
msgs[1].flags = I2C_M_RD;
|
||||
msgs[1].len = val_size;
|
||||
msgs[1].buf = val_bytes;
|
||||
|
||||
return tps6594_i2c_transfer(client->adapter, msgs, 2);
|
||||
}
|
||||
|
||||
static int tps6594_i2c_write(void *context, const void *data, size_t count)
|
||||
{
|
||||
struct i2c_client *client = context;
|
||||
struct tps6594 *tps = i2c_get_clientdata(client);
|
||||
struct i2c_msg msg;
|
||||
const u8 *bytes = data;
|
||||
u8 *buf;
|
||||
const u8 page = bytes[1];
|
||||
const u8 reg = bytes[0];
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
if (tps->use_crc) {
|
||||
/*
|
||||
* Auto-increment feature does not support CRC protocol.
|
||||
* Converts the bulk write operation into a series of single write operations.
|
||||
*/
|
||||
for (i = 0 ; ret == 0 && i < count - 2 ; i++)
|
||||
ret = tps6594_i2c_reg_write_with_crc(client, page, reg + i, bytes[i + 2]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Setup buffer: page byte is not sent */
|
||||
buf = kzalloc(--count, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
buf[0] = reg;
|
||||
for (i = 0 ; i < count - 1 ; i++)
|
||||
buf[i + 1] = bytes[i + 2];
|
||||
|
||||
/* Write register and data: I2C address = I2C base address + Page index */
|
||||
msg.addr = client->addr + page;
|
||||
msg.flags = client->flags & I2C_M_TEN;
|
||||
msg.len = count;
|
||||
msg.buf = buf;
|
||||
|
||||
ret = tps6594_i2c_transfer(client->adapter, &msg, 1);
|
||||
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct regmap_config tps6594_i2c_regmap_config = {
|
||||
.reg_bits = 16,
|
||||
.val_bits = 8,
|
||||
.max_register = TPS6594_REG_DWD_FAIL_CNT_REG,
|
||||
.volatile_reg = tps6594_is_volatile_reg,
|
||||
.read = tps6594_i2c_read,
|
||||
.write = tps6594_i2c_write,
|
||||
};
|
||||
|
||||
static const struct of_device_id tps6594_i2c_of_match_table[] = {
|
||||
{ .compatible = "ti,tps6594-q1", .data = (void *)TPS6594, },
|
||||
{ .compatible = "ti,tps6593-q1", .data = (void *)TPS6593, },
|
||||
{ .compatible = "ti,lp8764-q1", .data = (void *)LP8764, },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, tps6594_i2c_of_match_table);
|
||||
|
||||
static int tps6594_i2c_probe(struct i2c_client *client)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct tps6594 *tps;
|
||||
const struct of_device_id *match;
|
||||
|
||||
tps = devm_kzalloc(dev, sizeof(*tps), GFP_KERNEL);
|
||||
if (!tps)
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(client, tps);
|
||||
|
||||
tps->dev = dev;
|
||||
tps->reg = client->addr;
|
||||
tps->irq = client->irq;
|
||||
|
||||
tps->regmap = devm_regmap_init(dev, NULL, client, &tps6594_i2c_regmap_config);
|
||||
if (IS_ERR(tps->regmap))
|
||||
return dev_err_probe(dev, PTR_ERR(tps->regmap), "Failed to init regmap\n");
|
||||
|
||||
match = of_match_device(tps6594_i2c_of_match_table, dev);
|
||||
if (!match)
|
||||
return dev_err_probe(dev, PTR_ERR(match), "Failed to find matching chip ID\n");
|
||||
tps->chip_id = (unsigned long)match->data;
|
||||
|
||||
crc8_populate_msb(tps6594_i2c_crc_table, TPS6594_CRC8_POLYNOMIAL);
|
||||
|
||||
return tps6594_device_init(tps, enable_crc);
|
||||
}
|
||||
|
||||
static struct i2c_driver tps6594_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "tps6594",
|
||||
.of_match_table = tps6594_i2c_of_match_table,
|
||||
},
|
||||
.probe_new = tps6594_i2c_probe,
|
||||
};
|
||||
module_i2c_driver(tps6594_i2c_driver);
|
||||
|
||||
MODULE_AUTHOR("Julien Panis <jpanis@baylibre.com>");
|
||||
MODULE_DESCRIPTION("TPS6594 I2C Interface Driver");
|
||||
MODULE_LICENSE("GPL");
|
129
drivers/mfd/tps6594-spi.c
Normal file
129
drivers/mfd/tps6594-spi.c
Normal file
@@ -0,0 +1,129 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* SPI access driver for TI TPS6594/TPS6593/LP8764 PMICs
|
||||
*
|
||||
* Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
|
||||
*/
|
||||
|
||||
#include <linux/crc8.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
#include <linux/mfd/tps6594.h>
|
||||
|
||||
#define TPS6594_SPI_PAGE_SHIFT 5
|
||||
#define TPS6594_SPI_READ_BIT BIT(4)
|
||||
|
||||
static bool enable_crc;
|
||||
module_param(enable_crc, bool, 0444);
|
||||
MODULE_PARM_DESC(enable_crc, "Enable CRC feature for SPI interface");
|
||||
|
||||
DECLARE_CRC8_TABLE(tps6594_spi_crc_table);
|
||||
|
||||
static int tps6594_spi_reg_read(void *context, unsigned int reg, unsigned int *val)
|
||||
{
|
||||
struct spi_device *spi = context;
|
||||
struct tps6594 *tps = spi_get_drvdata(spi);
|
||||
u8 buf[4] = { 0 };
|
||||
size_t count_rx = 1;
|
||||
int ret;
|
||||
|
||||
buf[0] = reg;
|
||||
buf[1] = TPS6594_REG_TO_PAGE(reg) << TPS6594_SPI_PAGE_SHIFT | TPS6594_SPI_READ_BIT;
|
||||
|
||||
if (tps->use_crc)
|
||||
count_rx++;
|
||||
|
||||
ret = spi_write_then_read(spi, buf, 2, buf + 2, count_rx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (tps->use_crc && buf[3] != crc8(tps6594_spi_crc_table, buf, 3, CRC8_INIT_VALUE))
|
||||
return -EIO;
|
||||
|
||||
*val = buf[2];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tps6594_spi_reg_write(void *context, unsigned int reg, unsigned int val)
|
||||
{
|
||||
struct spi_device *spi = context;
|
||||
struct tps6594 *tps = spi_get_drvdata(spi);
|
||||
u8 buf[4] = { 0 };
|
||||
size_t count = 3;
|
||||
|
||||
buf[0] = reg;
|
||||
buf[1] = TPS6594_REG_TO_PAGE(reg) << TPS6594_SPI_PAGE_SHIFT;
|
||||
buf[2] = val;
|
||||
|
||||
if (tps->use_crc)
|
||||
buf[3] = crc8(tps6594_spi_crc_table, buf, count++, CRC8_INIT_VALUE);
|
||||
|
||||
return spi_write(spi, buf, count);
|
||||
}
|
||||
|
||||
static const struct regmap_config tps6594_spi_regmap_config = {
|
||||
.reg_bits = 16,
|
||||
.val_bits = 8,
|
||||
.max_register = TPS6594_REG_DWD_FAIL_CNT_REG,
|
||||
.volatile_reg = tps6594_is_volatile_reg,
|
||||
.reg_read = tps6594_spi_reg_read,
|
||||
.reg_write = tps6594_spi_reg_write,
|
||||
.use_single_read = true,
|
||||
.use_single_write = true,
|
||||
};
|
||||
|
||||
static const struct of_device_id tps6594_spi_of_match_table[] = {
|
||||
{ .compatible = "ti,tps6594-q1", .data = (void *)TPS6594, },
|
||||
{ .compatible = "ti,tps6593-q1", .data = (void *)TPS6593, },
|
||||
{ .compatible = "ti,lp8764-q1", .data = (void *)LP8764, },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, tps6594_spi_of_match_table);
|
||||
|
||||
static int tps6594_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
struct device *dev = &spi->dev;
|
||||
struct tps6594 *tps;
|
||||
const struct of_device_id *match;
|
||||
|
||||
tps = devm_kzalloc(dev, sizeof(*tps), GFP_KERNEL);
|
||||
if (!tps)
|
||||
return -ENOMEM;
|
||||
|
||||
spi_set_drvdata(spi, tps);
|
||||
|
||||
tps->dev = dev;
|
||||
tps->reg = spi->chip_select;
|
||||
tps->irq = spi->irq;
|
||||
|
||||
tps->regmap = devm_regmap_init(dev, NULL, spi, &tps6594_spi_regmap_config);
|
||||
if (IS_ERR(tps->regmap))
|
||||
return dev_err_probe(dev, PTR_ERR(tps->regmap), "Failed to init regmap\n");
|
||||
|
||||
match = of_match_device(tps6594_spi_of_match_table, dev);
|
||||
if (!match)
|
||||
return dev_err_probe(dev, PTR_ERR(match), "Failed to find matching chip ID\n");
|
||||
tps->chip_id = (unsigned long)match->data;
|
||||
|
||||
crc8_populate_msb(tps6594_spi_crc_table, TPS6594_CRC8_POLYNOMIAL);
|
||||
|
||||
return tps6594_device_init(tps, enable_crc);
|
||||
}
|
||||
|
||||
static struct spi_driver tps6594_spi_driver = {
|
||||
.driver = {
|
||||
.name = "tps6594",
|
||||
.of_match_table = tps6594_spi_of_match_table,
|
||||
},
|
||||
.probe = tps6594_spi_probe,
|
||||
};
|
||||
module_spi_driver(tps6594_spi_driver);
|
||||
|
||||
MODULE_AUTHOR("Julien Panis <jpanis@baylibre.com>");
|
||||
MODULE_DESCRIPTION("TPS6594 SPI Interface Driver");
|
||||
MODULE_LICENSE("GPL");
|
@@ -407,7 +407,7 @@ config PINCTRL_PISTACHIO
|
||||
|
||||
config PINCTRL_RK805
|
||||
tristate "Pinctrl and GPIO driver for RK805 PMIC"
|
||||
depends on MFD_RK808
|
||||
depends on MFD_RK8XX
|
||||
select GPIOLIB
|
||||
select PINMUX
|
||||
select GENERIC_PINCONF
|
||||
|
@@ -1,10 +1,12 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Pinctrl driver for Rockchip RK805 PMIC
|
||||
* Pinctrl driver for Rockchip RK805/RK806 PMIC
|
||||
*
|
||||
* Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
|
||||
* Copyright (c) 2021 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* Author: Joseph Chen <chenjh@rock-chips.com>
|
||||
* Author: Xu Shengfei <xsf@rock-chips.com>
|
||||
*
|
||||
* Based on the pinctrl-as3722 driver
|
||||
*/
|
||||
@@ -44,6 +46,7 @@ struct rk805_pin_group {
|
||||
|
||||
/*
|
||||
* @reg: gpio setting register;
|
||||
* @fun_reg: functions select register;
|
||||
* @fun_mask: functions select mask value, when set is gpio;
|
||||
* @dir_mask: input or output mask value, when set is output, otherwise input;
|
||||
* @val_mask: gpio set value, when set is level high, otherwise low;
|
||||
@@ -56,6 +59,7 @@ struct rk805_pin_group {
|
||||
*/
|
||||
struct rk805_pin_config {
|
||||
u8 reg;
|
||||
u8 fun_reg;
|
||||
u8 fun_msk;
|
||||
u8 dir_msk;
|
||||
u8 val_msk;
|
||||
@@ -80,22 +84,50 @@ enum rk805_pinmux_option {
|
||||
RK805_PINMUX_GPIO,
|
||||
};
|
||||
|
||||
enum rk806_pinmux_option {
|
||||
RK806_PINMUX_FUN0 = 0,
|
||||
RK806_PINMUX_FUN1,
|
||||
RK806_PINMUX_FUN2,
|
||||
RK806_PINMUX_FUN3,
|
||||
RK806_PINMUX_FUN4,
|
||||
RK806_PINMUX_FUN5,
|
||||
};
|
||||
|
||||
enum {
|
||||
RK805_GPIO0,
|
||||
RK805_GPIO1,
|
||||
};
|
||||
|
||||
enum {
|
||||
RK806_GPIO_DVS1,
|
||||
RK806_GPIO_DVS2,
|
||||
RK806_GPIO_DVS3
|
||||
};
|
||||
|
||||
static const char *const rk805_gpio_groups[] = {
|
||||
"gpio0",
|
||||
"gpio1",
|
||||
};
|
||||
|
||||
static const char *const rk806_gpio_groups[] = {
|
||||
"gpio_pwrctrl1",
|
||||
"gpio_pwrctrl2",
|
||||
"gpio_pwrctrl3",
|
||||
};
|
||||
|
||||
/* RK805: 2 output only GPIOs */
|
||||
static const struct pinctrl_pin_desc rk805_pins_desc[] = {
|
||||
PINCTRL_PIN(RK805_GPIO0, "gpio0"),
|
||||
PINCTRL_PIN(RK805_GPIO1, "gpio1"),
|
||||
};
|
||||
|
||||
/* RK806 */
|
||||
static const struct pinctrl_pin_desc rk806_pins_desc[] = {
|
||||
PINCTRL_PIN(RK806_GPIO_DVS1, "gpio_pwrctrl1"),
|
||||
PINCTRL_PIN(RK806_GPIO_DVS2, "gpio_pwrctrl2"),
|
||||
PINCTRL_PIN(RK806_GPIO_DVS3, "gpio_pwrctrl3"),
|
||||
};
|
||||
|
||||
static const struct rk805_pin_function rk805_pin_functions[] = {
|
||||
{
|
||||
.name = "gpio",
|
||||
@@ -105,6 +137,45 @@ static const struct rk805_pin_function rk805_pin_functions[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct rk805_pin_function rk806_pin_functions[] = {
|
||||
{
|
||||
.name = "pin_fun0",
|
||||
.groups = rk806_gpio_groups,
|
||||
.ngroups = ARRAY_SIZE(rk806_gpio_groups),
|
||||
.mux_option = RK806_PINMUX_FUN0,
|
||||
},
|
||||
{
|
||||
.name = "pin_fun1",
|
||||
.groups = rk806_gpio_groups,
|
||||
.ngroups = ARRAY_SIZE(rk806_gpio_groups),
|
||||
.mux_option = RK806_PINMUX_FUN1,
|
||||
},
|
||||
{
|
||||
.name = "pin_fun2",
|
||||
.groups = rk806_gpio_groups,
|
||||
.ngroups = ARRAY_SIZE(rk806_gpio_groups),
|
||||
.mux_option = RK806_PINMUX_FUN2,
|
||||
},
|
||||
{
|
||||
.name = "pin_fun3",
|
||||
.groups = rk806_gpio_groups,
|
||||
.ngroups = ARRAY_SIZE(rk806_gpio_groups),
|
||||
.mux_option = RK806_PINMUX_FUN3,
|
||||
},
|
||||
{
|
||||
.name = "pin_fun4",
|
||||
.groups = rk806_gpio_groups,
|
||||
.ngroups = ARRAY_SIZE(rk806_gpio_groups),
|
||||
.mux_option = RK806_PINMUX_FUN4,
|
||||
},
|
||||
{
|
||||
.name = "pin_fun5",
|
||||
.groups = rk806_gpio_groups,
|
||||
.ngroups = ARRAY_SIZE(rk806_gpio_groups),
|
||||
.mux_option = RK806_PINMUX_FUN5,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct rk805_pin_group rk805_pin_groups[] = {
|
||||
{
|
||||
.name = "gpio0",
|
||||
@@ -118,6 +189,24 @@ static const struct rk805_pin_group rk805_pin_groups[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct rk805_pin_group rk806_pin_groups[] = {
|
||||
{
|
||||
.name = "gpio_pwrctrl1",
|
||||
.pins = { RK806_GPIO_DVS1 },
|
||||
.npins = 1,
|
||||
},
|
||||
{
|
||||
.name = "gpio_pwrctrl2",
|
||||
.pins = { RK806_GPIO_DVS2 },
|
||||
.npins = 1,
|
||||
},
|
||||
{
|
||||
.name = "gpio_pwrctrl3",
|
||||
.pins = { RK806_GPIO_DVS3 },
|
||||
.npins = 1,
|
||||
}
|
||||
};
|
||||
|
||||
#define RK805_GPIO0_VAL_MSK BIT(0)
|
||||
#define RK805_GPIO1_VAL_MSK BIT(1)
|
||||
|
||||
@@ -132,6 +221,40 @@ static const struct rk805_pin_config rk805_gpio_cfgs[] = {
|
||||
},
|
||||
};
|
||||
|
||||
#define RK806_PWRCTRL1_DR BIT(0)
|
||||
#define RK806_PWRCTRL2_DR BIT(1)
|
||||
#define RK806_PWRCTRL3_DR BIT(2)
|
||||
#define RK806_PWRCTRL1_DATA BIT(4)
|
||||
#define RK806_PWRCTRL2_DATA BIT(5)
|
||||
#define RK806_PWRCTRL3_DATA BIT(6)
|
||||
#define RK806_PWRCTRL1_FUN GENMASK(2, 0)
|
||||
#define RK806_PWRCTRL2_FUN GENMASK(6, 4)
|
||||
#define RK806_PWRCTRL3_FUN GENMASK(2, 0)
|
||||
|
||||
static struct rk805_pin_config rk806_gpio_cfgs[] = {
|
||||
{
|
||||
.fun_reg = RK806_SLEEP_CONFIG0,
|
||||
.fun_msk = RK806_PWRCTRL1_FUN,
|
||||
.reg = RK806_SLEEP_GPIO,
|
||||
.val_msk = RK806_PWRCTRL1_DATA,
|
||||
.dir_msk = RK806_PWRCTRL1_DR,
|
||||
},
|
||||
{
|
||||
.fun_reg = RK806_SLEEP_CONFIG0,
|
||||
.fun_msk = RK806_PWRCTRL2_FUN,
|
||||
.reg = RK806_SLEEP_GPIO,
|
||||
.val_msk = RK806_PWRCTRL2_DATA,
|
||||
.dir_msk = RK806_PWRCTRL2_DR,
|
||||
},
|
||||
{
|
||||
.fun_reg = RK806_SLEEP_CONFIG1,
|
||||
.fun_msk = RK806_PWRCTRL3_FUN,
|
||||
.reg = RK806_SLEEP_GPIO,
|
||||
.val_msk = RK806_PWRCTRL3_DATA,
|
||||
.dir_msk = RK806_PWRCTRL3_DR,
|
||||
}
|
||||
};
|
||||
|
||||
/* generic gpio chip */
|
||||
static int rk805_gpio_get(struct gpio_chip *chip, unsigned int offset)
|
||||
{
|
||||
@@ -289,19 +412,13 @@ static int _rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev,
|
||||
if (!pci->pin_cfg[offset].fun_msk)
|
||||
return 0;
|
||||
|
||||
if (mux == RK805_PINMUX_GPIO) {
|
||||
ret = regmap_update_bits(pci->rk808->regmap,
|
||||
pci->pin_cfg[offset].reg,
|
||||
pci->pin_cfg[offset].fun_msk,
|
||||
pci->pin_cfg[offset].fun_msk);
|
||||
if (ret) {
|
||||
dev_err(pci->dev, "set gpio%d GPIO failed\n", offset);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
dev_err(pci->dev, "Couldn't find function mux %d\n", mux);
|
||||
return -EINVAL;
|
||||
}
|
||||
mux <<= ffs(pci->pin_cfg[offset].fun_msk) - 1;
|
||||
ret = regmap_update_bits(pci->rk808->regmap,
|
||||
pci->pin_cfg[offset].fun_reg,
|
||||
pci->pin_cfg[offset].fun_msk, mux);
|
||||
|
||||
if (ret)
|
||||
dev_err(pci->dev, "set gpio%d func%d failed\n", offset, mux);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -317,6 +434,22 @@ static int rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev,
|
||||
return _rk805_pinctrl_set_mux(pctldev, offset, mux);
|
||||
}
|
||||
|
||||
static int rk805_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_gpio_range *range,
|
||||
unsigned int offset)
|
||||
{
|
||||
struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
switch (pci->rk808->variant) {
|
||||
case RK805_ID:
|
||||
return _rk805_pinctrl_set_mux(pctldev, offset, RK805_PINMUX_GPIO);
|
||||
case RK806_ID:
|
||||
return _rk805_pinctrl_set_mux(pctldev, offset, RK806_PINMUX_FUN5);
|
||||
}
|
||||
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static int rk805_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_gpio_range *range,
|
||||
unsigned int offset, bool input)
|
||||
@@ -324,13 +457,6 @@ static int rk805_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
|
||||
struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
|
||||
int ret;
|
||||
|
||||
/* switch to gpio function */
|
||||
ret = _rk805_pinctrl_set_mux(pctldev, offset, RK805_PINMUX_GPIO);
|
||||
if (ret) {
|
||||
dev_err(pci->dev, "set gpio%d mux failed\n", offset);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* set direction */
|
||||
if (!pci->pin_cfg[offset].dir_msk)
|
||||
return 0;
|
||||
@@ -352,6 +478,7 @@ static const struct pinmux_ops rk805_pinmux_ops = {
|
||||
.get_function_name = rk805_pinctrl_get_func_name,
|
||||
.get_function_groups = rk805_pinctrl_get_func_groups,
|
||||
.set_mux = rk805_pinctrl_set_mux,
|
||||
.gpio_request_enable = rk805_pinctrl_gpio_request_enable,
|
||||
.gpio_set_direction = rk805_pmx_gpio_set_direction,
|
||||
};
|
||||
|
||||
@@ -364,6 +491,7 @@ static int rk805_pinconf_get(struct pinctrl_dev *pctldev,
|
||||
|
||||
switch (param) {
|
||||
case PIN_CONFIG_OUTPUT:
|
||||
case PIN_CONFIG_INPUT_ENABLE:
|
||||
arg = rk805_gpio_get(&pci->gpio_chip, pin);
|
||||
break;
|
||||
default:
|
||||
@@ -393,6 +521,12 @@ static int rk805_pinconf_set(struct pinctrl_dev *pctldev,
|
||||
rk805_gpio_set(&pci->gpio_chip, pin, arg);
|
||||
rk805_pmx_gpio_set_direction(pctldev, NULL, pin, false);
|
||||
break;
|
||||
case PIN_CONFIG_INPUT_ENABLE:
|
||||
if (pci->rk808->variant != RK805_ID && arg) {
|
||||
rk805_pmx_gpio_set_direction(pctldev, NULL, pin, true);
|
||||
break;
|
||||
}
|
||||
fallthrough;
|
||||
default:
|
||||
dev_err(pci->dev, "Properties not supported\n");
|
||||
return -ENOTSUPP;
|
||||
@@ -448,6 +582,18 @@ static int rk805_pinctrl_probe(struct platform_device *pdev)
|
||||
pci->pin_cfg = rk805_gpio_cfgs;
|
||||
pci->gpio_chip.ngpio = ARRAY_SIZE(rk805_gpio_cfgs);
|
||||
break;
|
||||
case RK806_ID:
|
||||
pci->pins = rk806_pins_desc;
|
||||
pci->num_pins = ARRAY_SIZE(rk806_pins_desc);
|
||||
pci->functions = rk806_pin_functions;
|
||||
pci->num_functions = ARRAY_SIZE(rk806_pin_functions);
|
||||
pci->groups = rk806_pin_groups;
|
||||
pci->num_pin_groups = ARRAY_SIZE(rk806_pin_groups);
|
||||
pci->pinctrl_desc.pins = rk806_pins_desc;
|
||||
pci->pinctrl_desc.npins = ARRAY_SIZE(rk806_pins_desc);
|
||||
pci->pin_cfg = rk806_gpio_cfgs;
|
||||
pci->gpio_chip.ngpio = ARRAY_SIZE(rk806_gpio_cfgs);
|
||||
break;
|
||||
default:
|
||||
dev_err(&pdev->dev, "unsupported RK805 ID %lu\n",
|
||||
pci->rk808->variant);
|
||||
@@ -488,5 +634,6 @@ static struct platform_driver rk805_pinctrl_driver = {
|
||||
module_platform_driver(rk805_pinctrl_driver);
|
||||
|
||||
MODULE_DESCRIPTION("RK805 pin control and GPIO driver");
|
||||
MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");
|
||||
MODULE_AUTHOR("Joseph Chen <chenjh@rock-chips.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@@ -706,7 +706,7 @@ config CHARGER_BQ256XX
|
||||
|
||||
config CHARGER_RK817
|
||||
tristate "Rockchip RK817 PMIC Battery Charger"
|
||||
depends on MFD_RK808
|
||||
depends on MFD_RK8XX
|
||||
help
|
||||
Say Y to include support for Rockchip RK817 Battery Charger.
|
||||
|
||||
|
@@ -104,7 +104,7 @@ static struct i2c_driver pg86x_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(pg86x_dt_ids),
|
||||
},
|
||||
.probe_new = pg86x_i2c_probe,
|
||||
.probe = pg86x_i2c_probe,
|
||||
.id_table = pg86x_i2c_id,
|
||||
};
|
||||
|
||||
|
@@ -1033,6 +1033,13 @@ config REGULATOR_QCOM_USB_VBUS
|
||||
Say M here if you want to include support for enabling the VBUS output
|
||||
as a module. The module will be named "qcom_usb_vbus_regulator".
|
||||
|
||||
config REGULATOR_RAA215300
|
||||
tristate "Renesas RAA215300 driver"
|
||||
select REGMAP_I2C
|
||||
depends on I2C
|
||||
help
|
||||
Support for the Renesas RAA215300 PMIC.
|
||||
|
||||
config REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY
|
||||
tristate "Raspberry Pi 7-inch touchscreen panel ATTINY regulator"
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
@@ -1056,7 +1063,7 @@ config REGULATOR_RC5T583
|
||||
|
||||
config REGULATOR_RK808
|
||||
tristate "Rockchip RK805/RK808/RK809/RK817/RK818 Power regulators"
|
||||
depends on MFD_RK808
|
||||
depends on MFD_RK8XX
|
||||
help
|
||||
Select this option to enable the power regulator of ROCKCHIP
|
||||
PMIC RK805,RK809&RK817,RK808 and RK818.
|
||||
@@ -1397,6 +1404,17 @@ config REGULATOR_TPS6286X
|
||||
high-frequency synchronous step-down converters with an I2C
|
||||
interface.
|
||||
|
||||
config REGULATOR_TPS6287X
|
||||
tristate "TI TPS6287x Power Regulator"
|
||||
depends on I2C && OF
|
||||
select REGMAP_I2C
|
||||
help
|
||||
This driver supports TPS6287x voltage regulator chips. These are
|
||||
pin-to-pin high-frequency synchronous step-down dc-dc converters
|
||||
with an I2C interface.
|
||||
|
||||
If built as a module it will be called tps6287x-regulator.
|
||||
|
||||
config REGULATOR_TPS65023
|
||||
tristate "TI TPS65023 Power regulators"
|
||||
depends on I2C
|
||||
@@ -1463,6 +1481,19 @@ config REGULATOR_TPS65219
|
||||
voltage regulators. It supports software based voltage control
|
||||
for different voltage domains.
|
||||
|
||||
config REGULATOR_TPS6594
|
||||
tristate "TI TPS6594 Power regulators"
|
||||
depends on MFD_TPS6594 && OF
|
||||
default MFD_TPS6594
|
||||
help
|
||||
This driver supports TPS6594 voltage regulator chips.
|
||||
TPS6594 series of PMICs have 5 BUCKs and 4 LDOs
|
||||
voltage regulators.
|
||||
BUCKs 1,2,3,4 can be used in single phase or multiphase mode.
|
||||
Part number defines which single or multiphase mode is i used.
|
||||
It supports software based voltage control
|
||||
for different voltage domains.
|
||||
|
||||
config REGULATOR_TPS6524X
|
||||
tristate "TI TPS6524X Power regulators"
|
||||
depends on SPI
|
||||
|
@@ -124,6 +124,7 @@ obj-$(CONFIG_REGULATOR_TPS51632) += tps51632-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_PBIAS) += pbias-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_RAA215300) += raa215300.o
|
||||
obj-$(CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY) += rpi-panel-attiny-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_RK808) += rk808-regulator.o
|
||||
@@ -163,6 +164,7 @@ obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS6286X) += tps6286x-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS6287X) += tps6287x-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS65086) += tps65086-regulator.o
|
||||
@@ -174,6 +176,7 @@ obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS6594) += tps6594-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS65132) += tps65132-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TPS68470) += tps68470-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o twl6030-regulator.o
|
||||
|
@@ -791,7 +791,7 @@ static struct i2c_driver act8865_pmic_driver = {
|
||||
.name = "act8865",
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
},
|
||||
.probe_new = act8865_pmic_probe,
|
||||
.probe = act8865_pmic_probe,
|
||||
.id_table = act8865_ids,
|
||||
};
|
||||
|
||||
|
@@ -254,7 +254,7 @@ static int ad5398_probe(struct i2c_client *client)
|
||||
}
|
||||
|
||||
static struct i2c_driver ad5398_driver = {
|
||||
.probe_new = ad5398_probe,
|
||||
.probe = ad5398_probe,
|
||||
.driver = {
|
||||
.name = "ad5398",
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
|
@@ -134,6 +134,11 @@
|
||||
#define AXP22X_PWR_OUT_DLDO4_MASK BIT_MASK(6)
|
||||
#define AXP22X_PWR_OUT_ALDO3_MASK BIT_MASK(7)
|
||||
|
||||
#define AXP313A_DCDC1_NUM_VOLTAGES 107
|
||||
#define AXP313A_DCDC23_NUM_VOLTAGES 88
|
||||
#define AXP313A_DCDC_V_OUT_MASK GENMASK(6, 0)
|
||||
#define AXP313A_LDO_V_OUT_MASK GENMASK(4, 0)
|
||||
|
||||
#define AXP803_PWR_OUT_DCDC1_MASK BIT_MASK(0)
|
||||
#define AXP803_PWR_OUT_DCDC2_MASK BIT_MASK(1)
|
||||
#define AXP803_PWR_OUT_DCDC3_MASK BIT_MASK(2)
|
||||
@@ -270,6 +275,74 @@
|
||||
|
||||
#define AXP813_PWR_OUT_DCDC7_MASK BIT_MASK(6)
|
||||
|
||||
#define AXP15060_DCDC1_V_CTRL_MASK GENMASK(4, 0)
|
||||
#define AXP15060_DCDC2_V_CTRL_MASK GENMASK(6, 0)
|
||||
#define AXP15060_DCDC3_V_CTRL_MASK GENMASK(6, 0)
|
||||
#define AXP15060_DCDC4_V_CTRL_MASK GENMASK(6, 0)
|
||||
#define AXP15060_DCDC5_V_CTRL_MASK GENMASK(6, 0)
|
||||
#define AXP15060_DCDC6_V_CTRL_MASK GENMASK(4, 0)
|
||||
#define AXP15060_ALDO1_V_CTRL_MASK GENMASK(4, 0)
|
||||
#define AXP15060_ALDO2_V_CTRL_MASK GENMASK(4, 0)
|
||||
#define AXP15060_ALDO3_V_CTRL_MASK GENMASK(4, 0)
|
||||
#define AXP15060_ALDO4_V_CTRL_MASK GENMASK(4, 0)
|
||||
#define AXP15060_ALDO5_V_CTRL_MASK GENMASK(4, 0)
|
||||
#define AXP15060_BLDO1_V_CTRL_MASK GENMASK(4, 0)
|
||||
#define AXP15060_BLDO2_V_CTRL_MASK GENMASK(4, 0)
|
||||
#define AXP15060_BLDO3_V_CTRL_MASK GENMASK(4, 0)
|
||||
#define AXP15060_BLDO4_V_CTRL_MASK GENMASK(4, 0)
|
||||
#define AXP15060_BLDO5_V_CTRL_MASK GENMASK(4, 0)
|
||||
#define AXP15060_CLDO1_V_CTRL_MASK GENMASK(4, 0)
|
||||
#define AXP15060_CLDO2_V_CTRL_MASK GENMASK(4, 0)
|
||||
#define AXP15060_CLDO3_V_CTRL_MASK GENMASK(4, 0)
|
||||
#define AXP15060_CLDO4_V_CTRL_MASK GENMASK(5, 0)
|
||||
#define AXP15060_CPUSLDO_V_CTRL_MASK GENMASK(3, 0)
|
||||
|
||||
#define AXP15060_PWR_OUT_DCDC1_MASK BIT_MASK(0)
|
||||
#define AXP15060_PWR_OUT_DCDC2_MASK BIT_MASK(1)
|
||||
#define AXP15060_PWR_OUT_DCDC3_MASK BIT_MASK(2)
|
||||
#define AXP15060_PWR_OUT_DCDC4_MASK BIT_MASK(3)
|
||||
#define AXP15060_PWR_OUT_DCDC5_MASK BIT_MASK(4)
|
||||
#define AXP15060_PWR_OUT_DCDC6_MASK BIT_MASK(5)
|
||||
#define AXP15060_PWR_OUT_ALDO1_MASK BIT_MASK(0)
|
||||
#define AXP15060_PWR_OUT_ALDO2_MASK BIT_MASK(1)
|
||||
#define AXP15060_PWR_OUT_ALDO3_MASK BIT_MASK(2)
|
||||
#define AXP15060_PWR_OUT_ALDO4_MASK BIT_MASK(3)
|
||||
#define AXP15060_PWR_OUT_ALDO5_MASK BIT_MASK(4)
|
||||
#define AXP15060_PWR_OUT_BLDO1_MASK BIT_MASK(5)
|
||||
#define AXP15060_PWR_OUT_BLDO2_MASK BIT_MASK(6)
|
||||
#define AXP15060_PWR_OUT_BLDO3_MASK BIT_MASK(7)
|
||||
#define AXP15060_PWR_OUT_BLDO4_MASK BIT_MASK(0)
|
||||
#define AXP15060_PWR_OUT_BLDO5_MASK BIT_MASK(1)
|
||||
#define AXP15060_PWR_OUT_CLDO1_MASK BIT_MASK(2)
|
||||
#define AXP15060_PWR_OUT_CLDO2_MASK BIT_MASK(3)
|
||||
#define AXP15060_PWR_OUT_CLDO3_MASK BIT_MASK(4)
|
||||
#define AXP15060_PWR_OUT_CLDO4_MASK BIT_MASK(5)
|
||||
#define AXP15060_PWR_OUT_CPUSLDO_MASK BIT_MASK(6)
|
||||
#define AXP15060_PWR_OUT_SW_MASK BIT_MASK(7)
|
||||
|
||||
#define AXP15060_DCDC23_POLYPHASE_DUAL_MASK BIT_MASK(6)
|
||||
#define AXP15060_DCDC46_POLYPHASE_DUAL_MASK BIT_MASK(7)
|
||||
|
||||
#define AXP15060_DCDC234_500mV_START 0x00
|
||||
#define AXP15060_DCDC234_500mV_STEPS 70
|
||||
#define AXP15060_DCDC234_500mV_END \
|
||||
(AXP15060_DCDC234_500mV_START + AXP15060_DCDC234_500mV_STEPS)
|
||||
#define AXP15060_DCDC234_1220mV_START 0x47
|
||||
#define AXP15060_DCDC234_1220mV_STEPS 16
|
||||
#define AXP15060_DCDC234_1220mV_END \
|
||||
(AXP15060_DCDC234_1220mV_START + AXP15060_DCDC234_1220mV_STEPS)
|
||||
#define AXP15060_DCDC234_NUM_VOLTAGES 88
|
||||
|
||||
#define AXP15060_DCDC5_800mV_START 0x00
|
||||
#define AXP15060_DCDC5_800mV_STEPS 32
|
||||
#define AXP15060_DCDC5_800mV_END \
|
||||
(AXP15060_DCDC5_800mV_START + AXP15060_DCDC5_800mV_STEPS)
|
||||
#define AXP15060_DCDC5_1140mV_START 0x21
|
||||
#define AXP15060_DCDC5_1140mV_STEPS 35
|
||||
#define AXP15060_DCDC5_1140mV_END \
|
||||
(AXP15060_DCDC5_1140mV_START + AXP15060_DCDC5_1140mV_STEPS)
|
||||
#define AXP15060_DCDC5_NUM_VOLTAGES 69
|
||||
|
||||
#define AXP_DESC_IO(_family, _id, _match, _supply, _min, _max, _step, _vreg, \
|
||||
_vmask, _ereg, _emask, _enable_val, _disable_val) \
|
||||
[_family##_##_id] = { \
|
||||
@@ -638,6 +711,48 @@ static const struct regulator_desc axp22x_drivevbus_regulator = {
|
||||
.ops = &axp20x_ops_sw,
|
||||
};
|
||||
|
||||
static const struct linear_range axp313a_dcdc1_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 0, 70, 10000),
|
||||
REGULATOR_LINEAR_RANGE(1220000, 71, 87, 20000),
|
||||
REGULATOR_LINEAR_RANGE(1600000, 88, 106, 100000),
|
||||
};
|
||||
|
||||
static const struct linear_range axp313a_dcdc2_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 0, 70, 10000),
|
||||
REGULATOR_LINEAR_RANGE(1220000, 71, 87, 20000),
|
||||
};
|
||||
|
||||
/*
|
||||
* This is deviating from the datasheet. The values here are taken from the
|
||||
* BSP driver and have been confirmed by measurements.
|
||||
*/
|
||||
static const struct linear_range axp313a_dcdc3_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 0, 70, 10000),
|
||||
REGULATOR_LINEAR_RANGE(1220000, 71, 102, 20000),
|
||||
};
|
||||
|
||||
static const struct regulator_desc axp313a_regulators[] = {
|
||||
AXP_DESC_RANGES(AXP313A, DCDC1, "dcdc1", "vin1",
|
||||
axp313a_dcdc1_ranges, AXP313A_DCDC1_NUM_VOLTAGES,
|
||||
AXP313A_DCDC1_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
|
||||
AXP313A_OUTPUT_CONTROL, BIT(0)),
|
||||
AXP_DESC_RANGES(AXP313A, DCDC2, "dcdc2", "vin2",
|
||||
axp313a_dcdc2_ranges, AXP313A_DCDC23_NUM_VOLTAGES,
|
||||
AXP313A_DCDC2_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
|
||||
AXP313A_OUTPUT_CONTROL, BIT(1)),
|
||||
AXP_DESC_RANGES(AXP313A, DCDC3, "dcdc3", "vin3",
|
||||
axp313a_dcdc3_ranges, AXP313A_DCDC23_NUM_VOLTAGES,
|
||||
AXP313A_DCDC3_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
|
||||
AXP313A_OUTPUT_CONTROL, BIT(2)),
|
||||
AXP_DESC(AXP313A, ALDO1, "aldo1", "vin1", 500, 3500, 100,
|
||||
AXP313A_ALDO1_CONRTOL, AXP313A_LDO_V_OUT_MASK,
|
||||
AXP313A_OUTPUT_CONTROL, BIT(3)),
|
||||
AXP_DESC(AXP313A, DLDO1, "dldo1", "vin1", 500, 3500, 100,
|
||||
AXP313A_DLDO1_CONRTOL, AXP313A_LDO_V_OUT_MASK,
|
||||
AXP313A_OUTPUT_CONTROL, BIT(4)),
|
||||
AXP_DESC_FIXED(AXP313A, RTC_LDO, "rtc-ldo", "vin1", 1800),
|
||||
};
|
||||
|
||||
/* DCDC ranges shared with AXP813 */
|
||||
static const struct linear_range axp803_dcdc234_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000,
|
||||
@@ -1001,6 +1116,104 @@ static const struct regulator_desc axp813_regulators[] = {
|
||||
AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DC1SW_MASK),
|
||||
};
|
||||
|
||||
static const struct linear_range axp15060_dcdc234_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000,
|
||||
AXP15060_DCDC234_500mV_START,
|
||||
AXP15060_DCDC234_500mV_END,
|
||||
10000),
|
||||
REGULATOR_LINEAR_RANGE(1220000,
|
||||
AXP15060_DCDC234_1220mV_START,
|
||||
AXP15060_DCDC234_1220mV_END,
|
||||
20000),
|
||||
};
|
||||
|
||||
static const struct linear_range axp15060_dcdc5_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(800000,
|
||||
AXP15060_DCDC5_800mV_START,
|
||||
AXP15060_DCDC5_800mV_END,
|
||||
10000),
|
||||
REGULATOR_LINEAR_RANGE(1140000,
|
||||
AXP15060_DCDC5_1140mV_START,
|
||||
AXP15060_DCDC5_1140mV_END,
|
||||
20000),
|
||||
};
|
||||
|
||||
static const struct regulator_desc axp15060_regulators[] = {
|
||||
AXP_DESC(AXP15060, DCDC1, "dcdc1", "vin1", 1500, 3400, 100,
|
||||
AXP15060_DCDC1_V_CTRL, AXP15060_DCDC1_V_CTRL_MASK,
|
||||
AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC1_MASK),
|
||||
AXP_DESC_RANGES(AXP15060, DCDC2, "dcdc2", "vin2",
|
||||
axp15060_dcdc234_ranges, AXP15060_DCDC234_NUM_VOLTAGES,
|
||||
AXP15060_DCDC2_V_CTRL, AXP15060_DCDC2_V_CTRL_MASK,
|
||||
AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC2_MASK),
|
||||
AXP_DESC_RANGES(AXP15060, DCDC3, "dcdc3", "vin3",
|
||||
axp15060_dcdc234_ranges, AXP15060_DCDC234_NUM_VOLTAGES,
|
||||
AXP15060_DCDC3_V_CTRL, AXP15060_DCDC3_V_CTRL_MASK,
|
||||
AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC3_MASK),
|
||||
AXP_DESC_RANGES(AXP15060, DCDC4, "dcdc4", "vin4",
|
||||
axp15060_dcdc234_ranges, AXP15060_DCDC234_NUM_VOLTAGES,
|
||||
AXP15060_DCDC4_V_CTRL, AXP15060_DCDC4_V_CTRL_MASK,
|
||||
AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC4_MASK),
|
||||
AXP_DESC_RANGES(AXP15060, DCDC5, "dcdc5", "vin5",
|
||||
axp15060_dcdc5_ranges, AXP15060_DCDC5_NUM_VOLTAGES,
|
||||
AXP15060_DCDC5_V_CTRL, AXP15060_DCDC5_V_CTRL_MASK,
|
||||
AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC5_MASK),
|
||||
AXP_DESC(AXP15060, DCDC6, "dcdc6", "vin6", 500, 3400, 100,
|
||||
AXP15060_DCDC6_V_CTRL, AXP15060_DCDC6_V_CTRL_MASK,
|
||||
AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC6_MASK),
|
||||
AXP_DESC(AXP15060, ALDO1, "aldo1", "aldoin", 700, 3300, 100,
|
||||
AXP15060_ALDO1_V_CTRL, AXP15060_ALDO1_V_CTRL_MASK,
|
||||
AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_ALDO1_MASK),
|
||||
AXP_DESC(AXP15060, ALDO2, "aldo2", "aldoin", 700, 3300, 100,
|
||||
AXP15060_ALDO2_V_CTRL, AXP15060_ALDO2_V_CTRL_MASK,
|
||||
AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_ALDO2_MASK),
|
||||
AXP_DESC(AXP15060, ALDO3, "aldo3", "aldoin", 700, 3300, 100,
|
||||
AXP15060_ALDO3_V_CTRL, AXP15060_ALDO3_V_CTRL_MASK,
|
||||
AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_ALDO3_MASK),
|
||||
AXP_DESC(AXP15060, ALDO4, "aldo4", "aldoin", 700, 3300, 100,
|
||||
AXP15060_ALDO4_V_CTRL, AXP15060_ALDO4_V_CTRL_MASK,
|
||||
AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_ALDO4_MASK),
|
||||
AXP_DESC(AXP15060, ALDO5, "aldo5", "aldoin", 700, 3300, 100,
|
||||
AXP15060_ALDO5_V_CTRL, AXP15060_ALDO5_V_CTRL_MASK,
|
||||
AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_ALDO5_MASK),
|
||||
AXP_DESC(AXP15060, BLDO1, "bldo1", "bldoin", 700, 3300, 100,
|
||||
AXP15060_BLDO1_V_CTRL, AXP15060_BLDO1_V_CTRL_MASK,
|
||||
AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_BLDO1_MASK),
|
||||
AXP_DESC(AXP15060, BLDO2, "bldo2", "bldoin", 700, 3300, 100,
|
||||
AXP15060_BLDO2_V_CTRL, AXP15060_BLDO2_V_CTRL_MASK,
|
||||
AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_BLDO2_MASK),
|
||||
AXP_DESC(AXP15060, BLDO3, "bldo3", "bldoin", 700, 3300, 100,
|
||||
AXP15060_BLDO3_V_CTRL, AXP15060_BLDO3_V_CTRL_MASK,
|
||||
AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_BLDO3_MASK),
|
||||
AXP_DESC(AXP15060, BLDO4, "bldo4", "bldoin", 700, 3300, 100,
|
||||
AXP15060_BLDO4_V_CTRL, AXP15060_BLDO4_V_CTRL_MASK,
|
||||
AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_BLDO4_MASK),
|
||||
AXP_DESC(AXP15060, BLDO5, "bldo5", "bldoin", 700, 3300, 100,
|
||||
AXP15060_BLDO5_V_CTRL, AXP15060_BLDO5_V_CTRL_MASK,
|
||||
AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_BLDO5_MASK),
|
||||
AXP_DESC(AXP15060, CLDO1, "cldo1", "cldoin", 700, 3300, 100,
|
||||
AXP15060_CLDO1_V_CTRL, AXP15060_CLDO1_V_CTRL_MASK,
|
||||
AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_CLDO1_MASK),
|
||||
AXP_DESC(AXP15060, CLDO2, "cldo2", "cldoin", 700, 3300, 100,
|
||||
AXP15060_CLDO2_V_CTRL, AXP15060_CLDO2_V_CTRL_MASK,
|
||||
AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_CLDO2_MASK),
|
||||
AXP_DESC(AXP15060, CLDO3, "cldo3", "cldoin", 700, 3300, 100,
|
||||
AXP15060_CLDO3_V_CTRL, AXP15060_CLDO3_V_CTRL_MASK,
|
||||
AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_CLDO3_MASK),
|
||||
AXP_DESC(AXP15060, CLDO4, "cldo4", "cldoin", 700, 4200, 100,
|
||||
AXP15060_CLDO4_V_CTRL, AXP15060_CLDO4_V_CTRL_MASK,
|
||||
AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_CLDO4_MASK),
|
||||
/* Supply comes from DCDC5 */
|
||||
AXP_DESC(AXP15060, CPUSLDO, "cpusldo", NULL, 700, 1400, 50,
|
||||
AXP15060_CPUSLDO_V_CTRL, AXP15060_CPUSLDO_V_CTRL_MASK,
|
||||
AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_CPUSLDO_MASK),
|
||||
/* Supply comes from DCDC1 */
|
||||
AXP_DESC_SW(AXP15060, SW, "sw", NULL,
|
||||
AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_SW_MASK),
|
||||
/* Supply comes from ALDO1 */
|
||||
AXP_DESC_FIXED(AXP15060, RTC_LDO, "rtc-ldo", NULL, 1800),
|
||||
};
|
||||
|
||||
static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
|
||||
{
|
||||
struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
|
||||
@@ -1040,6 +1253,16 @@ static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
|
||||
def = 3000;
|
||||
step = 150;
|
||||
break;
|
||||
case AXP313A_ID:
|
||||
case AXP15060_ID:
|
||||
/* The DCDC PWM frequency seems to be fixed to 3 MHz. */
|
||||
if (dcdcfreq != 0) {
|
||||
dev_err(&pdev->dev,
|
||||
"DCDC frequency on this PMIC is fixed to 3 MHz.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
default:
|
||||
dev_err(&pdev->dev,
|
||||
"Setting DCDC frequency for unsupported AXP variant\n");
|
||||
@@ -1145,6 +1368,15 @@ static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 work
|
||||
workmode <<= id - AXP813_DCDC1;
|
||||
break;
|
||||
|
||||
case AXP15060_ID:
|
||||
reg = AXP15060_DCDC_MODE_CTRL2;
|
||||
if (id < AXP15060_DCDC1 || id > AXP15060_DCDC6)
|
||||
return -EINVAL;
|
||||
|
||||
mask = AXP22X_WORKMODE_DCDCX_MASK(id - AXP15060_DCDC1);
|
||||
workmode <<= id - AXP15060_DCDC1;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* should not happen */
|
||||
WARN_ON(1);
|
||||
@@ -1164,7 +1396,7 @@ static bool axp20x_is_polyphase_slave(struct axp20x_dev *axp20x, int id)
|
||||
|
||||
/*
|
||||
* Currently in our supported AXP variants, only AXP803, AXP806,
|
||||
* and AXP813 have polyphase regulators.
|
||||
* AXP813 and AXP15060 have polyphase regulators.
|
||||
*/
|
||||
switch (axp20x->variant) {
|
||||
case AXP803_ID:
|
||||
@@ -1196,6 +1428,17 @@ static bool axp20x_is_polyphase_slave(struct axp20x_dev *axp20x, int id)
|
||||
}
|
||||
break;
|
||||
|
||||
case AXP15060_ID:
|
||||
regmap_read(axp20x->regmap, AXP15060_DCDC_MODE_CTRL1, ®);
|
||||
|
||||
switch (id) {
|
||||
case AXP15060_DCDC3:
|
||||
return !!(reg & AXP15060_DCDC23_POLYPHASE_DUAL_MASK);
|
||||
case AXP15060_DCDC6:
|
||||
return !!(reg & AXP15060_DCDC46_POLYPHASE_DUAL_MASK);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -1217,6 +1460,7 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
|
||||
u32 workmode;
|
||||
const char *dcdc1_name = axp22x_regulators[AXP22X_DCDC1].name;
|
||||
const char *dcdc5_name = axp22x_regulators[AXP22X_DCDC5].name;
|
||||
const char *aldo1_name = axp15060_regulators[AXP15060_ALDO1].name;
|
||||
bool drivevbus = false;
|
||||
|
||||
switch (axp20x->variant) {
|
||||
@@ -1232,6 +1476,10 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
|
||||
drivevbus = of_property_read_bool(pdev->dev.parent->of_node,
|
||||
"x-powers,drive-vbus-en");
|
||||
break;
|
||||
case AXP313A_ID:
|
||||
regulators = axp313a_regulators;
|
||||
nregulators = AXP313A_REG_ID_MAX;
|
||||
break;
|
||||
case AXP803_ID:
|
||||
regulators = axp803_regulators;
|
||||
nregulators = AXP803_REG_ID_MAX;
|
||||
@@ -1252,6 +1500,10 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
|
||||
drivevbus = of_property_read_bool(pdev->dev.parent->of_node,
|
||||
"x-powers,drive-vbus-en");
|
||||
break;
|
||||
case AXP15060_ID:
|
||||
regulators = axp15060_regulators;
|
||||
nregulators = AXP15060_REG_ID_MAX;
|
||||
break;
|
||||
default:
|
||||
dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n",
|
||||
axp20x->variant);
|
||||
@@ -1278,8 +1530,9 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Regulators DC1SW and DC5LDO are connected internally,
|
||||
* so we have to handle their supply names separately.
|
||||
* Regulators DC1SW, DC5LDO and RTCLDO on AXP15060 are
|
||||
* connected internally, so we have to handle their supply
|
||||
* names separately.
|
||||
*
|
||||
* We always register the regulators in proper sequence,
|
||||
* so the supply names are correctly read. See the last
|
||||
@@ -1288,7 +1541,8 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
|
||||
*/
|
||||
if ((regulators == axp22x_regulators && i == AXP22X_DC1SW) ||
|
||||
(regulators == axp803_regulators && i == AXP803_DC1SW) ||
|
||||
(regulators == axp809_regulators && i == AXP809_DC1SW)) {
|
||||
(regulators == axp809_regulators && i == AXP809_DC1SW) ||
|
||||
(regulators == axp15060_regulators && i == AXP15060_SW)) {
|
||||
new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
|
||||
GFP_KERNEL);
|
||||
if (!new_desc)
|
||||
@@ -1300,7 +1554,8 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
if ((regulators == axp22x_regulators && i == AXP22X_DC5LDO) ||
|
||||
(regulators == axp809_regulators && i == AXP809_DC5LDO)) {
|
||||
(regulators == axp809_regulators && i == AXP809_DC5LDO) ||
|
||||
(regulators == axp15060_regulators && i == AXP15060_CPUSLDO)) {
|
||||
new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
|
||||
GFP_KERNEL);
|
||||
if (!new_desc)
|
||||
@@ -1311,6 +1566,18 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
|
||||
desc = new_desc;
|
||||
}
|
||||
|
||||
|
||||
if (regulators == axp15060_regulators && i == AXP15060_RTC_LDO) {
|
||||
new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
|
||||
GFP_KERNEL);
|
||||
if (!new_desc)
|
||||
return -ENOMEM;
|
||||
|
||||
*new_desc = regulators[i];
|
||||
new_desc->supply_name = aldo1_name;
|
||||
desc = new_desc;
|
||||
}
|
||||
|
||||
rdev = devm_regulator_register(&pdev->dev, desc, &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(&pdev->dev, "Failed to register %s\n",
|
||||
@@ -1329,19 +1596,26 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
/*
|
||||
* Save AXP22X DCDC1 / DCDC5 regulator names for later.
|
||||
* Save AXP22X DCDC1 / DCDC5 / AXP15060 ALDO1 regulator names for later.
|
||||
*/
|
||||
if ((regulators == axp22x_regulators && i == AXP22X_DCDC1) ||
|
||||
(regulators == axp809_regulators && i == AXP809_DCDC1))
|
||||
(regulators == axp809_regulators && i == AXP809_DCDC1) ||
|
||||
(regulators == axp15060_regulators && i == AXP15060_DCDC1))
|
||||
of_property_read_string(rdev->dev.of_node,
|
||||
"regulator-name",
|
||||
&dcdc1_name);
|
||||
|
||||
if ((regulators == axp22x_regulators && i == AXP22X_DCDC5) ||
|
||||
(regulators == axp809_regulators && i == AXP809_DCDC5))
|
||||
(regulators == axp809_regulators && i == AXP809_DCDC5) ||
|
||||
(regulators == axp15060_regulators && i == AXP15060_DCDC5))
|
||||
of_property_read_string(rdev->dev.of_node,
|
||||
"regulator-name",
|
||||
&dcdc5_name);
|
||||
|
||||
if (regulators == axp15060_regulators && i == AXP15060_ALDO1)
|
||||
of_property_read_string(rdev->dev.of_node,
|
||||
"regulator-name",
|
||||
&aldo1_name);
|
||||
}
|
||||
|
||||
if (drivevbus) {
|
||||
|
@@ -1911,19 +1911,17 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
|
||||
|
||||
if (err != -EEXIST)
|
||||
regulator->debugfs = debugfs_create_dir(supply_name, rdev->debugfs);
|
||||
if (!regulator->debugfs) {
|
||||
if (IS_ERR(regulator->debugfs))
|
||||
rdev_dbg(rdev, "Failed to create debugfs directory\n");
|
||||
} else {
|
||||
debugfs_create_u32("uA_load", 0444, regulator->debugfs,
|
||||
®ulator->uA_load);
|
||||
debugfs_create_u32("min_uV", 0444, regulator->debugfs,
|
||||
®ulator->voltage[PM_SUSPEND_ON].min_uV);
|
||||
debugfs_create_u32("max_uV", 0444, regulator->debugfs,
|
||||
®ulator->voltage[PM_SUSPEND_ON].max_uV);
|
||||
debugfs_create_file("constraint_flags", 0444,
|
||||
regulator->debugfs, regulator,
|
||||
&constraint_flags_fops);
|
||||
}
|
||||
|
||||
debugfs_create_u32("uA_load", 0444, regulator->debugfs,
|
||||
®ulator->uA_load);
|
||||
debugfs_create_u32("min_uV", 0444, regulator->debugfs,
|
||||
®ulator->voltage[PM_SUSPEND_ON].min_uV);
|
||||
debugfs_create_u32("max_uV", 0444, regulator->debugfs,
|
||||
®ulator->voltage[PM_SUSPEND_ON].max_uV);
|
||||
debugfs_create_file("constraint_flags", 0444, regulator->debugfs,
|
||||
regulator, &constraint_flags_fops);
|
||||
|
||||
/*
|
||||
* Check now if the regulator is an always on regulator - if
|
||||
@@ -5256,10 +5254,8 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)
|
||||
}
|
||||
|
||||
rdev->debugfs = debugfs_create_dir(rname, debugfs_root);
|
||||
if (IS_ERR(rdev->debugfs)) {
|
||||
rdev_warn(rdev, "Failed to create debugfs directory\n");
|
||||
return;
|
||||
}
|
||||
if (IS_ERR(rdev->debugfs))
|
||||
rdev_dbg(rdev, "Failed to create debugfs directory\n");
|
||||
|
||||
debugfs_create_u32("use_count", 0444, rdev->debugfs,
|
||||
&rdev->use_count);
|
||||
@@ -6179,7 +6175,7 @@ static int __init regulator_init(void)
|
||||
|
||||
debugfs_root = debugfs_create_dir("regulator", NULL);
|
||||
if (IS_ERR(debugfs_root))
|
||||
pr_warn("regulator: Failed to create debugfs directory\n");
|
||||
pr_debug("regulator: Failed to create debugfs directory\n");
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
debugfs_create_file("supply_map", 0444, debugfs_root, NULL,
|
||||
|
@@ -1197,7 +1197,7 @@ static struct i2c_driver da9121_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(da9121_dt_ids),
|
||||
},
|
||||
.probe_new = da9121_i2c_probe,
|
||||
.probe = da9121_i2c_probe,
|
||||
.remove = da9121_i2c_remove,
|
||||
.id_table = da9121_i2c_id,
|
||||
};
|
||||
|
@@ -224,7 +224,7 @@ static struct i2c_driver da9210_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(da9210_dt_ids),
|
||||
},
|
||||
.probe_new = da9210_i2c_probe,
|
||||
.probe = da9210_i2c_probe,
|
||||
.id_table = da9210_i2c_id,
|
||||
};
|
||||
|
||||
|
@@ -555,7 +555,7 @@ static struct i2c_driver da9211_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(da9211_dt_ids),
|
||||
},
|
||||
.probe_new = da9211_i2c_probe,
|
||||
.probe = da9211_i2c_probe,
|
||||
.id_table = da9211_i2c_id,
|
||||
};
|
||||
|
||||
|
@@ -775,7 +775,7 @@ static struct i2c_driver fan53555_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(fan53555_dt_ids),
|
||||
},
|
||||
.probe_new = fan53555_regulator_probe,
|
||||
.probe = fan53555_regulator_probe,
|
||||
.id_table = fan53555_id,
|
||||
};
|
||||
|
||||
|
@@ -175,7 +175,7 @@ static struct i2c_driver fan53880_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = fan53880_dt_ids,
|
||||
},
|
||||
.probe_new = fan53880_i2c_probe,
|
||||
.probe = fan53880_i2c_probe,
|
||||
.id_table = fan53880_i2c_id,
|
||||
};
|
||||
module_i2c_driver(fan53880_regulator_driver);
|
||||
|
@@ -902,8 +902,21 @@ bool regulator_is_equal(struct regulator *reg1, struct regulator *reg2)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_is_equal);
|
||||
|
||||
static int find_closest_bigger(unsigned int target, const unsigned int *table,
|
||||
unsigned int num_sel, unsigned int *sel)
|
||||
/**
|
||||
* regulator_find_closest_bigger - helper to find offset in ramp delay table
|
||||
*
|
||||
* @target: targeted ramp_delay
|
||||
* @table: table with supported ramp delays
|
||||
* @num_sel: number of entries in the table
|
||||
* @sel: Pointer to store table offset
|
||||
*
|
||||
* This is the internal helper used by regulator_set_ramp_delay_regmap to
|
||||
* map ramp delay to register value. It should only be used directly if
|
||||
* regulator_set_ramp_delay_regmap cannot handle a specific device setup
|
||||
* (e.g. because the value is split over multiple registers).
|
||||
*/
|
||||
int regulator_find_closest_bigger(unsigned int target, const unsigned int *table,
|
||||
unsigned int num_sel, unsigned int *sel)
|
||||
{
|
||||
unsigned int s, tmp, max, maxsel = 0;
|
||||
bool found = false;
|
||||
@@ -933,11 +946,13 @@ static int find_closest_bigger(unsigned int target, const unsigned int *table,
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_find_closest_bigger);
|
||||
|
||||
/**
|
||||
* regulator_set_ramp_delay_regmap - set_ramp_delay() helper
|
||||
*
|
||||
* @rdev: regulator to operate on
|
||||
* @ramp_delay: ramp-rate value given in units V/S (uV/uS)
|
||||
*
|
||||
* Regulators that use regmap for their register I/O can set the ramp_reg
|
||||
* and ramp_mask fields in their descriptor and then use this as their
|
||||
@@ -951,8 +966,8 @@ int regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay)
|
||||
if (WARN_ON(!rdev->desc->n_ramp_values || !rdev->desc->ramp_delay_table))
|
||||
return -EINVAL;
|
||||
|
||||
ret = find_closest_bigger(ramp_delay, rdev->desc->ramp_delay_table,
|
||||
rdev->desc->n_ramp_values, &sel);
|
||||
ret = regulator_find_closest_bigger(ramp_delay, rdev->desc->ramp_delay_table,
|
||||
rdev->desc->n_ramp_values, &sel);
|
||||
|
||||
if (ret) {
|
||||
dev_warn(rdev_get_dev(rdev),
|
||||
|
@@ -149,7 +149,7 @@ static struct i2c_driver isl6271a_i2c_driver = {
|
||||
.name = "isl6271a",
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
},
|
||||
.probe_new = isl6271a_probe,
|
||||
.probe = isl6271a_probe,
|
||||
.id_table = isl6271a_id,
|
||||
};
|
||||
|
||||
|
@@ -198,7 +198,7 @@ static struct i2c_driver isl9305_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(isl9305_dt_ids),
|
||||
},
|
||||
.probe_new = isl9305_i2c_probe,
|
||||
.probe = isl9305_i2c_probe,
|
||||
.id_table = isl9305_i2c_id,
|
||||
};
|
||||
|
||||
|
@@ -449,7 +449,7 @@ static struct i2c_driver lp3971_i2c_driver = {
|
||||
.name = "LP3971",
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
},
|
||||
.probe_new = lp3971_i2c_probe,
|
||||
.probe = lp3971_i2c_probe,
|
||||
.id_table = lp3971_i2c_id,
|
||||
};
|
||||
|
||||
|
@@ -547,7 +547,7 @@ static struct i2c_driver lp3972_i2c_driver = {
|
||||
.name = "lp3972",
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
},
|
||||
.probe_new = lp3972_i2c_probe,
|
||||
.probe = lp3972_i2c_probe,
|
||||
.id_table = lp3972_i2c_id,
|
||||
};
|
||||
|
||||
|
@@ -947,7 +947,7 @@ static struct i2c_driver lp872x_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(lp872x_dt_ids),
|
||||
},
|
||||
.probe_new = lp872x_probe,
|
||||
.probe = lp872x_probe,
|
||||
.id_table = lp872x_ids,
|
||||
};
|
||||
|
||||
|
@@ -442,7 +442,7 @@ static struct i2c_driver lp8755_i2c_driver = {
|
||||
.name = LP8755_NAME,
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
},
|
||||
.probe_new = lp8755_probe,
|
||||
.probe = lp8755_probe,
|
||||
.remove = lp8755_remove,
|
||||
.id_table = lp8755_id,
|
||||
};
|
||||
|
@@ -348,7 +348,7 @@ static const struct regmap_config ltc3589_regmap_config = {
|
||||
.num_reg_defaults = ARRAY_SIZE(ltc3589_reg_defaults),
|
||||
.use_single_read = true,
|
||||
.use_single_write = true,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.cache_type = REGCACHE_MAPLE,
|
||||
};
|
||||
|
||||
static irqreturn_t ltc3589_isr(int irq, void *dev_id)
|
||||
@@ -477,7 +477,7 @@ static struct i2c_driver ltc3589_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(ltc3589_of_match),
|
||||
},
|
||||
.probe_new = ltc3589_probe,
|
||||
.probe = ltc3589_probe,
|
||||
.id_table = ltc3589_i2c_id,
|
||||
};
|
||||
module_i2c_driver(ltc3589_driver);
|
||||
|
@@ -261,7 +261,7 @@ static const struct regmap_config ltc3676_regmap_config = {
|
||||
.max_register = LTC3676_CLIRQ,
|
||||
.use_single_read = true,
|
||||
.use_single_write = true,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.cache_type = REGCACHE_MAPLE,
|
||||
};
|
||||
|
||||
static irqreturn_t ltc3676_isr(int irq, void *dev_id)
|
||||
@@ -374,7 +374,7 @@ static struct i2c_driver ltc3676_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(ltc3676_of_match),
|
||||
},
|
||||
.probe_new = ltc3676_regulator_probe,
|
||||
.probe = ltc3676_regulator_probe,
|
||||
.id_table = ltc3676_i2c_id,
|
||||
};
|
||||
module_i2c_driver(ltc3676_driver);
|
||||
|
@@ -289,7 +289,7 @@ static const struct i2c_device_id max1586_id[] = {
|
||||
MODULE_DEVICE_TABLE(i2c, max1586_id);
|
||||
|
||||
static struct i2c_driver max1586_pmic_driver = {
|
||||
.probe_new = max1586_pmic_probe,
|
||||
.probe = max1586_pmic_probe,
|
||||
.driver = {
|
||||
.name = "max1586",
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
|
@@ -323,7 +323,7 @@ static struct i2c_driver max20086_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(max20086_dt_ids),
|
||||
},
|
||||
.probe_new = max20086_i2c_probe,
|
||||
.probe = max20086_i2c_probe,
|
||||
.id_table = max20086_i2c_id,
|
||||
};
|
||||
|
||||
|
@@ -156,7 +156,7 @@ static struct i2c_driver max20411_i2c_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_max20411_match_tbl,
|
||||
},
|
||||
.probe_new = max20411_probe,
|
||||
.probe = max20411_probe,
|
||||
.id_table = max20411_id,
|
||||
};
|
||||
module_i2c_driver(max20411_i2c_driver);
|
||||
|
@@ -292,7 +292,7 @@ static struct i2c_driver max77826_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(max77826_of_match),
|
||||
},
|
||||
.probe_new = max77826_i2c_probe,
|
||||
.probe = max77826_i2c_probe,
|
||||
.id_table = max77826_id,
|
||||
};
|
||||
module_i2c_driver(max77826_regulator_driver);
|
||||
|
@@ -246,7 +246,7 @@ static const struct i2c_device_id max8649_id[] = {
|
||||
MODULE_DEVICE_TABLE(i2c, max8649_id);
|
||||
|
||||
static struct i2c_driver max8649_driver = {
|
||||
.probe_new = max8649_regulator_probe,
|
||||
.probe = max8649_regulator_probe,
|
||||
.driver = {
|
||||
.name = "max8649",
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
|
@@ -503,7 +503,7 @@ static const struct i2c_device_id max8660_id[] = {
|
||||
MODULE_DEVICE_TABLE(i2c, max8660_id);
|
||||
|
||||
static struct i2c_driver max8660_driver = {
|
||||
.probe_new = max8660_probe,
|
||||
.probe = max8660_probe,
|
||||
.driver = {
|
||||
.name = "max8660",
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
|
@@ -168,7 +168,7 @@ static const struct i2c_device_id max8893_ids[] = {
|
||||
MODULE_DEVICE_TABLE(i2c, max8893_ids);
|
||||
|
||||
static struct i2c_driver max8893_driver = {
|
||||
.probe_new = max8893_probe_new,
|
||||
.probe = max8893_probe_new,
|
||||
.driver = {
|
||||
.name = "max8893",
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
|
@@ -313,7 +313,7 @@ static const struct i2c_device_id max8952_ids[] = {
|
||||
MODULE_DEVICE_TABLE(i2c, max8952_ids);
|
||||
|
||||
static struct i2c_driver max8952_pmic_driver = {
|
||||
.probe_new = max8952_pmic_probe,
|
||||
.probe = max8952_pmic_probe,
|
||||
.driver = {
|
||||
.name = "max8952",
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
|
@@ -807,7 +807,7 @@ static struct i2c_driver max8973_i2c_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_max8973_match_tbl,
|
||||
},
|
||||
.probe_new = max8973_probe,
|
||||
.probe = max8973_probe,
|
||||
.id_table = max8973_id,
|
||||
};
|
||||
|
||||
|
@@ -584,7 +584,7 @@ static const struct i2c_device_id mcp16502_i2c_id[] = {
|
||||
MODULE_DEVICE_TABLE(i2c, mcp16502_i2c_id);
|
||||
|
||||
static struct i2c_driver mcp16502_drv = {
|
||||
.probe_new = mcp16502_probe,
|
||||
.probe = mcp16502_probe,
|
||||
.driver = {
|
||||
.name = "mcp16502-regulator",
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
|
@@ -240,7 +240,7 @@ static struct i2c_driver mp5416_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(mp5416_of_match),
|
||||
},
|
||||
.probe_new = mp5416_i2c_probe,
|
||||
.probe = mp5416_i2c_probe,
|
||||
.id_table = mp5416_id,
|
||||
};
|
||||
module_i2c_driver(mp5416_regulator_driver);
|
||||
|
@@ -147,7 +147,7 @@ static struct i2c_driver mp8859_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(mp8859_dt_id),
|
||||
},
|
||||
.probe_new = mp8859_i2c_probe,
|
||||
.probe = mp8859_i2c_probe,
|
||||
.id_table = mp8859_i2c_id,
|
||||
};
|
||||
|
||||
|
@@ -365,7 +365,7 @@ static struct i2c_driver mp886x_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = mp886x_dt_ids,
|
||||
},
|
||||
.probe_new = mp886x_i2c_probe,
|
||||
.probe = mp886x_i2c_probe,
|
||||
.id_table = mp886x_id,
|
||||
};
|
||||
module_i2c_driver(mp886x_regulator_driver);
|
||||
|
@@ -321,7 +321,7 @@ static struct i2c_driver mpq7920_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(mpq7920_of_match),
|
||||
},
|
||||
.probe_new = mpq7920_i2c_probe,
|
||||
.probe = mpq7920_i2c_probe,
|
||||
.id_table = mpq7920_id,
|
||||
};
|
||||
module_i2c_driver(mpq7920_regulator_driver);
|
||||
|
@@ -154,7 +154,7 @@ static struct i2c_driver mt6311_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(mt6311_dt_ids),
|
||||
},
|
||||
.probe_new = mt6311_i2c_probe,
|
||||
.probe = mt6311_i2c_probe,
|
||||
.id_table = mt6311_i2c_id,
|
||||
};
|
||||
|
||||
|
@@ -34,8 +34,10 @@ struct mt6358_regulator_info {
|
||||
u32 modeset_mask;
|
||||
};
|
||||
|
||||
#define to_regulator_info(x) container_of((x), struct mt6358_regulator_info, desc)
|
||||
|
||||
#define MT6358_BUCK(match, vreg, min, max, step, \
|
||||
volt_ranges, vosel_mask, _da_vsel_reg, _da_vsel_mask, \
|
||||
vosel_mask, _da_vsel_reg, _da_vsel_mask, \
|
||||
_modeset_reg, _modeset_shift) \
|
||||
[MT6358_ID_##vreg] = { \
|
||||
.desc = { \
|
||||
@@ -46,8 +48,8 @@ struct mt6358_regulator_info {
|
||||
.id = MT6358_ID_##vreg, \
|
||||
.owner = THIS_MODULE, \
|
||||
.n_voltages = ((max) - (min)) / (step) + 1, \
|
||||
.linear_ranges = volt_ranges, \
|
||||
.n_linear_ranges = ARRAY_SIZE(volt_ranges), \
|
||||
.min_uV = (min), \
|
||||
.uV_step = (step), \
|
||||
.vsel_reg = MT6358_BUCK_##vreg##_ELR0, \
|
||||
.vsel_mask = vosel_mask, \
|
||||
.enable_reg = MT6358_BUCK_##vreg##_CON0, \
|
||||
@@ -87,7 +89,7 @@ struct mt6358_regulator_info {
|
||||
}
|
||||
|
||||
#define MT6358_LDO1(match, vreg, min, max, step, \
|
||||
volt_ranges, _da_vsel_reg, _da_vsel_mask, \
|
||||
_da_vsel_reg, _da_vsel_mask, \
|
||||
vosel, vosel_mask) \
|
||||
[MT6358_ID_##vreg] = { \
|
||||
.desc = { \
|
||||
@@ -98,8 +100,8 @@ struct mt6358_regulator_info {
|
||||
.id = MT6358_ID_##vreg, \
|
||||
.owner = THIS_MODULE, \
|
||||
.n_voltages = ((max) - (min)) / (step) + 1, \
|
||||
.linear_ranges = volt_ranges, \
|
||||
.n_linear_ranges = ARRAY_SIZE(volt_ranges), \
|
||||
.min_uV = (min), \
|
||||
.uV_step = (step), \
|
||||
.vsel_reg = vosel, \
|
||||
.vsel_mask = vosel_mask, \
|
||||
.enable_reg = MT6358_LDO_##vreg##_CON0, \
|
||||
@@ -131,7 +133,7 @@ struct mt6358_regulator_info {
|
||||
}
|
||||
|
||||
#define MT6366_BUCK(match, vreg, min, max, step, \
|
||||
volt_ranges, vosel_mask, _da_vsel_reg, _da_vsel_mask, \
|
||||
vosel_mask, _da_vsel_reg, _da_vsel_mask, \
|
||||
_modeset_reg, _modeset_shift) \
|
||||
[MT6366_ID_##vreg] = { \
|
||||
.desc = { \
|
||||
@@ -142,8 +144,8 @@ struct mt6358_regulator_info {
|
||||
.id = MT6366_ID_##vreg, \
|
||||
.owner = THIS_MODULE, \
|
||||
.n_voltages = ((max) - (min)) / (step) + 1, \
|
||||
.linear_ranges = volt_ranges, \
|
||||
.n_linear_ranges = ARRAY_SIZE(volt_ranges), \
|
||||
.min_uV = (min), \
|
||||
.uV_step = (step), \
|
||||
.vsel_reg = MT6358_BUCK_##vreg##_ELR0, \
|
||||
.vsel_mask = vosel_mask, \
|
||||
.enable_reg = MT6358_BUCK_##vreg##_CON0, \
|
||||
@@ -183,7 +185,7 @@ struct mt6358_regulator_info {
|
||||
}
|
||||
|
||||
#define MT6366_LDO1(match, vreg, min, max, step, \
|
||||
volt_ranges, _da_vsel_reg, _da_vsel_mask, \
|
||||
_da_vsel_reg, _da_vsel_mask, \
|
||||
vosel, vosel_mask) \
|
||||
[MT6366_ID_##vreg] = { \
|
||||
.desc = { \
|
||||
@@ -194,8 +196,8 @@ struct mt6358_regulator_info {
|
||||
.id = MT6366_ID_##vreg, \
|
||||
.owner = THIS_MODULE, \
|
||||
.n_voltages = ((max) - (min)) / (step) + 1, \
|
||||
.linear_ranges = volt_ranges, \
|
||||
.n_linear_ranges = ARRAY_SIZE(volt_ranges), \
|
||||
.min_uV = (min), \
|
||||
.uV_step = (step), \
|
||||
.vsel_reg = vosel, \
|
||||
.vsel_mask = vosel_mask, \
|
||||
.enable_reg = MT6358_LDO_##vreg##_CON0, \
|
||||
@@ -226,21 +228,6 @@ struct mt6358_regulator_info {
|
||||
.qi = BIT(15), \
|
||||
}
|
||||
|
||||
static const struct linear_range buck_volt_range1[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 6250),
|
||||
};
|
||||
|
||||
static const struct linear_range buck_volt_range2[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 12500),
|
||||
};
|
||||
|
||||
static const struct linear_range buck_volt_range3[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 0, 0x3f, 50000),
|
||||
};
|
||||
|
||||
static const struct linear_range buck_volt_range4[] = {
|
||||
REGULATOR_LINEAR_RANGE(1000000, 0, 0x7f, 12500),
|
||||
};
|
||||
|
||||
static const unsigned int vdram2_voltages[] = {
|
||||
600000, 1800000,
|
||||
@@ -277,7 +264,7 @@ static const unsigned int vcama_voltages[] = {
|
||||
2800000, 2900000, 3000000,
|
||||
};
|
||||
|
||||
static const unsigned int vcn33_bt_wifi_voltages[] = {
|
||||
static const unsigned int vcn33_voltages[] = {
|
||||
3300000, 3400000, 3500000,
|
||||
};
|
||||
|
||||
@@ -321,7 +308,7 @@ static const u32 vcama_idx[] = {
|
||||
0, 7, 9, 10, 11, 12,
|
||||
};
|
||||
|
||||
static const u32 vcn33_bt_wifi_idx[] = {
|
||||
static const u32 vcn33_idx[] = {
|
||||
1, 2, 3,
|
||||
};
|
||||
|
||||
@@ -342,9 +329,9 @@ static unsigned int mt6358_map_mode(unsigned int mode)
|
||||
static int mt6358_set_voltage_sel(struct regulator_dev *rdev,
|
||||
unsigned int selector)
|
||||
{
|
||||
const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
|
||||
int idx, ret;
|
||||
const u32 *pvol;
|
||||
struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
|
||||
pvol = info->index_table;
|
||||
|
||||
@@ -358,9 +345,9 @@ static int mt6358_set_voltage_sel(struct regulator_dev *rdev,
|
||||
|
||||
static int mt6358_get_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
|
||||
int idx, ret;
|
||||
u32 selector;
|
||||
struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
const u32 *pvol;
|
||||
|
||||
ret = regmap_read(rdev->regmap, info->desc.vsel_reg, &selector);
|
||||
@@ -384,8 +371,8 @@ static int mt6358_get_voltage_sel(struct regulator_dev *rdev)
|
||||
|
||||
static int mt6358_get_buck_voltage_sel(struct regulator_dev *rdev)
|
||||
{
|
||||
const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
|
||||
int ret, regval;
|
||||
struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
|
||||
ret = regmap_read(rdev->regmap, info->da_vsel_reg, ®val);
|
||||
if (ret != 0) {
|
||||
@@ -402,9 +389,9 @@ static int mt6358_get_buck_voltage_sel(struct regulator_dev *rdev)
|
||||
|
||||
static int mt6358_get_status(struct regulator_dev *rdev)
|
||||
{
|
||||
const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
|
||||
int ret;
|
||||
u32 regval;
|
||||
struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
|
||||
ret = regmap_read(rdev->regmap, info->status_reg, ®val);
|
||||
if (ret != 0) {
|
||||
@@ -418,7 +405,7 @@ static int mt6358_get_status(struct regulator_dev *rdev)
|
||||
static int mt6358_regulator_set_mode(struct regulator_dev *rdev,
|
||||
unsigned int mode)
|
||||
{
|
||||
struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
|
||||
int val;
|
||||
|
||||
switch (mode) {
|
||||
@@ -443,7 +430,7 @@ static int mt6358_regulator_set_mode(struct regulator_dev *rdev,
|
||||
|
||||
static unsigned int mt6358_regulator_get_mode(struct regulator_dev *rdev)
|
||||
{
|
||||
struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
const struct mt6358_regulator_info *info = to_regulator_info(rdev->desc);
|
||||
int ret, regval;
|
||||
|
||||
ret = regmap_read(rdev->regmap, info->modeset_reg, ®val);
|
||||
@@ -464,8 +451,8 @@ static unsigned int mt6358_regulator_get_mode(struct regulator_dev *rdev)
|
||||
}
|
||||
|
||||
static const struct regulator_ops mt6358_volt_range_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 = mt6358_get_buck_voltage_sel,
|
||||
.set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||
@@ -498,37 +485,25 @@ static const struct regulator_ops mt6358_volt_fixed_ops = {
|
||||
};
|
||||
|
||||
/* The array is indexed by id(MT6358_ID_XXX) */
|
||||
static struct mt6358_regulator_info mt6358_regulators[] = {
|
||||
static const struct mt6358_regulator_info mt6358_regulators[] = {
|
||||
MT6358_BUCK("buck_vdram1", VDRAM1, 500000, 2087500, 12500,
|
||||
buck_volt_range2, 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f,
|
||||
MT6358_VDRAM1_ANA_CON0, 8),
|
||||
0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f, MT6358_VDRAM1_ANA_CON0, 8),
|
||||
MT6358_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250,
|
||||
buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f,
|
||||
MT6358_VCORE_VGPU_ANA_CON0, 1),
|
||||
MT6358_BUCK("buck_vcore_sshub", VCORE_SSHUB, 500000, 1293750, 6250,
|
||||
buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_SSHUB_ELR0, 0x7f,
|
||||
MT6358_VCORE_VGPU_ANA_CON0, 1),
|
||||
0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 1),
|
||||
MT6358_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
|
||||
buck_volt_range3, 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f,
|
||||
MT6358_VPA_ANA_CON0, 3),
|
||||
0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, MT6358_VPA_ANA_CON0, 3),
|
||||
MT6358_BUCK("buck_vproc11", VPROC11, 500000, 1293750, 6250,
|
||||
buck_volt_range1, 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f,
|
||||
MT6358_VPROC_ANA_CON0, 1),
|
||||
0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 1),
|
||||
MT6358_BUCK("buck_vproc12", VPROC12, 500000, 1293750, 6250,
|
||||
buck_volt_range1, 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f,
|
||||
MT6358_VPROC_ANA_CON0, 2),
|
||||
0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 2),
|
||||
MT6358_BUCK("buck_vgpu", VGPU, 500000, 1293750, 6250,
|
||||
buck_volt_range1, 0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f,
|
||||
MT6358_VCORE_VGPU_ANA_CON0, 2),
|
||||
0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 2),
|
||||
MT6358_BUCK("buck_vs2", VS2, 500000, 2087500, 12500,
|
||||
buck_volt_range2, 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f,
|
||||
MT6358_VS2_ANA_CON0, 8),
|
||||
0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, MT6358_VS2_ANA_CON0, 8),
|
||||
MT6358_BUCK("buck_vmodem", VMODEM, 500000, 1293750, 6250,
|
||||
buck_volt_range1, 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f,
|
||||
MT6358_VMODEM_ANA_CON0, 8),
|
||||
0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f, MT6358_VMODEM_ANA_CON0, 8),
|
||||
MT6358_BUCK("buck_vs1", VS1, 1000000, 2587500, 12500,
|
||||
buck_volt_range4, 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f,
|
||||
MT6358_VS1_ANA_CON0, 8),
|
||||
0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, MT6358_VS1_ANA_CON0, 8),
|
||||
MT6358_REG_FIXED("ldo_vrf12", VRF12,
|
||||
MT6358_LDO_VRF12_CON0, 0, 1200000),
|
||||
MT6358_REG_FIXED("ldo_vio18", VIO18,
|
||||
@@ -566,12 +541,8 @@ static struct mt6358_regulator_info mt6358_regulators[] = {
|
||||
MT6358_LDO_VCAMA1_CON0, 0, MT6358_VCAMA1_ANA_CON0, 0xf00),
|
||||
MT6358_LDO("ldo_vemc", VEMC, vmch_vemc_voltages, vmch_vemc_idx,
|
||||
MT6358_LDO_VEMC_CON0, 0, MT6358_VEMC_ANA_CON0, 0x700),
|
||||
MT6358_LDO("ldo_vcn33_bt", VCN33_BT, vcn33_bt_wifi_voltages,
|
||||
vcn33_bt_wifi_idx, MT6358_LDO_VCN33_CON0_0,
|
||||
0, MT6358_VCN33_ANA_CON0, 0x300),
|
||||
MT6358_LDO("ldo_vcn33_wifi", VCN33_WIFI, vcn33_bt_wifi_voltages,
|
||||
vcn33_bt_wifi_idx, MT6358_LDO_VCN33_CON0_1,
|
||||
0, MT6358_VCN33_ANA_CON0, 0x300),
|
||||
MT6358_LDO("ldo_vcn33", VCN33, vcn33_voltages, vcn33_idx,
|
||||
MT6358_LDO_VCN33_CON0_0, 0, MT6358_VCN33_ANA_CON0, 0x300),
|
||||
MT6358_LDO("ldo_vcama2", VCAMA2, vcama_voltages, vcama_idx,
|
||||
MT6358_LDO_VCAMA2_CON0, 0, MT6358_VCAMA2_ANA_CON0, 0xf00),
|
||||
MT6358_LDO("ldo_vmc", VMC, vmc_voltages, vmc_idx,
|
||||
@@ -582,55 +553,35 @@ static struct mt6358_regulator_info mt6358_regulators[] = {
|
||||
MT6358_LDO("ldo_vsim2", VSIM2, vsim_voltages, vsim_idx,
|
||||
MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00),
|
||||
MT6358_LDO1("ldo_vsram_proc11", VSRAM_PROC11, 500000, 1293750, 6250,
|
||||
buck_volt_range1, MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00,
|
||||
MT6358_LDO_VSRAM_CON0, 0x7f),
|
||||
MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON0, 0x7f),
|
||||
MT6358_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250,
|
||||
buck_volt_range1, MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00,
|
||||
MT6358_LDO_VSRAM_CON2, 0x7f),
|
||||
MT6358_LDO1("ldo_vsram_others_sshub", VSRAM_OTHERS_SSHUB, 500000,
|
||||
1293750, 6250, buck_volt_range1,
|
||||
MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f,
|
||||
MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f),
|
||||
MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON2, 0x7f),
|
||||
MT6358_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250,
|
||||
buck_volt_range1, MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00,
|
||||
MT6358_LDO_VSRAM_CON3, 0x7f),
|
||||
MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON3, 0x7f),
|
||||
MT6358_LDO1("ldo_vsram_proc12", VSRAM_PROC12, 500000, 1293750, 6250,
|
||||
buck_volt_range1, MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00,
|
||||
MT6358_LDO_VSRAM_CON1, 0x7f),
|
||||
MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON1, 0x7f),
|
||||
};
|
||||
|
||||
/* The array is indexed by id(MT6366_ID_XXX) */
|
||||
static struct mt6358_regulator_info mt6366_regulators[] = {
|
||||
static const struct mt6358_regulator_info mt6366_regulators[] = {
|
||||
MT6366_BUCK("buck_vdram1", VDRAM1, 500000, 2087500, 12500,
|
||||
buck_volt_range2, 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f,
|
||||
MT6358_VDRAM1_ANA_CON0, 8),
|
||||
0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f, MT6358_VDRAM1_ANA_CON0, 8),
|
||||
MT6366_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250,
|
||||
buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f,
|
||||
MT6358_VCORE_VGPU_ANA_CON0, 1),
|
||||
MT6366_BUCK("buck_vcore_sshub", VCORE_SSHUB, 500000, 1293750, 6250,
|
||||
buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_SSHUB_ELR0, 0x7f,
|
||||
MT6358_VCORE_VGPU_ANA_CON0, 1),
|
||||
0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 1),
|
||||
MT6366_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
|
||||
buck_volt_range3, 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f,
|
||||
MT6358_VPA_ANA_CON0, 3),
|
||||
0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, MT6358_VPA_ANA_CON0, 3),
|
||||
MT6366_BUCK("buck_vproc11", VPROC11, 500000, 1293750, 6250,
|
||||
buck_volt_range1, 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f,
|
||||
MT6358_VPROC_ANA_CON0, 1),
|
||||
0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 1),
|
||||
MT6366_BUCK("buck_vproc12", VPROC12, 500000, 1293750, 6250,
|
||||
buck_volt_range1, 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f,
|
||||
MT6358_VPROC_ANA_CON0, 2),
|
||||
0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 2),
|
||||
MT6366_BUCK("buck_vgpu", VGPU, 500000, 1293750, 6250,
|
||||
buck_volt_range1, 0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f,
|
||||
MT6358_VCORE_VGPU_ANA_CON0, 2),
|
||||
0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 2),
|
||||
MT6366_BUCK("buck_vs2", VS2, 500000, 2087500, 12500,
|
||||
buck_volt_range2, 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f,
|
||||
MT6358_VS2_ANA_CON0, 8),
|
||||
0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, MT6358_VS2_ANA_CON0, 8),
|
||||
MT6366_BUCK("buck_vmodem", VMODEM, 500000, 1293750, 6250,
|
||||
buck_volt_range1, 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f,
|
||||
MT6358_VMODEM_ANA_CON0, 8),
|
||||
0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f, MT6358_VMODEM_ANA_CON0, 8),
|
||||
MT6366_BUCK("buck_vs1", VS1, 1000000, 2587500, 12500,
|
||||
buck_volt_range4, 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f,
|
||||
MT6358_VS1_ANA_CON0, 8),
|
||||
0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, MT6358_VS1_ANA_CON0, 8),
|
||||
MT6366_REG_FIXED("ldo_vrf12", VRF12,
|
||||
MT6358_LDO_VRF12_CON0, 0, 1200000),
|
||||
MT6366_REG_FIXED("ldo_vio18", VIO18,
|
||||
@@ -662,41 +613,72 @@ static struct mt6358_regulator_info mt6366_regulators[] = {
|
||||
MT6358_LDO_VMCH_CON0, 0, MT6358_VMCH_ANA_CON0, 0x700),
|
||||
MT6366_LDO("ldo_vemc", VEMC, vmch_vemc_voltages, vmch_vemc_idx,
|
||||
MT6358_LDO_VEMC_CON0, 0, MT6358_VEMC_ANA_CON0, 0x700),
|
||||
MT6366_LDO("ldo_vcn33_bt", VCN33_BT, vcn33_bt_wifi_voltages,
|
||||
vcn33_bt_wifi_idx, MT6358_LDO_VCN33_CON0_0,
|
||||
0, MT6358_VCN33_ANA_CON0, 0x300),
|
||||
MT6366_LDO("ldo_vcn33_wifi", VCN33_WIFI, vcn33_bt_wifi_voltages,
|
||||
vcn33_bt_wifi_idx, MT6358_LDO_VCN33_CON0_1,
|
||||
0, MT6358_VCN33_ANA_CON0, 0x300),
|
||||
MT6366_LDO("ldo_vcn33", VCN33, vcn33_voltages, vcn33_idx,
|
||||
MT6358_LDO_VCN33_CON0_0, 0, MT6358_VCN33_ANA_CON0, 0x300),
|
||||
MT6366_LDO("ldo_vmc", VMC, vmc_voltages, vmc_idx,
|
||||
MT6358_LDO_VMC_CON0, 0, MT6358_VMC_ANA_CON0, 0xf00),
|
||||
MT6366_LDO("ldo_vsim2", VSIM2, vsim_voltages, vsim_idx,
|
||||
MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00),
|
||||
MT6366_LDO1("ldo_vsram_proc11", VSRAM_PROC11, 500000, 1293750, 6250,
|
||||
buck_volt_range1, MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00,
|
||||
MT6358_LDO_VSRAM_CON0, 0x7f),
|
||||
MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON0, 0x7f),
|
||||
MT6366_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250,
|
||||
buck_volt_range1, MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00,
|
||||
MT6358_LDO_VSRAM_CON2, 0x7f),
|
||||
MT6366_LDO1("ldo_vsram_others_sshub", VSRAM_OTHERS_SSHUB, 500000,
|
||||
1293750, 6250, buck_volt_range1,
|
||||
MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f,
|
||||
MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f),
|
||||
MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON2, 0x7f),
|
||||
MT6366_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250,
|
||||
buck_volt_range1, MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00,
|
||||
MT6358_LDO_VSRAM_CON3, 0x7f),
|
||||
MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON3, 0x7f),
|
||||
MT6366_LDO1("ldo_vsram_proc12", VSRAM_PROC12, 500000, 1293750, 6250,
|
||||
buck_volt_range1, MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00,
|
||||
MT6358_LDO_VSRAM_CON1, 0x7f),
|
||||
MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON1, 0x7f),
|
||||
};
|
||||
|
||||
static int mt6358_sync_vcn33_setting(struct device *dev)
|
||||
{
|
||||
struct mt6397_chip *mt6397 = dev_get_drvdata(dev->parent);
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* VCN33_WIFI and VCN33_BT are two separate enable bits for the same
|
||||
* regulator. They share the same voltage setting and output pin.
|
||||
* Instead of having two potentially conflicting regulators, just have
|
||||
* one VCN33 regulator. Sync the two enable bits and only use one in
|
||||
* the regulator device.
|
||||
*/
|
||||
ret = regmap_read(mt6397->regmap, MT6358_LDO_VCN33_CON0_1, &val);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to read VCN33_WIFI setting\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!(val & BIT(0)))
|
||||
return 0;
|
||||
|
||||
/* Sync VCN33_WIFI enable status to VCN33_BT */
|
||||
ret = regmap_update_bits(mt6397->regmap, MT6358_LDO_VCN33_CON0_0, BIT(0), BIT(0));
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to sync VCN33_WIFI setting to VCN33_BT\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Disable VCN33_WIFI */
|
||||
ret = regmap_update_bits(mt6397->regmap, MT6358_LDO_VCN33_CON0_1, BIT(0), 0);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to disable VCN33_BT\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt6358_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent);
|
||||
struct regulator_config config = {};
|
||||
struct regulator_dev *rdev;
|
||||
struct mt6358_regulator_info *mt6358_info;
|
||||
int i, max_regulator;
|
||||
const struct mt6358_regulator_info *mt6358_info;
|
||||
int i, max_regulator, ret;
|
||||
|
||||
ret = mt6358_sync_vcn33_setting(&pdev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (mt6397->chip_id == MT6366_CHIP_ID) {
|
||||
max_regulator = MT6366_MAX_REGULATOR;
|
||||
@@ -708,7 +690,6 @@ static int mt6358_regulator_probe(struct platform_device *pdev)
|
||||
|
||||
for (i = 0; i < max_regulator; i++) {
|
||||
config.dev = &pdev->dev;
|
||||
config.driver_data = &mt6358_info[i];
|
||||
config.regmap = mt6397->regmap;
|
||||
|
||||
rdev = devm_regulator_register(&pdev->dev,
|
||||
|
@@ -875,7 +875,7 @@ static struct i2c_driver pca9450_i2c_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = pca9450_of_match,
|
||||
},
|
||||
.probe_new = pca9450_i2c_probe,
|
||||
.probe = pca9450_i2c_probe,
|
||||
};
|
||||
|
||||
module_i2c_driver(pca9450_i2c_driver);
|
||||
|
@@ -610,7 +610,7 @@ static struct i2c_driver pf8x00_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = pf8x00_dt_ids,
|
||||
},
|
||||
.probe_new = pf8x00_i2c_probe,
|
||||
.probe = pf8x00_i2c_probe,
|
||||
};
|
||||
module_i2c_driver(pf8x00_regulator_driver);
|
||||
|
||||
|
@@ -848,7 +848,7 @@ static struct i2c_driver pfuze_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = pfuze_dt_ids,
|
||||
},
|
||||
.probe_new = pfuze100_regulator_probe,
|
||||
.probe = pfuze100_regulator_probe,
|
||||
};
|
||||
module_i2c_driver(pfuze_driver);
|
||||
|
||||
|
@@ -379,7 +379,7 @@ static struct i2c_driver pv88060_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(pv88060_dt_ids),
|
||||
},
|
||||
.probe_new = pv88060_i2c_probe,
|
||||
.probe = pv88060_i2c_probe,
|
||||
.id_table = pv88060_i2c_id,
|
||||
};
|
||||
|
||||
|
@@ -560,7 +560,7 @@ static struct i2c_driver pv88080_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(pv88080_dt_ids),
|
||||
},
|
||||
.probe_new = pv88080_i2c_probe,
|
||||
.probe = pv88080_i2c_probe,
|
||||
.id_table = pv88080_i2c_id,
|
||||
};
|
||||
|
||||
|
@@ -400,7 +400,7 @@ static struct i2c_driver pv88090_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(pv88090_dt_ids),
|
||||
},
|
||||
.probe_new = pv88090_i2c_probe,
|
||||
.probe = pv88090_i2c_probe,
|
||||
.id_table = pv88090_i2c_id,
|
||||
};
|
||||
|
||||
|
190
drivers/regulator/raa215300.c
Normal file
190
drivers/regulator/raa215300.c
Normal file
@@ -0,0 +1,190 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Renesas RAA215300 PMIC driver
|
||||
//
|
||||
// Copyright (C) 2023 Renesas Electronics Corporation
|
||||
//
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define RAA215300_FAULT_LATCHED_STATUS_1 0x59
|
||||
#define RAA215300_FAULT_LATCHED_STATUS_2 0x5a
|
||||
#define RAA215300_FAULT_LATCHED_STATUS_3 0x5b
|
||||
#define RAA215300_FAULT_LATCHED_STATUS_4 0x5c
|
||||
#define RAA215300_FAULT_LATCHED_STATUS_6 0x5e
|
||||
|
||||
#define RAA215300_INT_MASK_1 0x64
|
||||
#define RAA215300_INT_MASK_2 0x65
|
||||
#define RAA215300_INT_MASK_3 0x66
|
||||
#define RAA215300_INT_MASK_4 0x67
|
||||
#define RAA215300_INT_MASK_6 0x68
|
||||
|
||||
#define RAA215300_REG_BLOCK_EN 0x6c
|
||||
#define RAA215300_HW_REV 0xf8
|
||||
|
||||
#define RAA215300_INT_MASK_1_ALL GENMASK(5, 0)
|
||||
#define RAA215300_INT_MASK_2_ALL GENMASK(3, 0)
|
||||
#define RAA215300_INT_MASK_3_ALL GENMASK(5, 0)
|
||||
#define RAA215300_INT_MASK_4_ALL BIT(0)
|
||||
#define RAA215300_INT_MASK_6_ALL GENMASK(7, 0)
|
||||
|
||||
#define RAA215300_REG_BLOCK_EN_RTC_EN BIT(6)
|
||||
#define RAA215300_RTC_DEFAULT_ADDR 0x6f
|
||||
|
||||
const char *clkin_name = "clkin";
|
||||
const char *xin_name = "xin";
|
||||
static struct clk *clk;
|
||||
|
||||
static const struct regmap_config raa215300_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = 0xff,
|
||||
};
|
||||
|
||||
static void raa215300_rtc_unregister_device(void *data)
|
||||
{
|
||||
i2c_unregister_device(data);
|
||||
if (!clk) {
|
||||
clk_unregister_fixed_rate(clk);
|
||||
clk = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int raa215300_clk_present(struct i2c_client *client, const char *name)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
||||
clk = devm_clk_get_optional(&client->dev, name);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
|
||||
return !!clk;
|
||||
}
|
||||
|
||||
static int raa215300_i2c_probe(struct i2c_client *client)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
const char *clk_name = xin_name;
|
||||
unsigned int pmic_version, val;
|
||||
struct regmap *regmap;
|
||||
int ret;
|
||||
|
||||
regmap = devm_regmap_init_i2c(client, &raa215300_regmap_config);
|
||||
if (IS_ERR(regmap))
|
||||
return dev_err_probe(dev, PTR_ERR(regmap),
|
||||
"regmap i2c init failed\n");
|
||||
|
||||
ret = regmap_read(regmap, RAA215300_HW_REV, &pmic_version);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(dev, ret, "HW rev read failed\n");
|
||||
|
||||
dev_dbg(dev, "RAA215300 PMIC version 0x%04x\n", pmic_version);
|
||||
|
||||
/* Clear all blocks except RTC, if enabled */
|
||||
regmap_read(regmap, RAA215300_REG_BLOCK_EN, &val);
|
||||
val &= RAA215300_REG_BLOCK_EN_RTC_EN;
|
||||
regmap_write(regmap, RAA215300_REG_BLOCK_EN, val);
|
||||
|
||||
/*Clear the latched registers */
|
||||
regmap_read(regmap, RAA215300_FAULT_LATCHED_STATUS_1, &val);
|
||||
regmap_write(regmap, RAA215300_FAULT_LATCHED_STATUS_1, val);
|
||||
regmap_read(regmap, RAA215300_FAULT_LATCHED_STATUS_2, &val);
|
||||
regmap_write(regmap, RAA215300_FAULT_LATCHED_STATUS_2, val);
|
||||
regmap_read(regmap, RAA215300_FAULT_LATCHED_STATUS_3, &val);
|
||||
regmap_write(regmap, RAA215300_FAULT_LATCHED_STATUS_3, val);
|
||||
regmap_read(regmap, RAA215300_FAULT_LATCHED_STATUS_4, &val);
|
||||
regmap_write(regmap, RAA215300_FAULT_LATCHED_STATUS_4, val);
|
||||
regmap_read(regmap, RAA215300_FAULT_LATCHED_STATUS_6, &val);
|
||||
regmap_write(regmap, RAA215300_FAULT_LATCHED_STATUS_6, val);
|
||||
|
||||
/* Mask all the PMIC interrupts */
|
||||
regmap_write(regmap, RAA215300_INT_MASK_1, RAA215300_INT_MASK_1_ALL);
|
||||
regmap_write(regmap, RAA215300_INT_MASK_2, RAA215300_INT_MASK_2_ALL);
|
||||
regmap_write(regmap, RAA215300_INT_MASK_3, RAA215300_INT_MASK_3_ALL);
|
||||
regmap_write(regmap, RAA215300_INT_MASK_4, RAA215300_INT_MASK_4_ALL);
|
||||
regmap_write(regmap, RAA215300_INT_MASK_6, RAA215300_INT_MASK_6_ALL);
|
||||
|
||||
ret = raa215300_clk_present(client, xin_name);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
} else if (!ret) {
|
||||
ret = raa215300_clk_present(client, clkin_name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
clk_name = clkin_name;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
char *name = pmic_version >= 0x12 ? "isl1208" : "raa215300_a0";
|
||||
struct device_node *np = client->dev.of_node;
|
||||
u32 addr = RAA215300_RTC_DEFAULT_ADDR;
|
||||
struct i2c_board_info info = {};
|
||||
struct i2c_client *rtc_client;
|
||||
ssize_t size;
|
||||
|
||||
clk = clk_register_fixed_rate(NULL, clk_name, NULL, 0, 32000);
|
||||
clk_register_clkdev(clk, clk_name, NULL);
|
||||
|
||||
if (np) {
|
||||
int i;
|
||||
|
||||
i = of_property_match_string(np, "reg-names", "rtc");
|
||||
if (i >= 0)
|
||||
of_property_read_u32_index(np, "reg", i, &addr);
|
||||
}
|
||||
|
||||
info.addr = addr;
|
||||
if (client->irq > 0)
|
||||
info.irq = client->irq;
|
||||
|
||||
size = strscpy(info.type, name, sizeof(info.type));
|
||||
if (size < 0)
|
||||
return dev_err_probe(dev, size,
|
||||
"Invalid device name: %s\n", name);
|
||||
|
||||
/* Enable RTC block */
|
||||
regmap_update_bits(regmap, RAA215300_REG_BLOCK_EN,
|
||||
RAA215300_REG_BLOCK_EN_RTC_EN,
|
||||
RAA215300_REG_BLOCK_EN_RTC_EN);
|
||||
|
||||
rtc_client = i2c_new_client_device(client->adapter, &info);
|
||||
if (IS_ERR(rtc_client))
|
||||
return PTR_ERR(rtc_client);
|
||||
|
||||
ret = devm_add_action_or_reset(dev,
|
||||
raa215300_rtc_unregister_device,
|
||||
rtc_client);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id raa215300_dt_match[] = {
|
||||
{ .compatible = "renesas,raa215300" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, raa215300_dt_match);
|
||||
|
||||
static struct i2c_driver raa215300_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "raa215300",
|
||||
.of_match_table = raa215300_dt_match,
|
||||
},
|
||||
.probe_new = raa215300_i2c_probe,
|
||||
};
|
||||
module_i2c_driver(raa215300_i2c_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Renesas RAA215300 PMIC driver");
|
||||
MODULE_AUTHOR("Fabrizio Castro <fabrizio.castro.jz@renesas.com>");
|
||||
MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");
|
||||
MODULE_LICENSE("GPL");
|
@@ -3,9 +3,11 @@
|
||||
* Regulator driver for Rockchip RK805/RK808/RK818
|
||||
*
|
||||
* Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
|
||||
* Copyright (c) 2021 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* Author: Chris Zhong <zyw@rock-chips.com>
|
||||
* Author: Zhang Qing <zhangqing@rock-chips.com>
|
||||
* Author: Xu Shengfei <xsf@rock-chips.com>
|
||||
*
|
||||
* Copyright (C) 2016 PHYTEC Messtechnik GmbH
|
||||
*
|
||||
@@ -39,6 +41,13 @@
|
||||
#define RK818_LDO3_ON_VSEL_MASK 0xf
|
||||
#define RK818_BOOST_ON_VSEL_MASK 0xe0
|
||||
|
||||
#define RK806_DCDC_SLP_REG_OFFSET 0x0A
|
||||
#define RK806_NLDO_SLP_REG_OFFSET 0x05
|
||||
#define RK806_PLDO_SLP_REG_OFFSET 0x06
|
||||
|
||||
#define RK806_BUCK_SEL_CNT 0xff
|
||||
#define RK806_LDO_SEL_CNT 0xff
|
||||
|
||||
/* Ramp rate definitions for buck1 / buck2 only */
|
||||
#define RK808_RAMP_RATE_OFFSET 3
|
||||
#define RK808_RAMP_RATE_MASK (3 << RK808_RAMP_RATE_OFFSET)
|
||||
@@ -117,6 +126,34 @@
|
||||
RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg, \
|
||||
_vmask, _ereg, _emask, 0, 0, _etime, &rk805_reg_ops)
|
||||
|
||||
#define RK806_REGULATOR(_name, _supply_name, _id, _ops,\
|
||||
_n_voltages, _vr, _er, _lr, ctrl_bit,\
|
||||
_rr, _rm, _rt)\
|
||||
[_id] = {\
|
||||
.name = _name,\
|
||||
.supply_name = _supply_name,\
|
||||
.of_match = of_match_ptr(_name),\
|
||||
.regulators_node = of_match_ptr("regulators"),\
|
||||
.id = _id,\
|
||||
.ops = &_ops,\
|
||||
.type = REGULATOR_VOLTAGE,\
|
||||
.n_voltages = _n_voltages,\
|
||||
.linear_ranges = _lr,\
|
||||
.n_linear_ranges = ARRAY_SIZE(_lr),\
|
||||
.vsel_reg = _vr,\
|
||||
.vsel_mask = 0xff,\
|
||||
.enable_reg = _er,\
|
||||
.enable_mask = ENABLE_MASK(ctrl_bit),\
|
||||
.enable_val = ENABLE_MASK(ctrl_bit),\
|
||||
.disable_val = DISABLE_VAL(ctrl_bit),\
|
||||
.of_map_mode = rk8xx_regulator_of_map_mode,\
|
||||
.ramp_reg = _rr,\
|
||||
.ramp_mask = _rm,\
|
||||
.ramp_delay_table = _rt, \
|
||||
.n_ramp_values = ARRAY_SIZE(_rt), \
|
||||
.owner = THIS_MODULE,\
|
||||
}
|
||||
|
||||
#define RK8XX_DESC(_id, _match, _supply, _min, _max, _step, _vreg, \
|
||||
_vmask, _ereg, _emask, _etime) \
|
||||
RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg, \
|
||||
@@ -153,6 +190,17 @@
|
||||
RKXX_DESC_SWITCH_COM(_id, _match, _supply, _ereg, _emask, \
|
||||
0, 0, &rk808_switch_ops)
|
||||
|
||||
struct rk8xx_register_bit {
|
||||
u8 reg;
|
||||
u8 bit;
|
||||
};
|
||||
|
||||
#define RK8XX_REG_BIT(_reg, _bit) \
|
||||
{ \
|
||||
.reg = _reg, \
|
||||
.bit = BIT(_bit), \
|
||||
}
|
||||
|
||||
struct rk808_regulator_data {
|
||||
struct gpio_desc *dvs_gpio[2];
|
||||
};
|
||||
@@ -216,6 +264,133 @@ static const unsigned int rk817_buck1_4_ramp_table[] = {
|
||||
3000, 6300, 12500, 25000
|
||||
};
|
||||
|
||||
static int rk806_set_mode_dcdc(struct regulator_dev *rdev, unsigned int mode)
|
||||
{
|
||||
int rid = rdev_get_id(rdev);
|
||||
int ctr_bit, reg;
|
||||
|
||||
reg = RK806_POWER_FPWM_EN0 + rid / 8;
|
||||
ctr_bit = rid % 8;
|
||||
|
||||
switch (mode) {
|
||||
case REGULATOR_MODE_FAST:
|
||||
return regmap_update_bits(rdev->regmap, reg,
|
||||
PWM_MODE_MSK << ctr_bit,
|
||||
FPWM_MODE << ctr_bit);
|
||||
case REGULATOR_MODE_NORMAL:
|
||||
return regmap_update_bits(rdev->regmap, reg,
|
||||
PWM_MODE_MSK << ctr_bit,
|
||||
AUTO_PWM_MODE << ctr_bit);
|
||||
default:
|
||||
dev_err(rdev_get_dev(rdev), "mode unsupported: %u\n", mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int rk806_get_mode_dcdc(struct regulator_dev *rdev)
|
||||
{
|
||||
int rid = rdev_get_id(rdev);
|
||||
int ctr_bit, reg;
|
||||
unsigned int val;
|
||||
int err;
|
||||
|
||||
reg = RK806_POWER_FPWM_EN0 + rid / 8;
|
||||
ctr_bit = rid % 8;
|
||||
|
||||
err = regmap_read(rdev->regmap, reg, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if ((val >> ctr_bit) & FPWM_MODE)
|
||||
return REGULATOR_MODE_FAST;
|
||||
else
|
||||
return REGULATOR_MODE_NORMAL;
|
||||
}
|
||||
|
||||
static const struct rk8xx_register_bit rk806_dcdc_rate2[] = {
|
||||
RK8XX_REG_BIT(0xEB, 0),
|
||||
RK8XX_REG_BIT(0xEB, 1),
|
||||
RK8XX_REG_BIT(0xEB, 2),
|
||||
RK8XX_REG_BIT(0xEB, 3),
|
||||
RK8XX_REG_BIT(0xEB, 4),
|
||||
RK8XX_REG_BIT(0xEB, 5),
|
||||
RK8XX_REG_BIT(0xEB, 6),
|
||||
RK8XX_REG_BIT(0xEB, 7),
|
||||
RK8XX_REG_BIT(0xEA, 0),
|
||||
RK8XX_REG_BIT(0xEA, 1),
|
||||
};
|
||||
|
||||
static const unsigned int rk806_ramp_delay_table_dcdc[] = {
|
||||
50000, 25000, 12500, 6250, 3125, 1560, 961, 390
|
||||
};
|
||||
|
||||
static int rk806_set_ramp_delay_dcdc(struct regulator_dev *rdev, int ramp_delay)
|
||||
{
|
||||
int rid = rdev_get_id(rdev);
|
||||
int regval, ramp_value, ret;
|
||||
|
||||
ret = regulator_find_closest_bigger(ramp_delay, rdev->desc->ramp_delay_table,
|
||||
rdev->desc->n_ramp_values, &ramp_value);
|
||||
if (ret) {
|
||||
dev_warn(rdev_get_dev(rdev),
|
||||
"Can't set ramp-delay %u, setting %u\n", ramp_delay,
|
||||
rdev->desc->ramp_delay_table[ramp_value]);
|
||||
}
|
||||
|
||||
regval = ramp_value << (ffs(rdev->desc->ramp_mask) - 1);
|
||||
|
||||
ret = regmap_update_bits(rdev->regmap, rdev->desc->ramp_reg,
|
||||
rdev->desc->ramp_mask, regval);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* The above is effectively a copy of regulator_set_ramp_delay_regmap(),
|
||||
* but that only stores the lower 2 bits for rk806 DCDC ramp. The MSB must
|
||||
* be stored in a separate register, so this open codes the implementation
|
||||
* to have access to the ramp_value.
|
||||
*/
|
||||
|
||||
regval = (ramp_value >> 2) & 0x1 ? rk806_dcdc_rate2[rid].bit : 0;
|
||||
return regmap_update_bits(rdev->regmap, rk806_dcdc_rate2[rid].reg,
|
||||
rk806_dcdc_rate2[rid].bit,
|
||||
regval);
|
||||
}
|
||||
|
||||
static const unsigned int rk806_ramp_delay_table_ldo[] = {
|
||||
100000, 50000, 25000, 12500, 6280, 3120, 1900, 780
|
||||
};
|
||||
|
||||
static int rk806_set_suspend_voltage_range(struct regulator_dev *rdev, int reg_offset, int uv)
|
||||
{
|
||||
int sel = regulator_map_voltage_linear_range(rdev, uv, uv);
|
||||
unsigned int reg;
|
||||
|
||||
if (sel < 0)
|
||||
return -EINVAL;
|
||||
|
||||
reg = rdev->desc->vsel_reg + reg_offset;
|
||||
|
||||
return regmap_update_bits(rdev->regmap, reg, rdev->desc->vsel_mask, sel);
|
||||
}
|
||||
|
||||
static int rk806_set_suspend_voltage_range_dcdc(struct regulator_dev *rdev, int uv)
|
||||
{
|
||||
return rk806_set_suspend_voltage_range(rdev, RK806_DCDC_SLP_REG_OFFSET, uv);
|
||||
}
|
||||
|
||||
static int rk806_set_suspend_voltage_range_nldo(struct regulator_dev *rdev, int uv)
|
||||
{
|
||||
return rk806_set_suspend_voltage_range(rdev, RK806_NLDO_SLP_REG_OFFSET, uv);
|
||||
}
|
||||
|
||||
static int rk806_set_suspend_voltage_range_pldo(struct regulator_dev *rdev, int uv)
|
||||
{
|
||||
return rk806_set_suspend_voltage_range(rdev, RK806_PLDO_SLP_REG_OFFSET, uv);
|
||||
}
|
||||
|
||||
static int rk808_buck1_2_get_voltage_sel_regmap(struct regulator_dev *rdev)
|
||||
{
|
||||
struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev);
|
||||
@@ -393,6 +568,47 @@ static int rk805_set_suspend_disable(struct regulator_dev *rdev)
|
||||
0);
|
||||
}
|
||||
|
||||
static const struct rk8xx_register_bit rk806_suspend_bits[] = {
|
||||
RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 0),
|
||||
RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 1),
|
||||
RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 2),
|
||||
RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 3),
|
||||
RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 4),
|
||||
RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 5),
|
||||
RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 6),
|
||||
RK8XX_REG_BIT(RK806_POWER_SLP_EN0, 7),
|
||||
RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 6),
|
||||
RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 7),
|
||||
RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 0),
|
||||
RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 1),
|
||||
RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 2),
|
||||
RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 3),
|
||||
RK8XX_REG_BIT(RK806_POWER_SLP_EN1, 4),
|
||||
RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 1),
|
||||
RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 2),
|
||||
RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 3),
|
||||
RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 4),
|
||||
RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 5),
|
||||
RK8XX_REG_BIT(RK806_POWER_SLP_EN2, 0),
|
||||
};
|
||||
|
||||
static int rk806_set_suspend_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
int rid = rdev_get_id(rdev);
|
||||
|
||||
return regmap_update_bits(rdev->regmap, rk806_suspend_bits[rid].reg,
|
||||
rk806_suspend_bits[rid].bit,
|
||||
rk806_suspend_bits[rid].bit);
|
||||
}
|
||||
|
||||
static int rk806_set_suspend_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
int rid = rdev_get_id(rdev);
|
||||
|
||||
return regmap_update_bits(rdev->regmap, rk806_suspend_bits[rid].reg,
|
||||
rk806_suspend_bits[rid].bit, 0);
|
||||
}
|
||||
|
||||
static int rk808_set_suspend_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
unsigned int reg;
|
||||
@@ -561,6 +777,64 @@ static const struct regulator_ops rk805_switch_ops = {
|
||||
.set_suspend_disable = rk805_set_suspend_disable,
|
||||
};
|
||||
|
||||
static const struct regulator_ops rk806_ops_dcdc = {
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||
.set_mode = rk806_set_mode_dcdc,
|
||||
.get_mode = rk806_get_mode_dcdc,
|
||||
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = rk8xx_is_enabled_wmsk_regmap,
|
||||
|
||||
.set_suspend_mode = rk806_set_mode_dcdc,
|
||||
.set_ramp_delay = rk806_set_ramp_delay_dcdc,
|
||||
|
||||
.set_suspend_voltage = rk806_set_suspend_voltage_range_dcdc,
|
||||
.set_suspend_enable = rk806_set_suspend_enable,
|
||||
.set_suspend_disable = rk806_set_suspend_disable,
|
||||
};
|
||||
|
||||
static const struct regulator_ops rk806_ops_nldo = {
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
|
||||
.set_ramp_delay = regulator_set_ramp_delay_regmap,
|
||||
|
||||
.set_suspend_voltage = rk806_set_suspend_voltage_range_nldo,
|
||||
.set_suspend_enable = rk806_set_suspend_enable,
|
||||
.set_suspend_disable = rk806_set_suspend_disable,
|
||||
};
|
||||
|
||||
static const struct regulator_ops rk806_ops_pldo = {
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
|
||||
.set_ramp_delay = regulator_set_ramp_delay_regmap,
|
||||
|
||||
.set_suspend_voltage = rk806_set_suspend_voltage_range_pldo,
|
||||
.set_suspend_enable = rk806_set_suspend_enable,
|
||||
.set_suspend_disable = rk806_set_suspend_disable,
|
||||
};
|
||||
|
||||
static const struct regulator_ops rk808_buck1_2_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
@@ -743,6 +1017,112 @@ static const struct regulator_desc rk805_reg[] = {
|
||||
BIT(2), 400),
|
||||
};
|
||||
|
||||
static const struct linear_range rk806_buck_voltage_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 0, 160, 6250), /* 500mV ~ 1500mV */
|
||||
REGULATOR_LINEAR_RANGE(1500000, 161, 237, 25000), /* 1500mV ~ 3400mV */
|
||||
REGULATOR_LINEAR_RANGE(3400000, 238, 255, 0),
|
||||
};
|
||||
|
||||
static const struct linear_range rk806_ldo_voltage_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000, 0, 232, 12500), /* 500mV ~ 3400mV */
|
||||
REGULATOR_LINEAR_RANGE(3400000, 233, 255, 0), /* 500mV ~ 3400mV */
|
||||
};
|
||||
|
||||
static const struct regulator_desc rk806_reg[] = {
|
||||
RK806_REGULATOR("dcdc-reg1", "vcc1", RK806_ID_DCDC1, rk806_ops_dcdc,
|
||||
RK806_BUCK_SEL_CNT, RK806_BUCK1_ON_VSEL,
|
||||
RK806_POWER_EN0, rk806_buck_voltage_ranges, 0,
|
||||
RK806_BUCK1_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
|
||||
RK806_REGULATOR("dcdc-reg2", "vcc2", RK806_ID_DCDC2, rk806_ops_dcdc,
|
||||
RK806_BUCK_SEL_CNT, RK806_BUCK2_ON_VSEL,
|
||||
RK806_POWER_EN0, rk806_buck_voltage_ranges, 1,
|
||||
RK806_BUCK2_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
|
||||
RK806_REGULATOR("dcdc-reg3", "vcc3", RK806_ID_DCDC3, rk806_ops_dcdc,
|
||||
RK806_BUCK_SEL_CNT, RK806_BUCK3_ON_VSEL,
|
||||
RK806_POWER_EN0, rk806_buck_voltage_ranges, 2,
|
||||
RK806_BUCK3_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
|
||||
RK806_REGULATOR("dcdc-reg4", "vcc4", RK806_ID_DCDC4, rk806_ops_dcdc,
|
||||
RK806_BUCK_SEL_CNT, RK806_BUCK4_ON_VSEL,
|
||||
RK806_POWER_EN0, rk806_buck_voltage_ranges, 3,
|
||||
RK806_BUCK4_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
|
||||
|
||||
RK806_REGULATOR("dcdc-reg5", "vcc5", RK806_ID_DCDC5, rk806_ops_dcdc,
|
||||
RK806_BUCK_SEL_CNT, RK806_BUCK5_ON_VSEL,
|
||||
RK806_POWER_EN1, rk806_buck_voltage_ranges, 0,
|
||||
RK806_BUCK5_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
|
||||
RK806_REGULATOR("dcdc-reg6", "vcc6", RK806_ID_DCDC6, rk806_ops_dcdc,
|
||||
RK806_BUCK_SEL_CNT, RK806_BUCK6_ON_VSEL,
|
||||
RK806_POWER_EN1, rk806_buck_voltage_ranges, 1,
|
||||
RK806_BUCK6_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
|
||||
RK806_REGULATOR("dcdc-reg7", "vcc7", RK806_ID_DCDC7, rk806_ops_dcdc,
|
||||
RK806_BUCK_SEL_CNT, RK806_BUCK7_ON_VSEL,
|
||||
RK806_POWER_EN1, rk806_buck_voltage_ranges, 2,
|
||||
RK806_BUCK7_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
|
||||
RK806_REGULATOR("dcdc-reg8", "vcc8", RK806_ID_DCDC8, rk806_ops_dcdc,
|
||||
RK806_BUCK_SEL_CNT, RK806_BUCK8_ON_VSEL,
|
||||
RK806_POWER_EN1, rk806_buck_voltage_ranges, 3,
|
||||
RK806_BUCK8_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
|
||||
|
||||
RK806_REGULATOR("dcdc-reg9", "vcc9", RK806_ID_DCDC9, rk806_ops_dcdc,
|
||||
RK806_BUCK_SEL_CNT, RK806_BUCK9_ON_VSEL,
|
||||
RK806_POWER_EN2, rk806_buck_voltage_ranges, 0,
|
||||
RK806_BUCK9_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
|
||||
RK806_REGULATOR("dcdc-reg10", "vcc10", RK806_ID_DCDC10, rk806_ops_dcdc,
|
||||
RK806_BUCK_SEL_CNT, RK806_BUCK10_ON_VSEL,
|
||||
RK806_POWER_EN2, rk806_buck_voltage_ranges, 1,
|
||||
RK806_BUCK10_CONFIG, 0xc0, rk806_ramp_delay_table_dcdc),
|
||||
|
||||
RK806_REGULATOR("nldo-reg1", "vcc13", RK806_ID_NLDO1, rk806_ops_nldo,
|
||||
RK806_LDO_SEL_CNT, RK806_NLDO1_ON_VSEL,
|
||||
RK806_POWER_EN3, rk806_ldo_voltage_ranges, 0,
|
||||
0xEA, 0x38, rk806_ramp_delay_table_ldo),
|
||||
RK806_REGULATOR("nldo-reg2", "vcc13", RK806_ID_NLDO2, rk806_ops_nldo,
|
||||
RK806_LDO_SEL_CNT, RK806_NLDO2_ON_VSEL,
|
||||
RK806_POWER_EN3, rk806_ldo_voltage_ranges, 1,
|
||||
0xEA, 0x38, rk806_ramp_delay_table_ldo),
|
||||
RK806_REGULATOR("nldo-reg3", "vcc13", RK806_ID_NLDO3, rk806_ops_nldo,
|
||||
RK806_LDO_SEL_CNT, RK806_NLDO3_ON_VSEL,
|
||||
RK806_POWER_EN3, rk806_ldo_voltage_ranges, 2,
|
||||
0xEA, 0x38, rk806_ramp_delay_table_ldo),
|
||||
RK806_REGULATOR("nldo-reg4", "vcc14", RK806_ID_NLDO4, rk806_ops_nldo,
|
||||
RK806_LDO_SEL_CNT, RK806_NLDO4_ON_VSEL,
|
||||
RK806_POWER_EN3, rk806_ldo_voltage_ranges, 3,
|
||||
0xEA, 0x38, rk806_ramp_delay_table_ldo),
|
||||
|
||||
RK806_REGULATOR("nldo-reg5", "vcc14", RK806_ID_NLDO5, rk806_ops_nldo,
|
||||
RK806_LDO_SEL_CNT, RK806_NLDO5_ON_VSEL,
|
||||
RK806_POWER_EN5, rk806_ldo_voltage_ranges, 2,
|
||||
0xEA, 0x38, rk806_ramp_delay_table_ldo),
|
||||
|
||||
RK806_REGULATOR("pldo-reg1", "vcc11", RK806_ID_PLDO1, rk806_ops_pldo,
|
||||
RK806_LDO_SEL_CNT, RK806_PLDO1_ON_VSEL,
|
||||
RK806_POWER_EN4, rk806_ldo_voltage_ranges, 1,
|
||||
0xEA, 0x38, rk806_ramp_delay_table_ldo),
|
||||
RK806_REGULATOR("pldo-reg2", "vcc11", RK806_ID_PLDO2, rk806_ops_pldo,
|
||||
RK806_LDO_SEL_CNT, RK806_PLDO2_ON_VSEL,
|
||||
RK806_POWER_EN4, rk806_ldo_voltage_ranges, 2,
|
||||
0xEA, 0x38, rk806_ramp_delay_table_ldo),
|
||||
RK806_REGULATOR("pldo-reg3", "vcc11", RK806_ID_PLDO3, rk806_ops_pldo,
|
||||
RK806_LDO_SEL_CNT, RK806_PLDO3_ON_VSEL,
|
||||
RK806_POWER_EN4, rk806_ldo_voltage_ranges, 3,
|
||||
0xEA, 0x38, rk806_ramp_delay_table_ldo),
|
||||
|
||||
RK806_REGULATOR("pldo-reg4", "vcc12", RK806_ID_PLDO4, rk806_ops_pldo,
|
||||
RK806_LDO_SEL_CNT, RK806_PLDO4_ON_VSEL,
|
||||
RK806_POWER_EN5, rk806_ldo_voltage_ranges, 0,
|
||||
0xEA, 0x38, rk806_ramp_delay_table_ldo),
|
||||
RK806_REGULATOR("pldo-reg5", "vcc12", RK806_ID_PLDO5, rk806_ops_pldo,
|
||||
RK806_LDO_SEL_CNT, RK806_PLDO5_ON_VSEL,
|
||||
RK806_POWER_EN5, rk806_ldo_voltage_ranges, 1,
|
||||
0xEA, 0x38, rk806_ramp_delay_table_ldo),
|
||||
|
||||
RK806_REGULATOR("pldo-reg6", "vcca", RK806_ID_PLDO6, rk806_ops_pldo,
|
||||
RK806_LDO_SEL_CNT, RK806_PLDO6_ON_VSEL,
|
||||
RK806_POWER_EN4, rk806_ldo_voltage_ranges, 0,
|
||||
0xEA, 0x38, rk806_ramp_delay_table_ldo),
|
||||
};
|
||||
|
||||
|
||||
static const struct regulator_desc rk808_reg[] = {
|
||||
{
|
||||
.name = "DCDC_REG1",
|
||||
@@ -1245,20 +1625,19 @@ static const struct regulator_desc rk818_reg[] = {
|
||||
};
|
||||
|
||||
static int rk808_regulator_dt_parse_pdata(struct device *dev,
|
||||
struct device *client_dev,
|
||||
struct regmap *map,
|
||||
struct rk808_regulator_data *pdata)
|
||||
{
|
||||
struct device_node *np;
|
||||
int tmp, ret = 0, i;
|
||||
|
||||
np = of_get_child_by_name(client_dev->of_node, "regulators");
|
||||
np = of_get_child_by_name(dev->of_node, "regulators");
|
||||
if (!np)
|
||||
return -ENXIO;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(pdata->dvs_gpio); i++) {
|
||||
pdata->dvs_gpio[i] =
|
||||
devm_gpiod_get_index_optional(client_dev, "dvs", i,
|
||||
devm_gpiod_get_index_optional(dev, "dvs", i,
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(pdata->dvs_gpio[i])) {
|
||||
ret = PTR_ERR(pdata->dvs_gpio[i]);
|
||||
@@ -1292,6 +1671,9 @@ static int rk808_regulator_probe(struct platform_device *pdev)
|
||||
struct regmap *regmap;
|
||||
int ret, i, nregulators;
|
||||
|
||||
pdev->dev.of_node = pdev->dev.parent->of_node;
|
||||
pdev->dev.of_node_reused = true;
|
||||
|
||||
regmap = dev_get_regmap(pdev->dev.parent, NULL);
|
||||
if (!regmap)
|
||||
return -ENODEV;
|
||||
@@ -1300,8 +1682,7 @@ static int rk808_regulator_probe(struct platform_device *pdev)
|
||||
if (!pdata)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = rk808_regulator_dt_parse_pdata(&pdev->dev, pdev->dev.parent,
|
||||
regmap, pdata);
|
||||
ret = rk808_regulator_dt_parse_pdata(&pdev->dev, regmap, pdata);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -1312,6 +1693,10 @@ static int rk808_regulator_probe(struct platform_device *pdev)
|
||||
regulators = rk805_reg;
|
||||
nregulators = RK805_NUM_REGULATORS;
|
||||
break;
|
||||
case RK806_ID:
|
||||
regulators = rk806_reg;
|
||||
nregulators = ARRAY_SIZE(rk806_reg);
|
||||
break;
|
||||
case RK808_ID:
|
||||
regulators = rk808_reg;
|
||||
nregulators = RK808_NUM_REGULATORS;
|
||||
@@ -1335,7 +1720,6 @@ static int rk808_regulator_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
config.dev = &pdev->dev;
|
||||
config.dev->of_node = pdev->dev.parent->of_node;
|
||||
config.driver_data = pdata;
|
||||
config.regmap = regmap;
|
||||
|
||||
@@ -1355,7 +1739,7 @@ static struct platform_driver rk808_regulator_driver = {
|
||||
.probe = rk808_regulator_probe,
|
||||
.driver = {
|
||||
.name = "rk808-regulator",
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.probe_type = PROBE_FORCE_SYNCHRONOUS,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1366,5 +1750,6 @@ MODULE_AUTHOR("Tony xie <tony.xie@rock-chips.com>");
|
||||
MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
|
||||
MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
|
||||
MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
|
||||
MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:rk808-regulator");
|
||||
|
@@ -399,7 +399,7 @@ static struct i2c_driver attiny_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(attiny_dt_ids),
|
||||
},
|
||||
.probe_new = attiny_i2c_probe,
|
||||
.probe = attiny_i2c_probe,
|
||||
.remove = attiny_i2c_remove,
|
||||
};
|
||||
|
||||
|
@@ -242,7 +242,7 @@ static struct i2c_driver rt4801_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(rt4801_of_id),
|
||||
},
|
||||
.probe_new = rt4801_probe,
|
||||
.probe = rt4801_probe,
|
||||
};
|
||||
module_i2c_driver(rt4801_driver);
|
||||
|
||||
|
@@ -508,7 +508,7 @@ static struct i2c_driver rt5190a_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = rt5190a_device_table,
|
||||
},
|
||||
.probe_new = rt5190a_probe,
|
||||
.probe = rt5190a_probe,
|
||||
};
|
||||
module_i2c_driver(rt5190a_driver);
|
||||
|
||||
|
@@ -282,7 +282,7 @@ static struct i2c_driver rt5739_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = rt5739_device_table,
|
||||
},
|
||||
.probe_new = rt5739_probe,
|
||||
.probe = rt5739_probe,
|
||||
};
|
||||
module_i2c_driver(rt5739_driver);
|
||||
|
||||
|
@@ -362,7 +362,7 @@ static struct i2c_driver rt5759_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(rt5759_device_table),
|
||||
},
|
||||
.probe_new = rt5759_probe,
|
||||
.probe = rt5759_probe,
|
||||
};
|
||||
module_i2c_driver(rt5759_driver);
|
||||
|
||||
|
@@ -311,7 +311,7 @@ static struct i2c_driver rt6160_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = rt6160_of_match_table,
|
||||
},
|
||||
.probe_new = rt6160_probe,
|
||||
.probe = rt6160_probe,
|
||||
};
|
||||
module_i2c_driver(rt6160_driver);
|
||||
|
||||
|
@@ -487,7 +487,7 @@ static struct i2c_driver rt6190_driver = {
|
||||
.of_match_table = rt6190_of_dev_table,
|
||||
.pm = pm_ptr(&rt6190_dev_pm),
|
||||
},
|
||||
.probe_new = rt6190_probe,
|
||||
.probe = rt6190_probe,
|
||||
};
|
||||
module_i2c_driver(rt6190_driver);
|
||||
|
||||
|
@@ -246,7 +246,7 @@ static struct i2c_driver rt6245_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = rt6245_of_match_table,
|
||||
},
|
||||
.probe_new = rt6245_probe,
|
||||
.probe = rt6245_probe,
|
||||
};
|
||||
module_i2c_driver(rt6245_driver);
|
||||
|
||||
|
@@ -429,7 +429,7 @@ static struct i2c_driver rtmv20_driver = {
|
||||
.of_match_table = of_match_ptr(rtmv20_of_id),
|
||||
.pm = &rtmv20_pm,
|
||||
},
|
||||
.probe_new = rtmv20_probe,
|
||||
.probe = rtmv20_probe,
|
||||
};
|
||||
module_i2c_driver(rtmv20_driver);
|
||||
|
||||
|
@@ -366,7 +366,7 @@ static struct i2c_driver rtq2134_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = rtq2134_device_tables,
|
||||
},
|
||||
.probe_new = rtq2134_probe,
|
||||
.probe = rtq2134_probe,
|
||||
};
|
||||
module_i2c_driver(rtq2134_driver);
|
||||
|
||||
|
@@ -281,7 +281,7 @@ static struct i2c_driver rtq6752_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = rtq6752_device_table,
|
||||
},
|
||||
.probe_new = rtq6752_probe,
|
||||
.probe = rtq6752_probe,
|
||||
};
|
||||
module_i2c_driver(rtq6752_driver);
|
||||
|
||||
|
@@ -507,7 +507,7 @@ static struct i2c_driver slg51000_regulator_driver = {
|
||||
.name = "slg51000-regulator",
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
},
|
||||
.probe_new = slg51000_i2c_probe,
|
||||
.probe = slg51000_i2c_probe,
|
||||
.id_table = slg51000_i2c_id,
|
||||
};
|
||||
|
||||
|
@@ -93,7 +93,7 @@ static int stm32_pwr_reg_disable(struct regulator_dev *rdev)
|
||||
writel_relaxed(val, priv->base + REG_PWR_CR3);
|
||||
|
||||
/* use an arbitrary timeout of 20ms */
|
||||
ret = readx_poll_timeout(stm32_pwr_reg_is_ready, rdev, val, !val,
|
||||
ret = readx_poll_timeout(stm32_pwr_reg_is_enabled, rdev, val, !val,
|
||||
100, 20 * 1000);
|
||||
if (ret)
|
||||
dev_err(&rdev->dev, "regulator disable timed out!\n");
|
||||
|
@@ -141,7 +141,7 @@ static struct i2c_driver sy8106a_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = sy8106a_i2c_of_match,
|
||||
},
|
||||
.probe_new = sy8106a_i2c_probe,
|
||||
.probe = sy8106a_i2c_probe,
|
||||
.id_table = sy8106a_i2c_id,
|
||||
};
|
||||
|
||||
|
@@ -236,7 +236,7 @@ static struct i2c_driver sy8824_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = sy8824_dt_ids,
|
||||
},
|
||||
.probe_new = sy8824_i2c_probe,
|
||||
.probe = sy8824_i2c_probe,
|
||||
.id_table = sy8824_id,
|
||||
};
|
||||
module_i2c_driver(sy8824_regulator_driver);
|
||||
|
@@ -190,7 +190,7 @@ static struct i2c_driver sy8827n_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = sy8827n_dt_ids,
|
||||
},
|
||||
.probe_new = sy8827n_i2c_probe,
|
||||
.probe = sy8827n_i2c_probe,
|
||||
.id_table = sy8827n_id,
|
||||
};
|
||||
module_i2c_driver(sy8827n_regulator_driver);
|
||||
|
@@ -354,7 +354,7 @@ static struct i2c_driver tps51632_i2c_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(tps51632_of_match),
|
||||
},
|
||||
.probe_new = tps51632_probe,
|
||||
.probe = tps51632_probe,
|
||||
.id_table = tps51632_id,
|
||||
};
|
||||
|
||||
|
@@ -491,7 +491,7 @@ static struct i2c_driver tps62360_i2c_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(tps62360_of_match),
|
||||
},
|
||||
.probe_new = tps62360_probe,
|
||||
.probe = tps62360_probe,
|
||||
.shutdown = tps62360_shutdown,
|
||||
.id_table = tps62360_id,
|
||||
};
|
||||
|
@@ -150,7 +150,7 @@ static struct i2c_driver tps6286x_regulator_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(tps6286x_dt_ids),
|
||||
},
|
||||
.probe_new = tps6286x_i2c_probe,
|
||||
.probe = tps6286x_i2c_probe,
|
||||
.id_table = tps6286x_i2c_id,
|
||||
};
|
||||
|
||||
|
189
drivers/regulator/tps6287x-regulator.c
Normal file
189
drivers/regulator/tps6287x-regulator.c
Normal file
@@ -0,0 +1,189 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2023 Axis Communications AB
|
||||
*
|
||||
* Driver for Texas Instruments TPS6287x PMIC.
|
||||
* Datasheet: https://www.ti.com/lit/ds/symlink/tps62873.pdf
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/linear_range.h>
|
||||
|
||||
#define TPS6287X_VSET 0x00
|
||||
#define TPS6287X_CTRL1 0x01
|
||||
#define TPS6287X_CTRL1_VRAMP GENMASK(1, 0)
|
||||
#define TPS6287X_CTRL1_FPWMEN BIT(4)
|
||||
#define TPS6287X_CTRL1_SWEN BIT(5)
|
||||
#define TPS6287X_CTRL2 0x02
|
||||
#define TPS6287X_CTRL2_VRANGE GENMASK(3, 2)
|
||||
#define TPS6287X_CTRL3 0x03
|
||||
#define TPS6287X_STATUS 0x04
|
||||
|
||||
static const struct regmap_config tps6287x_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = TPS6287X_STATUS,
|
||||
};
|
||||
|
||||
static const struct linear_range tps6287x_voltage_ranges[] = {
|
||||
LINEAR_RANGE(400000, 0, 0xFF, 1250),
|
||||
LINEAR_RANGE(400000, 0, 0xFF, 2500),
|
||||
LINEAR_RANGE(400000, 0, 0xFF, 5000),
|
||||
LINEAR_RANGE(800000, 0, 0xFF, 10000),
|
||||
};
|
||||
|
||||
static const unsigned int tps6287x_voltage_range_sel[] = {
|
||||
0x0, 0x4, 0x8, 0xC
|
||||
};
|
||||
|
||||
static const unsigned int tps6287x_ramp_table[] = {
|
||||
10000, 5000, 1250, 500
|
||||
};
|
||||
|
||||
static int tps6287x_set_mode(struct regulator_dev *rdev, unsigned int mode)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
switch (mode) {
|
||||
case REGULATOR_MODE_NORMAL:
|
||||
val = 0;
|
||||
break;
|
||||
case REGULATOR_MODE_FAST:
|
||||
val = TPS6287X_CTRL1_FPWMEN;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return regmap_update_bits(rdev->regmap, TPS6287X_CTRL1,
|
||||
TPS6287X_CTRL1_FPWMEN, val);
|
||||
}
|
||||
|
||||
static unsigned int tps6287x_get_mode(struct regulator_dev *rdev)
|
||||
{
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(rdev->regmap, TPS6287X_CTRL1, &val);
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
|
||||
return (val & TPS6287X_CTRL1_FPWMEN) ? REGULATOR_MODE_FAST :
|
||||
REGULATOR_MODE_NORMAL;
|
||||
}
|
||||
|
||||
static unsigned int tps6287x_of_map_mode(unsigned int mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case REGULATOR_MODE_NORMAL:
|
||||
case REGULATOR_MODE_FAST:
|
||||
return mode;
|
||||
default:
|
||||
return REGULATOR_MODE_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct regulator_ops tps6287x_regulator_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.set_mode = tps6287x_set_mode,
|
||||
.get_mode = tps6287x_get_mode,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_pickable_regmap,
|
||||
.list_voltage = regulator_list_voltage_pickable_linear_range,
|
||||
.set_ramp_delay = regulator_set_ramp_delay_regmap,
|
||||
};
|
||||
|
||||
static struct regulator_desc tps6287x_reg = {
|
||||
.name = "tps6287x",
|
||||
.owner = THIS_MODULE,
|
||||
.ops = &tps6287x_regulator_ops,
|
||||
.of_map_mode = tps6287x_of_map_mode,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.enable_reg = TPS6287X_CTRL1,
|
||||
.enable_mask = TPS6287X_CTRL1_SWEN,
|
||||
.vsel_reg = TPS6287X_VSET,
|
||||
.vsel_mask = 0xFF,
|
||||
.vsel_range_reg = TPS6287X_CTRL2,
|
||||
.vsel_range_mask = TPS6287X_CTRL2_VRANGE,
|
||||
.ramp_reg = TPS6287X_CTRL1,
|
||||
.ramp_mask = TPS6287X_CTRL1_VRAMP,
|
||||
.ramp_delay_table = tps6287x_ramp_table,
|
||||
.n_ramp_values = ARRAY_SIZE(tps6287x_ramp_table),
|
||||
.n_voltages = 256,
|
||||
.linear_ranges = tps6287x_voltage_ranges,
|
||||
.n_linear_ranges = ARRAY_SIZE(tps6287x_voltage_ranges),
|
||||
.linear_range_selectors = tps6287x_voltage_range_sel,
|
||||
};
|
||||
|
||||
static int tps6287x_i2c_probe(struct i2c_client *i2c)
|
||||
{
|
||||
struct device *dev = &i2c->dev;
|
||||
struct regulator_config config = {};
|
||||
struct regulator_dev *rdev;
|
||||
|
||||
config.regmap = devm_regmap_init_i2c(i2c, &tps6287x_regmap_config);
|
||||
if (IS_ERR(config.regmap)) {
|
||||
dev_err(dev, "Failed to init i2c\n");
|
||||
return PTR_ERR(config.regmap);
|
||||
}
|
||||
|
||||
config.dev = dev;
|
||||
config.of_node = dev->of_node;
|
||||
config.init_data = of_get_regulator_init_data(dev, dev->of_node,
|
||||
&tps6287x_reg);
|
||||
|
||||
rdev = devm_regulator_register(dev, &tps6287x_reg, &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(dev, "Failed to register regulator\n");
|
||||
return PTR_ERR(rdev);
|
||||
}
|
||||
|
||||
dev_dbg(dev, "Probed regulator\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id tps6287x_dt_ids[] = {
|
||||
{ .compatible = "ti,tps62870", },
|
||||
{ .compatible = "ti,tps62871", },
|
||||
{ .compatible = "ti,tps62872", },
|
||||
{ .compatible = "ti,tps62873", },
|
||||
{ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, tps6287x_dt_ids);
|
||||
|
||||
static const struct i2c_device_id tps6287x_i2c_id[] = {
|
||||
{ "tps62870", 0 },
|
||||
{ "tps62871", 0 },
|
||||
{ "tps62872", 0 },
|
||||
{ "tps62873", 0 },
|
||||
{},
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, tps6287x_i2c_id);
|
||||
|
||||
static struct i2c_driver tps6287x_regulator_driver = {
|
||||
.driver = {
|
||||
.name = "tps6287x",
|
||||
.of_match_table = tps6287x_dt_ids,
|
||||
},
|
||||
.probe = tps6287x_i2c_probe,
|
||||
.id_table = tps6287x_i2c_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(tps6287x_regulator_driver);
|
||||
|
||||
MODULE_AUTHOR("Mårten Lindahl <marten.lindahl@axis.com>");
|
||||
MODULE_DESCRIPTION("Regulator driver for TI TPS6287X PMIC");
|
||||
MODULE_LICENSE("GPL");
|
@@ -337,7 +337,7 @@ static struct i2c_driver tps_65023_i2c_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(tps65023_of_match),
|
||||
},
|
||||
.probe_new = tps_65023_probe,
|
||||
.probe = tps_65023_probe,
|
||||
.id_table = tps_65023_id,
|
||||
};
|
||||
|
||||
|
@@ -272,7 +272,7 @@ static struct i2c_driver tps65132_i2c_driver = {
|
||||
.name = "tps65132",
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
},
|
||||
.probe_new = tps65132_probe,
|
||||
.probe = tps65132_probe,
|
||||
.id_table = tps65132_id,
|
||||
};
|
||||
|
||||
|
@@ -289,13 +289,13 @@ static irqreturn_t tps65219_regulator_irq_handler(int irq, void *data)
|
||||
|
||||
static int tps65219_get_rdev_by_name(const char *regulator_name,
|
||||
struct regulator_dev *rdevtbl[7],
|
||||
struct regulator_dev *dev)
|
||||
struct regulator_dev **dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(regulators); i++) {
|
||||
if (strcmp(regulator_name, regulators[i].name) == 0) {
|
||||
dev = rdevtbl[i];
|
||||
*dev = rdevtbl[i];
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -348,7 +348,7 @@ static int tps65219_regulator_probe(struct platform_device *pdev)
|
||||
irq_data[i].dev = tps->dev;
|
||||
irq_data[i].type = irq_type;
|
||||
|
||||
tps65219_get_rdev_by_name(irq_type->regulator_name, rdevtbl, rdev);
|
||||
tps65219_get_rdev_by_name(irq_type->regulator_name, rdevtbl, &rdev);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(tps->dev, "Failed to get rdev for %s\n",
|
||||
irq_type->regulator_name);
|
||||
|
615
drivers/regulator/tps6594-regulator.c
Normal file
615
drivers/regulator/tps6594-regulator.c
Normal file
@@ -0,0 +1,615 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Regulator driver for tps6594 PMIC
|
||||
//
|
||||
// Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.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/mfd/tps6594.h>
|
||||
|
||||
#define BUCK_NB 5
|
||||
#define LDO_NB 4
|
||||
#define MULTI_PHASE_NB 4
|
||||
#define REGS_INT_NB 4
|
||||
|
||||
enum tps6594_regulator_id {
|
||||
/* DCDC's */
|
||||
TPS6594_BUCK_1,
|
||||
TPS6594_BUCK_2,
|
||||
TPS6594_BUCK_3,
|
||||
TPS6594_BUCK_4,
|
||||
TPS6594_BUCK_5,
|
||||
|
||||
/* LDOs */
|
||||
TPS6594_LDO_1,
|
||||
TPS6594_LDO_2,
|
||||
TPS6594_LDO_3,
|
||||
TPS6594_LDO_4,
|
||||
};
|
||||
|
||||
enum tps6594_multi_regulator_id {
|
||||
/* Multi-phase DCDC's */
|
||||
TPS6594_BUCK_12,
|
||||
TPS6594_BUCK_34,
|
||||
TPS6594_BUCK_123,
|
||||
TPS6594_BUCK_1234,
|
||||
};
|
||||
|
||||
struct tps6594_regulator_irq_type {
|
||||
const char *irq_name;
|
||||
const char *regulator_name;
|
||||
const char *event_name;
|
||||
unsigned long event;
|
||||
};
|
||||
|
||||
static struct tps6594_regulator_irq_type tps6594_ext_regulator_irq_types[] = {
|
||||
{ TPS6594_IRQ_NAME_VCCA_OV, "VCCA", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
|
||||
{ TPS6594_IRQ_NAME_VCCA_UV, "VCCA", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
|
||||
{ TPS6594_IRQ_NAME_VMON1_OV, "VMON1", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
|
||||
{ TPS6594_IRQ_NAME_VMON1_UV, "VMON1", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
|
||||
{ TPS6594_IRQ_NAME_VMON1_RV, "VMON1", "residual voltage",
|
||||
REGULATOR_EVENT_OVER_VOLTAGE_WARN },
|
||||
{ TPS6594_IRQ_NAME_VMON2_OV, "VMON2", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
|
||||
{ TPS6594_IRQ_NAME_VMON2_UV, "VMON2", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
|
||||
{ TPS6594_IRQ_NAME_VMON2_RV, "VMON2", "residual voltage",
|
||||
REGULATOR_EVENT_OVER_VOLTAGE_WARN },
|
||||
};
|
||||
|
||||
struct tps6594_regulator_irq_data {
|
||||
struct device *dev;
|
||||
struct tps6594_regulator_irq_type *type;
|
||||
struct regulator_dev *rdev;
|
||||
};
|
||||
|
||||
struct tps6594_ext_regulator_irq_data {
|
||||
struct device *dev;
|
||||
struct tps6594_regulator_irq_type *type;
|
||||
};
|
||||
|
||||
#define TPS6594_REGULATOR(_name, _of, _id, _type, _ops, _n, _vr, _vm, _er, \
|
||||
_em, _cr, _cm, _lr, _nlr, _delay, _fuv, \
|
||||
_ct, _ncl, _bpm) \
|
||||
{ \
|
||||
.name = _name, \
|
||||
.of_match = _of, \
|
||||
.regulators_node = of_match_ptr("regulators"), \
|
||||
.supply_name = _of, \
|
||||
.id = _id, \
|
||||
.ops = &(_ops), \
|
||||
.n_voltages = _n, \
|
||||
.type = _type, \
|
||||
.owner = THIS_MODULE, \
|
||||
.vsel_reg = _vr, \
|
||||
.vsel_mask = _vm, \
|
||||
.csel_reg = _cr, \
|
||||
.csel_mask = _cm, \
|
||||
.curr_table = _ct, \
|
||||
.n_current_limits = _ncl, \
|
||||
.enable_reg = _er, \
|
||||
.enable_mask = _em, \
|
||||
.volt_table = NULL, \
|
||||
.linear_ranges = _lr, \
|
||||
.n_linear_ranges = _nlr, \
|
||||
.ramp_delay = _delay, \
|
||||
.fixed_uV = _fuv, \
|
||||
.bypass_reg = _vr, \
|
||||
.bypass_mask = _bpm, \
|
||||
} \
|
||||
|
||||
static const struct linear_range bucks_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(300000, 0x0, 0xe, 20000),
|
||||
REGULATOR_LINEAR_RANGE(600000, 0xf, 0x72, 5000),
|
||||
REGULATOR_LINEAR_RANGE(1100000, 0x73, 0xaa, 10000),
|
||||
REGULATOR_LINEAR_RANGE(1660000, 0xab, 0xff, 20000),
|
||||
};
|
||||
|
||||
static const struct linear_range ldos_1_2_3_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(600000, 0x4, 0x3a, 50000),
|
||||
};
|
||||
|
||||
static const struct linear_range ldos_4_ranges[] = {
|
||||
REGULATOR_LINEAR_RANGE(1200000, 0x20, 0x74, 25000),
|
||||
};
|
||||
|
||||
/* Operations permitted on BUCK1/2/3/4/5 */
|
||||
static const struct regulator_ops tps6594_bucks_ops = {
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
.set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||
|
||||
};
|
||||
|
||||
/* Operations permitted on LDO1/2/3 */
|
||||
static const struct regulator_ops tps6594_ldos_1_2_3_ops = {
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
.set_bypass = regulator_set_bypass_regmap,
|
||||
.get_bypass = regulator_get_bypass_regmap,
|
||||
};
|
||||
|
||||
/* Operations permitted on LDO4 */
|
||||
static const struct regulator_ops tps6594_ldos_4_ops = {
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
};
|
||||
|
||||
static const struct regulator_desc buck_regs[] = {
|
||||
TPS6594_REGULATOR("BUCK1", "buck1", TPS6594_BUCK_1,
|
||||
REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
|
||||
TPS6594_REG_BUCKX_VOUT_1(0),
|
||||
TPS6594_MASK_BUCKS_VSET,
|
||||
TPS6594_REG_BUCKX_CTRL(0),
|
||||
TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,
|
||||
4, 0, 0, NULL, 0, 0),
|
||||
TPS6594_REGULATOR("BUCK2", "buck2", TPS6594_BUCK_2,
|
||||
REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
|
||||
TPS6594_REG_BUCKX_VOUT_1(1),
|
||||
TPS6594_MASK_BUCKS_VSET,
|
||||
TPS6594_REG_BUCKX_CTRL(1),
|
||||
TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,
|
||||
4, 0, 0, NULL, 0, 0),
|
||||
TPS6594_REGULATOR("BUCK3", "buck3", TPS6594_BUCK_3,
|
||||
REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
|
||||
TPS6594_REG_BUCKX_VOUT_1(2),
|
||||
TPS6594_MASK_BUCKS_VSET,
|
||||
TPS6594_REG_BUCKX_CTRL(2),
|
||||
TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,
|
||||
4, 0, 0, NULL, 0, 0),
|
||||
TPS6594_REGULATOR("BUCK4", "buck4", TPS6594_BUCK_4,
|
||||
REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
|
||||
TPS6594_REG_BUCKX_VOUT_1(3),
|
||||
TPS6594_MASK_BUCKS_VSET,
|
||||
TPS6594_REG_BUCKX_CTRL(3),
|
||||
TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,
|
||||
4, 0, 0, NULL, 0, 0),
|
||||
TPS6594_REGULATOR("BUCK5", "buck5", TPS6594_BUCK_5,
|
||||
REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
|
||||
TPS6594_REG_BUCKX_VOUT_1(4),
|
||||
TPS6594_MASK_BUCKS_VSET,
|
||||
TPS6594_REG_BUCKX_CTRL(4),
|
||||
TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,
|
||||
4, 0, 0, NULL, 0, 0),
|
||||
};
|
||||
|
||||
static struct tps6594_regulator_irq_type tps6594_buck1_irq_types[] = {
|
||||
{ TPS6594_IRQ_NAME_BUCK1_OV, "BUCK1", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
|
||||
{ TPS6594_IRQ_NAME_BUCK1_UV, "BUCK1", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
|
||||
{ TPS6594_IRQ_NAME_BUCK1_SC, "BUCK1", "short circuit", REGULATOR_EVENT_REGULATION_OUT },
|
||||
{ TPS6594_IRQ_NAME_BUCK1_ILIM, "BUCK1", "reach ilim, overcurrent",
|
||||
REGULATOR_EVENT_OVER_CURRENT },
|
||||
};
|
||||
|
||||
static struct tps6594_regulator_irq_type tps6594_buck2_irq_types[] = {
|
||||
{ TPS6594_IRQ_NAME_BUCK2_OV, "BUCK2", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
|
||||
{ TPS6594_IRQ_NAME_BUCK2_UV, "BUCK2", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
|
||||
{ TPS6594_IRQ_NAME_BUCK2_SC, "BUCK2", "short circuit", REGULATOR_EVENT_REGULATION_OUT },
|
||||
{ TPS6594_IRQ_NAME_BUCK2_ILIM, "BUCK2", "reach ilim, overcurrent",
|
||||
REGULATOR_EVENT_OVER_CURRENT },
|
||||
};
|
||||
|
||||
static struct tps6594_regulator_irq_type tps6594_buck3_irq_types[] = {
|
||||
{ TPS6594_IRQ_NAME_BUCK3_OV, "BUCK3", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
|
||||
{ TPS6594_IRQ_NAME_BUCK3_UV, "BUCK3", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
|
||||
{ TPS6594_IRQ_NAME_BUCK3_SC, "BUCK3", "short circuit", REGULATOR_EVENT_REGULATION_OUT },
|
||||
{ TPS6594_IRQ_NAME_BUCK3_ILIM, "BUCK3", "reach ilim, overcurrent",
|
||||
REGULATOR_EVENT_OVER_CURRENT },
|
||||
};
|
||||
|
||||
static struct tps6594_regulator_irq_type tps6594_buck4_irq_types[] = {
|
||||
{ TPS6594_IRQ_NAME_BUCK4_OV, "BUCK4", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
|
||||
{ TPS6594_IRQ_NAME_BUCK4_UV, "BUCK4", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
|
||||
{ TPS6594_IRQ_NAME_BUCK4_SC, "BUCK4", "short circuit", REGULATOR_EVENT_REGULATION_OUT },
|
||||
{ TPS6594_IRQ_NAME_BUCK4_ILIM, "BUCK4", "reach ilim, overcurrent",
|
||||
REGULATOR_EVENT_OVER_CURRENT },
|
||||
};
|
||||
|
||||
static struct tps6594_regulator_irq_type tps6594_buck5_irq_types[] = {
|
||||
{ TPS6594_IRQ_NAME_BUCK5_OV, "BUCK5", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
|
||||
{ TPS6594_IRQ_NAME_BUCK5_UV, "BUCK5", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
|
||||
{ TPS6594_IRQ_NAME_BUCK5_SC, "BUCK5", "short circuit", REGULATOR_EVENT_REGULATION_OUT },
|
||||
{ TPS6594_IRQ_NAME_BUCK5_ILIM, "BUCK5", "reach ilim, overcurrent",
|
||||
REGULATOR_EVENT_OVER_CURRENT },
|
||||
};
|
||||
|
||||
static struct tps6594_regulator_irq_type tps6594_ldo1_irq_types[] = {
|
||||
{ TPS6594_IRQ_NAME_LDO1_OV, "LDO1", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
|
||||
{ TPS6594_IRQ_NAME_LDO1_UV, "LDO1", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
|
||||
{ TPS6594_IRQ_NAME_LDO1_SC, "LDO1", "short circuit", REGULATOR_EVENT_REGULATION_OUT },
|
||||
{ TPS6594_IRQ_NAME_LDO1_ILIM, "LDO1", "reach ilim, overcurrent",
|
||||
REGULATOR_EVENT_OVER_CURRENT },
|
||||
};
|
||||
|
||||
static struct tps6594_regulator_irq_type tps6594_ldo2_irq_types[] = {
|
||||
{ TPS6594_IRQ_NAME_LDO2_OV, "LDO2", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
|
||||
{ TPS6594_IRQ_NAME_LDO2_UV, "LDO2", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
|
||||
{ TPS6594_IRQ_NAME_LDO2_SC, "LDO2", "short circuit", REGULATOR_EVENT_REGULATION_OUT },
|
||||
{ TPS6594_IRQ_NAME_LDO2_ILIM, "LDO2", "reach ilim, overcurrent",
|
||||
REGULATOR_EVENT_OVER_CURRENT },
|
||||
};
|
||||
|
||||
static struct tps6594_regulator_irq_type tps6594_ldo3_irq_types[] = {
|
||||
{ TPS6594_IRQ_NAME_LDO3_OV, "LDO3", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
|
||||
{ TPS6594_IRQ_NAME_LDO3_UV, "LDO3", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
|
||||
{ TPS6594_IRQ_NAME_LDO3_SC, "LDO3", "short circuit", REGULATOR_EVENT_REGULATION_OUT },
|
||||
{ TPS6594_IRQ_NAME_LDO3_ILIM, "LDO3", "reach ilim, overcurrent",
|
||||
REGULATOR_EVENT_OVER_CURRENT },
|
||||
};
|
||||
|
||||
static struct tps6594_regulator_irq_type tps6594_ldo4_irq_types[] = {
|
||||
{ TPS6594_IRQ_NAME_LDO4_OV, "LDO4", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
|
||||
{ TPS6594_IRQ_NAME_LDO4_UV, "LDO4", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
|
||||
{ TPS6594_IRQ_NAME_LDO4_SC, "LDO4", "short circuit", REGULATOR_EVENT_REGULATION_OUT },
|
||||
{ TPS6594_IRQ_NAME_LDO4_ILIM, "LDO4", "reach ilim, overcurrent",
|
||||
REGULATOR_EVENT_OVER_CURRENT },
|
||||
};
|
||||
|
||||
static struct tps6594_regulator_irq_type *tps6594_bucks_irq_types[] = {
|
||||
tps6594_buck1_irq_types,
|
||||
tps6594_buck2_irq_types,
|
||||
tps6594_buck3_irq_types,
|
||||
tps6594_buck4_irq_types,
|
||||
tps6594_buck5_irq_types,
|
||||
};
|
||||
|
||||
static struct tps6594_regulator_irq_type *tps6594_ldos_irq_types[] = {
|
||||
tps6594_ldo1_irq_types,
|
||||
tps6594_ldo2_irq_types,
|
||||
tps6594_ldo3_irq_types,
|
||||
tps6594_ldo4_irq_types,
|
||||
};
|
||||
|
||||
static const struct regulator_desc multi_regs[] = {
|
||||
TPS6594_REGULATOR("BUCK12", "buck12", TPS6594_BUCK_1,
|
||||
REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
|
||||
TPS6594_REG_BUCKX_VOUT_1(1),
|
||||
TPS6594_MASK_BUCKS_VSET,
|
||||
TPS6594_REG_BUCKX_CTRL(1),
|
||||
TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,
|
||||
4, 4000, 0, NULL, 0, 0),
|
||||
TPS6594_REGULATOR("BUCK34", "buck34", TPS6594_BUCK_3,
|
||||
REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
|
||||
TPS6594_REG_BUCKX_VOUT_1(3),
|
||||
TPS6594_MASK_BUCKS_VSET,
|
||||
TPS6594_REG_BUCKX_CTRL(3),
|
||||
TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,
|
||||
4, 0, 0, NULL, 0, 0),
|
||||
TPS6594_REGULATOR("BUCK123", "buck123", TPS6594_BUCK_1,
|
||||
REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
|
||||
TPS6594_REG_BUCKX_VOUT_1(1),
|
||||
TPS6594_MASK_BUCKS_VSET,
|
||||
TPS6594_REG_BUCKX_CTRL(1),
|
||||
TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,
|
||||
4, 4000, 0, NULL, 0, 0),
|
||||
TPS6594_REGULATOR("BUCK1234", "buck1234", TPS6594_BUCK_1,
|
||||
REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
|
||||
TPS6594_REG_BUCKX_VOUT_1(1),
|
||||
TPS6594_MASK_BUCKS_VSET,
|
||||
TPS6594_REG_BUCKX_CTRL(1),
|
||||
TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,
|
||||
4, 4000, 0, NULL, 0, 0),
|
||||
};
|
||||
|
||||
static const struct regulator_desc ldo_regs[] = {
|
||||
TPS6594_REGULATOR("LDO1", "ldo1", TPS6594_LDO_1,
|
||||
REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,
|
||||
TPS6594_REG_LDOX_VOUT(0),
|
||||
TPS6594_MASK_LDO123_VSET,
|
||||
TPS6594_REG_LDOX_CTRL(0),
|
||||
TPS6594_BIT_LDO_EN, 0, 0, ldos_1_2_3_ranges,
|
||||
1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),
|
||||
TPS6594_REGULATOR("LDO2", "ldo2", TPS6594_LDO_2,
|
||||
REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,
|
||||
TPS6594_REG_LDOX_VOUT(1),
|
||||
TPS6594_MASK_LDO123_VSET,
|
||||
TPS6594_REG_LDOX_CTRL(1),
|
||||
TPS6594_BIT_LDO_EN, 0, 0, ldos_1_2_3_ranges,
|
||||
1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),
|
||||
TPS6594_REGULATOR("LDO3", "ldo3", TPS6594_LDO_3,
|
||||
REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,
|
||||
TPS6594_REG_LDOX_VOUT(2),
|
||||
TPS6594_MASK_LDO123_VSET,
|
||||
TPS6594_REG_LDOX_CTRL(2),
|
||||
TPS6594_BIT_LDO_EN, 0, 0, ldos_1_2_3_ranges,
|
||||
1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),
|
||||
TPS6594_REGULATOR("LDO4", "ldo4", TPS6594_LDO_4,
|
||||
REGULATOR_VOLTAGE, tps6594_ldos_4_ops, TPS6594_MASK_LDO4_VSET >> 1,
|
||||
TPS6594_REG_LDOX_VOUT(3),
|
||||
TPS6594_MASK_LDO4_VSET,
|
||||
TPS6594_REG_LDOX_CTRL(3),
|
||||
TPS6594_BIT_LDO_EN, 0, 0, ldos_4_ranges,
|
||||
1, 0, 0, NULL, 0, 0),
|
||||
};
|
||||
|
||||
static irqreturn_t tps6594_regulator_irq_handler(int irq, void *data)
|
||||
{
|
||||
struct tps6594_regulator_irq_data *irq_data = data;
|
||||
|
||||
if (irq_data->type->event_name[0] == '\0') {
|
||||
/* This is the timeout interrupt no specific regulator */
|
||||
dev_err(irq_data->dev,
|
||||
"System was put in shutdown due to timeout during an active or standby transition.\n");
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
dev_err(irq_data->dev, "Error IRQ trap %s for %s\n",
|
||||
irq_data->type->event_name, irq_data->type->regulator_name);
|
||||
|
||||
regulator_notifier_call_chain(irq_data->rdev,
|
||||
irq_data->type->event, NULL);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int tps6594_request_reg_irqs(struct platform_device *pdev,
|
||||
struct regulator_dev *rdev,
|
||||
struct tps6594_regulator_irq_data *irq_data,
|
||||
struct tps6594_regulator_irq_type *tps6594_regs_irq_types,
|
||||
int *irq_idx)
|
||||
{
|
||||
struct tps6594_regulator_irq_type *irq_type;
|
||||
struct tps6594 *tps = dev_get_drvdata(pdev->dev.parent);
|
||||
int j;
|
||||
int irq;
|
||||
int error;
|
||||
|
||||
for (j = 0; j < REGS_INT_NB; j++) {
|
||||
irq_type = &tps6594_regs_irq_types[j];
|
||||
irq = platform_get_irq_byname(pdev, irq_type->irq_name);
|
||||
if (irq < 0)
|
||||
return -EINVAL;
|
||||
|
||||
irq_data[*irq_idx + j].dev = tps->dev;
|
||||
irq_data[*irq_idx + j].type = irq_type;
|
||||
irq_data[*irq_idx + j].rdev = rdev;
|
||||
|
||||
error = devm_request_threaded_irq(tps->dev, irq, NULL,
|
||||
tps6594_regulator_irq_handler,
|
||||
IRQF_ONESHOT,
|
||||
irq_type->irq_name,
|
||||
&irq_data[*irq_idx]);
|
||||
(*irq_idx)++;
|
||||
if (error) {
|
||||
dev_err(tps->dev, "tps6594 failed to request %s IRQ %d: %d\n",
|
||||
irq_type->irq_name, irq, error);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tps6594_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct tps6594 *tps = dev_get_drvdata(pdev->dev.parent);
|
||||
struct regulator_dev *rdev;
|
||||
struct device_node *np = NULL;
|
||||
struct device_node *np_pmic_parent = NULL;
|
||||
struct regulator_config config = {};
|
||||
struct tps6594_regulator_irq_data *irq_data;
|
||||
struct tps6594_ext_regulator_irq_data *irq_ext_reg_data;
|
||||
struct tps6594_regulator_irq_type *irq_type;
|
||||
u8 buck_configured[BUCK_NB] = { 0 };
|
||||
u8 buck_multi[MULTI_PHASE_NB] = { 0 };
|
||||
static const char * const multiphases[] = {"buck12", "buck123", "buck1234", "buck34"};
|
||||
static const char *npname;
|
||||
int error, i, irq, multi, delta;
|
||||
int irq_idx = 0;
|
||||
int buck_idx = 0;
|
||||
int ext_reg_irq_nb = 2;
|
||||
|
||||
enum {
|
||||
MULTI_BUCK12,
|
||||
MULTI_BUCK123,
|
||||
MULTI_BUCK1234,
|
||||
MULTI_BUCK12_34,
|
||||
MULTI_FIRST = MULTI_BUCK12,
|
||||
MULTI_LAST = MULTI_BUCK12_34,
|
||||
MULTI_NUM = MULTI_LAST - MULTI_FIRST + 1
|
||||
};
|
||||
|
||||
config.dev = tps->dev;
|
||||
config.driver_data = tps;
|
||||
config.regmap = tps->regmap;
|
||||
|
||||
/*
|
||||
* Switch case defines different possible multi phase config
|
||||
* This is based on dts buck node name.
|
||||
* Buck node name must be chosen accordingly.
|
||||
* Default case is no Multiphase buck.
|
||||
* In case of Multiphase configuration, value should be defined for
|
||||
* buck_configured to avoid creating bucks for every buck in multiphase
|
||||
*/
|
||||
for (multi = MULTI_FIRST; multi < MULTI_NUM; multi++) {
|
||||
np = of_find_node_by_name(tps->dev->of_node, multiphases[multi]);
|
||||
npname = of_node_full_name(np);
|
||||
np_pmic_parent = of_get_parent(of_get_parent(np));
|
||||
if (of_node_cmp(of_node_full_name(np_pmic_parent), tps->dev->of_node->full_name))
|
||||
continue;
|
||||
delta = strcmp(npname, multiphases[multi]);
|
||||
if (!delta) {
|
||||
switch (multi) {
|
||||
case MULTI_BUCK12:
|
||||
buck_multi[0] = 1;
|
||||
buck_configured[0] = 1;
|
||||
buck_configured[1] = 1;
|
||||
break;
|
||||
/* multiphase buck34 is supported only with buck12 */
|
||||
case MULTI_BUCK12_34:
|
||||
buck_multi[0] = 1;
|
||||
buck_multi[1] = 1;
|
||||
buck_configured[0] = 1;
|
||||
buck_configured[1] = 1;
|
||||
buck_configured[2] = 1;
|
||||
buck_configured[3] = 1;
|
||||
break;
|
||||
case MULTI_BUCK123:
|
||||
buck_multi[2] = 1;
|
||||
buck_configured[0] = 1;
|
||||
buck_configured[1] = 1;
|
||||
buck_configured[2] = 1;
|
||||
break;
|
||||
case MULTI_BUCK1234:
|
||||
buck_multi[3] = 1;
|
||||
buck_configured[0] = 1;
|
||||
buck_configured[1] = 1;
|
||||
buck_configured[2] = 1;
|
||||
buck_configured[3] = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tps->chip_id == LP8764)
|
||||
/* There is only 4 buck on LP8764 */
|
||||
buck_configured[4] = 1;
|
||||
|
||||
irq_data = devm_kmalloc_array(tps->dev,
|
||||
REGS_INT_NB * sizeof(struct tps6594_regulator_irq_data),
|
||||
ARRAY_SIZE(tps6594_bucks_irq_types) +
|
||||
ARRAY_SIZE(tps6594_ldos_irq_types),
|
||||
GFP_KERNEL);
|
||||
if (!irq_data)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < MULTI_PHASE_NB; i++) {
|
||||
if (buck_multi[i] == 0)
|
||||
continue;
|
||||
|
||||
rdev = devm_regulator_register(&pdev->dev, &multi_regs[i], &config);
|
||||
if (IS_ERR(rdev))
|
||||
return dev_err_probe(tps->dev, PTR_ERR(rdev),
|
||||
"failed to register %s regulator\n",
|
||||
pdev->name);
|
||||
|
||||
/* config multiphase buck12+buck34 */
|
||||
if (i == 1)
|
||||
buck_idx = 2;
|
||||
error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
|
||||
tps6594_bucks_irq_types[buck_idx], &irq_idx);
|
||||
if (error)
|
||||
return error;
|
||||
error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
|
||||
tps6594_bucks_irq_types[buck_idx + 1], &irq_idx);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (i == 2 || i == 3) {
|
||||
error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
|
||||
tps6594_bucks_irq_types[buck_idx + 2],
|
||||
&irq_idx);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
if (i == 3) {
|
||||
error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
|
||||
tps6594_bucks_irq_types[buck_idx + 3],
|
||||
&irq_idx);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < BUCK_NB; i++) {
|
||||
if (buck_configured[i] == 1)
|
||||
continue;
|
||||
|
||||
rdev = devm_regulator_register(&pdev->dev, &buck_regs[i], &config);
|
||||
if (IS_ERR(rdev))
|
||||
return dev_err_probe(tps->dev, PTR_ERR(rdev),
|
||||
"failed to register %s regulator\n",
|
||||
pdev->name);
|
||||
|
||||
error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
|
||||
tps6594_bucks_irq_types[i], &irq_idx);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
/* LP8764 dosen't have LDO */
|
||||
if (tps->chip_id != LP8764) {
|
||||
for (i = 0; i < ARRAY_SIZE(ldo_regs); i++) {
|
||||
rdev = devm_regulator_register(&pdev->dev, &ldo_regs[i], &config);
|
||||
if (IS_ERR(rdev))
|
||||
return dev_err_probe(tps->dev, PTR_ERR(rdev),
|
||||
"failed to register %s regulator\n",
|
||||
pdev->name);
|
||||
|
||||
error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
|
||||
tps6594_ldos_irq_types[i],
|
||||
&irq_idx);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
if (tps->chip_id == LP8764)
|
||||
ext_reg_irq_nb = ARRAY_SIZE(tps6594_ext_regulator_irq_types);
|
||||
|
||||
irq_ext_reg_data = devm_kmalloc_array(tps->dev,
|
||||
ext_reg_irq_nb,
|
||||
sizeof(struct tps6594_ext_regulator_irq_data),
|
||||
GFP_KERNEL);
|
||||
if (!irq_ext_reg_data)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < ext_reg_irq_nb; ++i) {
|
||||
irq_type = &tps6594_ext_regulator_irq_types[i];
|
||||
|
||||
irq = platform_get_irq_byname(pdev, irq_type->irq_name);
|
||||
if (irq < 0)
|
||||
return -EINVAL;
|
||||
|
||||
irq_ext_reg_data[i].dev = tps->dev;
|
||||
irq_ext_reg_data[i].type = irq_type;
|
||||
|
||||
error = devm_request_threaded_irq(tps->dev, irq, NULL,
|
||||
tps6594_regulator_irq_handler,
|
||||
IRQF_ONESHOT,
|
||||
irq_type->irq_name,
|
||||
&irq_ext_reg_data[i]);
|
||||
if (error)
|
||||
return dev_err_probe(tps->dev, error,
|
||||
"failed to request %s IRQ %d\n",
|
||||
irq_type->irq_name, irq);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver tps6594_regulator_driver = {
|
||||
.driver = {
|
||||
.name = "tps6594-regulator",
|
||||
},
|
||||
.probe = tps6594_regulator_probe,
|
||||
};
|
||||
|
||||
module_platform_driver(tps6594_regulator_driver);
|
||||
|
||||
MODULE_ALIAS("platform:tps6594-regulator");
|
||||
MODULE_AUTHOR("Jerome Neanne <jneanne@baylibre.com>");
|
||||
MODULE_DESCRIPTION("TPS6594 voltage regulator driver");
|
||||
MODULE_LICENSE("GPL");
|
@@ -395,7 +395,7 @@ config RTC_DRV_NCT3018Y
|
||||
|
||||
config RTC_DRV_RK808
|
||||
tristate "Rockchip RK805/RK808/RK809/RK817/RK818 RTC"
|
||||
depends on MFD_RK808
|
||||
depends on MFD_RK8XX
|
||||
help
|
||||
If you say yes here you will get support for the
|
||||
RTC of RK805, RK809 and RK817, RK808 and RK818 PMIC.
|
||||
|
@@ -682,6 +682,30 @@ EXPORT_SYMBOL(geni_se_clk_freq_match);
|
||||
#define GENI_SE_DMA_EOT_EN BIT(1)
|
||||
#define GENI_SE_DMA_AHB_ERR_EN BIT(2)
|
||||
#define GENI_SE_DMA_EOT_BUF BIT(0)
|
||||
|
||||
/**
|
||||
* geni_se_tx_init_dma() - Initiate TX DMA transfer on the serial engine
|
||||
* @se: Pointer to the concerned serial engine.
|
||||
* @iova: Mapped DMA address.
|
||||
* @len: Length of the TX buffer.
|
||||
*
|
||||
* This function is used to initiate DMA TX transfer.
|
||||
*/
|
||||
void geni_se_tx_init_dma(struct geni_se *se, dma_addr_t iova, size_t len)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = GENI_SE_DMA_DONE_EN;
|
||||
val |= GENI_SE_DMA_EOT_EN;
|
||||
val |= GENI_SE_DMA_AHB_ERR_EN;
|
||||
writel_relaxed(val, se->base + SE_DMA_TX_IRQ_EN_SET);
|
||||
writel_relaxed(lower_32_bits(iova), se->base + SE_DMA_TX_PTR_L);
|
||||
writel_relaxed(upper_32_bits(iova), se->base + SE_DMA_TX_PTR_H);
|
||||
writel_relaxed(GENI_SE_DMA_EOT_BUF, se->base + SE_DMA_TX_ATTR);
|
||||
writel(len, se->base + SE_DMA_TX_LEN);
|
||||
}
|
||||
EXPORT_SYMBOL(geni_se_tx_init_dma);
|
||||
|
||||
/**
|
||||
* geni_se_tx_dma_prep() - Prepare the serial engine for TX DMA transfer
|
||||
* @se: Pointer to the concerned serial engine.
|
||||
@@ -697,7 +721,6 @@ int geni_se_tx_dma_prep(struct geni_se *se, void *buf, size_t len,
|
||||
dma_addr_t *iova)
|
||||
{
|
||||
struct geni_wrapper *wrapper = se->wrapper;
|
||||
u32 val;
|
||||
|
||||
if (!wrapper)
|
||||
return -EINVAL;
|
||||
@@ -706,18 +729,35 @@ int geni_se_tx_dma_prep(struct geni_se *se, void *buf, size_t len,
|
||||
if (dma_mapping_error(wrapper->dev, *iova))
|
||||
return -EIO;
|
||||
|
||||
val = GENI_SE_DMA_DONE_EN;
|
||||
val |= GENI_SE_DMA_EOT_EN;
|
||||
val |= GENI_SE_DMA_AHB_ERR_EN;
|
||||
writel_relaxed(val, se->base + SE_DMA_TX_IRQ_EN_SET);
|
||||
writel_relaxed(lower_32_bits(*iova), se->base + SE_DMA_TX_PTR_L);
|
||||
writel_relaxed(upper_32_bits(*iova), se->base + SE_DMA_TX_PTR_H);
|
||||
writel_relaxed(GENI_SE_DMA_EOT_BUF, se->base + SE_DMA_TX_ATTR);
|
||||
writel(len, se->base + SE_DMA_TX_LEN);
|
||||
geni_se_tx_init_dma(se, *iova, len);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(geni_se_tx_dma_prep);
|
||||
|
||||
/**
|
||||
* geni_se_rx_init_dma() - Initiate RX DMA transfer on the serial engine
|
||||
* @se: Pointer to the concerned serial engine.
|
||||
* @iova: Mapped DMA address.
|
||||
* @len: Length of the RX buffer.
|
||||
*
|
||||
* This function is used to initiate DMA RX transfer.
|
||||
*/
|
||||
void geni_se_rx_init_dma(struct geni_se *se, dma_addr_t iova, size_t len)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = GENI_SE_DMA_DONE_EN;
|
||||
val |= GENI_SE_DMA_EOT_EN;
|
||||
val |= GENI_SE_DMA_AHB_ERR_EN;
|
||||
writel_relaxed(val, se->base + SE_DMA_RX_IRQ_EN_SET);
|
||||
writel_relaxed(lower_32_bits(iova), se->base + SE_DMA_RX_PTR_L);
|
||||
writel_relaxed(upper_32_bits(iova), se->base + SE_DMA_RX_PTR_H);
|
||||
/* RX does not have EOT buffer type bit. So just reset RX_ATTR */
|
||||
writel_relaxed(0, se->base + SE_DMA_RX_ATTR);
|
||||
writel(len, se->base + SE_DMA_RX_LEN);
|
||||
}
|
||||
EXPORT_SYMBOL(geni_se_rx_init_dma);
|
||||
|
||||
/**
|
||||
* geni_se_rx_dma_prep() - Prepare the serial engine for RX DMA transfer
|
||||
* @se: Pointer to the concerned serial engine.
|
||||
@@ -733,7 +773,6 @@ int geni_se_rx_dma_prep(struct geni_se *se, void *buf, size_t len,
|
||||
dma_addr_t *iova)
|
||||
{
|
||||
struct geni_wrapper *wrapper = se->wrapper;
|
||||
u32 val;
|
||||
|
||||
if (!wrapper)
|
||||
return -EINVAL;
|
||||
@@ -742,15 +781,7 @@ int geni_se_rx_dma_prep(struct geni_se *se, void *buf, size_t len,
|
||||
if (dma_mapping_error(wrapper->dev, *iova))
|
||||
return -EIO;
|
||||
|
||||
val = GENI_SE_DMA_DONE_EN;
|
||||
val |= GENI_SE_DMA_EOT_EN;
|
||||
val |= GENI_SE_DMA_AHB_ERR_EN;
|
||||
writel_relaxed(val, se->base + SE_DMA_RX_IRQ_EN_SET);
|
||||
writel_relaxed(lower_32_bits(*iova), se->base + SE_DMA_RX_PTR_L);
|
||||
writel_relaxed(upper_32_bits(*iova), se->base + SE_DMA_RX_PTR_H);
|
||||
/* RX does not have EOT buffer type bit. So just reset RX_ATTR */
|
||||
writel_relaxed(0, se->base + SE_DMA_RX_ATTR);
|
||||
writel(len, se->base + SE_DMA_RX_LEN);
|
||||
geni_se_rx_init_dma(se, *iova, len);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(geni_se_rx_dma_prep);
|
||||
|
@@ -97,8 +97,6 @@ struct spi_geni_master {
|
||||
struct dma_chan *tx;
|
||||
struct dma_chan *rx;
|
||||
int cur_xfer_mode;
|
||||
dma_addr_t tx_se_dma;
|
||||
dma_addr_t rx_se_dma;
|
||||
};
|
||||
|
||||
static int get_spi_clk_cfg(unsigned int speed_hz,
|
||||
@@ -174,7 +172,7 @@ static void handle_se_timeout(struct spi_master *spi,
|
||||
unmap_if_dma:
|
||||
if (mas->cur_xfer_mode == GENI_SE_DMA) {
|
||||
if (xfer) {
|
||||
if (xfer->tx_buf && mas->tx_se_dma) {
|
||||
if (xfer->tx_buf) {
|
||||
spin_lock_irq(&mas->lock);
|
||||
reinit_completion(&mas->tx_reset_done);
|
||||
writel(1, se->base + SE_DMA_TX_FSM_RST);
|
||||
@@ -182,9 +180,8 @@ unmap_if_dma:
|
||||
time_left = wait_for_completion_timeout(&mas->tx_reset_done, HZ);
|
||||
if (!time_left)
|
||||
dev_err(mas->dev, "DMA TX RESET failed\n");
|
||||
geni_se_tx_dma_unprep(se, mas->tx_se_dma, xfer->len);
|
||||
}
|
||||
if (xfer->rx_buf && mas->rx_se_dma) {
|
||||
if (xfer->rx_buf) {
|
||||
spin_lock_irq(&mas->lock);
|
||||
reinit_completion(&mas->rx_reset_done);
|
||||
writel(1, se->base + SE_DMA_RX_FSM_RST);
|
||||
@@ -192,7 +189,6 @@ unmap_if_dma:
|
||||
time_left = wait_for_completion_timeout(&mas->rx_reset_done, HZ);
|
||||
if (!time_left)
|
||||
dev_err(mas->dev, "DMA RX RESET failed\n");
|
||||
geni_se_rx_dma_unprep(se, mas->rx_se_dma, xfer->len);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
@@ -523,17 +519,36 @@ static int setup_gsi_xfer(struct spi_transfer *xfer, struct spi_geni_master *mas
|
||||
return 1;
|
||||
}
|
||||
|
||||
static u32 get_xfer_len_in_words(struct spi_transfer *xfer,
|
||||
struct spi_geni_master *mas)
|
||||
{
|
||||
u32 len;
|
||||
|
||||
if (!(mas->cur_bits_per_word % MIN_WORD_LEN))
|
||||
len = xfer->len * BITS_PER_BYTE / mas->cur_bits_per_word;
|
||||
else
|
||||
len = xfer->len / (mas->cur_bits_per_word / BITS_PER_BYTE + 1);
|
||||
len &= TRANS_LEN_MSK;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static bool geni_can_dma(struct spi_controller *ctlr,
|
||||
struct spi_device *slv, struct spi_transfer *xfer)
|
||||
{
|
||||
struct spi_geni_master *mas = spi_master_get_devdata(slv->master);
|
||||
u32 len, fifo_size;
|
||||
|
||||
/*
|
||||
* Return true if transfer needs to be mapped prior to
|
||||
* calling transfer_one which is the case only for GPI_DMA.
|
||||
* For SE_DMA mode, map/unmap is done in geni_se_*x_dma_prep.
|
||||
*/
|
||||
return mas->cur_xfer_mode == GENI_GPI_DMA;
|
||||
if (mas->cur_xfer_mode == GENI_GPI_DMA)
|
||||
return true;
|
||||
|
||||
len = get_xfer_len_in_words(xfer, mas);
|
||||
fifo_size = mas->tx_fifo_depth * mas->fifo_width_bits / mas->cur_bits_per_word;
|
||||
|
||||
if (len > fifo_size)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static int spi_geni_prepare_message(struct spi_master *spi,
|
||||
@@ -774,7 +789,7 @@ static int setup_se_xfer(struct spi_transfer *xfer,
|
||||
u16 mode, struct spi_master *spi)
|
||||
{
|
||||
u32 m_cmd = 0;
|
||||
u32 len, fifo_size;
|
||||
u32 len;
|
||||
struct geni_se *se = &mas->se;
|
||||
int ret;
|
||||
|
||||
@@ -806,11 +821,7 @@ static int setup_se_xfer(struct spi_transfer *xfer,
|
||||
mas->tx_rem_bytes = 0;
|
||||
mas->rx_rem_bytes = 0;
|
||||
|
||||
if (!(mas->cur_bits_per_word % MIN_WORD_LEN))
|
||||
len = xfer->len * BITS_PER_BYTE / mas->cur_bits_per_word;
|
||||
else
|
||||
len = xfer->len / (mas->cur_bits_per_word / BITS_PER_BYTE + 1);
|
||||
len &= TRANS_LEN_MSK;
|
||||
len = get_xfer_len_in_words(xfer, mas);
|
||||
|
||||
mas->cur_xfer = xfer;
|
||||
if (xfer->tx_buf) {
|
||||
@@ -825,9 +836,20 @@ static int setup_se_xfer(struct spi_transfer *xfer,
|
||||
mas->rx_rem_bytes = xfer->len;
|
||||
}
|
||||
|
||||
/* Select transfer mode based on transfer length */
|
||||
fifo_size = mas->tx_fifo_depth * mas->fifo_width_bits / mas->cur_bits_per_word;
|
||||
mas->cur_xfer_mode = (len <= fifo_size) ? GENI_SE_FIFO : GENI_SE_DMA;
|
||||
/*
|
||||
* Select DMA mode if sgt are present; and with only 1 entry
|
||||
* This is not a serious limitation because the xfer buffers are
|
||||
* expected to fit into in 1 entry almost always, and if any
|
||||
* doesn't for any reason we fall back to FIFO mode anyway
|
||||
*/
|
||||
if (!xfer->tx_sg.nents && !xfer->rx_sg.nents)
|
||||
mas->cur_xfer_mode = GENI_SE_FIFO;
|
||||
else if (xfer->tx_sg.nents > 1 || xfer->rx_sg.nents > 1) {
|
||||
dev_warn_once(mas->dev, "Doing FIFO, cannot handle tx_nents-%d, rx_nents-%d\n",
|
||||
xfer->tx_sg.nents, xfer->rx_sg.nents);
|
||||
mas->cur_xfer_mode = GENI_SE_FIFO;
|
||||
} else
|
||||
mas->cur_xfer_mode = GENI_SE_DMA;
|
||||
geni_se_select_mode(se, mas->cur_xfer_mode);
|
||||
|
||||
/*
|
||||
@@ -838,35 +860,17 @@ static int setup_se_xfer(struct spi_transfer *xfer,
|
||||
geni_se_setup_m_cmd(se, m_cmd, FRAGMENTATION);
|
||||
|
||||
if (mas->cur_xfer_mode == GENI_SE_DMA) {
|
||||
if (m_cmd & SPI_RX_ONLY) {
|
||||
ret = geni_se_rx_dma_prep(se, xfer->rx_buf,
|
||||
xfer->len, &mas->rx_se_dma);
|
||||
if (ret) {
|
||||
dev_err(mas->dev, "Failed to setup Rx dma %d\n", ret);
|
||||
mas->rx_se_dma = 0;
|
||||
goto unlock_and_return;
|
||||
}
|
||||
}
|
||||
if (m_cmd & SPI_TX_ONLY) {
|
||||
ret = geni_se_tx_dma_prep(se, (void *)xfer->tx_buf,
|
||||
xfer->len, &mas->tx_se_dma);
|
||||
if (ret) {
|
||||
dev_err(mas->dev, "Failed to setup Tx dma %d\n", ret);
|
||||
mas->tx_se_dma = 0;
|
||||
if (m_cmd & SPI_RX_ONLY) {
|
||||
/* Unmap rx buffer if duplex transfer */
|
||||
geni_se_rx_dma_unprep(se, mas->rx_se_dma, xfer->len);
|
||||
mas->rx_se_dma = 0;
|
||||
}
|
||||
goto unlock_and_return;
|
||||
}
|
||||
}
|
||||
if (m_cmd & SPI_RX_ONLY)
|
||||
geni_se_rx_init_dma(se, sg_dma_address(xfer->rx_sg.sgl),
|
||||
sg_dma_len(xfer->rx_sg.sgl));
|
||||
if (m_cmd & SPI_TX_ONLY)
|
||||
geni_se_tx_init_dma(se, sg_dma_address(xfer->tx_sg.sgl),
|
||||
sg_dma_len(xfer->tx_sg.sgl));
|
||||
} else if (m_cmd & SPI_TX_ONLY) {
|
||||
if (geni_spi_handle_tx(mas))
|
||||
writel(mas->tx_wm, se->base + SE_GENI_TX_WATERMARK_REG);
|
||||
}
|
||||
|
||||
unlock_and_return:
|
||||
spin_unlock_irq(&mas->lock);
|
||||
return ret;
|
||||
}
|
||||
@@ -967,14 +971,6 @@ static irqreturn_t geni_spi_isr(int irq, void *data)
|
||||
if (dma_rx_status & RX_RESET_DONE)
|
||||
complete(&mas->rx_reset_done);
|
||||
if (!mas->tx_rem_bytes && !mas->rx_rem_bytes && xfer) {
|
||||
if (xfer->tx_buf && mas->tx_se_dma) {
|
||||
geni_se_tx_dma_unprep(se, mas->tx_se_dma, xfer->len);
|
||||
mas->tx_se_dma = 0;
|
||||
}
|
||||
if (xfer->rx_buf && mas->rx_se_dma) {
|
||||
geni_se_rx_dma_unprep(se, mas->rx_se_dma, xfer->len);
|
||||
mas->rx_se_dma = 0;
|
||||
}
|
||||
spi_finalize_current_transfer(spi);
|
||||
mas->cur_xfer = NULL;
|
||||
}
|
||||
@@ -1059,6 +1055,7 @@ static int spi_geni_probe(struct platform_device *pdev)
|
||||
spi->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
|
||||
spi->num_chipselect = 4;
|
||||
spi->max_speed_hz = 50000000;
|
||||
spi->max_dma_len = 0xffff0; /* 24 bits for tx/rx dma length */
|
||||
spi->prepare_message = spi_geni_prepare_message;
|
||||
spi->transfer_one = spi_geni_transfer_one;
|
||||
spi->can_dma = geni_can_dma;
|
||||
|
@@ -17,6 +17,7 @@ enum axp20x_variants {
|
||||
AXP221_ID,
|
||||
AXP223_ID,
|
||||
AXP288_ID,
|
||||
AXP313A_ID,
|
||||
AXP803_ID,
|
||||
AXP806_ID,
|
||||
AXP809_ID,
|
||||
@@ -92,6 +93,17 @@ enum axp20x_variants {
|
||||
#define AXP22X_ALDO3_V_OUT 0x2a
|
||||
#define AXP22X_CHRG_CTRL3 0x35
|
||||
|
||||
#define AXP313A_ON_INDICATE 0x00
|
||||
#define AXP313A_OUTPUT_CONTROL 0x10
|
||||
#define AXP313A_DCDC1_CONRTOL 0x13
|
||||
#define AXP313A_DCDC2_CONRTOL 0x14
|
||||
#define AXP313A_DCDC3_CONRTOL 0x15
|
||||
#define AXP313A_ALDO1_CONRTOL 0x16
|
||||
#define AXP313A_DLDO1_CONRTOL 0x17
|
||||
#define AXP313A_SHUTDOWN_CTRL 0x1a
|
||||
#define AXP313A_IRQ_EN 0x20
|
||||
#define AXP313A_IRQ_STATE 0x21
|
||||
|
||||
#define AXP806_STARTUP_SRC 0x00
|
||||
#define AXP806_CHIP_ID 0x03
|
||||
#define AXP806_PWR_OUT_CTRL1 0x10
|
||||
@@ -363,6 +375,16 @@ enum {
|
||||
AXP22X_REG_ID_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
AXP313A_DCDC1 = 0,
|
||||
AXP313A_DCDC2,
|
||||
AXP313A_DCDC3,
|
||||
AXP313A_ALDO1,
|
||||
AXP313A_DLDO1,
|
||||
AXP313A_RTC_LDO,
|
||||
AXP313A_REG_ID_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
AXP806_DCDCA = 0,
|
||||
AXP806_DCDCB,
|
||||
@@ -616,6 +638,16 @@ enum axp288_irqs {
|
||||
AXP288_IRQ_BC_USB_CHNG,
|
||||
};
|
||||
|
||||
enum axp313a_irqs {
|
||||
AXP313A_IRQ_DIE_TEMP_HIGH,
|
||||
AXP313A_IRQ_DCDC2_V_LOW = 2,
|
||||
AXP313A_IRQ_DCDC3_V_LOW,
|
||||
AXP313A_IRQ_PEK_LONG,
|
||||
AXP313A_IRQ_PEK_SHORT,
|
||||
AXP313A_IRQ_PEK_FAL_EDGE,
|
||||
AXP313A_IRQ_PEK_RIS_EDGE,
|
||||
};
|
||||
|
||||
enum axp803_irqs {
|
||||
AXP803_IRQ_ACIN_OVER_V = 1,
|
||||
AXP803_IRQ_ACIN_PLUGIN,
|
||||
|
@@ -289,6 +289,414 @@ enum rk805_reg {
|
||||
#define RK805_INT_ALARM_EN (1 << 3)
|
||||
#define RK805_INT_TIMER_EN (1 << 2)
|
||||
|
||||
/* RK806 */
|
||||
#define RK806_POWER_EN0 0x0
|
||||
#define RK806_POWER_EN1 0x1
|
||||
#define RK806_POWER_EN2 0x2
|
||||
#define RK806_POWER_EN3 0x3
|
||||
#define RK806_POWER_EN4 0x4
|
||||
#define RK806_POWER_EN5 0x5
|
||||
#define RK806_POWER_SLP_EN0 0x6
|
||||
#define RK806_POWER_SLP_EN1 0x7
|
||||
#define RK806_POWER_SLP_EN2 0x8
|
||||
#define RK806_POWER_DISCHRG_EN0 0x9
|
||||
#define RK806_POWER_DISCHRG_EN1 0xA
|
||||
#define RK806_POWER_DISCHRG_EN2 0xB
|
||||
#define RK806_BUCK_FB_CONFIG 0xC
|
||||
#define RK806_SLP_LP_CONFIG 0xD
|
||||
#define RK806_POWER_FPWM_EN0 0xE
|
||||
#define RK806_POWER_FPWM_EN1 0xF
|
||||
#define RK806_BUCK1_CONFIG 0x10
|
||||
#define RK806_BUCK2_CONFIG 0x11
|
||||
#define RK806_BUCK3_CONFIG 0x12
|
||||
#define RK806_BUCK4_CONFIG 0x13
|
||||
#define RK806_BUCK5_CONFIG 0x14
|
||||
#define RK806_BUCK6_CONFIG 0x15
|
||||
#define RK806_BUCK7_CONFIG 0x16
|
||||
#define RK806_BUCK8_CONFIG 0x17
|
||||
#define RK806_BUCK9_CONFIG 0x18
|
||||
#define RK806_BUCK10_CONFIG 0x19
|
||||
#define RK806_BUCK1_ON_VSEL 0x1A
|
||||
#define RK806_BUCK2_ON_VSEL 0x1B
|
||||
#define RK806_BUCK3_ON_VSEL 0x1C
|
||||
#define RK806_BUCK4_ON_VSEL 0x1D
|
||||
#define RK806_BUCK5_ON_VSEL 0x1E
|
||||
#define RK806_BUCK6_ON_VSEL 0x1F
|
||||
#define RK806_BUCK7_ON_VSEL 0x20
|
||||
#define RK806_BUCK8_ON_VSEL 0x21
|
||||
#define RK806_BUCK9_ON_VSEL 0x22
|
||||
#define RK806_BUCK10_ON_VSEL 0x23
|
||||
#define RK806_BUCK1_SLP_VSEL 0x24
|
||||
#define RK806_BUCK2_SLP_VSEL 0x25
|
||||
#define RK806_BUCK3_SLP_VSEL 0x26
|
||||
#define RK806_BUCK4_SLP_VSEL 0x27
|
||||
#define RK806_BUCK5_SLP_VSEL 0x28
|
||||
#define RK806_BUCK6_SLP_VSEL 0x29
|
||||
#define RK806_BUCK7_SLP_VSEL 0x2A
|
||||
#define RK806_BUCK8_SLP_VSEL 0x2B
|
||||
#define RK806_BUCK9_SLP_VSEL 0x2D
|
||||
#define RK806_BUCK10_SLP_VSEL 0x2E
|
||||
#define RK806_BUCK_DEBUG1 0x30
|
||||
#define RK806_BUCK_DEBUG2 0x31
|
||||
#define RK806_BUCK_DEBUG3 0x32
|
||||
#define RK806_BUCK_DEBUG4 0x33
|
||||
#define RK806_BUCK_DEBUG5 0x34
|
||||
#define RK806_BUCK_DEBUG6 0x35
|
||||
#define RK806_BUCK_DEBUG7 0x36
|
||||
#define RK806_BUCK_DEBUG8 0x37
|
||||
#define RK806_BUCK_DEBUG9 0x38
|
||||
#define RK806_BUCK_DEBUG10 0x39
|
||||
#define RK806_BUCK_DEBUG11 0x3A
|
||||
#define RK806_BUCK_DEBUG12 0x3B
|
||||
#define RK806_BUCK_DEBUG13 0x3C
|
||||
#define RK806_BUCK_DEBUG14 0x3D
|
||||
#define RK806_BUCK_DEBUG15 0x3E
|
||||
#define RK806_BUCK_DEBUG16 0x3F
|
||||
#define RK806_BUCK_DEBUG17 0x40
|
||||
#define RK806_BUCK_DEBUG18 0x41
|
||||
#define RK806_NLDO_IMAX 0x42
|
||||
#define RK806_NLDO1_ON_VSEL 0x43
|
||||
#define RK806_NLDO2_ON_VSEL 0x44
|
||||
#define RK806_NLDO3_ON_VSEL 0x45
|
||||
#define RK806_NLDO4_ON_VSEL 0x46
|
||||
#define RK806_NLDO5_ON_VSEL 0x47
|
||||
#define RK806_NLDO1_SLP_VSEL 0x48
|
||||
#define RK806_NLDO2_SLP_VSEL 0x49
|
||||
#define RK806_NLDO3_SLP_VSEL 0x4A
|
||||
#define RK806_NLDO4_SLP_VSEL 0x4B
|
||||
#define RK806_NLDO5_SLP_VSEL 0x4C
|
||||
#define RK806_PLDO_IMAX 0x4D
|
||||
#define RK806_PLDO1_ON_VSEL 0x4E
|
||||
#define RK806_PLDO2_ON_VSEL 0x4F
|
||||
#define RK806_PLDO3_ON_VSEL 0x50
|
||||
#define RK806_PLDO4_ON_VSEL 0x51
|
||||
#define RK806_PLDO5_ON_VSEL 0x52
|
||||
#define RK806_PLDO6_ON_VSEL 0x53
|
||||
#define RK806_PLDO1_SLP_VSEL 0x54
|
||||
#define RK806_PLDO2_SLP_VSEL 0x55
|
||||
#define RK806_PLDO3_SLP_VSEL 0x56
|
||||
#define RK806_PLDO4_SLP_VSEL 0x57
|
||||
#define RK806_PLDO5_SLP_VSEL 0x58
|
||||
#define RK806_PLDO6_SLP_VSEL 0x59
|
||||
#define RK806_CHIP_NAME 0x5A
|
||||
#define RK806_CHIP_VER 0x5B
|
||||
#define RK806_OTP_VER 0x5C
|
||||
#define RK806_SYS_STS 0x5D
|
||||
#define RK806_SYS_CFG0 0x5E
|
||||
#define RK806_SYS_CFG1 0x5F
|
||||
#define RK806_SYS_OPTION 0x61
|
||||
#define RK806_SLEEP_CONFIG0 0x62
|
||||
#define RK806_SLEEP_CONFIG1 0x63
|
||||
#define RK806_SLEEP_CTR_SEL0 0x64
|
||||
#define RK806_SLEEP_CTR_SEL1 0x65
|
||||
#define RK806_SLEEP_CTR_SEL2 0x66
|
||||
#define RK806_SLEEP_CTR_SEL3 0x67
|
||||
#define RK806_SLEEP_CTR_SEL4 0x68
|
||||
#define RK806_SLEEP_CTR_SEL5 0x69
|
||||
#define RK806_DVS_CTRL_SEL0 0x6A
|
||||
#define RK806_DVS_CTRL_SEL1 0x6B
|
||||
#define RK806_DVS_CTRL_SEL2 0x6C
|
||||
#define RK806_DVS_CTRL_SEL3 0x6D
|
||||
#define RK806_DVS_CTRL_SEL4 0x6E
|
||||
#define RK806_DVS_CTRL_SEL5 0x6F
|
||||
#define RK806_DVS_START_CTRL 0x70
|
||||
#define RK806_SLEEP_GPIO 0x71
|
||||
#define RK806_SYS_CFG3 0x72
|
||||
#define RK806_ON_SOURCE 0x74
|
||||
#define RK806_OFF_SOURCE 0x75
|
||||
#define RK806_PWRON_KEY 0x76
|
||||
#define RK806_INT_STS0 0x77
|
||||
#define RK806_INT_MSK0 0x78
|
||||
#define RK806_INT_STS1 0x79
|
||||
#define RK806_INT_MSK1 0x7A
|
||||
#define RK806_GPIO_INT_CONFIG 0x7B
|
||||
#define RK806_DATA_REG0 0x7C
|
||||
#define RK806_DATA_REG1 0x7D
|
||||
#define RK806_DATA_REG2 0x7E
|
||||
#define RK806_DATA_REG3 0x7F
|
||||
#define RK806_DATA_REG4 0x80
|
||||
#define RK806_DATA_REG5 0x81
|
||||
#define RK806_DATA_REG6 0x82
|
||||
#define RK806_DATA_REG7 0x83
|
||||
#define RK806_DATA_REG8 0x84
|
||||
#define RK806_DATA_REG9 0x85
|
||||
#define RK806_DATA_REG10 0x86
|
||||
#define RK806_DATA_REG11 0x87
|
||||
#define RK806_DATA_REG12 0x88
|
||||
#define RK806_DATA_REG13 0x89
|
||||
#define RK806_DATA_REG14 0x8A
|
||||
#define RK806_DATA_REG15 0x8B
|
||||
#define RK806_TM_REG 0x8C
|
||||
#define RK806_OTP_EN_REG 0x8D
|
||||
#define RK806_FUNC_OTP_EN_REG 0x8E
|
||||
#define RK806_TEST_REG1 0x8F
|
||||
#define RK806_TEST_REG2 0x90
|
||||
#define RK806_TEST_REG3 0x91
|
||||
#define RK806_TEST_REG4 0x92
|
||||
#define RK806_TEST_REG5 0x93
|
||||
#define RK806_BUCK_VSEL_OTP_REG0 0x94
|
||||
#define RK806_BUCK_VSEL_OTP_REG1 0x95
|
||||
#define RK806_BUCK_VSEL_OTP_REG2 0x96
|
||||
#define RK806_BUCK_VSEL_OTP_REG3 0x97
|
||||
#define RK806_BUCK_VSEL_OTP_REG4 0x98
|
||||
#define RK806_BUCK_VSEL_OTP_REG5 0x99
|
||||
#define RK806_BUCK_VSEL_OTP_REG6 0x9A
|
||||
#define RK806_BUCK_VSEL_OTP_REG7 0x9B
|
||||
#define RK806_BUCK_VSEL_OTP_REG8 0x9C
|
||||
#define RK806_BUCK_VSEL_OTP_REG9 0x9D
|
||||
#define RK806_NLDO1_VSEL_OTP_REG0 0x9E
|
||||
#define RK806_NLDO1_VSEL_OTP_REG1 0x9F
|
||||
#define RK806_NLDO1_VSEL_OTP_REG2 0xA0
|
||||
#define RK806_NLDO1_VSEL_OTP_REG3 0xA1
|
||||
#define RK806_NLDO1_VSEL_OTP_REG4 0xA2
|
||||
#define RK806_PLDO_VSEL_OTP_REG0 0xA3
|
||||
#define RK806_PLDO_VSEL_OTP_REG1 0xA4
|
||||
#define RK806_PLDO_VSEL_OTP_REG2 0xA5
|
||||
#define RK806_PLDO_VSEL_OTP_REG3 0xA6
|
||||
#define RK806_PLDO_VSEL_OTP_REG4 0xA7
|
||||
#define RK806_PLDO_VSEL_OTP_REG5 0xA8
|
||||
#define RK806_BUCK_EN_OTP_REG1 0xA9
|
||||
#define RK806_NLDO_EN_OTP_REG1 0xAA
|
||||
#define RK806_PLDO_EN_OTP_REG1 0xAB
|
||||
#define RK806_BUCK_FB_RES_OTP_REG1 0xAC
|
||||
#define RK806_OTP_RESEV_REG0 0xAD
|
||||
#define RK806_OTP_RESEV_REG1 0xAE
|
||||
#define RK806_OTP_RESEV_REG2 0xAF
|
||||
#define RK806_OTP_RESEV_REG3 0xB0
|
||||
#define RK806_OTP_RESEV_REG4 0xB1
|
||||
#define RK806_BUCK_SEQ_REG0 0xB2
|
||||
#define RK806_BUCK_SEQ_REG1 0xB3
|
||||
#define RK806_BUCK_SEQ_REG2 0xB4
|
||||
#define RK806_BUCK_SEQ_REG3 0xB5
|
||||
#define RK806_BUCK_SEQ_REG4 0xB6
|
||||
#define RK806_BUCK_SEQ_REG5 0xB7
|
||||
#define RK806_BUCK_SEQ_REG6 0xB8
|
||||
#define RK806_BUCK_SEQ_REG7 0xB9
|
||||
#define RK806_BUCK_SEQ_REG8 0xBA
|
||||
#define RK806_BUCK_SEQ_REG9 0xBB
|
||||
#define RK806_BUCK_SEQ_REG10 0xBC
|
||||
#define RK806_BUCK_SEQ_REG11 0xBD
|
||||
#define RK806_BUCK_SEQ_REG12 0xBE
|
||||
#define RK806_BUCK_SEQ_REG13 0xBF
|
||||
#define RK806_BUCK_SEQ_REG14 0xC0
|
||||
#define RK806_BUCK_SEQ_REG15 0xC1
|
||||
#define RK806_BUCK_SEQ_REG16 0xC2
|
||||
#define RK806_BUCK_SEQ_REG17 0xC3
|
||||
#define RK806_HK_TRIM_REG1 0xC4
|
||||
#define RK806_HK_TRIM_REG2 0xC5
|
||||
#define RK806_BUCK_REF_TRIM_REG1 0xC6
|
||||
#define RK806_BUCK_REF_TRIM_REG2 0xC7
|
||||
#define RK806_BUCK_REF_TRIM_REG3 0xC8
|
||||
#define RK806_BUCK_REF_TRIM_REG4 0xC9
|
||||
#define RK806_BUCK_REF_TRIM_REG5 0xCA
|
||||
#define RK806_BUCK_OSC_TRIM_REG1 0xCB
|
||||
#define RK806_BUCK_OSC_TRIM_REG2 0xCC
|
||||
#define RK806_BUCK_OSC_TRIM_REG3 0xCD
|
||||
#define RK806_BUCK_OSC_TRIM_REG4 0xCE
|
||||
#define RK806_BUCK_OSC_TRIM_REG5 0xCF
|
||||
#define RK806_BUCK_TRIM_ZCDIOS_REG1 0xD0
|
||||
#define RK806_BUCK_TRIM_ZCDIOS_REG2 0xD1
|
||||
#define RK806_NLDO_TRIM_REG1 0xD2
|
||||
#define RK806_NLDO_TRIM_REG2 0xD3
|
||||
#define RK806_NLDO_TRIM_REG3 0xD4
|
||||
#define RK806_PLDO_TRIM_REG1 0xD5
|
||||
#define RK806_PLDO_TRIM_REG2 0xD6
|
||||
#define RK806_PLDO_TRIM_REG3 0xD7
|
||||
#define RK806_TRIM_ICOMP_REG1 0xD8
|
||||
#define RK806_TRIM_ICOMP_REG2 0xD9
|
||||
#define RK806_EFUSE_CONTROL_REGH 0xDA
|
||||
#define RK806_FUSE_PROG_REG 0xDB
|
||||
#define RK806_MAIN_FSM_STS_REG 0xDD
|
||||
#define RK806_FSM_REG 0xDE
|
||||
#define RK806_TOP_RESEV_OFFR 0xEC
|
||||
#define RK806_TOP_RESEV_POR 0xED
|
||||
#define RK806_BUCK_VRSN_REG1 0xEE
|
||||
#define RK806_BUCK_VRSN_REG2 0xEF
|
||||
#define RK806_NLDO_RLOAD_SEL_REG1 0xF0
|
||||
#define RK806_PLDO_RLOAD_SEL_REG1 0xF1
|
||||
#define RK806_PLDO_RLOAD_SEL_REG2 0xF2
|
||||
#define RK806_BUCK_CMIN_MX_REG1 0xF3
|
||||
#define RK806_BUCK_CMIN_MX_REG2 0xF4
|
||||
#define RK806_BUCK_FREQ_SET_REG1 0xF5
|
||||
#define RK806_BUCK_FREQ_SET_REG2 0xF6
|
||||
#define RK806_BUCK_RS_MEABS_REG1 0xF7
|
||||
#define RK806_BUCK_RS_MEABS_REG2 0xF8
|
||||
#define RK806_BUCK_RS_ZDLEB_REG1 0xF9
|
||||
#define RK806_BUCK_RS_ZDLEB_REG2 0xFA
|
||||
#define RK806_BUCK_RSERVE_REG1 0xFB
|
||||
#define RK806_BUCK_RSERVE_REG2 0xFC
|
||||
#define RK806_BUCK_RSERVE_REG3 0xFD
|
||||
#define RK806_BUCK_RSERVE_REG4 0xFE
|
||||
#define RK806_BUCK_RSERVE_REG5 0xFF
|
||||
|
||||
/* INT_STS Register field definitions */
|
||||
#define RK806_INT_STS_PWRON_FALL BIT(0)
|
||||
#define RK806_INT_STS_PWRON_RISE BIT(1)
|
||||
#define RK806_INT_STS_PWRON BIT(2)
|
||||
#define RK806_INT_STS_PWRON_LP BIT(3)
|
||||
#define RK806_INT_STS_HOTDIE BIT(4)
|
||||
#define RK806_INT_STS_VDC_RISE BIT(5)
|
||||
#define RK806_INT_STS_VDC_FALL BIT(6)
|
||||
#define RK806_INT_STS_VB_LO BIT(7)
|
||||
#define RK806_INT_STS_REV0 BIT(0)
|
||||
#define RK806_INT_STS_REV1 BIT(1)
|
||||
#define RK806_INT_STS_REV2 BIT(2)
|
||||
#define RK806_INT_STS_CRC_ERROR BIT(3)
|
||||
#define RK806_INT_STS_SLP3_GPIO BIT(4)
|
||||
#define RK806_INT_STS_SLP2_GPIO BIT(5)
|
||||
#define RK806_INT_STS_SLP1_GPIO BIT(6)
|
||||
#define RK806_INT_STS_WDT BIT(7)
|
||||
|
||||
/* SPI command */
|
||||
#define RK806_CMD_READ 0
|
||||
#define RK806_CMD_WRITE BIT(7)
|
||||
#define RK806_CMD_CRC_EN BIT(6)
|
||||
#define RK806_CMD_CRC_DIS 0
|
||||
#define RK806_CMD_LEN_MSK 0x0f
|
||||
#define RK806_REG_H 0x00
|
||||
|
||||
#define VERSION_AB 0x01
|
||||
|
||||
enum rk806_reg_id {
|
||||
RK806_ID_DCDC1 = 0,
|
||||
RK806_ID_DCDC2,
|
||||
RK806_ID_DCDC3,
|
||||
RK806_ID_DCDC4,
|
||||
RK806_ID_DCDC5,
|
||||
RK806_ID_DCDC6,
|
||||
RK806_ID_DCDC7,
|
||||
RK806_ID_DCDC8,
|
||||
RK806_ID_DCDC9,
|
||||
RK806_ID_DCDC10,
|
||||
|
||||
RK806_ID_NLDO1,
|
||||
RK806_ID_NLDO2,
|
||||
RK806_ID_NLDO3,
|
||||
RK806_ID_NLDO4,
|
||||
RK806_ID_NLDO5,
|
||||
|
||||
RK806_ID_PLDO1,
|
||||
RK806_ID_PLDO2,
|
||||
RK806_ID_PLDO3,
|
||||
RK806_ID_PLDO4,
|
||||
RK806_ID_PLDO5,
|
||||
RK806_ID_PLDO6,
|
||||
RK806_ID_END,
|
||||
};
|
||||
|
||||
/* Define the RK806 IRQ numbers */
|
||||
enum rk806_irqs {
|
||||
/* INT_STS0 registers */
|
||||
RK806_IRQ_PWRON_FALL,
|
||||
RK806_IRQ_PWRON_RISE,
|
||||
RK806_IRQ_PWRON,
|
||||
RK806_IRQ_PWRON_LP,
|
||||
RK806_IRQ_HOTDIE,
|
||||
RK806_IRQ_VDC_RISE,
|
||||
RK806_IRQ_VDC_FALL,
|
||||
RK806_IRQ_VB_LO,
|
||||
|
||||
/* INT_STS0 registers */
|
||||
RK806_IRQ_REV0,
|
||||
RK806_IRQ_REV1,
|
||||
RK806_IRQ_REV2,
|
||||
RK806_IRQ_CRC_ERROR,
|
||||
RK806_IRQ_SLP3_GPIO,
|
||||
RK806_IRQ_SLP2_GPIO,
|
||||
RK806_IRQ_SLP1_GPIO,
|
||||
RK806_IRQ_WDT,
|
||||
};
|
||||
|
||||
/* VCC1 Low Voltage Threshold */
|
||||
enum rk806_lv_sel {
|
||||
VB_LO_SEL_2800,
|
||||
VB_LO_SEL_2900,
|
||||
VB_LO_SEL_3000,
|
||||
VB_LO_SEL_3100,
|
||||
VB_LO_SEL_3200,
|
||||
VB_LO_SEL_3300,
|
||||
VB_LO_SEL_3400,
|
||||
VB_LO_SEL_3500,
|
||||
};
|
||||
|
||||
/* System Shutdown Voltage Select */
|
||||
enum rk806_uv_sel {
|
||||
VB_UV_SEL_2700,
|
||||
VB_UV_SEL_2800,
|
||||
VB_UV_SEL_2900,
|
||||
VB_UV_SEL_3000,
|
||||
VB_UV_SEL_3100,
|
||||
VB_UV_SEL_3200,
|
||||
VB_UV_SEL_3300,
|
||||
VB_UV_SEL_3400,
|
||||
};
|
||||
|
||||
/* Pin Function */
|
||||
enum rk806_pwrctrl_fun {
|
||||
PWRCTRL_NULL_FUN,
|
||||
PWRCTRL_SLP_FUN,
|
||||
PWRCTRL_POWOFF_FUN,
|
||||
PWRCTRL_RST_FUN,
|
||||
PWRCTRL_DVS_FUN,
|
||||
PWRCTRL_GPIO_FUN,
|
||||
};
|
||||
|
||||
/* Pin Polarity */
|
||||
enum rk806_pin_level {
|
||||
POL_LOW,
|
||||
POL_HIGH,
|
||||
};
|
||||
|
||||
enum rk806_vsel_ctr_sel {
|
||||
CTR_BY_NO_EFFECT,
|
||||
CTR_BY_PWRCTRL1,
|
||||
CTR_BY_PWRCTRL2,
|
||||
CTR_BY_PWRCTRL3,
|
||||
};
|
||||
|
||||
enum rk806_dvs_ctr_sel {
|
||||
CTR_SEL_NO_EFFECT,
|
||||
CTR_SEL_DVS_START1,
|
||||
CTR_SEL_DVS_START2,
|
||||
CTR_SEL_DVS_START3,
|
||||
};
|
||||
|
||||
enum rk806_pin_dr_sel {
|
||||
RK806_PIN_INPUT,
|
||||
RK806_PIN_OUTPUT,
|
||||
};
|
||||
|
||||
#define RK806_INT_POL_MSK BIT(1)
|
||||
#define RK806_INT_POL_H BIT(1)
|
||||
#define RK806_INT_POL_L 0
|
||||
|
||||
#define RK806_SLAVE_RESTART_FUN_MSK BIT(1)
|
||||
#define RK806_SLAVE_RESTART_FUN_EN BIT(1)
|
||||
#define RK806_SLAVE_RESTART_FUN_OFF 0
|
||||
|
||||
#define RK806_SYS_ENB2_2M_MSK BIT(1)
|
||||
#define RK806_SYS_ENB2_2M_EN BIT(1)
|
||||
#define RK806_SYS_ENB2_2M_OFF 0
|
||||
|
||||
enum rk806_int_fun {
|
||||
RK806_INT_ONLY,
|
||||
RK806_INT_ADN_WKUP,
|
||||
};
|
||||
|
||||
enum rk806_dvs_mode {
|
||||
RK806_DVS_NOT_SUPPORT,
|
||||
RK806_DVS_START1,
|
||||
RK806_DVS_START2,
|
||||
RK806_DVS_START3,
|
||||
RK806_DVS_PWRCTRL1,
|
||||
RK806_DVS_PWRCTRL2,
|
||||
RK806_DVS_PWRCTRL3,
|
||||
RK806_DVS_START_PWRCTR1,
|
||||
RK806_DVS_START_PWRCTR2,
|
||||
RK806_DVS_START_PWRCTR3,
|
||||
RK806_DVS_END,
|
||||
};
|
||||
|
||||
/* RK808 IRQ Definitions */
|
||||
#define RK808_IRQ_VOUT_LO 0
|
||||
#define RK808_IRQ_VB_LO 1
|
||||
@@ -780,6 +1188,7 @@ enum {
|
||||
|
||||
enum {
|
||||
RK805_ID = 0x8050,
|
||||
RK806_ID = 0x8060,
|
||||
RK808_ID = 0x0000,
|
||||
RK809_ID = 0x8090,
|
||||
RK817_ID = 0x8170,
|
||||
@@ -787,11 +1196,17 @@ enum {
|
||||
};
|
||||
|
||||
struct rk808 {
|
||||
struct i2c_client *i2c;
|
||||
struct device *dev;
|
||||
struct regmap_irq_chip_data *irq_data;
|
||||
struct regmap *regmap;
|
||||
long variant;
|
||||
const struct regmap_config *regmap_cfg;
|
||||
const struct regmap_irq_chip *regmap_irq_chip;
|
||||
};
|
||||
|
||||
void rk8xx_shutdown(struct device *dev);
|
||||
int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap *regmap);
|
||||
int rk8xx_suspend(struct device *dev);
|
||||
int rk8xx_resume(struct device *dev);
|
||||
|
||||
#endif /* __LINUX_REGULATOR_RK808_H */
|
||||
|
1020
include/linux/mfd/tps6594.h
Normal file
1020
include/linux/mfd/tps6594.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -758,6 +758,8 @@ 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);
|
||||
int regulator_find_closest_bigger(unsigned int target, const unsigned int *table,
|
||||
unsigned int num_sel, unsigned int *sel);
|
||||
int regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay);
|
||||
int regulator_sync_voltage_rdev(struct regulator_dev *rdev);
|
||||
|
||||
|
@@ -41,15 +41,12 @@ enum {
|
||||
MT6358_ID_VIO28,
|
||||
MT6358_ID_VA12,
|
||||
MT6358_ID_VRF18,
|
||||
MT6358_ID_VCN33_BT,
|
||||
MT6358_ID_VCN33_WIFI,
|
||||
MT6358_ID_VCN33,
|
||||
MT6358_ID_VCAMA2,
|
||||
MT6358_ID_VMC,
|
||||
MT6358_ID_VLDO28,
|
||||
MT6358_ID_VAUD28,
|
||||
MT6358_ID_VSIM2,
|
||||
MT6358_ID_VCORE_SSHUB,
|
||||
MT6358_ID_VSRAM_OTHERS_SSHUB,
|
||||
MT6358_ID_RG_MAX,
|
||||
};
|
||||
|
||||
@@ -85,13 +82,10 @@ enum {
|
||||
MT6366_ID_VIO28,
|
||||
MT6366_ID_VA12,
|
||||
MT6366_ID_VRF18,
|
||||
MT6366_ID_VCN33_BT,
|
||||
MT6366_ID_VCN33_WIFI,
|
||||
MT6366_ID_VCN33,
|
||||
MT6366_ID_VMC,
|
||||
MT6366_ID_VAUD28,
|
||||
MT6366_ID_VSIM2,
|
||||
MT6366_ID_VCORE_SSHUB,
|
||||
MT6366_ID_VSRAM_OTHERS_SSHUB,
|
||||
MT6366_ID_RG_MAX,
|
||||
};
|
||||
|
||||
|
@@ -490,9 +490,13 @@ int geni_se_clk_freq_match(struct geni_se *se, unsigned long req_freq,
|
||||
unsigned int *index, unsigned long *res_freq,
|
||||
bool exact);
|
||||
|
||||
void geni_se_tx_init_dma(struct geni_se *se, dma_addr_t iova, size_t len);
|
||||
|
||||
int geni_se_tx_dma_prep(struct geni_se *se, void *buf, size_t len,
|
||||
dma_addr_t *iova);
|
||||
|
||||
void geni_se_rx_init_dma(struct geni_se *se, dma_addr_t iova, size_t len);
|
||||
|
||||
int geni_se_rx_dma_prep(struct geni_se *se, void *buf, size_t len,
|
||||
dma_addr_t *iova);
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user