MFD for v6.20

- New Support & Features
   * Add comprehensive support for the ROHM BD72720 PMIC, including core MFD, regulator, GPIO,
     clock gate, RTC, and power-supply drivers.
   * Add support for the Rockchip RK801 PMIC, including core MFD and regulator drivers.
   * Add support for the ROHM BD73900 PMIC by leveraging existing common drivers.
   * Wire up RTC, hwmon, and input sub-devices for the Apple SMC (macsmc) driver.
   * Add support for the Delta Networks TN48M switch CPLD via the simple-mfd-i2c driver.
   * Add support for the TS133 variant to the QNAP MCU driver.
   * Provide support for the sama7d65 XLCD controller in the Atmel HLCDC driver.
   * Add backlight sub-device support to the Congatec Board Controller (cgbc).
   * Add Intel Nova Lake-S (NVL-S) PCI IDs to the Intel LPSS driver.
 
 - Improvements & Fixes
   * Implement a "wrapper regmap" for the ROHM BD72720 to handle dual I2C slave addresses (0x4b and
     0x4c) transparently for child devices.
   * Introduce mutex locking around 'mfd_of_node_list' in the MFD core to ensure safe concurrent
     access.
   * Fix a potential regulator resource leak in the Arizona core driver during boot sequence
     failures.
   * Resolve child device duplication issues on driver rebind for Qualcomm PM8xxx and OMAP USB host
     drivers by using of_platform_depopulate().
   * Fix IRQ domain name duplication for the Samsung S2MPG10 by adding a unique domain suffix.
   * Implement LOCK register handling for the TI TPS65214 variant to unlock registers at probe
     time.
   * Fully convert the Loongson-2K BMC driver to use managed resources (pcim) and the standard PCI
     resource API.
   * Ensure the Apple SMC mutex is correctly initialized during probe to prevent NULL pointer
     dereferences.
   * Expand the ROHM BD71828 power-supply driver to support 9-bit register addresses.
   * Simplify the Samsung S5M RTC driver by querying platform device IRQ resources directly.
   * Revert an incorrect read-to-write mask change in the DA9052 SPI driver to restore default OTP
     behavior.
   * Fix kernel-doc warnings in the TI TPS6105x driver.
 
 - Cleanups & Refactoring
   * Simplify the MFD core by utilizing the scoped for_each_child_of_node_scoped() macro and
     streamlining device_node storage.
   * Rename ROHM BD71828 IC-specific entities to use consistent prefixes for better extensibility.
   * Refactor ROHM BD71828 regmap definitions using the regmap_reg_range() macro.
   * Update the ROHM BD71828 driver to use standard C-style comment headers.
   * Remove the now unused 'irq_data' field from the Samsung SEC core structure.
   * Drop unnecessary use of irqd_get_trigger_type() in the Maxim MAX77759 driver.
   * Default MFD_SPACEMIT_P1 to 'm' if ARCH_SPACEMIT is selected.
   * Add missing charger-related registers to the ROHM BD71828 core header and Type-C CC registers
     to the AXP717.
 
 - Device Tree Binding Updates
   * Add new bindings for the ROHM BD72720 PMIC, Rockchip RK801 PMIC, Bitmain BM1880 System
     Controller, and NXP LPC32xx System Control Block.
   * Clarify trickle-charge terminology and add properties for voltage drop (VDR) correction and
     upper charge limits to the generic battery binding.
   * Document GPR syscon for NXP S32 SoCs and the smp-memram subnode for Aspeed SCU.
   * Document numerous new Qualcomm SPMI PMIC compatibles (pmcx0102, pmh0101, pmk8850, etc.).
   * Add compatibles for the sama7d65 XLCD (Atmel), LAN9691 Flexcom (Microchip), and various
     MediaTek SCPSYS and regulator components.
   * Fix a dead link to the audio codec binding in the DA9055 documentation.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEdrbJNaO+IJqU8IdIUa+KL4f8d2EFAmmN1SgACgkQUa+KL4f8
 d2FmCg//dSaWBfdNSIibUQg08g/hUUx+TTZ3RsRdBqGym0/+n6cTRqxSRM9LwWmC
 4jAq+fdqBhWEdTvB28aJT/UxFkDuKTsXtoycwLVvX0Vfb5zvE8SjAIycS4/PMRqZ
 qYyZ3fblfwx/bm+/1+0yVsi4TVtjLZdiRQEpKAXN/FNd9/6mHD8x4VNjtB5jj0nR
 tcCXKevmgRcCqXi2OfAWQ20VO/N04rkRj0r07UI4+u+lC3iet5XMmWaPc+QbQ0Be
 EkTCHBvfqtC6+C6aZtGjCOx8OA08I3MZAmS5eNly4T3GuVTHVtzobZEM7lEk4ScQ
 mzdXnhNBxxJzLXcv5B7FuDlaEcBya1tf5fe2lPgyD5Mp4khPynBZWQdDQe5Zv0TV
 9EhdGazltNdYXUcTX5yhgQOpFgdGBb59AczRG5j/EMpLVJSwyUJQC7HMf3OyirCo
 d4ZtCVXAp9KlUuEAvkLIgq6ZU/8fY5LVWK07tO0QJDHz7vEhEzZ7us5kvHQ9gFzu
 ihE3EKMBrAnjx/ZJ6pHFcfiEpPxO1rRhIFMCg5SGFVeJWKhvBycz5CjFs26GQzX6
 OTREzRbcOtuIAwBow4yafozUh0z2HWlpMNPbeuyz1h4jg5RbcYWmKG+eO5dKQXU0
 8UGTJelPzMvfx3NJ/LC9pImLrGh+twz42aqwv8LakH0y/zuT1dw=
 =BxGL
 -----END PGP SIGNATURE-----

Merge tag 'mfd-next-6.20' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd

Pull MFD updates from Lee Jones:
 "New Support & Features:
   - Add comprehensive support for the ROHM BD72720 PMIC, including core
     MFD, regulator, GPIO, clock gate, RTC, and power-supply drivers
   - Add support for the Rockchip RK801 PMIC, including core MFD and
     regulator drivers
   - Add support for the ROHM BD73900 PMIC by leveraging existing common
     drivers
   - Wire up RTC, hwmon, and input sub-devices for the Apple SMC
     (macsmc) driver
   - Add support for the Delta Networks TN48M switch CPLD via the
     simple-mfd-i2c driver
   - Add support for the TS133 variant to the QNAP MCU driver
   - Provide support for the sama7d65 XLCD controller in the Atmel HLCDC
     driver
   - Add backlight sub-device support to the Congatec Board Controller
     (cgbc)
   - Add Intel Nova Lake-S (NVL-S) PCI IDs to the Intel LPSS driver

  Improvements & Fixes:
   - Implement a "wrapper regmap" for the ROHM BD72720 to handle dual
     I2C slave addresses (0x4b and 0x4c) transparently for child devices
   - Introduce mutex locking around 'mfd_of_node_list' in the MFD core
     to ensure safe concurrent access
   - Fix a potential regulator resource leak in the Arizona core driver
     during boot sequence failures
   - Resolve child device duplication issues on driver rebind for
     Qualcomm PM8xxx and OMAP USB host drivers by using
     of_platform_depopulate()
   - Fix IRQ domain name duplication for the Samsung S2MPG10 by adding a
     unique domain suffix
   - Implement LOCK register handling for the TI TPS65214 variant to
     unlock registers at probe time
   - Fully convert the Loongson-2K BMC driver to use managed resources
     (pcim) and the standard PCI resource API
   - Ensure the Apple SMC mutex is correctly initialized during probe to
     prevent NULL pointer dereferences
   - Expand the ROHM BD71828 power-supply driver to support 9-bit
     register addresses
   - Simplify the Samsung S5M RTC driver by querying platform device IRQ
     resources directly
   - Revert an incorrect read-to-write mask change in the DA9052 SPI
     driver to restore default OTP behavior
   - Fix kernel-doc warnings in the TI TPS6105x driver

