regulator: Updates for v6.5

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).
 
  - Support for Renesas RAA215300, Rockchip RK808, Texas Instruments
    TPS6594 and TPS6287x, and X-Powers AXP15060 and AXP313a
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmSZkRUACgkQJNaLcl1U
 h9A0bAf+IM6F/vTF7R/2NTlR3M/Z7HGinxK1oit6LuZfKnveaRRCEWvBVoZzZpjs
 CzdWTPBWA2jyETzEqmX7gxYnxf2aaLieLEpKRZSh3uQd5OKmrizQDs5/OdaVUViK
 /ytmqd/IFgFfwaI+az38CQlTf+dDyuJDB0OwlkEkoaxWjeiAh6INBh6xO9aKczoW
 lFd0tOVQt1EcBKdB4tBJLTFIWWsG66xy9NZ018FrcA+bCmQVBvkbqcahayI5Q6Kw
 m5H7cZuFbKV51AlyYMF/C4Lwhy1mOT166eRmSrgxBXCsqhpFeHYkJQkmumNd3gkQ
 oSQPTZHqSblJA7Utw09mlT6r/xqL0Q==
 =/f85
 -----END PGP SIGNATURE-----

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:
Linus Torvalds 2023-06-28 13:32:47 -07:00
commit 362067b6d5
101 changed files with 5619 additions and 609 deletions

View 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;
};
};
};
};
};

View File

@ -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>;
};
};
};

View File

@ -36,6 +36,9 @@ properties:
reg:
maxItems: 1
interrupts:
maxItems: 1
fsl,pfuze-support-disable-sw:
$ref: /schemas/types.yaml#/definitions/flag
description: |

View File

@ -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:

View File

@ -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";
};
};

View 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>;
};
};
...

View File

@ -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.

View File

@ -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;

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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 },

View File

@ -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;

View File

@ -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
View 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
View 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
View 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
View 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 = &reg;
/* 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 = &reg;
/* 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
View 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");

View File

@ -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

View File

@ -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");

View File

@ -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.

View File

@ -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,
};

View File

@ -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

View File

@ -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

View File

@ -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,
};

View File

@ -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,

View File

@ -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, &reg);
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) {

View File

@ -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,
&regulator->uA_load);
debugfs_create_u32("min_uV", 0444, regulator->debugfs,
&regulator->voltage[PM_SUSPEND_ON].min_uV);
debugfs_create_u32("max_uV", 0444, regulator->debugfs,
&regulator->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,
&regulator->uA_load);
debugfs_create_u32("min_uV", 0444, regulator->debugfs,
&regulator->voltage[PM_SUSPEND_ON].min_uV);
debugfs_create_u32("max_uV", 0444, regulator->debugfs,
&regulator->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,

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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);

View File

@ -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),

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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,
};

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,
};

View File

@ -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,

View File

@ -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);

View File

@ -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,
};

View File

@ -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);

View File

@ -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);

View File

@ -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,
};

View File

@ -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, &regval);
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, &regval);
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, &regval);
@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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,
};

View 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");

View File

@ -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");

View File

@ -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,
};

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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,
};

View File

@ -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");

View File

@ -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,
};

View File

@ -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);

View File

@ -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);

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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,
};

View 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");

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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);

View 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");

View File

@ -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.

View File

@ -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);

View File

@ -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;

View File

@ -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,

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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);

View File

@ -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,
};

View File

@ -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