- Cleanups & Refactoring
   - Simplify the MFD core by utilizing the scoped
     for_each_child_of_node_scoped() macro and streamlining device_node
     storage
   - Rename ROHM BD71828 IC-specific entities to use consistent prefixes
     for better extensibility
   - Refactor ROHM BD71828 regmap definitions using the
     regmap_reg_range() macro
   - Update the ROHM BD71828 driver to use standard C-style comment
     headers
   - Remove the now unused 'irq_data' field from the Samsung SEC core
     structure
   - Drop unnecessary use of irqd_get_trigger_type() in the Maxim
     MAX77759 driver
   - Default MFD_SPACEMIT_P1 to 'm' if ARCH_SPACEMIT is selected
   - Add missing charger-related registers to the ROHM BD71828 core
     header and Type-C CC registers to the AXP717

  Device Tree Binding Updates:
   - Add new bindings for the ROHM BD72720 PMIC, Rockchip RK801 PMIC,
     Bitmain BM1880 System Controller, and NXP LPC32xx System Control
     Block
   - Clarify trickle-charge terminology and add properties for voltage
     drop (VDR) correction and upper charge limits to the generic
     battery binding
   - Document GPR syscon for NXP S32 SoCs and the smp-memram subnode for
     Aspeed SCU
   - Document numerous new Qualcomm SPMI PMIC compatibles (pmcx0102,
     pmh0101, pmk8850, etc)
   - Add compatibles for the sama7d65 XLCD (Atmel), LAN9691 Flexcom
     (Microchip), and various MediaTek SCPSYS and regulator components
   - Fix a dead link to the audio codec binding in the DA9055
     documentation"

* tag 'mfd-next-6.20' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (41 commits)
  dt-bindings: mfd: da9055: Fix dead link to codec binding
  mfd: cgbc: Add support for backlight
  dt-bindings: mfd: qcom,spmi-pmic: Document PMICs present on Glymur and Kaanapali
  dt-bindings: mfd: Document smp-memram subnode for aspeed,ast2x00-scu
  mfd: intel-lpss: Add Intel Nova Lake-S PCI IDs
  mfd: ls2kbmc: Use PCI API instead of direct accesses
  mfd: ls2kbmc: Fully convert to use managed resources
  dt-bindings: mfd: mediatek: mt6397: Add missing MT6331 regulator compat
  dt-bindings: mfd: mediatek,mt8195-scpsys: Add mediatek,mt6795-scpsys
  dt-bindings: mfd: atmel,sama5d2-flexcom: Add microchip,lan9691-flexcom
  mfd: omap-usb-host: Fix OF populate on driver rebind
  mfd: qcom-pm8xxx: Fix OF populate on driver rebind
  dt-bindings: mfd: syscon: Allow syscon compatible for mediatek,mt7981-topmisc
  mfd: qnap-mcu: Add driver data for TS133 variant
  dt-bindings: mfd: qnap,ts433-mcu: Add qnap,ts133-mcu compatible
  mfd: sec: Fix IRQ domain names duplication
  mfd: simple-mfd-i2c: Add Delta TN48M CPLD support
  mfd: macsmc: Initialize mutex
  dt-bindings: mfd: nxp: Add NXP LPC32xx System Control Block
  mfd: Kconfig: Default MFD_SPACEMIT_P1 to 'm' if ARCH_SPACEMIT
  ...
This commit is contained in:
Linus Torvalds 2026-02-16 11:05:44 -08:00
commit 4668c4831f
37 changed files with 955 additions and 79 deletions

View file

@ -130,6 +130,23 @@ patternProperties:
- description: silicon id information registers
- description: unique chip id registers
'^smp-memram@[0-9a-f]+$':
description: Memory region used for the AST2600's custom SMP bringup protocol
type: object
additionalProperties: false
properties:
compatible:
const: aspeed,ast2600-smpmem
reg:
description: The SMP memory region
maxItems: 1
required:
- compatible
- reg
required:
- compatible
- reg

View file

@ -25,6 +25,7 @@ properties:
- atmel,sama5d4-hlcdc
- microchip,sam9x60-hlcdc
- microchip,sam9x75-xlcdc
- microchip,sama7d65-xlcdc
reg:
maxItems: 1

View file

@ -20,6 +20,7 @@ properties:
- const: atmel,sama5d2-flexcom
- items:
- enum:
- microchip,lan9691-flexcom
- microchip,sam9x7-flexcom
- microchip,sama7d65-flexcom
- microchip,sama7g5-flexcom

View file

@ -0,0 +1,66 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/mfd/bitmain,bm1880-sctrl.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Bitmain BM1880 System Controller
maintainers:
- Manivannan Sadhasivam <mani@kernel.org>
properties:
compatible:
items:
- const: bitmain,bm1880-sctrl
- const: syscon
- const: simple-mfd
reg:
maxItems: 1
ranges: true
'#address-cells':
const: 1
'#size-cells':
const: 1
patternProperties:
'^pinctrl@[0-9a-f]+$':
type: object
additionalProperties: true
properties:
compatible:
contains:
const: bitmain,bm1880-pinctrl
'^clock-controller@[0-9a-f]+$':
type: object
additionalProperties: true
properties:
compatible:
contains:
const: bitmain,bm1880-clk
'^reset-controller@[0-9a-f]+$':
type: object
additionalProperties: true
properties:
compatible:
contains:
const: bitmain,bm1880-reset
required:
- compatible
- reg
- ranges
- '#address-cells'
- '#size-cells'
additionalProperties: false
...

View file

@ -15,7 +15,7 @@ The CODEC device in DA9055 has a separate, configurable I2C address and so
is instantiated separately from the PMIC.
For details on accompanying CODEC I2C device, see the following:
Documentation/devicetree/bindings/sound/da9055.txt
Documentation/devicetree/bindings/sound/trivial-codec.yaml
======

View file

@ -90,6 +90,7 @@ properties:
- enum:
- mediatek,mt6323-regulator
- mediatek,mt6328-regulator
- mediatek,mt6331-regulator
- mediatek,mt6358-regulator
- mediatek,mt6359-regulator
- mediatek,mt6397-regulator

View file

@ -19,6 +19,7 @@ properties:
compatible:
items:
- enum:
- mediatek,mt6795-scpsys
- mediatek,mt6893-scpsys
- mediatek,mt8167-scpsys
- mediatek,mt8173-scpsys

View file

@ -0,0 +1,74 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/mfd/nxp,lpc3220-scb.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NXP LPC32xx System Control Block
maintainers:
- Vladimir Zapolskiy <vz@mleia.com>
description:
NXP LPC32xx SoC series have a System Control Block, which serves for
a multitude of purposes including clock management, DMA muxes, storing
SoC unique ID etc.
properties:
compatible:
items:
- enum:
- nxp,lpc3220-scb
- const: syscon
- const: simple-mfd
reg:
maxItems: 1
ranges: true
"#address-cells":
const: 1
"#size-cells":
const: 1
patternProperties:
"^clock-controller@[0-9a-f]+$":
$ref: /schemas/clock/nxp,lpc3220-clk.yaml#
"^dma-router@[0-9a-f]+$":
$ref: /schemas/dma/nxp,lpc3220-dmamux.yaml#
required:
- compatible
- reg
- "#address-cells"
- "#size-cells"
additionalProperties: false
examples:
- |
syscon@400040000 {
compatible = "nxp,lpc3220-scb", "syscon", "simple-mfd";
reg = <0x40004000 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x40004000 0x1000>;
clock-controller@0 {
compatible = "nxp,lpc3220-clk";
reg = <0x0 0x114>;
clocks = <&xtal_32k>, <&xtal>;
clock-names = "xtal_32k", "xtal";
#clock-cells = <1>;
};
dma-router@78 {
compatible = "nxp,lpc3220-dmamux";
reg = <0x78 0x8>;
dma-masters = <&dma>;
#dma-cells = <3>;
};
};

View file

@ -77,8 +77,12 @@ properties:
- qcom,pmc8180
- qcom,pmc8180c
- qcom,pmc8380
- qcom,pmcx0102
- qcom,pmd8028
- qcom,pmd9635
- qcom,pmh0101
- qcom,pmh0104
- qcom,pmh0110
- qcom,pmi632
- qcom,pmi8950
- qcom,pmi8962
@ -89,6 +93,7 @@ properties:
- qcom,pmk8002
- qcom,pmk8350
- qcom,pmk8550
- qcom,pmk8850
- qcom,pmm8155au
- qcom,pmm8654au
- qcom,pmp8074
@ -101,6 +106,7 @@ properties:
- qcom,pmx75
- qcom,smb2351
- qcom,smb2360
- qcom,smb2370
- const: qcom,spmi-pmic
reg:

View file

@ -16,6 +16,7 @@ description:
properties:
compatible:
enum:
- qnap,ts133-mcu
- qnap,ts233-mcu
- qnap,ts433-mcu

View file

@ -0,0 +1,197 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/mfd/rockchip,rk801.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: RK801 Power Management Integrated Circuit
maintainers:
- Joseph Chen <chenjh@rock-chips.com>
description: |
Rockchip RK801 series PMIC. This device consists of an i2c controlled MFD
that includes multiple switchable regulators.
properties:
compatible:
enum:
- rockchip,rk801
reg:
maxItems: 1
interrupts:
maxItems: 1
system-power-controller:
type: boolean
description:
Telling whether or not this PMIC is controlling the system power.
wakeup-source:
type: boolean
description:
Device can be used as a wakeup source.
vcc1-supply:
description:
The input supply for dcdc1.
vcc2-supply:
description:
The input supply for dcdc2.
vcc3-supply:
description:
The input supply for dcdc3.
vcc4-supply:
description:
The input supply for dcdc4.
vcc5-supply:
description:
The input supply for ldo1.
vcc6-supply:
description:
The input supply for ldo2.
vcc7-supply:
description:
The input supply for switch.
regulators:
type: object
patternProperties:
"^(dcdc[1-4]|ldo[1-2]|switch)$":
type: object
$ref: /schemas/regulator/regulator.yaml#
unevaluatedProperties: false
additionalProperties: false
required:
- compatible
- reg
- interrupts
additionalProperties: false
examples:
- |
#include <dt-bindings/pinctrl/rockchip.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/gpio/gpio.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
rk801: pmic@27 {
compatible = "rockchip,rk801";
reg = <0x27>;
interrupt-parent = <&gpio0>;
interrupts = <RK_PC0 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&pmic_int_l>;
system-power-controller;
wakeup-source;
vcc1-supply = <&vcc_sys>;
vcc2-supply = <&vcc_sys>;
vcc3-supply = <&vcc_sys>;
vcc4-supply = <&vcc_sys>;
vcc5-supply = <&vcc3v3_sys>;
vcc6-supply = <&vcc3v3_sys>;
vcc7-supply = <&vcc3v3_sys>;
regulators {
vdd_cpu: dcdc1 {
regulator-name = "vdd_cpu";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1500000>;
regulator-initial-mode = <0x1>;
regulator-boot-on;
regulator-always-on;
regulator-state-mem {
regulator-mode = <0x2>;
regulator-off-in-suspend;
regulator-suspend-microvolt = <950000>;
};
};
vcc3v3_sys: dcdc2 {
regulator-name = "vcc3v3_sys";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-initial-mode = <0x1>;
regulator-boot-on;
regulator-always-on;
regulator-state-mem {
regulator-mode = <0x2>;
regulator-on-in-suspend;
regulator-suspend-microvolt = <3300000>;
};
};
vcc_ddr: dcdc3 {
regulator-name = "vcc_ddr";
regulator-boot-on;
regulator-always-on;
regulator-state-mem {
regulator-mode = <0x2>;
regulator-on-in-suspend;
};
};
vdd_logic: dcdc4 {
regulator-name = "vdd_logic";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1500000>;
regulator-initial-mode = <0x1>;
regulator-boot-on;
regulator-always-on;
regulator-state-mem {
regulator-mode = <0x2>;
regulator-off-in-suspend;
regulator-suspend-microvolt = <900000>;
};
};
vdd0v9_sys: ldo1 {
regulator-name = "vdd0v9_sys";
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <900000>;
regulator-boot-on;
regulator-always-on;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <900000>;
};
};
vcc_1v8: ldo2 {
regulator-name = "vcc_1v8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-boot-on;
regulator-always-on;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <1800000>;
};
};
vcc_3v3: switch {
regulator-name = "vcc_3v3";
regulator-boot-on;
regulator-always-on;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <3300000>;
};
};
};
};
};

View file

@ -102,6 +102,8 @@ select:
- mstar,msc313-pmsleep
- nuvoton,ma35d1-sys
- nuvoton,wpcm450-shm
- nxp,s32g2-gpr
- nxp,s32g3-gpr
- qcom,apq8064-mmss-sfpb
- qcom,apq8064-sps-sic
- rockchip,px30-qos
@ -195,6 +197,7 @@ properties:
- mediatek,mt2701-pctl-a-syscfg
- mediatek,mt2712-pctl-a-syscfg
- mediatek,mt6397-pctl-pmic-syscfg
- mediatek,mt7981-topmisc
- mediatek,mt7988-topmisc
- mediatek,mt8135-pctl-a-syscfg
- mediatek,mt8135-pctl-b-syscfg
@ -212,6 +215,8 @@ properties:
- mstar,msc313-pmsleep
- nuvoton,ma35d1-sys
- nuvoton,wpcm450-shm
- nxp,s32g2-gpr
- nxp,s32g3-gpr
- qcom,apq8064-mmss-sfpb
- qcom,apq8064-sps-sic
- rockchip,px30-qos

View file

@ -407,6 +407,17 @@ config MFD_CS47L92
help
Support for Cirrus Logic CS42L92, CS47L92 and CS47L93 Smart Codecs
config MFD_TN48M_CPLD
tristate "Delta Networks TN48M switch CPLD driver"
depends on I2C
depends on ARCH_MVEBU || COMPILE_TEST
select MFD_SIMPLE_MFD_I2C
help
Select this option to enable support for Delta Networks TN48M switch
CPLD. It consists of reset and GPIO drivers. CPLD provides GPIOS-s
for the SFP slots as well as power supply related information.
SFP support depends on the GPIO driver being selected.
config PMIC_DA903X
bool "Dialog Semiconductor DA9030/DA9034 PMIC Support"
depends on I2C=y
@ -1276,6 +1287,7 @@ config MFD_SPACEMIT_P1
depends on ARCH_SPACEMIT || COMPILE_TEST
depends on I2C
select MFD_SIMPLE_MFD_I2C
default m if ARCH_SPACEMIT
help
This option supports the I2C-based SpacemiT P1 PMIC, which
contains regulators, a power switch, GPIOs, an RTC, and more.
@ -1371,15 +1383,15 @@ config MFD_RK8XX
select MFD_CORE
config MFD_RK8XX_I2C
tristate "Rockchip RK805/RK808/RK809/RK816/RK817/RK818 Power Management Chip"
tristate "Rockchip RK8xx Power Management Chips"
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,
RK816, RK817 and RK818 Power Management chips.
If you say yes here you get support for the RK801, RK805, RK808,
RK809, RK816, RK817 and RK818 Power Management chips.
This driver provides common support for accessing the device
through I2C interface. The device supports multiple sub-devices
including interrupts, RTC, LDO & DCDC regulators, and onkey.

View file

@ -1100,7 +1100,7 @@ int arizona_dev_init(struct arizona *arizona)
} else if (val & 0x01) {
ret = wm5102_clear_write_sequencer(arizona);
if (ret)
return ret;
goto err_reset;
}
break;
default:

View file

@ -140,6 +140,7 @@ static const struct of_device_id atmel_hlcdc_match[] = {
{ .compatible = "atmel,sama5d4-hlcdc" },
{ .compatible = "microchip,sam9x60-hlcdc" },
{ .compatible = "microchip,sam9x75-xlcdc" },
{ .compatible = "microchip,sama7d65-xlcdc" },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, atmel_hlcdc_match);

View file

@ -229,6 +229,8 @@ static const struct regmap_range axp717_writeable_ranges[] = {
regmap_reg_range(AXP717_DCDC_OUTPUT_CONTROL, AXP717_CPUSLDO_CONTROL),
regmap_reg_range(AXP717_ADC_CH_EN_CONTROL, AXP717_ADC_CH_EN_CONTROL),
regmap_reg_range(AXP717_ADC_DATA_SEL, AXP717_ADC_DATA_SEL),
regmap_reg_range(AXP717_TYPEC_CC_AA_EN, AXP717_TYPEC_CC_AA_EN),
regmap_reg_range(AXP717_TYPEC_CC_MODE_CONTROL, AXP717_TYPEC_CC_MODE_CONTROL),
};
static const struct regmap_range axp717_volatile_ranges[] = {
@ -237,6 +239,7 @@ static const struct regmap_range axp717_volatile_ranges[] = {
regmap_reg_range(AXP717_BATT_PERCENT_DATA, AXP717_BATT_PERCENT_DATA),
regmap_reg_range(AXP717_BATT_V_H, AXP717_BATT_CHRG_I_L),
regmap_reg_range(AXP717_ADC_DATA_H, AXP717_ADC_DATA_L),
regmap_reg_range(AXP717_TYPEC_CC_STATUS, AXP717_TYPEC_CC_STATUS),
};
static const struct regmap_access_table axp717_writeable_table = {
@ -458,7 +461,7 @@ static const struct regmap_config axp717_regmap_config = {
.val_bits = 8,
.wr_table = &axp717_writeable_table,
.volatile_table = &axp717_volatile_table,
.max_register = AXP717_ADC_DATA_L,
.max_register = AXP717_TYPEC_CC_STATUS,
.cache_type = REGCACHE_MAPLE,
};

View file

@ -237,6 +237,7 @@ static struct mfd_cell cgbc_devs[] = {
{ .name = "cgbc-i2c", .id = 1 },
{ .name = "cgbc-i2c", .id = 2 },
{ .name = "cgbc-hwmon" },
{ .name = "cgbc-backlight" },
};
static int cgbc_map(struct cgbc_device_data *cgbc)

View file

@ -37,7 +37,7 @@ static int da9052_spi_probe(struct spi_device *spi)
spi_set_drvdata(spi, da9052);
config = da9052_regmap_config;
config.write_flag_mask = 1;
config.read_flag_mask = 1;
config.reg_bits = 7;
config.pad_bits = 1;
config.val_bits = 8;

View file

@ -437,6 +437,19 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
{ PCI_VDEVICE(INTEL, 0x5ac4), (kernel_ulong_t)&bxt_spi_info },
{ PCI_VDEVICE(INTEL, 0x5ac6), (kernel_ulong_t)&bxt_spi_info },
{ PCI_VDEVICE(INTEL, 0x5aee), (kernel_ulong_t)&bxt_uart_info },
/* NVL-S */
{ PCI_VDEVICE(INTEL, 0x6e28), (kernel_ulong_t)&bxt_uart_info },
{ PCI_VDEVICE(INTEL, 0x6e29), (kernel_ulong_t)&bxt_uart_info },
{ PCI_VDEVICE(INTEL, 0x6e2a), (kernel_ulong_t)&tgl_spi_info },
{ PCI_VDEVICE(INTEL, 0x6e2b), (kernel_ulong_t)&tgl_spi_info },
{ PCI_VDEVICE(INTEL, 0x6e4c), (kernel_ulong_t)&ehl_i2c_info },
{ PCI_VDEVICE(INTEL, 0x6e4d), (kernel_ulong_t)&ehl_i2c_info },
{ PCI_VDEVICE(INTEL, 0x6e4e), (kernel_ulong_t)&ehl_i2c_info },
{ PCI_VDEVICE(INTEL, 0x6e4f), (kernel_ulong_t)&ehl_i2c_info },
{ PCI_VDEVICE(INTEL, 0x6e5c), (kernel_ulong_t)&bxt_uart_info },
{ PCI_VDEVICE(INTEL, 0x6e5e), (kernel_ulong_t)&tgl_spi_info },
{ PCI_VDEVICE(INTEL, 0x6e7a), (kernel_ulong_t)&ehl_i2c_info },
{ PCI_VDEVICE(INTEL, 0x6e7b), (kernel_ulong_t)&ehl_i2c_info },
/* ARL-H */
{ PCI_VDEVICE(INTEL, 0x7725), (kernel_ulong_t)&bxt_uart_info },
{ PCI_VDEVICE(INTEL, 0x7726), (kernel_ulong_t)&bxt_uart_info },

View file

@ -464,53 +464,36 @@ static int ls2k_bmc_probe(struct pci_dev *dev, const struct pci_device_id *id)
resource_size_t base;
int ret;
ret = pci_enable_device(dev);
ret = pcim_enable_device(dev);
if (ret)
return ret;
ddata = devm_kzalloc(&dev->dev, sizeof(*ddata), GFP_KERNEL);
if (!ddata) {
ret = -ENOMEM;
goto disable_pci;
}
if (!ddata)
return -ENOMEM;
ddata->dev = &dev->dev;
ret = ls2k_bmc_init(ddata);
if (ret)
goto disable_pci;
return ret;
ret = ls2k_bmc_parse_mode(dev, &pd);
if (ret)
goto disable_pci;
return ret;
ls2k_bmc_cells[LS2K_BMC_DISPLAY].platform_data = &pd;
ls2k_bmc_cells[LS2K_BMC_DISPLAY].pdata_size = sizeof(pd);
base = dev->resource[0].start + LS2K_DISPLAY_RES_START;
base = pci_resource_start(dev, 0) + LS2K_DISPLAY_RES_START;
/* Remove conflicting efifb device */
ret = aperture_remove_conflicting_devices(base, SZ_4M, "simple-framebuffer");
if (ret) {
dev_err(&dev->dev, "Failed to removed firmware framebuffers: %d\n", ret);
goto disable_pci;
}
ret = devm_mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO,
ls2k_bmc_cells, ARRAY_SIZE(ls2k_bmc_cells),
&dev->resource[0], 0, NULL);
if (ret)
goto disable_pci;
return dev_err_probe(&dev->dev, ret, "Failed to removed firmware framebuffers\n");
return 0;
disable_pci:
pci_disable_device(dev);
return ret;
}
static void ls2k_bmc_remove(struct pci_dev *dev)
{
pci_disable_device(dev);
return devm_mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO,
ls2k_bmc_cells, ARRAY_SIZE(ls2k_bmc_cells),
pci_resource_n(dev, 0), 0, NULL);
}
static struct pci_device_id ls2k_bmc_devices[] = {
@ -523,7 +506,6 @@ static struct pci_driver ls2k_bmc_driver = {
.name = "ls2k-bmc",
.id_table = ls2k_bmc_devices,
.probe = ls2k_bmc_probe,
.remove = ls2k_bmc_remove,
};
module_pci_driver(ls2k_bmc_driver);

View file

@ -45,8 +45,11 @@
#define SMC_TIMEOUT_MS 500
static const struct mfd_cell apple_smc_devs[] = {
MFD_CELL_NAME("macsmc-input"),
MFD_CELL_OF("macsmc-gpio", NULL, NULL, 0, 0, "apple,smc-gpio"),
MFD_CELL_OF("macsmc-hwmon", NULL, NULL, 0, 0, "apple,smc-hwmon"),
MFD_CELL_OF("macsmc-reboot", NULL, NULL, 0, 0, "apple,smc-reboot"),
MFD_CELL_OF("macsmc-rtc", NULL, NULL, 0, 0, "apple,smc-rtc"),
};
static int apple_smc_cmd_locked(struct apple_smc *smc, u64 cmd, u64 arg,
@ -413,6 +416,7 @@ static int apple_smc_probe(struct platform_device *pdev)
if (!smc)
return -ENOMEM;
mutex_init(&smc->mutex);
smc->dev = &pdev->dev;
smc->sram_base = devm_platform_get_and_ioremap_resource(pdev, 1, &smc->sram);
if (IS_ERR(smc->sram_base))

View file

@ -587,9 +587,7 @@ static int max77759_add_chained_charger(struct i2c_client *client,
static int max77759_probe(struct i2c_client *client)
{
struct regmap_irq_chip_data *irq_chip_data_pmic;
struct irq_data *irq_data;
struct max77759 *max77759;
unsigned long irq_flags;
unsigned int pmic_id;
int ret;
@ -628,16 +626,8 @@ static int max77759_probe(struct i2c_client *client)
return ret;
}
irq_data = irq_get_irq_data(client->irq);
if (!irq_data)
return dev_err_probe(&client->dev, -EINVAL,
"invalid IRQ: %d\n", client->irq);
irq_flags = IRQF_ONESHOT | IRQF_SHARED;
irq_flags |= irqd_get_trigger_type(irq_data);
ret = devm_regmap_add_irq_chip(&client->dev, max77759->regmap_top,
client->irq, irq_flags, 0,
client->irq, IRQF_ONESHOT | IRQF_SHARED, 0,
&max77759_pmic_irq_chip,
&irq_chip_data_pmic);
if (ret)

View file

@ -22,6 +22,7 @@
#include <linux/regulator/consumer.h>
static LIST_HEAD(mfd_of_node_list);
static DEFINE_MUTEX(mfd_of_node_mutex);
struct mfd_of_node_entry {
struct list_head list;
@ -100,14 +101,15 @@ static int mfd_match_of_node_to_dev(struct platform_device *pdev,
struct device_node *np,
const struct mfd_cell *cell)
{
#if IS_ENABLED(CONFIG_OF)
struct mfd_of_node_entry *of_entry;
u64 of_node_addr;
/* Skip if OF node has previously been allocated to a device */
list_for_each_entry(of_entry, &mfd_of_node_list, list)
if (of_entry->np == np)
return -EAGAIN;
scoped_guard(mutex, &mfd_of_node_mutex) {
list_for_each_entry(of_entry, &mfd_of_node_list, list)
if (of_entry->np == np)
return -EAGAIN;
}
if (!cell->use_of_reg)
/* No of_reg defined - allocate first free compatible match */
@ -128,12 +130,11 @@ allocate_of_node:
return -ENOMEM;
of_entry->dev = &pdev->dev;
of_entry->np = np;
list_add_tail(&of_entry->list, &mfd_of_node_list);
of_entry->np = of_node_get(np);
scoped_guard(mutex, &mfd_of_node_mutex)
list_add_tail(&of_entry->list, &mfd_of_node_list);
of_node_get(np);
device_set_node(&pdev->dev, of_fwnode_handle(np));
#endif
return 0;
}
@ -144,7 +145,6 @@ static int mfd_add_device(struct device *parent, int id,
{
struct resource *res;
struct platform_device *pdev;
struct device_node *np = NULL;
struct mfd_of_node_entry *of_entry, *tmp;
bool disabled = false;
int ret = -ENOMEM;
@ -182,7 +182,7 @@ static int mfd_add_device(struct device *parent, int id,
goto fail_res;
if (IS_ENABLED(CONFIG_OF) && parent->of_node && cell->of_compatible) {
for_each_child_of_node(parent->of_node, np) {
for_each_child_of_node_scoped(parent->of_node, np) {
if (of_device_is_compatible(np, cell->of_compatible)) {
/* Skip 'disabled' devices */
if (!of_device_is_available(np)) {
@ -193,7 +193,6 @@ static int mfd_add_device(struct device *parent, int id,
ret = mfd_match_of_node_to_dev(pdev, np, cell);
if (ret == -EAGAIN)
continue;
of_node_put(np);
if (ret)
goto fail_alias;
@ -286,11 +285,13 @@ fail_res_conflict:
if (cell->swnode)
device_remove_software_node(&pdev->dev);
fail_of_entry:
list_for_each_entry_safe(of_entry, tmp, &mfd_of_node_list, list)
if (of_entry->dev == &pdev->dev) {
list_del(&of_entry->list);
kfree(of_entry);
}
scoped_guard(mutex, &mfd_of_node_mutex) {
list_for_each_entry_safe(of_entry, tmp, &mfd_of_node_list, list)
if (of_entry->dev == &pdev->dev) {
list_del(&of_entry->list);
kfree(of_entry);
}
}
fail_alias:
regulator_bulk_unregister_supply_alias(&pdev->dev,
cell->parent_supplies,
@ -360,11 +361,13 @@ static int mfd_remove_devices_fn(struct device *dev, void *data)
if (cell->swnode)
device_remove_software_node(&pdev->dev);
list_for_each_entry_safe(of_entry, tmp, &mfd_of_node_list, list)
if (of_entry->dev == &pdev->dev) {
list_del(&of_entry->list);
kfree(of_entry);
}
scoped_guard(mutex, &mfd_of_node_mutex) {
list_for_each_entry_safe(of_entry, tmp, &mfd_of_node_list, list)
if (of_entry->dev == &pdev->dev) {
list_del(&of_entry->list);
kfree(of_entry);
}
}
regulator_bulk_unregister_supply_alias(dev, cell->parent_supplies,
cell->num_parent_supplies);

View file

@ -819,8 +819,10 @@ static void usbhs_omap_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
/* remove children */
device_for_each_child(&pdev->dev, NULL, usbhs_omap_remove_child);
if (pdev->dev.of_node)
of_platform_depopulate(&pdev->dev);
else
device_for_each_child(&pdev->dev, NULL, usbhs_omap_remove_child);
}
static const struct dev_pm_ops usbhsomap_dev_pm_ops = {

View file

@ -577,17 +577,11 @@ static int pm8xxx_probe(struct platform_device *pdev)
return rc;
}
static int pm8xxx_remove_child(struct device *dev, void *unused)
{
platform_device_unregister(to_platform_device(dev));
return 0;
}
static void pm8xxx_remove(struct platform_device *pdev)
{
struct pm_irq_chip *chip = platform_get_drvdata(pdev);
device_for_each_child(&pdev->dev, NULL, pm8xxx_remove_child);
of_platform_depopulate(&pdev->dev);
irq_domain_remove(chip->irqdomain);
}

View file

@ -316,6 +316,14 @@ static int qnap_mcu_power_off(struct sys_off_data *data)
return NOTIFY_DONE;
}
static const struct qnap_mcu_variant qnap_ts133_mcu = {
.baud_rate = 115200,
.num_drives = 1,
.fan_pwm_min = 51, /* Specified in original model.conf */
.fan_pwm_max = 255,
.usb_led = false,
};
static const struct qnap_mcu_variant qnap_ts233_mcu = {
.baud_rate = 115200,
.num_drives = 2,
@ -397,6 +405,7 @@ static int qnap_mcu_probe(struct serdev_device *serdev)
}
static const struct of_device_id qnap_mcu_dt_ids[] = {
{ .compatible = "qnap,ts133-mcu", .data = &qnap_ts133_mcu },
{ .compatible = "qnap,ts233-mcu", .data = &qnap_ts233_mcu },
{ .compatible = "qnap,ts433-mcu", .data = &qnap_ts433_mcu },
{ /* sentinel */ }

View file

@ -37,6 +37,11 @@ static const struct resource rk817_rtc_resources[] = {
DEFINE_RES_IRQ(RK817_IRQ_RTC_ALARM),
};
static const struct resource rk801_key_resources[] = {
DEFINE_RES_IRQ(RK801_IRQ_PWRON_FALL),
DEFINE_RES_IRQ(RK801_IRQ_PWRON_RISE),
};
static const struct resource rk805_key_resources[] = {
DEFINE_RES_IRQ(RK805_IRQ_PWRON_RISE),
DEFINE_RES_IRQ(RK805_IRQ_PWRON_FALL),
@ -57,6 +62,14 @@ static const struct resource rk817_charger_resources[] = {
DEFINE_RES_IRQ(RK817_IRQ_PLUG_OUT),
};
static const struct mfd_cell rk801s[] = {
{ .name = "rk808-regulator", },
{ .name = "rk805-pwrkey",
.num_resources = ARRAY_SIZE(rk801_key_resources),
.resources = &rk801_key_resources[0],
},
};
static const struct mfd_cell rk805s[] = {
{ .name = "rk808-clkout", },
{ .name = "rk808-regulator", },
@ -139,6 +152,15 @@ static const struct mfd_cell rk818s[] = {
},
};
static const struct rk808_reg_data rk801_pre_init_reg[] = {
{ RK801_SLEEP_CFG_REG, RK801_SLEEP_FUN_MSK, RK801_NONE_FUN },
{ RK801_SYS_CFG2_REG, RK801_RST_MSK, RK801_RST_RESTART_REG_RESETB },
{ RK801_INT_CONFIG_REG, RK801_INT_POL_MSK, RK801_INT_ACT_L },
{ RK801_POWER_FPWM_EN_REG, RK801_PLDO_HRDEC_EN, RK801_PLDO_HRDEC_EN },
{ RK801_BUCK_DEBUG5_REG, MASK_ALL, 0x54 },
{ RK801_CON_BACK1_REG, MASK_ALL, 0x18 },
};
static const struct rk808_reg_data rk805_pre_init_reg[] = {
{RK805_BUCK1_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK,
RK805_BUCK1_2_ILMAX_4000MA},
@ -284,6 +306,37 @@ static const struct rk808_reg_data rk818_pre_init_reg[] = {
VB_LO_SEL_3500MV },
};
static const struct regmap_irq rk801_irqs[] = {
[RK801_IRQ_PWRON_FALL] = {
.mask = RK801_IRQ_PWRON_FALL_MSK,
.reg_offset = 0,
},
[RK801_IRQ_PWRON_RISE] = {
.mask = RK801_IRQ_PWRON_RISE_MSK,
.reg_offset = 0,
},
[RK801_IRQ_PWRON] = {
.mask = RK801_IRQ_PWRON_MSK,
.reg_offset = 0,
},
[RK801_IRQ_PWRON_LP] = {
.mask = RK801_IRQ_PWRON_LP_MSK,
.reg_offset = 0,
},
[RK801_IRQ_HOTDIE] = {
.mask = RK801_IRQ_HOTDIE_MSK,
.reg_offset = 0,
},
[RK801_IRQ_VDC_RISE] = {
.mask = RK801_IRQ_VDC_RISE_MSK,
.reg_offset = 0,
},
[RK801_IRQ_VDC_FALL] = {
.mask = RK801_IRQ_VDC_FALL_MSK,
.reg_offset = 0,
},
};
static const struct regmap_irq rk805_irqs[] = {
[RK805_IRQ_PWRON_RISE] = {
.mask = RK805_IRQ_PWRON_RISE_MSK,
@ -532,6 +585,17 @@ static const struct regmap_irq rk817_irqs[RK817_IRQ_END] = {
REGMAP_IRQ_REG_LINE(23, 8)
};
static const struct regmap_irq_chip rk801_irq_chip = {
.name = "rk801",
.irqs = rk801_irqs,
.num_irqs = ARRAY_SIZE(rk801_irqs),
.num_regs = 1,
.status_base = RK801_INT_STS0_REG,
.mask_base = RK801_INT_MASK0_REG,
.ack_base = RK801_INT_STS0_REG,
.init_ack_masked = true,
};
static const struct regmap_irq_chip rk805_irq_chip = {
.name = "rk805",
.irqs = rk805_irqs,
@ -610,6 +674,10 @@ static int rk808_power_off(struct sys_off_data *data)
unsigned int reg, bit;
switch (rk808->variant) {
case RK801_ID:
reg = RK801_SYS_CFG2_REG;
bit = DEV_OFF;
break;
case RK805_ID:
reg = RK805_DEV_CTRL_REG;
bit = DEV_OFF;
@ -714,6 +782,13 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
dev_set_drvdata(dev, rk808);
switch (rk808->variant) {
case RK801_ID:
rk808->regmap_irq_chip = &rk801_irq_chip;
pre_init_reg = rk801_pre_init_reg;
nr_pre_init_regs = ARRAY_SIZE(rk801_pre_init_reg);
cells = rk801s;
nr_cells = ARRAY_SIZE(rk801s);
break;
case RK805_ID:
rk808->regmap_irq_chip = &rk805_irq_chip;
pre_init_reg = rk805_pre_init_reg;
@ -831,6 +906,12 @@ int rk8xx_suspend(struct device *dev)
int ret = 0;
switch (rk808->variant) {
case RK801_ID:
ret = regmap_update_bits(rk808->regmap,
RK801_SLEEP_CFG_REG,
RK801_SLEEP_FUN_MSK,
RK801_SLEEP_FUN);
break;
case RK805_ID:
ret = regmap_update_bits(rk808->regmap,
RK805_GPIO_IO_POL_REG,

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Rockchip RK805/RK808/RK816/RK817/RK818 Core (I2C) driver
* Rockchip RK801/RK805/RK808/RK816/RK817/RK818 Core (I2C) driver
*
* Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
* Copyright (C) 2016 PHYTEC Messtechnik GmbH
@ -21,6 +21,23 @@ struct rk8xx_i2c_platform_data {
int variant;
};
static bool rk801_is_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case RK801_SYS_STS_REG:
case RK801_INT_STS0_REG:
case RK801_SYS_CFG0_REG:
case RK801_SYS_CFG1_REG:
case RK801_SYS_CFG2_REG:
case RK801_SYS_CFG3_REG:
case RK801_SYS_CFG4_REG:
case RK801_SLEEP_CFG_REG:
return true;
}
return false;
}
static bool rk806_is_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
@ -124,6 +141,14 @@ static const struct regmap_config rk818_regmap_config = {
.volatile_reg = rk808_is_volatile_reg,
};
static const struct regmap_config rk801_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = RK801_SYS_CFG3_OTP_REG,
.cache_type = REGCACHE_RBTREE,
.volatile_reg = rk801_is_volatile_reg,
};
static const struct regmap_config rk805_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
@ -164,6 +189,11 @@ static const struct regmap_config rk817_regmap_config = {
.volatile_reg = rk817_is_volatile_reg,
};
static const struct rk8xx_i2c_platform_data rk801_data = {
.regmap_cfg = &rk801_regmap_config,
.variant = RK801_ID,
};
static const struct rk8xx_i2c_platform_data rk805_data = {
.regmap_cfg = &rk805_regmap_config,
.variant = RK805_ID,
@ -224,6 +254,7 @@ static void rk8xx_i2c_shutdown(struct i2c_client *client)
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,rk801", .data = &rk801_data },
{ .compatible = "rockchip,rk805", .data = &rk805_data },
{ .compatible = "rockchip,rk806", .data = &rk806_data },
{ .compatible = "rockchip,rk808", .data = &rk808_data },

View file

@ -257,6 +257,7 @@ static const struct regmap_irq_chip s2mpg10_irq_chip = {
static const struct regmap_irq_chip s2mpg10_irq_chip_pmic = {
.name = "s2mpg10-pmic",
.domain_suffix = "pmic",
.status_base = S2MPG10_PMIC_INT1,
.mask_base = S2MPG10_PMIC_INT1M,
.num_regs = 6,

View file

@ -116,6 +116,7 @@ static const struct simple_mfd_data spacemit_p1 = {
};
static const struct of_device_id simple_mfd_i2c_of_match[] = {
{ .compatible = "delta,tn48m-cpld" },
{ .compatible = "fsl,ls1028aqds-fpga" },
{ .compatible = "fsl,lx2160aqds-fpga" },
{ .compatible = "fsl,lx2160ardb-fpga" },

View file

@ -498,6 +498,15 @@ static int tps65219_probe(struct i2c_client *client)
return ret;
}
if (chip_id == TPS65214) {
ret = i2c_smbus_write_byte_data(client, TPS65214_REG_LOCK,
TPS65214_LOCK_ACCESS_CMD);
if (ret) {
dev_err(tps->dev, "Failed to unlock registers %d\n", ret);
return ret;
}
}
ret = devm_regmap_add_irq_chip(tps->dev, tps->regmap, client->irq,
IRQF_ONESHOT, 0, pmic->irq_chip,
&tps->irq_data);

View file

@ -24,6 +24,9 @@
#include <linux/gpio/consumer.h>
/* Field definitions */
#define RK801_BUCK_VSEL_MASK 0x7f
#define RK801_LDO_VSEL_MASK 0x3f
#define RK808_BUCK_VSEL_MASK 0x3f
#define RK808_BUCK4_VSEL_MASK 0xf
#define RK808_LDO_VSEL_MASK 0x1f
@ -158,6 +161,11 @@
RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg, \
_vmask, _ereg, _emask, 0, 0, _etime, &rk808_reg_ops)
#define RK801_DESC(_id, _match, _supply, _min, _max, _step, _vreg, \
_vmask, _ereg, _emask, _disval, _etime) \
RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg, \
_vmask, _ereg, _emask, _emask, _disval, _etime, &rk801_reg_ops)
#define RK816_DESC(_id, _match, _supply, _min, _max, _step, _vreg, \
_vmask, _ereg, _emask, _disval, _etime) \
RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg, \
@ -185,6 +193,11 @@
.ops = _ops \
}
#define RK801_DESC_SWITCH(_id, _match, _supply, _ereg, _emask, \
_disval) \
RKXX_DESC_SWITCH_COM(_id, _match, _supply, _ereg, _emask, \
_emask, _disval, &rk801_switch_ops)
#define RK817_DESC_SWITCH(_id, _match, _supply, _ereg, _emask, \
_disval) \
RKXX_DESC_SWITCH_COM(_id, _match, _supply, _ereg, _emask, \
@ -802,6 +815,115 @@ static unsigned int rk8xx_regulator_of_map_mode(unsigned int mode)
}
}
static unsigned int rk801_get_mode(struct regulator_dev *rdev)
{
unsigned int val;
int err;
err = regmap_read(rdev->regmap, RK801_POWER_FPWM_EN_REG, &val);
if (err)
return err;
if (val & BIT(rdev->desc->id))
return REGULATOR_MODE_FAST;
else
return REGULATOR_MODE_NORMAL;
}
static int rk801_set_mode(struct regulator_dev *rdev, unsigned int mode)
{
unsigned int offset = rdev->desc->id;
switch (mode) {
case REGULATOR_MODE_FAST:
return regmap_update_bits(rdev->regmap, RK801_POWER_FPWM_EN_REG,
BIT(offset), RK801_FPWM_MODE << offset);
case REGULATOR_MODE_NORMAL:
return regmap_update_bits(rdev->regmap, RK801_POWER_FPWM_EN_REG,
BIT(offset), RK801_AUTO_PWM_MODE << offset);
default:
dev_err(&rdev->dev, "do not support this mode\n");
return -EINVAL;
}
return 0;
}
static int rk801_set_suspend_voltage(struct regulator_dev *rdev, int uv)
{
unsigned int reg;
int sel;
if (rdev->desc->id < RK801_ID_LDO1)
sel = regulator_map_voltage_linear_range(rdev, uv, uv);
else
sel = regulator_map_voltage_linear(rdev, uv, uv);
if (sel < 0)
return -EINVAL;
reg = rdev->desc->vsel_reg + RK801_SLP_REG_OFFSET;
return regmap_update_bits(rdev->regmap, reg,
rdev->desc->vsel_mask, sel);
}
static int rk801_set_suspend_enable(struct regulator_dev *rdev)
{
return regmap_update_bits(rdev->regmap, RK801_POWER_SLP_EN_REG,
BIT(rdev->desc->id), BIT(rdev->desc->id));
}
static int rk801_set_suspend_disable(struct regulator_dev *rdev)
{
return regmap_update_bits(rdev->regmap, RK801_POWER_SLP_EN_REG,
BIT(rdev->desc->id), 0);
}
static int rk801_set_voltage_time_sel(struct regulator_dev *rdev,
unsigned int old_selector,
unsigned int new_selector)
{
return regulator_set_voltage_time_sel(rdev, old_selector,
new_selector) + RK801_HW_SYNC_US;
}
static const struct regulator_ops rk801_buck_ops = {
.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 = rk801_set_voltage_time_sel,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.set_mode = rk801_set_mode,
.get_mode = rk801_get_mode,
.set_suspend_voltage = rk801_set_suspend_voltage,
.set_suspend_enable = rk801_set_suspend_enable,
.set_suspend_disable = rk801_set_suspend_disable,
};
static const struct regulator_ops rk801_reg_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.set_suspend_voltage = rk801_set_suspend_voltage,
.set_suspend_enable = rk801_set_suspend_enable,
.set_suspend_disable = rk801_set_suspend_disable,
};
static const struct regulator_ops rk801_switch_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.set_suspend_enable = rk801_set_suspend_enable,
.set_suspend_disable = rk801_set_suspend_disable,
};
static const struct regulator_ops rk805_reg_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
@ -1049,6 +1171,123 @@ static const struct regulator_ops rk817_switch_ops = {
.set_suspend_disable = rk817_set_suspend_disable,
};
static const struct linear_range rk801_buck1_voltage_ranges[] = {
REGULATOR_LINEAR_RANGE(500000, 0, 80, 12500), /* 0.5v - 1.5v */
REGULATOR_LINEAR_RANGE(1800000, 81, 82, 400000),/* 1.8v - 2.2v */
REGULATOR_LINEAR_RANGE(3300000, 83, 83, 0), /* 3.3v */
REGULATOR_LINEAR_RANGE(5000000, 84, 84, 0), /* 5.0v */
REGULATOR_LINEAR_RANGE(5250000, 85, 85, 0), /* 5.25v */
};
static const struct linear_range rk801_buck2_voltage_ranges[] = {
REGULATOR_LINEAR_RANGE(800000, 0, 2, 50000), /* 0.8v - 0.9v */
REGULATOR_LINEAR_RANGE(1800000, 3, 4, 400000), /* 1.8v - 2.2v */
REGULATOR_LINEAR_RANGE(3300000, 5, 5, 0), /* 3.3v */
REGULATOR_LINEAR_RANGE(5000000, 6, 6, 0), /* 5.0v */
REGULATOR_LINEAR_RANGE(5250000, 7, 7, 0), /* 5.25v */
};
static const struct linear_range rk801_buck4_voltage_ranges[] = {
REGULATOR_LINEAR_RANGE(500000, 0, 80, 12500), /* 0.5v - 1.5v */
REGULATOR_LINEAR_RANGE(1800000, 81, 82, 400000),/* 1.8v - 2.2v */
REGULATOR_LINEAR_RANGE(2500000, 83, 83, 0), /* 2.5v */
REGULATOR_LINEAR_RANGE(2800000, 84, 84, 0), /* 2.8v */
REGULATOR_LINEAR_RANGE(3000000, 85, 85, 0), /* 3.0v */
REGULATOR_LINEAR_RANGE(3300000, 86, 86, 0), /* 3.3v */
};
static const struct regulator_desc rk801_reg[] = {
{
.name = "dcdc1",
.supply_name = "vcc1",
.of_match = of_match_ptr("dcdc1"),
.regulators_node = of_match_ptr("regulators"),
.id = RK801_ID_DCDC1,
.ops = &rk801_buck_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = 86,
.linear_ranges = rk801_buck1_voltage_ranges,
.n_linear_ranges = ARRAY_SIZE(rk801_buck1_voltage_ranges),
.vsel_reg = RK801_BUCK1_ON_VSEL_REG,
.vsel_mask = RK801_BUCK_VSEL_MASK,
.enable_reg = RK801_POWER_EN0_REG,
.enable_mask = ENABLE_MASK(RK801_ID_DCDC1),
.enable_val = ENABLE_MASK(RK801_ID_DCDC1),
.disable_val = DISABLE_VAL(RK801_ID_DCDC1),
.ramp_delay = 1000,
.of_map_mode = rk8xx_regulator_of_map_mode,
.enable_time = 400,
.owner = THIS_MODULE,
}, {
.name = "dcdc2",
.supply_name = "vcc2",
.of_match = of_match_ptr("dcdc2"),
.regulators_node = of_match_ptr("regulators"),
.id = RK801_ID_DCDC2,
.ops = &rk801_buck_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = 8,
.linear_ranges = rk801_buck2_voltage_ranges,
.n_linear_ranges = ARRAY_SIZE(rk801_buck2_voltage_ranges),
.vsel_reg = RK801_BUCK2_ON_VSEL_REG,
.vsel_mask = RK801_BUCK_VSEL_MASK,
.enable_reg = RK801_POWER_EN0_REG,
.enable_mask = ENABLE_MASK(RK801_ID_DCDC2),
.enable_val = ENABLE_MASK(RK801_ID_DCDC2),
.disable_val = DISABLE_VAL(RK801_ID_DCDC2),
.ramp_delay = 1000,
.of_map_mode = rk8xx_regulator_of_map_mode,
.enable_time = 400,
.owner = THIS_MODULE,
}, {
.name = "dcdc3",
.supply_name = "vcc3",
.of_match = of_match_ptr("dcdc3"),
.regulators_node = of_match_ptr("regulators"),
.id = RK801_ID_DCDC3,
.ops = &rk801_switch_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = 1,
.enable_reg = RK801_POWER_EN0_REG,
.enable_mask = ENABLE_MASK(RK801_ID_DCDC3),
.enable_val = ENABLE_MASK(RK801_ID_DCDC3),
.disable_val = DISABLE_VAL(RK801_ID_DCDC3),
.of_map_mode = rk8xx_regulator_of_map_mode,
.enable_time = 400,
.owner = THIS_MODULE,
}, {
.name = "dcdc4",
.supply_name = "vcc4",
.of_match = of_match_ptr("dcdc4"),
.regulators_node = of_match_ptr("regulators"),
.id = RK801_ID_DCDC4,
.ops = &rk801_buck_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = 87,
.linear_ranges = rk801_buck4_voltage_ranges,
.n_linear_ranges = ARRAY_SIZE(rk801_buck4_voltage_ranges),
.vsel_reg = RK801_BUCK4_ON_VSEL_REG,
.vsel_mask = RK801_BUCK_VSEL_MASK,
.enable_reg = RK801_POWER_EN0_REG,
.enable_mask = ENABLE_MASK(RK801_ID_DCDC4),
.enable_val = ENABLE_MASK(RK801_ID_DCDC4),
.disable_val = DISABLE_VAL(RK801_ID_DCDC4),
.ramp_delay = 1000,
.of_map_mode = rk8xx_regulator_of_map_mode,
.enable_time = 400,
.owner = THIS_MODULE,
},
RK801_DESC(RK801_ID_LDO1, "ldo1", "vcc5", 500, 3400, 50,
RK801_LDO1_ON_VSEL_REG, RK801_LDO_VSEL_MASK, RK801_POWER_EN1_REG,
ENABLE_MASK(0), DISABLE_VAL(0), 400),
RK801_DESC(RK801_ID_LDO2, "ldo2", "vcc6", 500, 3400, 50,
RK801_LDO2_ON_VSEL_REG, RK801_LDO_VSEL_MASK, RK801_POWER_EN1_REG,
ENABLE_MASK(1), DISABLE_VAL(1), 400),
RK801_DESC_SWITCH(RK801_ID_SWITCH, "switch", "vcc7", RK801_POWER_EN1_REG,
ENABLE_MASK(2), DISABLE_VAL(2)),
};
static const struct regulator_desc rk805_reg[] = {
{
.name = "DCDC_REG1",
@ -1887,6 +2126,10 @@ static int rk808_regulator_probe(struct platform_device *pdev)
return -ENOMEM;
switch (rk808->variant) {
case RK801_ID:
regulators = rk801_reg;
nregulators = RK801_NUM_REGULATORS;
break;
case RK805_ID:
regulators = rk805_reg;
nregulators = RK805_NUM_REGULATORS;

View file

@ -174,6 +174,9 @@ enum axp20x_variants {
#define AXP717_ADC_DATA_SEL 0xcd
#define AXP717_ADC_DATA_H 0xce
#define AXP717_ADC_DATA_L 0xcf
#define AXP717_TYPEC_CC_AA_EN 0xe1
#define AXP717_TYPEC_CC_MODE_CONTROL 0xe3
#define AXP717_TYPEC_CC_STATUS 0xe7
#define AXP806_STARTUP_SRC 0x00
#define AXP806_CHIP_ID 0x03

View file

@ -340,6 +340,123 @@ enum rk818_reg {
#define RK818_USB_ILMIN_2000MA 0x7
#define RK818_USB_CHG_SD_VSEL_MASK 0x70
/* RK801 */
enum rk801_reg {
RK801_ID_DCDC1,
RK801_ID_DCDC2,
RK801_ID_DCDC4,
RK801_ID_DCDC3,
RK801_ID_LDO1,
RK801_ID_LDO2,
RK801_ID_SWITCH,
RK801_ID_MAX,
};
#define RK801_SLP_REG_OFFSET 5
#define RK801_NUM_REGULATORS 7
#define RK801_HW_SYNC_US 32
/* RK801 Register Definitions */
#define RK801_ID_MSB 0x00
#define RK801_ID_LSB 0x01
#define RK801_OTP_VER_REG 0x02
#define RK801_POWER_EN0_REG 0x03
#define RK801_POWER_EN1_REG 0x04
#define RK801_POWER_SLP_EN_REG 0x05
#define RK801_POWER_FPWM_EN_REG 0x06
#define RK801_SLP_LP_CONFIG_REG 0x07
#define RK801_BUCK_CONFIG_REG 0x08
#define RK801_BUCK1_ON_VSEL_REG 0x09
#define RK801_BUCK2_ON_VSEL_REG 0x0a
#define RK801_BUCK4_ON_VSEL_REG 0x0b
#define RK801_LDO1_ON_VSEL_REG 0x0c
#define RK801_LDO2_ON_VSEL_REG 0x0d
#define RK801_BUCK1_SLP_VSEL_REG 0x0e
#define RK801_BUCK2_SLP_VSEL_REG 0x0f
#define RK801_BUCK4_SLP_VSEL_REG 0x10
#define RK801_LDO1_SLP_VSEL_REG 0x11
#define RK801_LDO2_SLP_VSEL_REG 0x12
#define RK801_LDO_SW_IMAX_REG 0x13
#define RK801_SYS_STS_REG 0x14
#define RK801_SYS_CFG0_REG 0x15
#define RK801_SYS_CFG1_REG 0x16
#define RK801_SYS_CFG2_REG 0x17
#define RK801_SYS_CFG3_REG 0x18
#define RK801_SYS_CFG4_REG 0x19
#define RK801_SLEEP_CFG_REG 0x1a
#define RK801_ON_SOURCE_REG 0x1b
#define RK801_OFF_SOURCE_REG 0x1c
#define RK801_PWRON_KEY_REG 0x1d
#define RK801_INT_STS0_REG 0x1e
#define RK801_INT_MASK0_REG 0x1f
#define RK801_INT_CONFIG_REG 0x20
#define RK801_CON_BACK1_REG 0x21
#define RK801_CON_BACK2_REG 0x22
#define RK801_DATA_CON0_REG 0x23
#define RK801_DATA_CON1_REG 0x24
#define RK801_DATA_CON2_REG 0x25
#define RK801_DATA_CON3_REG 0x26
#define RK801_POWER_EXIT_SLP_SEQ0_REG 0x27
#define RK801_POWER_EXIT_SLP_SEQ1_REG 0x28
#define RK801_POWER_EXIT_SLP_SEQ2_REG 0x29
#define RK801_POWER_EXIT_SLP_SEQ3_REG 0x2a
#define RK801_POWER_ENTER_SLP_OR_SHTD_SEQ0_REG 0x2b
#define RK801_POWER_ENTER_SLP_OR_SHTD_SEQ1_REG 0x2c
#define RK801_POWER_ENTER_SLP_OR_SHTD_SEQ2_REG 0x2d
#define RK801_POWER_ENTER_SLP_OR_SHTD_SEQ3_REG 0x2e
#define RK801_BUCK_DEBUG1_REG 0x2f
#define RK801_BUCK_DEBUG2_REG 0x30
#define RK801_BUCK_DEBUG3_REG 0x31
#define RK801_BUCK_DEBUG4_REG 0x32
#define RK801_BUCK_DEBUG5_REG 0x33
#define RK801_BUCK_DEBUG7_REG 0x34
#define RK801_OTP_EN_CON_REG 0x35
#define RK801_TEST_CON_REG 0x36
#define RK801_EFUSE_CONTROL_REG 0x37
#define RK801_SYS_CFG3_OTP_REG 0x38
/* RK801 IRQ Definitions */
#define RK801_IRQ_PWRON_FALL 0
#define RK801_IRQ_PWRON_RISE 1
#define RK801_IRQ_PWRON 2
#define RK801_IRQ_PWRON_LP 3
#define RK801_IRQ_HOTDIE 4
#define RK801_IRQ_VDC_RISE 5
#define RK801_IRQ_VDC_FALL 6
#define RK801_IRQ_PWRON_FALL_MSK BIT(0)
#define RK801_IRQ_PWRON_RISE_MSK BIT(1)
#define RK801_IRQ_PWRON_MSK BIT(2)
#define RK801_IRQ_PWRON_LP_MSK BIT(3)
#define RK801_IRQ_HOTDIE_MSK BIT(4)
#define RK801_IRQ_VDC_RISE_MSK BIT(5)
#define RK801_IRQ_VDC_FALL_MSK BIT(6)
/* RK801_SLP_LP_CONFIG_REG */
#define RK801_BUCK_SLP_LP_EN BIT(3)
#define RK801_PLDO_SLP_LP_EN BIT(1)
#define RK801_SLP_LP_MASK (RK801_PLDO_SLP_LP_EN | RK801_BUCK_SLP_LP_EN)
/* RK801_SLEEP_CFG_REG */
#define RK801_SLEEP_FUN_MSK 0x3
#define RK801_NONE_FUN 0x0
#define RK801_SLEEP_FUN 0x1
#define RK801_SHUTDOWN_FUN 0x2
#define RK801_RESET_FUN 0x3
/* RK801_SYS_CFG2_REG */
#define RK801_SLEEP_POL_MSK BIT(1)
#define RK801_SLEEP_ACT_H BIT(1)
#define RK801_SLEEP_ACT_L 0
#define RK801_RST_MSK (0x3 << 4)
#define RK801_RST_RESTART_PMU (0x0 << 4)
#define RK801_RST_RESTART_REG (0x1 << 4)
#define RK801_RST_RESTART_REG_RESETB (0x2 << 4)
/* RK801_INT_CONFIG_REG */
#define RK801_INT_POL_MSK BIT(1)
#define RK801_INT_ACT_H BIT(1)
#define RK801_INT_ACT_L 0
#define RK801_FPWM_MODE 1
#define RK801_AUTO_PWM_MODE 0
#define RK801_PLDO_HRDEC_EN BIT(6)
/* RK805 */
enum rk805_reg {
RK805_ID_DCDC1,
@ -1332,6 +1449,7 @@ enum {
};
enum {
RK801_ID = 0x8010,
RK805_ID = 0x8050,
RK806_ID = 0x8060,
RK808_ID = 0x0000,

View file

@ -249,6 +249,8 @@ enum {
#define BD71828_REG_BATCAP_MON_LIMIT_U 0xcc
#define BD71828_REG_CONF 0x64
#define BD71828_REG_ILIM_STAT 0x6d
#define BD71828_REG_DCIN_SET 0x70
#define BD71828_REG_DCIN_CLPS 0x71
#define BD71828_REG_MEAS_CLEAR 0xaf

View file

@ -53,7 +53,7 @@
/**
* enum tps6105x_mode - desired mode for the TPS6105x
* @TPS6105X_MODE_SHUTDOWN: this instance is inactive, not used for anything
* @TPS61905X_MODE_TORCH: this instance is used as a LED, usually a while
* @TPS6105X_MODE_TORCH: this instance is used as a LED, usually a while
* LED, for example as backlight or flashlight. If this is set, the
* TPS6105X will register to the LED framework
* @TPS6105X_MODE_TORCH_FLASH: this instance is used as a flashgun, usually
@ -82,7 +82,8 @@ struct tps6105x_platform_data {
/**
* struct tps6105x - state holder for the TPS6105x drivers
* @i2c_client: corresponding I2C client
* @pdata: associated platform data
* @client: corresponding I2C client
* @regulator: regulator device if used in voltage mode
* @regmap: used for i2c communcation on accessing registers
*/

View file

@ -149,6 +149,8 @@ enum pmic_id {
#define TPS65215_ENABLE_LDO2_EN_MASK BIT(5)
#define TPS65214_ENABLE_LDO1_EN_MASK BIT(5)
#define TPS65219_ENABLE_LDO4_EN_MASK BIT(6)
/* Register Unlock */
#define TPS65214_LOCK_ACCESS_CMD 0x5a
/* power ON-OFF sequence slot */
#define TPS65219_BUCKS_LDOS_SEQUENCE_OFF_SLOT_MASK GENMASK(3, 0)
#define TPS65219_BUCKS_LDOS_SEQUENCE_ON_SLOT_MASK GENMASK(7, 4)