mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-01-12 01:20:14 +00:00
MFD for v6.16
* Samsung Exynos ACPM:
* Populate child platform devices from device tree data
* Introduce a new API, `devm_acpm_get_by_node()`, for child devices to get the ACPM handle
* ROHM PMICs:
* Add support for the ROHM BD96802 scalable companion PMIC to the BD96801 core driver
* Add support for controlling the BD96802 using the BD96801 regulator driver
* Add support to the BD96805, which is almost identical to the BD96801
* Add support to the BD96806, which is similar to the BD96802
* Maxim MAX77759:
* Add a core driver for the MAX77759 companion PMIC
* Add a GPIO driver for the expander functions on the MAX77759
* Add an NVMEM driver to expose the non-volatile memory on the MAX77759
* STMicroelectronics STM32MP25:
* Add support for the STM32MP25 SoC to the stm32-lptimer
* Add support for the STM32MP25 to the clocksource driver, handling new register access requirements
* Add support for the STM32MP25 to the PWM driver, enabling up to two PWM outputs
* Broadcom BCM590xx:
* Add support for the BCM59054 PMU
* Parse the PMU ID and revision to support behavioral differences between chip revisions
* Add regulator support for the BCM59054
* Samsung S2MPG10:
* Add support for the S2MPG10 PMIC, which communicates via the Samsung ACPM firmware instead of I2C
* Exynos ACPM:
* Improve timeout detection reliability by using ktime APIs instead of a loop counter assumption
* Allow PMIC access during late system shutdown by switching to `udelay()` instead of a sleeping function
* Fix an issue where reading command results longer than 8 bytes would fail
* Silence non-error `-EPROBE_DEFER` messages during boot to clean up logs
* Exynos LPASS:
* Fix an error handling path by switching to `devm_regmap_init_mmio()` to prevent resource leaks
* Fix a bug where `exynos_lpass_disable()` was called twice in the remove function
* Fix another resource leak in the probe's error path by using `devm_add_action_or_reset()`
* Samsung SEC:
* Handle the s2dos05, which does not have IRQ support, explicitly to prevent warnings
* Fix the core driver to correctly handle errors from `sec_irq_init()` instead of ignoring them
* STMPE-SPI:
* Correct an undeclared identifier in the `MODULE_DEVICE_TABLE` macro
* MAINTAINERS:
* Adjust a file path for the Siemens IPC LED drivers entry to fix a broken reference
* Maxim Drivers:
* Correct the spelling of "Electronics" in Samsung copyright headers across multiple files
* General:
* Fix wakeup source memory leaks on device unbind for 88pm886, as3722, max14577, max77541, max77705,
max8925, rt5033, and sprd-sc27xx drivers
* Samsung SEC Drivers:
* Split the driver into a transport-agnostic core (`sec-core`) and transport-specific (`sec-i2c`,
`sec-acpm`) modules to support non-I2C devices
* Merge the `sec-core` and `sec-irq` modules to reduce memory consumption
* Move internal APIs to a private header to clean up the public API
* Improve code style by sorting includes, cleaning up headers, sorting device tables, and using helper
macros like `dev_err_probe()`, `MFD_CELL`, and `REGMAP_IRQ_REG`
* Make regmap configuration for s2dos05/s2mpu05 explicit to improve clarity
* Rework platform data and regmap instantiation to use OF match data instead of a large switch statement
* ROHM BD96801/2:
* Prepare the driver for new models by separating chip-specific data into its own structure
* Drop IC name prefix from IRQ resource names in both the MFD and regulator drivers for simplification
* Broadcom BCM590xx:
* Refactor the regulator driver to store descriptions in a table to ease support for new chips
* Rename BCM59056-specific data to prepare for the addition of other regulators
* Use `dev_err_probe()` for cleaner error handling
* Exynos ACPM:
* Correct kerneldoc warnings and use the conventional 'np' argument name
* General MFD:
* Convert `aat2870` and `tps65010` to use the per-client debugfs directory provided by the I2C core
* Convert `sm501`, `tps65010` and `ucb1x00` to use the new GPIO line value setter callbacks
* Constify `regmap_irq_chip` and other structures in `88pm886` to move data to read-only sections
* BCM590xx:
* Drop the unused "id" member from the `bcm590xx` struct in preparation for a replacement
* Samsung SEC Core:
* Remove forward declarations for functions that no longer exist
* SM501:
* Remove the unused `sm501_find_clock()` function
* New Compatibles:
* Google: Add a PMIC child node to the `google,gs101-acpm-ipc` binding
* ROHM: Add new bindings for `rohm,bd96802-regulator` and `rohm,bd96802-pmic`, and add compatibles
for BD96805 and BD96806
* Maxim: Add new bindings for `maxim,max77759-gpio`, `maxim,max77759-nvmem`, and the top-level
`maxim,max77759`
* STM: Add `stm32mp25` compatible to the `stm32-lptimer` binding
* Broadcom: Add `bcm59054` compatible
* Atmel/Microchip: Add `microchip,sama7d65-gpbr` and `microchip,sama7d65-secumod` compatibles
* Samsung: Add `s2mpg10` compatible to the `samsung,s2mps11` MFD binding
* MediaTek: Add compatibles for `mt6893` (scpsys), `mt7988-topmisc`, and `mt8365-infracfg-nao`
* Qualcomm: Add `qcom,apq8064-mmss-sfpb` and `qcom,apq8064-sps-sic` syscon compatibles
* Refactoring & Cleanup:
* Convert Broadcom BCM59056 devicetree bindings to YAML and split them into MFD and regulator parts
* Convert the Microchip AT91 secumod binding to YAML
* Drop unrelated consumer nodes from binding examples to reduce bloat
* Correct indentation and style in various DTS examples
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEdrbJNaO+IJqU8IdIUa+KL4f8d2EFAmg+xmQACgkQUa+KL4f8
d2FJAxAApmk3kxAlb9r6E268SY1qQSeQKhhzQZeQz1Dt9ZfMurgnou+EdY5juxCH
owu4AjyQdaC/eIJJRaBcBjcskmNRsVd7mGwQfhMyg7IvhM9k1PxTuad/PSRauGqy
p7XnYFYeDa9fwwAZ8qD01gpCenQ3oLm4ef05FGC5SDlqcZzxOzc4iGYgHYjE7ACp
Iuv5tN0JkxCzTGtpZ6kXn5tp895KcndzPWgS0eQxf6Plw2syF0KKxlVCWUfLjAaZ
Db1VFOkc2vgjhxuFPpybGzRhgtVKRdYRJqL4EQEhnB/u23cuxxqBSJ3BPGIjfqrA
h6zaxbYJyBF3cHz9kOqi99inN4T3cZssOSdqIVuWTYSuH+FDdsVi5BF2WlrSgWqn
hgyVZYjMEB4UbEU+0VdZMqTWjY0+kmAEl7xWQ++sp2cuTtYdcufrldLVl0d/HOCm
zLXia1A2KHgFoBFN/sP0ffZD9ceM/ng1h1tfz+48MWWO7obpwbdFNtWllblfpm9d
cYPlg0uddFljjzP/gm3jgJAZkMer2m5eSVfvf2L5VrSROFSfbxwHcvVgRTxmPR0K
1rQqLm1w2Tp8HCocuO95bRv5g0Z4jWDu+CssM1XZrEXaNCZ5E0qm374JArpAFctb
cAVFcLYSUT73S6lgBOjF05F2zGPCmqW26S+R2cMPcM2SA1N89Go=
=hiAm
-----END PGP SIGNATURE-----
Merge tag 'mfd-next-6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull MFD updates from Lee Jones:
"Samsung Exynos ACPM:
- Populate child platform devices from device tree data
- Introduce a new API, 'devm_acpm_get_by_node()', for child devices
to get the ACPM handle
ROHM PMICs:
- Add support for the ROHM BD96802 scalable companion PMIC to the
BD96801 core driver
- Add support for controlling the BD96802 using the BD96801 regulator
driver
- Add support to the BD96805, which is almost identical to the
BD96801
- Add support to the BD96806, which is similar to the BD96802
Maxim MAX77759:
- Add a core driver for the MAX77759 companion PMIC
- Add a GPIO driver for the expander functions on the MAX77759
- Add an NVMEM driver to expose the non-volatile memory on the
MAX77759
STMicroelectronics STM32MP25:
- Add support for the STM32MP25 SoC to the stm32-lptimer
- Add support for the STM32MP25 to the clocksource driver, handling
new register access requirements
- Add support for the STM32MP25 to the PWM driver, enabling up to two
PWM outputs
Broadcom BCM590xx:
- Add support for the BCM59054 PMU
- Parse the PMU ID and revision to support behavioral differences
between chip revisions
- Add regulator support for the BCM59054
Samsung S2MPG10:
- Add support for the S2MPG10 PMIC, which communicates via the
Samsung ACPM firmware instead of I2C
Exynos ACPM:
- Improve timeout detection reliability by using ktime APIs instead
of a loop counter assumption
- Allow PMIC access during late system shutdown by switching to
'udelay()' instead of a sleeping function
- Fix an issue where reading command results longer than 8 bytes
would fail
- Silence non-error '-EPROBE_DEFER' messages during boot to clean up
logs
Exynos LPASS:
- Fix an error handling path by switching to
'devm_regmap_init_mmio()' to prevent resource leaks
- Fix a bug where 'exynos_lpass_disable()' was called twice in the
remove function
- Fix another resource leak in the probe's error path by using
'devm_add_action_or_reset()'
Samsung SEC:
- Handle the s2dos05, which does not have IRQ support, explicitly to
prevent warnings
- Fix the core driver to correctly handle errors from
'sec_irq_init()' instead of ignoring them
STMPE-SPI:
- Correct an undeclared identifier in the 'MODULE_DEVICE_TABLE' macro
MAINTAINERS:
- Adjust a file path for the Siemens IPC LED drivers entry to fix a
broken reference
Maxim Drivers:
- Correct the spelling of "Electronics" in Samsung copyright headers
across multiple files
General:
- Fix wakeup source memory leaks on device unbind for 88pm886,
as3722, max14577, max77541, max77705, max8925, rt5033, and
sprd-sc27xx drivers
Samsung SEC Drivers:
- Split the driver into a transport-agnostic core ('sec-core') and
transport-specific ('sec-i2c', 'sec-acpm') modules to support
non-I2C devices
- Merge the 'sec-core' and 'sec-irq' modules to reduce memory
consumption
- Move internal APIs to a private header to clean up the public API
- Improve code style by sorting includes, cleaning up headers,
sorting device tables, and using helper macros like
'dev_err_probe()', 'MFD_CELL', and 'REGMAP_IRQ_REG'
- Make regmap configuration for s2dos05/s2mpu05 explicit to improve
clarity
- Rework platform data and regmap instantiation to use OF match data
instead of a large switch statement
ROHM BD96801/2:
- Prepare the driver for new models by separating chip-specific data
into its own structure
- Drop IC name prefix from IRQ resource names in both the MFD and
regulator drivers for simplification
Broadcom BCM590xx:
- Refactor the regulator driver to store descriptions in a table to
ease support for new chips
- Rename BCM59056-specific data to prepare for the addition of other
regulators
- Use 'dev_err_probe()' for cleaner error handling
Exynos ACPM:
- Correct kerneldoc warnings and use the conventional 'np' argument
name
General MFD:
- Convert 'aat2870' and 'tps65010' to use the per-client debugfs
directory provided by the I2C core
- Convert 'sm501', 'tps65010' and 'ucb1x00' to use the new GPIO line
value setter callbacks
- Constify 'regmap_irq_chip' and other structures in '88pm886' to
move data to read-only sections
BCM590xx:
- Drop the unused "id" member from the 'bcm590xx' struct in
preparation for a replacement
Samsung SEC Core:
- Remove forward declarations for functions that no longer exist
SM501:
- Remove the unused 'sm501_find_clock()' function
New Compatibles:
- Google: Add a PMIC child node to the 'google,gs101-acpm-ipc'
binding
- ROHM: Add new bindings for 'rohm,bd96802-regulator' and
'rohm,bd96802-pmic', and add compatibles for BD96805 and BD96806
- Maxim: Add new bindings for 'maxim,max77759-gpio',
'maxim,max77759-nvmem', and the top-level 'maxim,max77759'
- STM: Add 'stm32mp25' compatible to the 'stm32-lptimer' binding
- Broadcom: Add 'bcm59054' compatible
- Atmel/Microchip: Add 'microchip,sama7d65-gpbr' and
'microchip,sama7d65-secumod' compatibles
- Samsung: Add 's2mpg10' compatible to the 'samsung,s2mps11' MFD
binding
- MediaTek: Add compatibles for 'mt6893' (scpsys), 'mt7988-topmisc',
and 'mt8365-infracfg-nao'
- Qualcomm: Add 'qcom,apq8064-mmss-sfpb' and 'qcom,apq8064-sps-sic'
syscon compatibles
Refactoring & Cleanup:
- Convert Broadcom BCM59056 devicetree bindings to YAML and split
them into MFD and regulator parts
- Convert the Microchip AT91 secumod binding to YAML
- Drop unrelated consumer nodes from binding examples to reduce bloat
- Correct indentation and style in various DTS examples"
* tag 'mfd-next-6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (81 commits)
mfd: maxim: Correct Samsung "Electronics" spelling in copyright headers
mfd: maxim: Correct Samsung "Electronics" spelling in headers
mfd: sm501: Remove unused sm501_find_clock
mfd: 88pm886: Constify struct regmap_irq_chip and some other structures
dt-bindings: mfd: syscon: Add mediatek,mt8365-infracfg-nao
mfd: sprd-sc27xx: Fix wakeup source leaks on device unbind
mfd: rt5033: Fix wakeup source leaks on device unbind
mfd: max8925: Fix wakeup source leaks on device unbind
mfd: max77705: Fix wakeup source leaks on device unbind
mfd: max77541: Fix wakeup source leaks on device unbind
mfd: max14577: Fix wakeup source leaks on device unbind
mfd: as3722: Fix wakeup source leaks on device unbind
mfd: 88pm886: Fix wakeup source leaks on device unbind
dt-bindings: mfd: Correct indentation and style in DTS example
dt-bindings: mfd: Drop unrelated nodes from DTS example
dt-bindings: mfd: syscon: Add qcom,apq8064-sps-sic
dt-bindings: mfd: syscon: Add qcom,apq8064-mmss-sfpb
mfd: stmpe-spi: Correct the name used in MODULE_DEVICE_TABLE
dt-bindings: mfd: syscon: Add mt7988-topmisc
mfd: exynos-lpass: Fix another error handling path in exynos_lpass_probe()
...
This commit is contained in:
commit
69352bd52b
@ -0,0 +1,49 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/arm/atmel,sama5d2-secumod.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Microchip AT91 Security Module (SECUMOD)
|
||||
|
||||
maintainers:
|
||||
- Nicolas Ferre <nicolas.ferre@microchip.com>
|
||||
|
||||
description:
|
||||
The Security Module also offers the PIOBU pins which can be used as GPIO pins.
|
||||
Note that they maintain their voltage during Backup/Self-refresh.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- items:
|
||||
- const: atmel,sama5d2-secumod
|
||||
- const: syscon
|
||||
- items:
|
||||
- enum:
|
||||
- microchip,sama7d65-secumod
|
||||
- microchip,sama7g5-secumod
|
||||
- const: atmel,sama5d2-secumod
|
||||
- const: syscon
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
gpio-controller: true
|
||||
|
||||
"#gpio-cells":
|
||||
const: 2
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
security-module@fc040000 {
|
||||
compatible = "atmel,sama5d2-secumod", "syscon";
|
||||
reg = <0xfc040000 0x100>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
@ -46,28 +46,3 @@ Examples:
|
||||
reg = <0xffffe800 0x200>;
|
||||
};
|
||||
|
||||
Security Module (SECUMOD)
|
||||
|
||||
The Security Module macrocell provides all necessary secure functions to avoid
|
||||
voltage, temperature, frequency and mechanical attacks on the chip. It also
|
||||
embeds secure memories that can be scrambled.
|
||||
|
||||
The Security Module also offers the PIOBU pins which can be used as GPIO pins.
|
||||
Note that they maintain their voltage during Backup/Self-refresh.
|
||||
|
||||
required properties:
|
||||
- compatible: Should be "atmel,<chip>-secumod", "syscon".
|
||||
<chip> can be "sama5d2".
|
||||
- reg: Should contain registers location and length
|
||||
- gpio-controller: Marks the port as GPIO controller.
|
||||
- #gpio-cells: There are 2. The pin number is the
|
||||
first, the second represents additional
|
||||
parameters such as GPIO_ACTIVE_HIGH/LOW.
|
||||
|
||||
|
||||
secumod@fc040000 {
|
||||
compatible = "atmel,sama5d2-secumod", "syscon";
|
||||
reg = <0xfc040000 0x100>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
@ -19,6 +19,7 @@ properties:
|
||||
- items:
|
||||
- enum:
|
||||
- atmel,at91sam9260-gpbr
|
||||
- microchip,sama7d65-gpbr
|
||||
- const: syscon
|
||||
- items:
|
||||
- enum:
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
-------------------------------
|
||||
BCM590xx Power Management Units
|
||||
-------------------------------
|
||||
|
||||
Required properties:
|
||||
- compatible: "brcm,bcm59056"
|
||||
- reg: I2C slave address
|
||||
- interrupts: interrupt for the PMU. Generic interrupt client node bindings
|
||||
are described in interrupt-controller/interrupts.txt
|
||||
|
||||
------------------
|
||||
Voltage Regulators
|
||||
------------------
|
||||
|
||||
Optional child nodes:
|
||||
- regulators: container node for regulators following the generic
|
||||
regulator binding in regulator/regulator.txt
|
||||
|
||||
The valid regulator node names for BCM59056 are:
|
||||
rfldo, camldo1, camldo2, simldo1, simldo2, sdldo, sdxldo,
|
||||
mmcldo1, mmcldo2, audldo, micldo, usbldo, vibldo,
|
||||
csr, iosr1, iosr2, msr, sdsr1, sdsr2, vsr,
|
||||
gpldo1, gpldo2, gpldo3, gpldo4, gpldo5, gpldo6,
|
||||
vbus
|
||||
|
||||
Example:
|
||||
pmu: bcm59056@8 {
|
||||
compatible = "brcm,bcm59056";
|
||||
reg = <0x08>;
|
||||
interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
|
||||
regulators {
|
||||
rfldo_reg: rfldo {
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
|
||||
...
|
||||
};
|
||||
};
|
||||
76
Documentation/devicetree/bindings/mfd/brcm,bcm59056.yaml
Normal file
76
Documentation/devicetree/bindings/mfd/brcm,bcm59056.yaml
Normal file
@ -0,0 +1,76 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mfd/brcm,bcm59056.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Broadcom BCM590xx Power Management Units
|
||||
|
||||
maintainers:
|
||||
- Artur Weber <aweber.kernel@gmail.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- brcm,bcm59054
|
||||
- brcm,bcm59056
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
regulators:
|
||||
type: object
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: brcm,bcm59054
|
||||
then:
|
||||
properties:
|
||||
regulators:
|
||||
$ref: /schemas/regulator/brcm,bcm59054.yaml#
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: brcm,bcm59056
|
||||
then:
|
||||
properties:
|
||||
regulators:
|
||||
$ref: /schemas/regulator/brcm,bcm59056.yaml#
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pmic@8 {
|
||||
compatible = "brcm,bcm59056";
|
||||
reg = <0x08>;
|
||||
interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
regulators {
|
||||
rfldo {
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -60,43 +60,34 @@ examples:
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
iqs620a@44 {
|
||||
compatible = "azoteq,iqs620a";
|
||||
reg = <0x44>;
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
|
||||
iqs620a@44 {
|
||||
compatible = "azoteq,iqs620a";
|
||||
reg = <0x44>;
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
|
||||
|
||||
keys {
|
||||
compatible = "azoteq,iqs620a-keys";
|
||||
keys {
|
||||
compatible = "azoteq,iqs620a-keys";
|
||||
|
||||
linux,keycodes = <KEY_SELECT>,
|
||||
<KEY_MENU>,
|
||||
<KEY_OK>,
|
||||
<KEY_MENU>;
|
||||
linux,keycodes = <KEY_SELECT>,
|
||||
<KEY_MENU>,
|
||||
<KEY_OK>,
|
||||
<KEY_MENU>;
|
||||
|
||||
hall-switch-south {
|
||||
linux,code = <SW_LID>;
|
||||
azoteq,use-prox;
|
||||
};
|
||||
};
|
||||
|
||||
iqs620a_pwm: pwm {
|
||||
compatible = "azoteq,iqs620a-pwm";
|
||||
#pwm-cells = <2>;
|
||||
};
|
||||
hall-switch-south {
|
||||
linux,code = <SW_LID>;
|
||||
azoteq,use-prox;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
pwmleds {
|
||||
compatible = "pwm-leds";
|
||||
|
||||
led-1 {
|
||||
pwms = <&iqs620a_pwm 0 1000000>;
|
||||
max-brightness = <255>;
|
||||
iqs620a_pwm: pwm {
|
||||
compatible = "azoteq,iqs620a-pwm";
|
||||
#pwm-cells = <2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
@ -105,37 +96,37 @@ examples:
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
iqs620a@44 {
|
||||
compatible = "azoteq,iqs620a";
|
||||
reg = <0x44>;
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
|
||||
iqs620a@44 {
|
||||
compatible = "azoteq,iqs620a";
|
||||
reg = <0x44>;
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
|
||||
|
||||
firmware-name = "iqs620a_coil.bin";
|
||||
firmware-name = "iqs620a_coil.bin";
|
||||
|
||||
keys {
|
||||
compatible = "azoteq,iqs620a-keys";
|
||||
keys {
|
||||
compatible = "azoteq,iqs620a-keys";
|
||||
|
||||
linux,keycodes = <0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<KEY_MUTE>;
|
||||
linux,keycodes = <0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<KEY_MUTE>;
|
||||
|
||||
hall-switch-north {
|
||||
linux,code = <SW_DOCK>;
|
||||
};
|
||||
hall-switch-north {
|
||||
linux,code = <SW_DOCK>;
|
||||
};
|
||||
|
||||
hall-switch-south {
|
||||
linux,code = <SW_TABLET_MODE>;
|
||||
};
|
||||
};
|
||||
hall-switch-south {
|
||||
linux,code = <SW_TABLET_MODE>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
@ -144,36 +135,36 @@ examples:
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
iqs624@44 {
|
||||
compatible = "azoteq,iqs624";
|
||||
reg = <0x44>;
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
|
||||
iqs624@44 {
|
||||
compatible = "azoteq,iqs624";
|
||||
reg = <0x44>;
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
|
||||
|
||||
keys {
|
||||
compatible = "azoteq,iqs624-keys";
|
||||
keys {
|
||||
compatible = "azoteq,iqs624-keys";
|
||||
|
||||
linux,keycodes = <BTN_0>,
|
||||
<0>,
|
||||
<BTN_1>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<KEY_VOLUMEUP>,
|
||||
<KEY_VOLUMEDOWN>;
|
||||
};
|
||||
linux,keycodes = <BTN_0>,
|
||||
<0>,
|
||||
<BTN_1>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<KEY_VOLUMEUP>,
|
||||
<KEY_VOLUMEDOWN>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
@ -18,6 +18,7 @@ properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- mediatek,mt6893-scpsys
|
||||
- mediatek,mt8167-scpsys
|
||||
- mediatek,mt8173-scpsys
|
||||
- mediatek,mt8183-scpsys
|
||||
|
||||
@ -76,12 +76,6 @@ additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
ocelot_clock: ocelot-clock {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <125000000>;
|
||||
};
|
||||
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
@ -48,29 +48,18 @@ examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ec: embedded-controller@43 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_ntxec>;
|
||||
ec: embedded-controller@43 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_ntxec>;
|
||||
|
||||
compatible = "netronix,ntxec";
|
||||
reg = <0x43>;
|
||||
system-power-controller;
|
||||
interrupt-parent = <&gpio4>;
|
||||
interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
|
||||
#pwm-cells = <2>;
|
||||
};
|
||||
};
|
||||
|
||||
backlight {
|
||||
compatible = "pwm-backlight";
|
||||
pwms = <&ec 0 50000>;
|
||||
power-supply = <&backlight_regulator>;
|
||||
};
|
||||
|
||||
backlight_regulator: regulator-dummy {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "backlight";
|
||||
compatible = "netronix,ntxec";
|
||||
reg = <0x43>;
|
||||
system-power-controller;
|
||||
interrupt-parent = <&gpio4>;
|
||||
interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
|
||||
#pwm-cells = <2>;
|
||||
};
|
||||
};
|
||||
|
||||
@ -99,29 +99,29 @@ examples:
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pmic: pmic@30 {
|
||||
compatible = "rohm,bd9571mwv";
|
||||
reg = <0x30>;
|
||||
interrupt-parent = <&gpio2>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
rohm,ddr-backup-power = <0xf>;
|
||||
rohm,rstbmode-pulse;
|
||||
pmic: pmic@30 {
|
||||
compatible = "rohm,bd9571mwv";
|
||||
reg = <0x30>;
|
||||
interrupt-parent = <&gpio2>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
rohm,ddr-backup-power = <0xf>;
|
||||
rohm,rstbmode-pulse;
|
||||
|
||||
regulators {
|
||||
dvfs: dvfs {
|
||||
regulator-name = "dvfs";
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <1030000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
};
|
||||
};
|
||||
regulators {
|
||||
dvfs: dvfs {
|
||||
regulator-name = "dvfs";
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <1030000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@ -4,19 +4,21 @@
|
||||
$id: http://devicetree.org/schemas/mfd/rohm,bd96801-pmic.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: ROHM BD96801 Scalable Power Management Integrated Circuit
|
||||
title: ROHM BD96801/BD96805 Scalable Power Management Integrated Circuit
|
||||
|
||||
maintainers:
|
||||
- Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
|
||||
|
||||
description:
|
||||
BD96801 is an automotive grade single-chip power management IC.
|
||||
It integrates 4 buck converters and 3 LDOs with safety features like
|
||||
BD96801 and BD96805 are automotive grade, single-chip power management ICs.
|
||||
They both integrate 4 buck converters and 3 LDOs with safety features like
|
||||
over-/under voltage and over current detection and a watchdog.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: rohm,bd96801
|
||||
enum:
|
||||
- rohm,bd96801
|
||||
- rohm,bd96805
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
101
Documentation/devicetree/bindings/mfd/rohm,bd96802-pmic.yaml
Normal file
101
Documentation/devicetree/bindings/mfd/rohm,bd96802-pmic.yaml
Normal file
@ -0,0 +1,101 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mfd/rohm,bd96802-pmic.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: ROHM BD96802 / BD96806 Scalable Power Management Integrated Circuit
|
||||
|
||||
maintainers:
|
||||
- Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
|
||||
|
||||
description: |
|
||||
BD96802Qxx-C and BD96806 are automotive grade configurable Power Management
|
||||
Integrated Circuits supporting Functional Safety features for application
|
||||
processors, SoCs and FPGAs
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- rohm,bd96802
|
||||
- rohm,bd96806
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
description:
|
||||
The PMIC provides intb and errb IRQ lines. The errb IRQ line is used
|
||||
for fatal IRQs which will cause the PMIC to shut down power outputs.
|
||||
In many systems this will shut down the SoC contolling the PMIC and
|
||||
connecting/handling the errb can be omitted. However, there are cases
|
||||
where the SoC is not powered by the PMIC or has a short time backup
|
||||
energy to handle shutdown of critical hardware. In that case it may be
|
||||
useful to connect the errb and handle errb events.
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
interrupt-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- enum: [intb, errb]
|
||||
- const: errb
|
||||
|
||||
regulators:
|
||||
$ref: ../regulator/rohm,bd96802-regulator.yaml
|
||||
description:
|
||||
List of child nodes that specify the regulators.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- regulators
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
pmic: pmic@62 {
|
||||
reg = <0x62>;
|
||||
compatible = "rohm,bd96802";
|
||||
interrupt-parent = <&gpio1>;
|
||||
interrupts = <29 IRQ_TYPE_LEVEL_LOW>, <6 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-names = "intb", "errb";
|
||||
|
||||
regulators {
|
||||
buck1 {
|
||||
regulator-name = "buck1";
|
||||
regulator-ramp-delay = <1250>;
|
||||
/* 0.5V min INITIAL - 150 mV tune */
|
||||
regulator-min-microvolt = <350000>;
|
||||
/* 3.3V + 150mV tune */
|
||||
regulator-max-microvolt = <3450000>;
|
||||
|
||||
/* These can be set only when PMIC is in STBY */
|
||||
rohm,initial-voltage-microvolt = <500000>;
|
||||
regulator-ov-error-microvolt = <230000>;
|
||||
regulator-uv-error-microvolt = <230000>;
|
||||
regulator-temp-protection-kelvin = <1>;
|
||||
regulator-temp-warn-kelvin = <0>;
|
||||
};
|
||||
buck2 {
|
||||
regulator-name = "buck2";
|
||||
regulator-min-microvolt = <350000>;
|
||||
regulator-max-microvolt = <3450000>;
|
||||
|
||||
rohm,initial-voltage-microvolt = <3000000>;
|
||||
regulator-ov-error-microvolt = <18000>;
|
||||
regulator-uv-error-microvolt = <18000>;
|
||||
regulator-temp-protection-kelvin = <1>;
|
||||
regulator-temp-warn-kelvin = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -20,6 +20,7 @@ description: |
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- samsung,s2mpg10-pmic
|
||||
- samsung,s2mps11-pmic
|
||||
- samsung,s2mps13-pmic
|
||||
- samsung,s2mps14-pmic
|
||||
@ -58,16 +59,39 @@ properties:
|
||||
reset (setting buck voltages to default values).
|
||||
type: boolean
|
||||
|
||||
system-power-controller: true
|
||||
|
||||
wakeup-source: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- regulators
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: samsung,s2mpg10-pmic
|
||||
then:
|
||||
properties:
|
||||
reg: false
|
||||
samsung,s2mps11-acokb-ground: false
|
||||
samsung,s2mps11-wrstbi-ground: false
|
||||
|
||||
oneOf:
|
||||
- required: [interrupts]
|
||||
- required: [interrupts-extended]
|
||||
|
||||
else:
|
||||
properties:
|
||||
system-power-controller: false
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
|
||||
@ -21,7 +21,12 @@ maintainers:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: st,stm32-lptimer
|
||||
oneOf:
|
||||
- items:
|
||||
- const: st,stm32mp25-lptimer
|
||||
- const: st,stm32-lptimer
|
||||
- items:
|
||||
- const: st,stm32-lptimer
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@ -48,13 +53,21 @@ properties:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
pwm:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: st,stm32-pwm-lp
|
||||
oneOf:
|
||||
- items:
|
||||
- const: st,stm32mp25-pwm-lp
|
||||
- const: st,stm32-pwm-lp
|
||||
- items:
|
||||
- const: st,stm32-pwm-lp
|
||||
|
||||
"#pwm-cells":
|
||||
const: 3
|
||||
@ -69,7 +82,12 @@ properties:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: st,stm32-lptimer-counter
|
||||
oneOf:
|
||||
- items:
|
||||
- const: st,stm32mp25-lptimer-counter
|
||||
- const: st,stm32-lptimer-counter
|
||||
- items:
|
||||
- const: st,stm32-lptimer-counter
|
||||
|
||||
required:
|
||||
- compatible
|
||||
@ -80,7 +98,12 @@ properties:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: st,stm32-lptimer-timer
|
||||
oneOf:
|
||||
- items:
|
||||
- const: st,stm32mp25-lptimer-timer
|
||||
- const: st,stm32-lptimer-timer
|
||||
- items:
|
||||
- const: st,stm32-lptimer-timer
|
||||
|
||||
required:
|
||||
- compatible
|
||||
@ -92,13 +115,18 @@ patternProperties:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: st,stm32-lptimer-trigger
|
||||
oneOf:
|
||||
- items:
|
||||
- const: st,stm32mp25-lptimer-trigger
|
||||
- const: st,stm32-lptimer-trigger
|
||||
- items:
|
||||
- const: st,stm32-lptimer-trigger
|
||||
|
||||
reg:
|
||||
description: Identify trigger hardware block.
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 2
|
||||
maximum: 4
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
@ -84,6 +84,7 @@ select:
|
||||
- mediatek,mt2701-pctl-a-syscfg
|
||||
- mediatek,mt2712-pctl-a-syscfg
|
||||
- mediatek,mt6397-pctl-pmic-syscfg
|
||||
- mediatek,mt7988-topmisc
|
||||
- mediatek,mt8135-pctl-a-syscfg
|
||||
- mediatek,mt8135-pctl-b-syscfg
|
||||
- mediatek,mt8173-pctl-a-syscfg
|
||||
@ -98,6 +99,8 @@ select:
|
||||
- mstar,msc313-pmsleep
|
||||
- nuvoton,ma35d1-sys
|
||||
- nuvoton,wpcm450-shm
|
||||
- qcom,apq8064-mmss-sfpb
|
||||
- qcom,apq8064-sps-sic
|
||||
- rockchip,px30-qos
|
||||
- rockchip,rk3036-qos
|
||||
- rockchip,rk3066-qos
|
||||
@ -187,9 +190,11 @@ properties:
|
||||
- mediatek,mt2701-pctl-a-syscfg
|
||||
- mediatek,mt2712-pctl-a-syscfg
|
||||
- mediatek,mt6397-pctl-pmic-syscfg
|
||||
- mediatek,mt7988-topmisc
|
||||
- mediatek,mt8135-pctl-a-syscfg
|
||||
- mediatek,mt8135-pctl-b-syscfg
|
||||
- mediatek,mt8173-pctl-a-syscfg
|
||||
- mediatek,mt8365-infracfg-nao
|
||||
- mediatek,mt8365-syscfg
|
||||
- microchip,lan966x-cpu-syscon
|
||||
- microchip,mpfs-sysreg-scb
|
||||
@ -201,6 +206,8 @@ properties:
|
||||
- mstar,msc313-pmsleep
|
||||
- nuvoton,ma35d1-sys
|
||||
- nuvoton,wpcm450-shm
|
||||
- qcom,apq8064-mmss-sfpb
|
||||
- qcom,apq8064-sps-sic
|
||||
- rockchip,px30-qos
|
||||
- rockchip,rk3036-qos
|
||||
- rockchip,rk3066-qos
|
||||
|
||||
@ -316,106 +316,106 @@ additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pmic@30 {
|
||||
compatible = "x-powers,axp152";
|
||||
reg = <0x30>;
|
||||
interrupts = <0>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
};
|
||||
};
|
||||
pmic@30 {
|
||||
compatible = "x-powers,axp152";
|
||||
reg = <0x30>;
|
||||
interrupts = <0>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pmic@34 {
|
||||
compatible = "x-powers,axp209";
|
||||
reg = <0x34>;
|
||||
interrupt-parent = <&nmi_intc>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
pmic@34 {
|
||||
compatible = "x-powers,axp209";
|
||||
reg = <0x34>;
|
||||
interrupt-parent = <&nmi_intc>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
ac_power_supply: ac-power {
|
||||
compatible = "x-powers,axp202-ac-power-supply";
|
||||
};
|
||||
ac_power_supply: ac-power {
|
||||
compatible = "x-powers,axp202-ac-power-supply";
|
||||
};
|
||||
|
||||
axp_adc: adc {
|
||||
compatible = "x-powers,axp209-adc";
|
||||
#io-channel-cells = <1>;
|
||||
};
|
||||
axp_adc: adc {
|
||||
compatible = "x-powers,axp209-adc";
|
||||
#io-channel-cells = <1>;
|
||||
};
|
||||
|
||||
axp_gpio: gpio {
|
||||
compatible = "x-powers,axp209-gpio";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
axp_gpio: gpio {
|
||||
compatible = "x-powers,axp209-gpio";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
|
||||
gpio0-adc-pin {
|
||||
pins = "GPIO0";
|
||||
function = "adc";
|
||||
};
|
||||
};
|
||||
gpio0-adc-pin {
|
||||
pins = "GPIO0";
|
||||
function = "adc";
|
||||
};
|
||||
};
|
||||
|
||||
battery_power_supply: battery-power {
|
||||
compatible = "x-powers,axp209-battery-power-supply";
|
||||
};
|
||||
battery_power_supply: battery-power {
|
||||
compatible = "x-powers,axp209-battery-power-supply";
|
||||
};
|
||||
|
||||
regulators {
|
||||
/* Default work frequency for buck regulators */
|
||||
x-powers,dcdc-freq = <1500>;
|
||||
regulators {
|
||||
/* Default work frequency for buck regulators */
|
||||
x-powers,dcdc-freq = <1500>;
|
||||
|
||||
reg_dcdc2: dcdc2 {
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <1000000>;
|
||||
regulator-max-microvolt = <1450000>;
|
||||
regulator-name = "vdd-cpu";
|
||||
};
|
||||
reg_dcdc2: dcdc2 {
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <1000000>;
|
||||
regulator-max-microvolt = <1450000>;
|
||||
regulator-name = "vdd-cpu";
|
||||
};
|
||||
|
||||
reg_dcdc3: dcdc3 {
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <1000000>;
|
||||
regulator-max-microvolt = <1400000>;
|
||||
regulator-name = "vdd-int-dll";
|
||||
};
|
||||
reg_dcdc3: dcdc3 {
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <1000000>;
|
||||
regulator-max-microvolt = <1400000>;
|
||||
regulator-name = "vdd-int-dll";
|
||||
};
|
||||
|
||||
reg_ldo1: ldo1 {
|
||||
/* LDO1 is a fixed output regulator */
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <1300000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
regulator-name = "vdd-rtc";
|
||||
};
|
||||
reg_ldo1: ldo1 {
|
||||
/* LDO1 is a fixed output regulator */
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <1300000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
regulator-name = "vdd-rtc";
|
||||
};
|
||||
|
||||
reg_ldo2: ldo2 {
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <3000000>;
|
||||
regulator-max-microvolt = <3000000>;
|
||||
regulator-name = "avcc";
|
||||
};
|
||||
reg_ldo2: ldo2 {
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <3000000>;
|
||||
regulator-max-microvolt = <3000000>;
|
||||
regulator-name = "avcc";
|
||||
};
|
||||
|
||||
reg_ldo3: ldo3 {
|
||||
regulator-name = "ldo3";
|
||||
};
|
||||
reg_ldo3: ldo3 {
|
||||
regulator-name = "ldo3";
|
||||
};
|
||||
|
||||
reg_ldo4: ldo4 {
|
||||
regulator-name = "ldo4";
|
||||
};
|
||||
reg_ldo4: ldo4 {
|
||||
regulator-name = "ldo4";
|
||||
};
|
||||
|
||||
reg_ldo5: ldo5 {
|
||||
regulator-name = "ldo5";
|
||||
};
|
||||
};
|
||||
reg_ldo5: ldo5 {
|
||||
regulator-name = "ldo5";
|
||||
};
|
||||
};
|
||||
|
||||
usb_power_supply: usb-power {
|
||||
compatible = "x-powers,axp202-usb-power-supply";
|
||||
};
|
||||
};
|
||||
};
|
||||
usb_power_supply: usb-power {
|
||||
compatible = "x-powers,axp202-usb-power-supply";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@ -0,0 +1,56 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/regulator/brcm,bcm59054.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Broadcom BCM59054 Power Management Unit regulators
|
||||
|
||||
description: |
|
||||
This is a part of device tree bindings for the BCM59054 power
|
||||
management unit.
|
||||
|
||||
See Documentation/devicetree/bindings/mfd/brcm,bcm59056.yaml for
|
||||
additional information and example.
|
||||
|
||||
maintainers:
|
||||
- Artur Weber <aweber.kernel@gmail.com>
|
||||
|
||||
patternProperties:
|
||||
"^(cam|sim|mmc)ldo[1-2]$":
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
"^(rf|sd|sdx|aud|mic|usb|vib|tcx)ldo$":
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
"^(c|mm|v)sr$":
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
"^(io|sd)sr[1-2]$":
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
"^gpldo[1-3]$":
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
"^lvldo[1-2]$":
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
vbus:
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
additionalProperties: false
|
||||
@ -0,0 +1,51 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/regulator/brcm,bcm59056.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Broadcom BCM59056 Power Management Unit regulators
|
||||
|
||||
description: |
|
||||
This is a part of device tree bindings for the BCM59056 power
|
||||
management unit.
|
||||
|
||||
See Documentation/devicetree/bindings/mfd/brcm,bcm59056.yaml for
|
||||
additional information and example.
|
||||
|
||||
maintainers:
|
||||
- Artur Weber <aweber.kernel@gmail.com>
|
||||
|
||||
patternProperties:
|
||||
"^(cam|sim|mmc)ldo[1-2]$":
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
"^(rf|sd|sdx|aud|mic|usb|vib)ldo$":
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
"^(c|m|v)sr$":
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
"^(io|sd)sr[1-2]$":
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
"^gpldo[1-6]$":
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
vbus:
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
additionalProperties: false
|
||||
@ -0,0 +1,44 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/regulator/rohm,bd96802-regulator.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: ROHM BD96802 Power Management Integrated Circuit regulators
|
||||
|
||||
maintainers:
|
||||
- Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
|
||||
|
||||
description:
|
||||
This module is part of the ROHM BD96802 MFD device. For more details
|
||||
see Documentation/devicetree/bindings/mfd/rohm,bd96802-pmic.yaml.
|
||||
|
||||
The regulator controller is represented as a sub-node of the PMIC node
|
||||
on the device tree.
|
||||
|
||||
Regulator nodes should be named to buck1 and buck2.
|
||||
|
||||
patternProperties:
|
||||
"^buck[1-2]$":
|
||||
type: object
|
||||
description:
|
||||
Properties for single BUCK regulator.
|
||||
$ref: regulator.yaml#
|
||||
|
||||
properties:
|
||||
rohm,initial-voltage-microvolt:
|
||||
description:
|
||||
Initial voltage for regulator. Voltage can be tuned +/-150 mV from
|
||||
this value. NOTE, This can be modified via I2C only when PMIC is in
|
||||
STBY state.
|
||||
minimum: 500000
|
||||
maximum: 3300000
|
||||
|
||||
rohm,keep-on-stby:
|
||||
description:
|
||||
Keep the regulator powered when PMIC transitions to STBY state.
|
||||
type: boolean
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
additionalProperties: false
|
||||
@ -21475,6 +21475,7 @@ F: include/linux/mfd/rohm-bd71828.h
|
||||
F: include/linux/mfd/rohm-bd718x7.h
|
||||
F: include/linux/mfd/rohm-bd957x.h
|
||||
F: include/linux/mfd/rohm-bd96801.h
|
||||
F: include/linux/mfd/rohm-bd96802.h
|
||||
F: include/linux/mfd/rohm-generic.h
|
||||
F: include/linux/mfd/rohm-shared.h
|
||||
|
||||
@ -21912,6 +21913,7 @@ F: drivers/platform/x86/samsung-laptop.c
|
||||
|
||||
SAMSUNG MULTIFUNCTION PMIC DEVICE DRIVERS
|
||||
M: Krzysztof Kozlowski <krzk@kernel.org>
|
||||
R: André Draszik <andre.draszik@linaro.org>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
L: linux-samsung-soc@vger.kernel.org
|
||||
S: Maintained
|
||||
@ -21922,7 +21924,7 @@ F: Documentation/devicetree/bindings/mfd/samsung,s5m*.yaml
|
||||
F: Documentation/devicetree/bindings/regulator/samsung,s2m*.yaml
|
||||
F: Documentation/devicetree/bindings/regulator/samsung,s5m*.yaml
|
||||
F: drivers/clk/clk-s2mps11.c
|
||||
F: drivers/mfd/sec*.c
|
||||
F: drivers/mfd/sec*.[ch]
|
||||
F: drivers/regulator/s2m*.c
|
||||
F: drivers/regulator/s5m*.c
|
||||
F: drivers/rtc/rtc-s5m.c
|
||||
@ -22575,7 +22577,7 @@ M: Benedikt Niedermayr <benedikt.niedermayr@siemens.com>
|
||||
M: Tobias Schaffner <tobias.schaffner@siemens.com>
|
||||
L: linux-leds@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/leds/simple/
|
||||
F: drivers/leds/simatic/
|
||||
|
||||
SIEMENS IPC PLATFORM DRIVERS
|
||||
M: Bao Cheng Su <baocheng.su@siemens.com>
|
||||
|
||||
@ -167,7 +167,7 @@ CONFIG_MFD_MAX77686=y
|
||||
CONFIG_MFD_MAX77693=y
|
||||
CONFIG_MFD_MAX8997=y
|
||||
CONFIG_MFD_MAX8998=y
|
||||
CONFIG_MFD_SEC_CORE=y
|
||||
CONFIG_MFD_SEC_I2C=y
|
||||
CONFIG_MFD_STMPE=y
|
||||
CONFIG_STMPE_I2C=y
|
||||
CONFIG_MFD_TPS65090=y
|
||||
|
||||
@ -612,7 +612,7 @@ CONFIG_MFD_QCOM_RPM=y
|
||||
CONFIG_MFD_SPMI_PMIC=y
|
||||
CONFIG_MFD_RK8XX_I2C=y
|
||||
CONFIG_MFD_RN5T618=y
|
||||
CONFIG_MFD_SEC_CORE=y
|
||||
CONFIG_MFD_SEC_I2C=y
|
||||
CONFIG_MFD_STMPE=y
|
||||
CONFIG_MFD_PALMAS=y
|
||||
CONFIG_MFD_TPS65090=y
|
||||
|
||||
@ -335,7 +335,7 @@ CONFIG_MFD_MAX77693=y
|
||||
CONFIG_MFD_MAX8907=m
|
||||
CONFIG_EZX_PCAP=y
|
||||
CONFIG_UCB1400_CORE=m
|
||||
CONFIG_MFD_SEC_CORE=y
|
||||
CONFIG_MFD_SEC_I2C=y
|
||||
CONFIG_MFD_PALMAS=y
|
||||
CONFIG_MFD_TPS65090=y
|
||||
CONFIG_MFD_TPS6586X=y
|
||||
|
||||
@ -774,7 +774,7 @@ CONFIG_MFD_MT6397=y
|
||||
CONFIG_MFD_SPMI_PMIC=y
|
||||
CONFIG_MFD_RK8XX_I2C=y
|
||||
CONFIG_MFD_RK8XX_SPI=y
|
||||
CONFIG_MFD_SEC_CORE=y
|
||||
CONFIG_MFD_SEC_I2C=y
|
||||
CONFIG_MFD_SL28CPLD=y
|
||||
CONFIG_RZ_MTU3=y
|
||||
CONFIG_MFD_TI_AM335X_TSCADC=m
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
* Pascal Paillet <p.paillet@st.com> for STMicroelectronics.
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/interrupt.h>
|
||||
@ -27,6 +28,7 @@ struct stm32_lp_private {
|
||||
u32 psc;
|
||||
struct device *dev;
|
||||
struct clk *clk;
|
||||
u32 version;
|
||||
};
|
||||
|
||||
static struct stm32_lp_private*
|
||||
@ -47,12 +49,46 @@ static int stm32_clkevent_lp_shutdown(struct clock_event_device *clkevt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32_clkevent_lp_set_timer(unsigned long evt,
|
||||
struct clock_event_device *clkevt,
|
||||
int is_periodic)
|
||||
static int stm32mp25_clkevent_lp_set_evt(struct stm32_lp_private *priv, unsigned long evt)
|
||||
{
|
||||
struct stm32_lp_private *priv = to_priv(clkevt);
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
regmap_read(priv->reg, STM32_LPTIM_CR, &val);
|
||||
if (!FIELD_GET(STM32_LPTIM_ENABLE, val)) {
|
||||
/* Enable LPTIMER to be able to write into IER and ARR registers */
|
||||
regmap_write(priv->reg, STM32_LPTIM_CR, STM32_LPTIM_ENABLE);
|
||||
/*
|
||||
* After setting the ENABLE bit, a delay of two counter clock cycles is needed
|
||||
* before the LPTIM is actually enabled. For 32KHz rate, this makes approximately
|
||||
* 62.5 micro-seconds, round it up.
|
||||
*/
|
||||
udelay(63);
|
||||
}
|
||||
/* set next event counter */
|
||||
regmap_write(priv->reg, STM32_LPTIM_ARR, evt);
|
||||
/* enable ARR interrupt */
|
||||
regmap_write(priv->reg, STM32_LPTIM_IER, STM32_LPTIM_ARRMIE);
|
||||
|
||||
/* Poll DIEROK and ARROK to ensure register access has completed */
|
||||
ret = regmap_read_poll_timeout_atomic(priv->reg, STM32_LPTIM_ISR, val,
|
||||
(val & STM32_LPTIM_DIEROK_ARROK) ==
|
||||
STM32_LPTIM_DIEROK_ARROK,
|
||||
10, 500);
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "access to LPTIM timed out\n");
|
||||
/* Disable LPTIMER */
|
||||
regmap_write(priv->reg, STM32_LPTIM_CR, 0);
|
||||
return ret;
|
||||
}
|
||||
/* Clear DIEROK and ARROK flags */
|
||||
regmap_write(priv->reg, STM32_LPTIM_ICR, STM32_LPTIM_DIEROKCF_ARROKCF);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void stm32_clkevent_lp_set_evt(struct stm32_lp_private *priv, unsigned long evt)
|
||||
{
|
||||
/* disable LPTIMER to be able to write into IER register*/
|
||||
regmap_write(priv->reg, STM32_LPTIM_CR, 0);
|
||||
/* enable ARR interrupt */
|
||||
@ -61,6 +97,22 @@ static int stm32_clkevent_lp_set_timer(unsigned long evt,
|
||||
regmap_write(priv->reg, STM32_LPTIM_CR, STM32_LPTIM_ENABLE);
|
||||
/* set next event counter */
|
||||
regmap_write(priv->reg, STM32_LPTIM_ARR, evt);
|
||||
}
|
||||
|
||||
static int stm32_clkevent_lp_set_timer(unsigned long evt,
|
||||
struct clock_event_device *clkevt,
|
||||
int is_periodic)
|
||||
{
|
||||
struct stm32_lp_private *priv = to_priv(clkevt);
|
||||
int ret;
|
||||
|
||||
if (priv->version == STM32_LPTIM_VERR_23) {
|
||||
ret = stm32mp25_clkevent_lp_set_evt(priv, evt);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
stm32_clkevent_lp_set_evt(priv, evt);
|
||||
}
|
||||
|
||||
/* start counter */
|
||||
if (is_periodic)
|
||||
@ -176,6 +228,7 @@ static int stm32_clkevent_lp_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->reg = ddata->regmap;
|
||||
priv->version = ddata->version;
|
||||
priv->clk = ddata->clk;
|
||||
ret = clk_prepare_enable(priv->clk);
|
||||
if (ret)
|
||||
|
||||
@ -16,11 +16,11 @@ static const struct regmap_config pm886_regmap_config = {
|
||||
.max_register = PM886_REG_RTC_SPARE6,
|
||||
};
|
||||
|
||||
static struct regmap_irq pm886_regmap_irqs[] = {
|
||||
static const struct regmap_irq pm886_regmap_irqs[] = {
|
||||
REGMAP_IRQ_REG(PM886_IRQ_ONKEY, 0, PM886_INT_ENA1_ONKEY),
|
||||
};
|
||||
|
||||
static struct regmap_irq_chip pm886_regmap_irq_chip = {
|
||||
static const struct regmap_irq_chip pm886_regmap_irq_chip = {
|
||||
.name = "88pm886",
|
||||
.irqs = pm886_regmap_irqs,
|
||||
.num_irqs = ARRAY_SIZE(pm886_regmap_irqs),
|
||||
@ -30,11 +30,11 @@ static struct regmap_irq_chip pm886_regmap_irq_chip = {
|
||||
.unmask_base = PM886_REG_INT_ENA_1,
|
||||
};
|
||||
|
||||
static struct resource pm886_onkey_resources[] = {
|
||||
static const struct resource pm886_onkey_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(PM886_IRQ_ONKEY, "88pm886-onkey"),
|
||||
};
|
||||
|
||||
static struct mfd_cell pm886_devs[] = {
|
||||
static const struct mfd_cell pm886_devs[] = {
|
||||
MFD_CELL_RES("88pm886-onkey", pm886_onkey_resources),
|
||||
MFD_CELL_NAME("88pm886-regulator"),
|
||||
MFD_CELL_NAME("88pm886-rtc"),
|
||||
@ -124,7 +124,11 @@ static int pm886_probe(struct i2c_client *client)
|
||||
if (err)
|
||||
return dev_err_probe(dev, err, "Failed to register power off handler\n");
|
||||
|
||||
device_init_wakeup(dev, device_property_read_bool(dev, "wakeup-source"));
|
||||
if (device_property_read_bool(dev, "wakeup-source")) {
|
||||
err = devm_device_init_wakeup(dev);
|
||||
if (err)
|
||||
return dev_err_probe(dev, err, "Failed to init wakeup\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1312,21 +1312,42 @@ config MFD_RN5T618
|
||||
functionality of the device.
|
||||
|
||||
config MFD_SEC_CORE
|
||||
tristate "Samsung Electronics PMIC Series Support"
|
||||
tristate
|
||||
select MFD_CORE
|
||||
select REGMAP_IRQ
|
||||
|
||||
config MFD_SEC_ACPM
|
||||
tristate "Samsung Electronics S2MPG1x PMICs"
|
||||
depends on EXYNOS_ACPM_PROTOCOL
|
||||
depends on OF
|
||||
select MFD_SEC_CORE
|
||||
help
|
||||
Support for the Samsung Electronics PMICs with ACPM interface.
|
||||
This is a Power Management IC for mobile applications with buck
|
||||
converters, various LDOs, power meters, RTC, clock outputs, and
|
||||
additional GPIOs interfaces.
|
||||
This driver provides common support for accessing the device;
|
||||
additional drivers must be enabled in order to use the functionality
|
||||
of the device.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will be
|
||||
called sec-acpm.
|
||||
|
||||
config MFD_SEC_I2C
|
||||
tristate "Samsung Electronics S2MPA/S2MPS1X/S2MPU/S5M series PMICs"
|
||||
depends on I2C=y
|
||||
depends on OF
|
||||
select MFD_CORE
|
||||
select MFD_SEC_CORE
|
||||
select REGMAP_I2C
|
||||
select REGMAP_IRQ
|
||||
help
|
||||
Support for the Samsung Electronics PMIC devices coming
|
||||
usually along with Samsung Exynos SoC chipset.
|
||||
Support for the Samsung Electronics PMIC devices with I2C interface
|
||||
coming usually along with Samsung Exynos SoC chipset.
|
||||
This driver provides common support for accessing the device,
|
||||
additional drivers must be enabled in order to use the functionality
|
||||
of the device
|
||||
of the device.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called sec-core.
|
||||
module will be called sec-i2c.
|
||||
Have in mind that important core drivers (like regulators) depend
|
||||
on this driver so building this as a module might require proper
|
||||
initial ramdisk or might not boot up as well in certain scenarios.
|
||||
|
||||
@ -229,7 +229,10 @@ 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
|
||||
sec-core-objs := sec-common.o sec-irq.o
|
||||
obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o
|
||||
obj-$(CONFIG_MFD_SEC_ACPM) += sec-acpm.o
|
||||
obj-$(CONFIG_MFD_SEC_I2C) += sec-i2c.o
|
||||
obj-$(CONFIG_MFD_SYSCON) += syscon.o
|
||||
obj-$(CONFIG_MFD_LM3533) += lm3533-core.o lm3533-ctrlbank.o
|
||||
obj-$(CONFIG_MFD_VEXPRESS_SYSREG) += vexpress-sysreg.o
|
||||
|
||||
@ -320,9 +320,7 @@ static const struct file_operations aat2870_reg_fops = {
|
||||
|
||||
static void aat2870_init_debugfs(struct aat2870_data *aat2870)
|
||||
{
|
||||
aat2870->dentry_root = debugfs_create_dir("aat2870", NULL);
|
||||
|
||||
debugfs_create_file("regs", 0644, aat2870->dentry_root, aat2870,
|
||||
debugfs_create_file("regs", 0644, aat2870->client->debugfs, aat2870,
|
||||
&aat2870_reg_fops);
|
||||
}
|
||||
|
||||
|
||||
@ -394,7 +394,9 @@ static int as3722_i2c_probe(struct i2c_client *i2c)
|
||||
return ret;
|
||||
}
|
||||
|
||||
device_init_wakeup(as3722->dev, true);
|
||||
ret = devm_device_init_wakeup(as3722->dev);
|
||||
if (ret)
|
||||
return dev_err_probe(as3722->dev, ret, "Failed to init wakeup\n");
|
||||
|
||||
dev_dbg(as3722->dev, "AS3722 core driver initialized successfully\n");
|
||||
return 0;
|
||||
|
||||
@ -17,6 +17,15 @@
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
/* Under primary I2C address: */
|
||||
#define BCM590XX_REG_PMUID 0x1e
|
||||
|
||||
#define BCM590XX_REG_PMUREV 0x1f
|
||||
#define BCM590XX_PMUREV_DIG_MASK 0xF
|
||||
#define BCM590XX_PMUREV_DIG_SHIFT 0
|
||||
#define BCM590XX_PMUREV_ANA_MASK 0xF0
|
||||
#define BCM590XX_PMUREV_ANA_SHIFT 4
|
||||
|
||||
static const struct mfd_cell bcm590xx_devs[] = {
|
||||
{
|
||||
.name = "bcm590xx-vregs",
|
||||
@ -37,6 +46,47 @@ static const struct regmap_config bcm590xx_regmap_config_sec = {
|
||||
.cache_type = REGCACHE_MAPLE,
|
||||
};
|
||||
|
||||
/* Map PMU ID value to model name string */
|
||||
static const char * const bcm590xx_names[] = {
|
||||
[BCM590XX_PMUID_BCM59054] = "BCM59054",
|
||||
[BCM590XX_PMUID_BCM59056] = "BCM59056",
|
||||
};
|
||||
|
||||
static int bcm590xx_parse_version(struct bcm590xx *bcm590xx)
|
||||
{
|
||||
unsigned int id, rev;
|
||||
int ret;
|
||||
|
||||
/* Get PMU ID and verify that it matches compatible */
|
||||
ret = regmap_read(bcm590xx->regmap_pri, BCM590XX_REG_PMUID, &id);
|
||||
if (ret) {
|
||||
dev_err(bcm590xx->dev, "failed to read PMU ID: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (id != bcm590xx->pmu_id) {
|
||||
dev_err(bcm590xx->dev, "Incorrect ID for %s: expected %x, got %x.\n",
|
||||
bcm590xx_names[bcm590xx->pmu_id], bcm590xx->pmu_id, id);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Get PMU revision and store it in the info struct */
|
||||
ret = regmap_read(bcm590xx->regmap_pri, BCM590XX_REG_PMUREV, &rev);
|
||||
if (ret) {
|
||||
dev_err(bcm590xx->dev, "failed to read PMU revision: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bcm590xx->rev_digital = (rev & BCM590XX_PMUREV_DIG_MASK) >> BCM590XX_PMUREV_DIG_SHIFT;
|
||||
|
||||
bcm590xx->rev_analog = (rev & BCM590XX_PMUREV_ANA_MASK) >> BCM590XX_PMUREV_ANA_SHIFT;
|
||||
|
||||
dev_dbg(bcm590xx->dev, "PMU ID 0x%x (%s), revision: digital %d, analog %d",
|
||||
id, bcm590xx_names[id], bcm590xx->rev_digital, bcm590xx->rev_analog);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bcm590xx_i2c_probe(struct i2c_client *i2c_pri)
|
||||
{
|
||||
struct bcm590xx *bcm590xx;
|
||||
@ -50,6 +100,8 @@ static int bcm590xx_i2c_probe(struct i2c_client *i2c_pri)
|
||||
bcm590xx->dev = &i2c_pri->dev;
|
||||
bcm590xx->i2c_pri = i2c_pri;
|
||||
|
||||
bcm590xx->pmu_id = (uintptr_t) of_device_get_match_data(bcm590xx->dev);
|
||||
|
||||
bcm590xx->regmap_pri = devm_regmap_init_i2c(i2c_pri,
|
||||
&bcm590xx_regmap_config_pri);
|
||||
if (IS_ERR(bcm590xx->regmap_pri)) {
|
||||
@ -76,6 +128,10 @@ static int bcm590xx_i2c_probe(struct i2c_client *i2c_pri)
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = bcm590xx_parse_version(bcm590xx);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = devm_mfd_add_devices(&i2c_pri->dev, -1, bcm590xx_devs,
|
||||
ARRAY_SIZE(bcm590xx_devs), NULL, 0, NULL);
|
||||
if (ret < 0) {
|
||||
@ -91,12 +147,20 @@ err:
|
||||
}
|
||||
|
||||
static const struct of_device_id bcm590xx_of_match[] = {
|
||||
{ .compatible = "brcm,bcm59056" },
|
||||
{
|
||||
.compatible = "brcm,bcm59054",
|
||||
.data = (void *)BCM590XX_PMUID_BCM59054,
|
||||
},
|
||||
{
|
||||
.compatible = "brcm,bcm59056",
|
||||
.data = (void *)BCM590XX_PMUID_BCM59056,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, bcm590xx_of_match);
|
||||
|
||||
static const struct i2c_device_id bcm590xx_i2c_id[] = {
|
||||
{ "bcm59054" },
|
||||
{ "bcm59056" },
|
||||
{ }
|
||||
};
|
||||
|
||||
@ -104,11 +104,22 @@ static const struct regmap_config exynos_lpass_reg_conf = {
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static void exynos_lpass_disable_lpass(void *data)
|
||||
{
|
||||
struct platform_device *pdev = data;
|
||||
struct exynos_lpass *lpass = platform_get_drvdata(pdev);
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
if (!pm_runtime_status_suspended(&pdev->dev))
|
||||
exynos_lpass_disable(lpass);
|
||||
}
|
||||
|
||||
static int exynos_lpass_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct exynos_lpass *lpass;
|
||||
void __iomem *base_top;
|
||||
int ret;
|
||||
|
||||
lpass = devm_kzalloc(dev, sizeof(*lpass), GFP_KERNEL);
|
||||
if (!lpass)
|
||||
@ -122,8 +133,8 @@ static int exynos_lpass_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(lpass->sfr0_clk))
|
||||
return PTR_ERR(lpass->sfr0_clk);
|
||||
|
||||
lpass->top = regmap_init_mmio(dev, base_top,
|
||||
&exynos_lpass_reg_conf);
|
||||
lpass->top = devm_regmap_init_mmio(dev, base_top,
|
||||
&exynos_lpass_reg_conf);
|
||||
if (IS_ERR(lpass->top)) {
|
||||
dev_err(dev, "LPASS top regmap initialization failed\n");
|
||||
return PTR_ERR(lpass->top);
|
||||
@ -134,20 +145,13 @@ static int exynos_lpass_probe(struct platform_device *pdev)
|
||||
pm_runtime_enable(dev);
|
||||
exynos_lpass_enable(lpass);
|
||||
|
||||
ret = devm_add_action_or_reset(dev, exynos_lpass_disable_lpass, pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return devm_of_platform_populate(dev);
|
||||
}
|
||||
|
||||
static void exynos_lpass_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct exynos_lpass *lpass = platform_get_drvdata(pdev);
|
||||
|
||||
exynos_lpass_disable(lpass);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
if (!pm_runtime_status_suspended(&pdev->dev))
|
||||
exynos_lpass_disable(lpass);
|
||||
regmap_exit(lpass->top);
|
||||
}
|
||||
|
||||
static int __maybe_unused exynos_lpass_suspend(struct device *dev)
|
||||
{
|
||||
struct exynos_lpass *lpass = dev_get_drvdata(dev);
|
||||
@ -185,7 +189,6 @@ static struct platform_driver exynos_lpass_driver = {
|
||||
.of_match_table = exynos_lpass_of_match,
|
||||
},
|
||||
.probe = exynos_lpass_probe,
|
||||
.remove = exynos_lpass_remove,
|
||||
};
|
||||
module_platform_driver(exynos_lpass_driver);
|
||||
|
||||
|
||||
@ -456,6 +456,7 @@ static void max14577_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
struct max14577 *max14577 = i2c_get_clientdata(i2c);
|
||||
|
||||
device_init_wakeup(max14577->dev, false);
|
||||
mfd_remove_devices(max14577->dev);
|
||||
regmap_del_irq_chip(max14577->irq, max14577->irq_data);
|
||||
if (max14577->dev_type == MAXIM_DEVICE_TYPE_MAX77836)
|
||||
|
||||
@ -152,7 +152,7 @@ static int max77541_pmic_setup(struct device *dev)
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to initialize IRQ\n");
|
||||
|
||||
ret = device_init_wakeup(dev, true);
|
||||
ret = devm_device_init_wakeup(dev);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Unable to init wakeup\n");
|
||||
|
||||
|
||||
@ -131,7 +131,9 @@ static int max77705_i2c_probe(struct i2c_client *i2c)
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to register child devices\n");
|
||||
|
||||
device_init_wakeup(dev, true);
|
||||
ret = devm_device_init_wakeup(dev);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to init wakeup\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -201,6 +201,7 @@ static void max8925_remove(struct i2c_client *client)
|
||||
struct max8925_chip *chip = i2c_get_clientdata(client);
|
||||
|
||||
max8925_device_exit(chip);
|
||||
device_init_wakeup(&client->dev, false);
|
||||
i2c_unregister_device(chip->adc);
|
||||
i2c_unregister_device(chip->rtc);
|
||||
}
|
||||
|
||||
@ -38,108 +38,172 @@
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <linux/mfd/rohm-bd96801.h>
|
||||
#include <linux/mfd/rohm-bd96802.h>
|
||||
#include <linux/mfd/rohm-generic.h>
|
||||
|
||||
static const struct resource regulator_errb_irqs[] = {
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_OTP_ERR_STAT, "bd96801-otp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_DBIST_ERR_STAT, "bd96801-dbist-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_EEP_ERR_STAT, "bd96801-eep-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_ABIST_ERR_STAT, "bd96801-abist-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_PRSTB_ERR_STAT, "bd96801-prstb-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_DRMOS1_ERR_STAT, "bd96801-drmoserr1"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_DRMOS2_ERR_STAT, "bd96801-drmoserr2"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_SLAVE_ERR_STAT, "bd96801-slave-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_VREF_ERR_STAT, "bd96801-vref-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_TSD_ERR_STAT, "bd96801-tsd"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_UVLO_ERR_STAT, "bd96801-uvlo-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_OVLO_ERR_STAT, "bd96801-ovlo-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_OSC_ERR_STAT, "bd96801-osc-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_PON_ERR_STAT, "bd96801-pon-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_POFF_ERR_STAT, "bd96801-poff-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_CMD_SHDN_ERR_STAT, "bd96801-cmd-shdn-err"),
|
||||
struct bd968xx {
|
||||
const struct resource *errb_irqs;
|
||||
const struct resource *intb_irqs;
|
||||
int num_errb_irqs;
|
||||
int num_intb_irqs;
|
||||
const struct regmap_irq_chip *errb_irq_chip;
|
||||
const struct regmap_irq_chip *intb_irq_chip;
|
||||
const struct regmap_config *regmap_config;
|
||||
struct mfd_cell *cells;
|
||||
int num_cells;
|
||||
int unlock_reg;
|
||||
int unlock_val;
|
||||
};
|
||||
|
||||
static const struct resource bd96801_reg_errb_irqs[] = {
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_OTP_ERR_STAT, "otp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_DBIST_ERR_STAT, "dbist-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_EEP_ERR_STAT, "eep-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_ABIST_ERR_STAT, "abist-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_PRSTB_ERR_STAT, "prstb-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_DRMOS1_ERR_STAT, "drmoserr1"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_DRMOS2_ERR_STAT, "drmoserr2"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_SLAVE_ERR_STAT, "slave-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_VREF_ERR_STAT, "vref-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_TSD_ERR_STAT, "tsd"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_UVLO_ERR_STAT, "uvlo-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_OVLO_ERR_STAT, "ovlo-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_OSC_ERR_STAT, "osc-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_PON_ERR_STAT, "pon-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_POFF_ERR_STAT, "poff-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_CMD_SHDN_ERR_STAT, "cmd-shdn-err"),
|
||||
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_INT_PRSTB_WDT_ERR, "bd96801-prstb-wdt-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_INT_CHIP_IF_ERR, "bd96801-chip-if-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_INT_SHDN_ERR_STAT, "bd96801-int-shdn-err"),
|
||||
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_PVIN_ERR_STAT, "bd96801-buck1-pvin-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OVP_ERR_STAT, "bd96801-buck1-ovp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_UVP_ERR_STAT, "bd96801-buck1-uvp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_SHDN_ERR_STAT, "bd96801-buck1-shdn-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_INT_SHDN_ERR_STAT, "int-shdn-err"),
|
||||
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_PVIN_ERR_STAT, "bd96801-buck2-pvin-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OVP_ERR_STAT, "bd96801-buck2-ovp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_UVP_ERR_STAT, "bd96801-buck2-uvp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_SHDN_ERR_STAT, "bd96801-buck2-shdn-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_PVIN_ERR_STAT, "buck1-pvin-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OVP_ERR_STAT, "buck1-ovp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_UVP_ERR_STAT, "buck1-uvp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_SHDN_ERR_STAT, "buck1-shdn-err"),
|
||||
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_PVIN_ERR_STAT, "bd96801-buck3-pvin-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OVP_ERR_STAT, "bd96801-buck3-ovp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_UVP_ERR_STAT, "bd96801-buck3-uvp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_SHDN_ERR_STAT, "bd96801-buck3-shdn-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_PVIN_ERR_STAT, "buck2-pvin-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OVP_ERR_STAT, "buck2-ovp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_UVP_ERR_STAT, "buck2-uvp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_SHDN_ERR_STAT, "buck2-shdn-err"),
|
||||
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_PVIN_ERR_STAT, "bd96801-buck4-pvin-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OVP_ERR_STAT, "bd96801-buck4-ovp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_UVP_ERR_STAT, "bd96801-buck4-uvp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_SHDN_ERR_STAT, "bd96801-buck4-shdn-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_PVIN_ERR_STAT, "buck3-pvin-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OVP_ERR_STAT, "buck3-ovp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_UVP_ERR_STAT, "buck3-uvp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_SHDN_ERR_STAT, "buck3-shdn-err"),
|
||||
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO5_PVIN_ERR_STAT, "bd96801-ldo5-pvin-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO5_OVP_ERR_STAT, "bd96801-ldo5-ovp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO5_UVP_ERR_STAT, "bd96801-ldo5-uvp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO5_SHDN_ERR_STAT, "bd96801-ldo5-shdn-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_PVIN_ERR_STAT, "buck4-pvin-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OVP_ERR_STAT, "buck4-ovp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_UVP_ERR_STAT, "buck4-uvp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_SHDN_ERR_STAT, "buck4-shdn-err"),
|
||||
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO6_PVIN_ERR_STAT, "bd96801-ldo6-pvin-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO6_OVP_ERR_STAT, "bd96801-ldo6-ovp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO6_UVP_ERR_STAT, "bd96801-ldo6-uvp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO6_SHDN_ERR_STAT, "bd96801-ldo6-shdn-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO5_PVIN_ERR_STAT, "ldo5-pvin-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO5_OVP_ERR_STAT, "ldo5-ovp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO5_UVP_ERR_STAT, "ldo5-uvp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO5_SHDN_ERR_STAT, "ldo5-shdn-err"),
|
||||
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO7_PVIN_ERR_STAT, "bd96801-ldo7-pvin-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO7_OVP_ERR_STAT, "bd96801-ldo7-ovp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO7_UVP_ERR_STAT, "bd96801-ldo7-uvp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO7_SHDN_ERR_STAT, "bd96801-ldo7-shdn-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO6_PVIN_ERR_STAT, "ldo6-pvin-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO6_OVP_ERR_STAT, "ldo6-ovp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO6_UVP_ERR_STAT, "ldo6-uvp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO6_SHDN_ERR_STAT, "ldo6-shdn-err"),
|
||||
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO7_PVIN_ERR_STAT, "ldo7-pvin-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO7_OVP_ERR_STAT, "ldo7-ovp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO7_UVP_ERR_STAT, "ldo7-uvp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO7_SHDN_ERR_STAT, "ldo7-shdn-err"),
|
||||
};
|
||||
|
||||
static const struct resource regulator_intb_irqs[] = {
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_TW_STAT, "bd96801-core-thermal"),
|
||||
static const struct resource bd96802_reg_errb_irqs[] = {
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_OTP_ERR_STAT, "otp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_DBIST_ERR_STAT, "dbist-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_EEP_ERR_STAT, "eep-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_ABIST_ERR_STAT, "abist-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_PRSTB_ERR_STAT, "prstb-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_DRMOS1_ERR_STAT, "drmoserr1"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_DRMOS1_ERR_STAT, "drmoserr2"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_SLAVE_ERR_STAT, "slave-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_VREF_ERR_STAT, "vref-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_TSD_ERR_STAT, "tsd"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_UVLO_ERR_STAT, "uvlo-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_OVLO_ERR_STAT, "ovlo-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_OSC_ERR_STAT, "osc-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_PON_ERR_STAT, "pon-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_POFF_ERR_STAT, "poff-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_CMD_SHDN_ERR_STAT, "cmd-shdn-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_INT_SHDN_ERR_STAT, "int-shdn-err"),
|
||||
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OCPH_STAT, "bd96801-buck1-overcurr-h"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OCPL_STAT, "bd96801-buck1-overcurr-l"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OCPN_STAT, "bd96801-buck1-overcurr-n"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OVD_STAT, "bd96801-buck1-overvolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_UVD_STAT, "bd96801-buck1-undervolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_TW_CH_STAT, "bd96801-buck1-thermal"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_PVIN_ERR_STAT, "buck1-pvin-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_OVP_ERR_STAT, "buck1-ovp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_UVP_ERR_STAT, "buck1-uvp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_SHDN_ERR_STAT, "buck1-shdn-err"),
|
||||
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OCPH_STAT, "bd96801-buck2-overcurr-h"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OCPL_STAT, "bd96801-buck2-overcurr-l"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OCPN_STAT, "bd96801-buck2-overcurr-n"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OVD_STAT, "bd96801-buck2-overvolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_UVD_STAT, "bd96801-buck2-undervolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_TW_CH_STAT, "bd96801-buck2-thermal"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_PVIN_ERR_STAT, "buck2-pvin-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_OVP_ERR_STAT, "buck2-ovp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_UVP_ERR_STAT, "buck2-uvp-err"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_SHDN_ERR_STAT, "buck2-shdn-err"),
|
||||
};
|
||||
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OCPH_STAT, "bd96801-buck3-overcurr-h"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OCPL_STAT, "bd96801-buck3-overcurr-l"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OCPN_STAT, "bd96801-buck3-overcurr-n"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OVD_STAT, "bd96801-buck3-overvolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_UVD_STAT, "bd96801-buck3-undervolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_TW_CH_STAT, "bd96801-buck3-thermal"),
|
||||
static const struct resource bd96801_reg_intb_irqs[] = {
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_TW_STAT, "core-thermal"),
|
||||
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OCPH_STAT, "bd96801-buck4-overcurr-h"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OCPL_STAT, "bd96801-buck4-overcurr-l"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OCPN_STAT, "bd96801-buck4-overcurr-n"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OVD_STAT, "bd96801-buck4-overvolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_UVD_STAT, "bd96801-buck4-undervolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_TW_CH_STAT, "bd96801-buck4-thermal"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OCPH_STAT, "buck1-overcurr-h"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OCPL_STAT, "buck1-overcurr-l"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OCPN_STAT, "buck1-overcurr-n"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OVD_STAT, "buck1-overvolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_UVD_STAT, "buck1-undervolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_TW_CH_STAT, "buck1-thermal"),
|
||||
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO5_OCPH_STAT, "bd96801-ldo5-overcurr"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO5_OVD_STAT, "bd96801-ldo5-overvolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO5_UVD_STAT, "bd96801-ldo5-undervolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OCPH_STAT, "buck2-overcurr-h"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OCPL_STAT, "buck2-overcurr-l"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OCPN_STAT, "buck2-overcurr-n"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OVD_STAT, "buck2-overvolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_UVD_STAT, "buck2-undervolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_TW_CH_STAT, "buck2-thermal"),
|
||||
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO6_OCPH_STAT, "bd96801-ldo6-overcurr"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO6_OVD_STAT, "bd96801-ldo6-overvolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO6_UVD_STAT, "bd96801-ldo6-undervolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OCPH_STAT, "buck3-overcurr-h"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OCPL_STAT, "buck3-overcurr-l"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OCPN_STAT, "buck3-overcurr-n"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OVD_STAT, "buck3-overvolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_UVD_STAT, "buck3-undervolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_TW_CH_STAT, "buck3-thermal"),
|
||||
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO7_OCPH_STAT, "bd96801-ldo7-overcurr"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO7_OVD_STAT, "bd96801-ldo7-overvolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO7_UVD_STAT, "bd96801-ldo7-undervolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OCPH_STAT, "buck4-overcurr-h"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OCPL_STAT, "buck4-overcurr-l"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OCPN_STAT, "buck4-overcurr-n"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OVD_STAT, "buck4-overvolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_UVD_STAT, "buck4-undervolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_TW_CH_STAT, "buck4-thermal"),
|
||||
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO5_OCPH_STAT, "ldo5-overcurr"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO5_OVD_STAT, "ldo5-overvolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO5_UVD_STAT, "ldo5-undervolt"),
|
||||
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO6_OCPH_STAT, "ldo6-overcurr"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO6_OVD_STAT, "ldo6-overvolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO6_UVD_STAT, "ldo6-undervolt"),
|
||||
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO7_OCPH_STAT, "ldo7-overcurr"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO7_OVD_STAT, "ldo7-overvolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96801_LDO7_UVD_STAT, "ldo7-undervolt"),
|
||||
};
|
||||
|
||||
static const struct resource bd96802_reg_intb_irqs[] = {
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_TW_STAT, "core-thermal"),
|
||||
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_OCPH_STAT, "buck1-overcurr-h"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_OCPL_STAT, "buck1-overcurr-l"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_OCPN_STAT, "buck1-overcurr-n"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_OVD_STAT, "buck1-overvolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_UVD_STAT, "buck1-undervolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_TW_CH_STAT, "buck1-thermal"),
|
||||
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_OCPH_STAT, "buck2-overcurr-h"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_OCPL_STAT, "buck2-overcurr-l"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_OCPN_STAT, "buck2-overcurr-n"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_OVD_STAT, "buck2-overvolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_UVD_STAT, "buck2-undervolt"),
|
||||
DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_TW_CH_STAT, "buck2-thermal"),
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -152,6 +216,20 @@ static struct mfd_cell bd96801_cells[] = {
|
||||
[REGULATOR_CELL] = { .name = "bd96801-regulator", },
|
||||
};
|
||||
|
||||
static struct mfd_cell bd96802_cells[] = {
|
||||
[WDG_CELL] = { .name = "bd96801-wdt", },
|
||||
[REGULATOR_CELL] = { .name = "bd96802-regulator", },
|
||||
};
|
||||
static struct mfd_cell bd96805_cells[] = {
|
||||
[WDG_CELL] = { .name = "bd96801-wdt", },
|
||||
[REGULATOR_CELL] = { .name = "bd96805-regulator", },
|
||||
};
|
||||
|
||||
static struct mfd_cell bd96806_cells[] = {
|
||||
[WDG_CELL] = { .name = "bd96806-wdt", },
|
||||
[REGULATOR_CELL] = { .name = "bd96806-regulator", },
|
||||
};
|
||||
|
||||
static const struct regmap_range bd96801_volatile_ranges[] = {
|
||||
/* Status registers */
|
||||
regmap_reg_range(BD96801_REG_WD_FEED, BD96801_REG_WD_FAILCOUNT),
|
||||
@ -169,11 +247,28 @@ static const struct regmap_range bd96801_volatile_ranges[] = {
|
||||
regmap_reg_range(BD96801_LDO5_VOL_LVL_REG, BD96801_LDO7_VOL_LVL_REG),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table volatile_regs = {
|
||||
static const struct regmap_range bd96802_volatile_ranges[] = {
|
||||
/* Status regs */
|
||||
regmap_reg_range(BD96801_REG_WD_FEED, BD96801_REG_WD_FAILCOUNT),
|
||||
regmap_reg_range(BD96801_REG_WD_ASK, BD96801_REG_WD_ASK),
|
||||
regmap_reg_range(BD96801_REG_WD_STATUS, BD96801_REG_WD_STATUS),
|
||||
regmap_reg_range(BD96801_REG_PMIC_STATE, BD96801_REG_INT_BUCK2_ERRB),
|
||||
regmap_reg_range(BD96801_REG_INT_SYS_INTB, BD96801_REG_INT_BUCK2_INTB),
|
||||
/* Registers which do not update value unless PMIC is in STBY */
|
||||
regmap_reg_range(BD96801_REG_SSCG_CTRL, BD96801_REG_SHD_INTB),
|
||||
regmap_reg_range(BD96801_REG_BUCK_OVP, BD96801_REG_BOOT_OVERTIME),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table bd96801_volatile_regs = {
|
||||
.yes_ranges = bd96801_volatile_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(bd96801_volatile_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table bd96802_volatile_regs = {
|
||||
.yes_ranges = bd96802_volatile_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(bd96802_volatile_ranges),
|
||||
};
|
||||
|
||||
/*
|
||||
* For ERRB we need main register bit mapping as bit(0) indicates active IRQ
|
||||
* in one of the first 3 sub IRQ registers, For INTB we can use default 1 to 1
|
||||
@ -188,7 +283,7 @@ static unsigned int bit5_offsets[] = {7}; /* LDO 5 stat */
|
||||
static unsigned int bit6_offsets[] = {8}; /* LDO 6 stat */
|
||||
static unsigned int bit7_offsets[] = {9}; /* LDO 7 stat */
|
||||
|
||||
static const struct regmap_irq_sub_irq_map errb_sub_irq_offsets[] = {
|
||||
static const struct regmap_irq_sub_irq_map bd96801_errb_sub_irq_offsets[] = {
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets),
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(bit1_offsets),
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(bit2_offsets),
|
||||
@ -199,6 +294,12 @@ static const struct regmap_irq_sub_irq_map errb_sub_irq_offsets[] = {
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(bit7_offsets),
|
||||
};
|
||||
|
||||
static const struct regmap_irq_sub_irq_map bd96802_errb_sub_irq_offsets[] = {
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets),
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(bit1_offsets),
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(bit2_offsets),
|
||||
};
|
||||
|
||||
static const struct regmap_irq bd96801_errb_irqs[] = {
|
||||
/* Reg 0x52 Fatal ERRB1 */
|
||||
REGMAP_IRQ_REG(BD96801_OTP_ERR_STAT, 0, BD96801_OTP_ERR_MASK),
|
||||
@ -259,6 +360,39 @@ static const struct regmap_irq bd96801_errb_irqs[] = {
|
||||
REGMAP_IRQ_REG(BD96801_LDO7_SHDN_ERR_STAT, 9, BD96801_OUT_SHDN_ERR_MASK),
|
||||
};
|
||||
|
||||
static const struct regmap_irq bd96802_errb_irqs[] = {
|
||||
/* Reg 0x52 Fatal ERRB1 */
|
||||
REGMAP_IRQ_REG(BD96802_OTP_ERR_STAT, 0, BD96801_OTP_ERR_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_DBIST_ERR_STAT, 0, BD96801_DBIST_ERR_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_EEP_ERR_STAT, 0, BD96801_EEP_ERR_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_ABIST_ERR_STAT, 0, BD96801_ABIST_ERR_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_PRSTB_ERR_STAT, 0, BD96801_PRSTB_ERR_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_DRMOS1_ERR_STAT, 0, BD96801_DRMOS1_ERR_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_DRMOS2_ERR_STAT, 0, BD96801_DRMOS2_ERR_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_SLAVE_ERR_STAT, 0, BD96801_SLAVE_ERR_MASK),
|
||||
/* 0x53 Fatal ERRB2 */
|
||||
REGMAP_IRQ_REG(BD96802_VREF_ERR_STAT, 1, BD96801_VREF_ERR_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_TSD_ERR_STAT, 1, BD96801_TSD_ERR_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_UVLO_ERR_STAT, 1, BD96801_UVLO_ERR_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_OVLO_ERR_STAT, 1, BD96801_OVLO_ERR_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_OSC_ERR_STAT, 1, BD96801_OSC_ERR_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_PON_ERR_STAT, 1, BD96801_PON_ERR_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_POFF_ERR_STAT, 1, BD96801_POFF_ERR_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_CMD_SHDN_ERR_STAT, 1, BD96801_CMD_SHDN_ERR_MASK),
|
||||
/* 0x54 Fatal INTB shadowed to ERRB */
|
||||
REGMAP_IRQ_REG(BD96802_INT_SHDN_ERR_STAT, 2, BD96801_INT_SHDN_ERR_MASK),
|
||||
/* Reg 0x55 BUCK1 ERR IRQs */
|
||||
REGMAP_IRQ_REG(BD96802_BUCK1_PVIN_ERR_STAT, 3, BD96801_OUT_PVIN_ERR_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_BUCK1_OVP_ERR_STAT, 3, BD96801_OUT_OVP_ERR_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_BUCK1_UVP_ERR_STAT, 3, BD96801_OUT_UVP_ERR_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_BUCK1_SHDN_ERR_STAT, 3, BD96801_OUT_SHDN_ERR_MASK),
|
||||
/* Reg 0x56 BUCK2 ERR IRQs */
|
||||
REGMAP_IRQ_REG(BD96802_BUCK2_PVIN_ERR_STAT, 4, BD96801_OUT_PVIN_ERR_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_BUCK2_OVP_ERR_STAT, 4, BD96801_OUT_OVP_ERR_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_BUCK2_UVP_ERR_STAT, 4, BD96801_OUT_UVP_ERR_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_BUCK2_SHDN_ERR_STAT, 4, BD96801_OUT_SHDN_ERR_MASK),
|
||||
};
|
||||
|
||||
static const struct regmap_irq bd96801_intb_irqs[] = {
|
||||
/* STATUS SYSTEM INTB */
|
||||
REGMAP_IRQ_REG(BD96801_TW_STAT, 0, BD96801_TW_STAT_MASK),
|
||||
@ -307,6 +441,69 @@ static const struct regmap_irq bd96801_intb_irqs[] = {
|
||||
REGMAP_IRQ_REG(BD96801_LDO7_UVD_STAT, 7, BD96801_LDO_UVD_STAT_MASK),
|
||||
};
|
||||
|
||||
static const struct regmap_irq bd96802_intb_irqs[] = {
|
||||
/* STATUS SYSTEM INTB */
|
||||
REGMAP_IRQ_REG(BD96802_TW_STAT, 0, BD96801_TW_STAT_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_WDT_ERR_STAT, 0, BD96801_WDT_ERR_STAT_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_I2C_ERR_STAT, 0, BD96801_I2C_ERR_STAT_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_CHIP_IF_ERR_STAT, 0, BD96801_CHIP_IF_ERR_STAT_MASK),
|
||||
/* STATUS BUCK1 INTB */
|
||||
REGMAP_IRQ_REG(BD96802_BUCK1_OCPH_STAT, 1, BD96801_BUCK_OCPH_STAT_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_BUCK1_OCPL_STAT, 1, BD96801_BUCK_OCPL_STAT_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_BUCK1_OCPN_STAT, 1, BD96801_BUCK_OCPN_STAT_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_BUCK1_OVD_STAT, 1, BD96801_BUCK_OVD_STAT_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_BUCK1_UVD_STAT, 1, BD96801_BUCK_UVD_STAT_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_BUCK1_TW_CH_STAT, 1, BD96801_BUCK_TW_CH_STAT_MASK),
|
||||
/* BUCK 2 INTB */
|
||||
REGMAP_IRQ_REG(BD96802_BUCK2_OCPH_STAT, 2, BD96801_BUCK_OCPH_STAT_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_BUCK2_OCPL_STAT, 2, BD96801_BUCK_OCPL_STAT_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_BUCK2_OCPN_STAT, 2, BD96801_BUCK_OCPN_STAT_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_BUCK2_OVD_STAT, 2, BD96801_BUCK_OVD_STAT_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_BUCK2_UVD_STAT, 2, BD96801_BUCK_UVD_STAT_MASK),
|
||||
REGMAP_IRQ_REG(BD96802_BUCK2_TW_CH_STAT, 2, BD96801_BUCK_TW_CH_STAT_MASK),
|
||||
};
|
||||
|
||||
/*
|
||||
* The IRQ stuff is a bit hairy. The BD96801 / BD96802 provide two physical
|
||||
* IRQ lines called INTB and ERRB. They share the same main status register.
|
||||
*
|
||||
* For ERRB, mapping from main status to sub-status is such that the
|
||||
* 'global' faults are mapped to first 3 sub-status registers - and indicated
|
||||
* by the first bit[0] in main status reg.
|
||||
*
|
||||
* Rest of the status registers are for indicating stuff for individual
|
||||
* regulators, 1 sub register / regulator and 1 main status register bit /
|
||||
* regulator, starting from bit[1].
|
||||
*
|
||||
* Eg, regulator specific stuff has 1 to 1 mapping from main-status to sub
|
||||
* registers but 'global' ERRB IRQs require mapping from main status bit[0] to
|
||||
* 3 status registers.
|
||||
*
|
||||
* Furthermore, the BD96801 has 7 regulators where the BD96802 has only 2.
|
||||
*
|
||||
* INTB has only 1 sub status register for 'global' events and then own sub
|
||||
* status register for each of the regulators. So, for INTB we have direct
|
||||
* 1 to 1 mapping - BD96801 just having 5 register and 5 main status bits
|
||||
* more than the BD96802.
|
||||
*
|
||||
* Sharing the main status bits could be a problem if we had both INTB and
|
||||
* ERRB IRQs asserted but for different sub-status offsets. This might lead
|
||||
* IRQ controller code to go read a sub status register which indicates no
|
||||
* active IRQs. I assume this occurring repeteadly might lead the IRQ to be
|
||||
* disabled by core as a result of repeteadly returned IRQ_NONEs.
|
||||
*
|
||||
* I don't consider this as a fatal problem for now because:
|
||||
* a) Having ERRB asserted leads to PMIC fault state which will kill
|
||||
* the SoC powered by the PMIC. (So, relevant only for potential
|
||||
* case of not powering the processor with this PMIC).
|
||||
* b) Having ERRB set without having respective INTB is unlikely
|
||||
* (haven't actually verified this).
|
||||
*
|
||||
* So, let's proceed with main status enabled for both INTB and ERRB. We can
|
||||
* later disable main-status usage on systems where this ever proves to be
|
||||
* a problem.
|
||||
*/
|
||||
|
||||
static const struct regmap_irq_chip bd96801_irq_chip_errb = {
|
||||
.name = "bd96801-irq-errb",
|
||||
.domain_suffix = "errb",
|
||||
@ -320,7 +517,23 @@ static const struct regmap_irq_chip bd96801_irq_chip_errb = {
|
||||
.init_ack_masked = true,
|
||||
.num_regs = 10,
|
||||
.irq_reg_stride = 1,
|
||||
.sub_reg_offsets = &errb_sub_irq_offsets[0],
|
||||
.sub_reg_offsets = &bd96801_errb_sub_irq_offsets[0],
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip bd96802_irq_chip_errb = {
|
||||
.name = "bd96802-irq-errb",
|
||||
.domain_suffix = "errb",
|
||||
.main_status = BD96801_REG_INT_MAIN,
|
||||
.num_main_regs = 1,
|
||||
.irqs = &bd96802_errb_irqs[0],
|
||||
.num_irqs = ARRAY_SIZE(bd96802_errb_irqs),
|
||||
.status_base = BD96801_REG_INT_SYS_ERRB1,
|
||||
.mask_base = BD96801_REG_MASK_SYS_ERRB,
|
||||
.ack_base = BD96801_REG_INT_SYS_ERRB1,
|
||||
.init_ack_masked = true,
|
||||
.num_regs = 5,
|
||||
.irq_reg_stride = 1,
|
||||
.sub_reg_offsets = &bd96802_errb_sub_irq_offsets[0],
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip bd96801_irq_chip_intb = {
|
||||
@ -338,25 +551,124 @@ static const struct regmap_irq_chip bd96801_irq_chip_intb = {
|
||||
.irq_reg_stride = 1,
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip bd96802_irq_chip_intb = {
|
||||
.name = "bd96802-irq-intb",
|
||||
.domain_suffix = "intb",
|
||||
.main_status = BD96801_REG_INT_MAIN,
|
||||
.num_main_regs = 1,
|
||||
.irqs = &bd96802_intb_irqs[0],
|
||||
.num_irqs = ARRAY_SIZE(bd96802_intb_irqs),
|
||||
.status_base = BD96801_REG_INT_SYS_INTB,
|
||||
.mask_base = BD96801_REG_MASK_SYS_INTB,
|
||||
.ack_base = BD96801_REG_INT_SYS_INTB,
|
||||
.init_ack_masked = true,
|
||||
.num_regs = 3,
|
||||
.irq_reg_stride = 1,
|
||||
};
|
||||
|
||||
static const struct regmap_config bd96801_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.volatile_table = &volatile_regs,
|
||||
.volatile_table = &bd96801_volatile_regs,
|
||||
.cache_type = REGCACHE_MAPLE,
|
||||
};
|
||||
|
||||
static const struct regmap_config bd96802_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.volatile_table = &bd96802_volatile_regs,
|
||||
.cache_type = REGCACHE_MAPLE,
|
||||
};
|
||||
|
||||
static const struct bd968xx bd96801_data = {
|
||||
.errb_irqs = bd96801_reg_errb_irqs,
|
||||
.intb_irqs = bd96801_reg_intb_irqs,
|
||||
.num_errb_irqs = ARRAY_SIZE(bd96801_reg_errb_irqs),
|
||||
.num_intb_irqs = ARRAY_SIZE(bd96801_reg_intb_irqs),
|
||||
.errb_irq_chip = &bd96801_irq_chip_errb,
|
||||
.intb_irq_chip = &bd96801_irq_chip_intb,
|
||||
.regmap_config = &bd96801_regmap_config,
|
||||
.cells = bd96801_cells,
|
||||
.num_cells = ARRAY_SIZE(bd96801_cells),
|
||||
.unlock_reg = BD96801_LOCK_REG,
|
||||
.unlock_val = BD96801_UNLOCK,
|
||||
};
|
||||
|
||||
static const struct bd968xx bd96802_data = {
|
||||
.errb_irqs = bd96802_reg_errb_irqs,
|
||||
.intb_irqs = bd96802_reg_intb_irqs,
|
||||
.num_errb_irqs = ARRAY_SIZE(bd96802_reg_errb_irqs),
|
||||
.num_intb_irqs = ARRAY_SIZE(bd96802_reg_intb_irqs),
|
||||
.errb_irq_chip = &bd96802_irq_chip_errb,
|
||||
.intb_irq_chip = &bd96802_irq_chip_intb,
|
||||
.regmap_config = &bd96802_regmap_config,
|
||||
.cells = bd96802_cells,
|
||||
.num_cells = ARRAY_SIZE(bd96802_cells),
|
||||
.unlock_reg = BD96801_LOCK_REG,
|
||||
.unlock_val = BD96801_UNLOCK,
|
||||
};
|
||||
|
||||
static const struct bd968xx bd96805_data = {
|
||||
.errb_irqs = bd96801_reg_errb_irqs,
|
||||
.intb_irqs = bd96801_reg_intb_irqs,
|
||||
.num_errb_irqs = ARRAY_SIZE(bd96801_reg_errb_irqs),
|
||||
.num_intb_irqs = ARRAY_SIZE(bd96801_reg_intb_irqs),
|
||||
.errb_irq_chip = &bd96801_irq_chip_errb,
|
||||
.intb_irq_chip = &bd96801_irq_chip_intb,
|
||||
.regmap_config = &bd96801_regmap_config,
|
||||
.cells = bd96805_cells,
|
||||
.num_cells = ARRAY_SIZE(bd96805_cells),
|
||||
.unlock_reg = BD96801_LOCK_REG,
|
||||
.unlock_val = BD96801_UNLOCK,
|
||||
};
|
||||
|
||||
static struct bd968xx bd96806_data = {
|
||||
.errb_irqs = bd96802_reg_errb_irqs,
|
||||
.intb_irqs = bd96802_reg_intb_irqs,
|
||||
.num_errb_irqs = ARRAY_SIZE(bd96802_reg_errb_irqs),
|
||||
.num_intb_irqs = ARRAY_SIZE(bd96802_reg_intb_irqs),
|
||||
.errb_irq_chip = &bd96802_irq_chip_errb,
|
||||
.intb_irq_chip = &bd96802_irq_chip_intb,
|
||||
.regmap_config = &bd96802_regmap_config,
|
||||
.cells = bd96806_cells,
|
||||
.num_cells = ARRAY_SIZE(bd96806_cells),
|
||||
.unlock_reg = BD96801_LOCK_REG,
|
||||
.unlock_val = BD96801_UNLOCK,
|
||||
};
|
||||
|
||||
static int bd96801_i2c_probe(struct i2c_client *i2c)
|
||||
{
|
||||
struct regmap_irq_chip_data *intb_irq_data, *errb_irq_data;
|
||||
struct irq_domain *intb_domain, *errb_domain;
|
||||
const struct bd968xx *ddata;
|
||||
const struct fwnode_handle *fwnode;
|
||||
struct resource *regulator_res;
|
||||
struct resource wdg_irq;
|
||||
struct regmap *regmap;
|
||||
int intb_irq, errb_irq, num_intb, num_errb = 0;
|
||||
int intb_irq, errb_irq, num_errb = 0;
|
||||
int num_regu_irqs, wdg_irq_no;
|
||||
unsigned int chip_type;
|
||||
int i, ret;
|
||||
|
||||
chip_type = (unsigned int)(uintptr_t)device_get_match_data(&i2c->dev);
|
||||
switch (chip_type) {
|
||||
case ROHM_CHIP_TYPE_BD96801:
|
||||
ddata = &bd96801_data;
|
||||
break;
|
||||
case ROHM_CHIP_TYPE_BD96802:
|
||||
ddata = &bd96802_data;
|
||||
break;
|
||||
case ROHM_CHIP_TYPE_BD96805:
|
||||
ddata = &bd96805_data;
|
||||
break;
|
||||
case ROHM_CHIP_TYPE_BD96806:
|
||||
ddata = &bd96806_data;
|
||||
break;
|
||||
default:
|
||||
dev_err(&i2c->dev, "Unknown IC\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
fwnode = dev_fwnode(&i2c->dev);
|
||||
if (!fwnode)
|
||||
return dev_err_probe(&i2c->dev, -EINVAL, "Failed to find fwnode\n");
|
||||
@ -365,34 +677,32 @@ static int bd96801_i2c_probe(struct i2c_client *i2c)
|
||||
if (intb_irq < 0)
|
||||
return dev_err_probe(&i2c->dev, intb_irq, "INTB IRQ not configured\n");
|
||||
|
||||
num_intb = ARRAY_SIZE(regulator_intb_irqs);
|
||||
|
||||
/* ERRB may be omitted if processor is powered by the PMIC */
|
||||
errb_irq = fwnode_irq_get_byname(fwnode, "errb");
|
||||
if (errb_irq < 0)
|
||||
errb_irq = 0;
|
||||
if (errb_irq == -EPROBE_DEFER)
|
||||
return errb_irq;
|
||||
|
||||
if (errb_irq)
|
||||
num_errb = ARRAY_SIZE(regulator_errb_irqs);
|
||||
if (errb_irq > 0)
|
||||
num_errb = ddata->num_errb_irqs;
|
||||
|
||||
num_regu_irqs = num_intb + num_errb;
|
||||
num_regu_irqs = ddata->num_intb_irqs + num_errb;
|
||||
|
||||
regulator_res = devm_kcalloc(&i2c->dev, num_regu_irqs,
|
||||
sizeof(*regulator_res), GFP_KERNEL);
|
||||
if (!regulator_res)
|
||||
return -ENOMEM;
|
||||
|
||||
regmap = devm_regmap_init_i2c(i2c, &bd96801_regmap_config);
|
||||
regmap = devm_regmap_init_i2c(i2c, ddata->regmap_config);
|
||||
if (IS_ERR(regmap))
|
||||
return dev_err_probe(&i2c->dev, PTR_ERR(regmap),
|
||||
"Regmap initialization failed\n");
|
||||
|
||||
ret = regmap_write(regmap, BD96801_LOCK_REG, BD96801_UNLOCK);
|
||||
ret = regmap_write(regmap, ddata->unlock_reg, ddata->unlock_val);
|
||||
if (ret)
|
||||
return dev_err_probe(&i2c->dev, ret, "Failed to unlock PMIC\n");
|
||||
|
||||
ret = devm_regmap_add_irq_chip(&i2c->dev, regmap, intb_irq,
|
||||
IRQF_ONESHOT, 0, &bd96801_irq_chip_intb,
|
||||
IRQF_ONESHOT, 0, ddata->intb_irq_chip,
|
||||
&intb_irq_data);
|
||||
if (ret)
|
||||
return dev_err_probe(&i2c->dev, ret, "Failed to add INTB IRQ chip\n");
|
||||
@ -404,24 +714,25 @@ static int bd96801_i2c_probe(struct i2c_client *i2c)
|
||||
* has two domains so we do IRQ mapping here and provide the
|
||||
* already mapped IRQ numbers to sub-devices.
|
||||
*/
|
||||
for (i = 0; i < num_intb; i++) {
|
||||
for (i = 0; i < ddata->num_intb_irqs; i++) {
|
||||
struct resource *res = ®ulator_res[i];
|
||||
|
||||
*res = regulator_intb_irqs[i];
|
||||
*res = ddata->intb_irqs[i];
|
||||
res->start = res->end = irq_create_mapping(intb_domain,
|
||||
res->start);
|
||||
}
|
||||
|
||||
wdg_irq_no = irq_create_mapping(intb_domain, BD96801_WDT_ERR_STAT);
|
||||
wdg_irq = DEFINE_RES_IRQ_NAMED(wdg_irq_no, "bd96801-wdg");
|
||||
bd96801_cells[WDG_CELL].resources = &wdg_irq;
|
||||
bd96801_cells[WDG_CELL].num_resources = 1;
|
||||
|
||||
ddata->cells[WDG_CELL].resources = &wdg_irq;
|
||||
ddata->cells[WDG_CELL].num_resources = 1;
|
||||
|
||||
if (!num_errb)
|
||||
goto skip_errb;
|
||||
|
||||
ret = devm_regmap_add_irq_chip(&i2c->dev, regmap, errb_irq, IRQF_ONESHOT,
|
||||
0, &bd96801_irq_chip_errb, &errb_irq_data);
|
||||
0, ddata->errb_irq_chip, &errb_irq_data);
|
||||
if (ret)
|
||||
return dev_err_probe(&i2c->dev, ret,
|
||||
"Failed to add ERRB IRQ chip\n");
|
||||
@ -429,18 +740,17 @@ static int bd96801_i2c_probe(struct i2c_client *i2c)
|
||||
errb_domain = regmap_irq_get_domain(errb_irq_data);
|
||||
|
||||
for (i = 0; i < num_errb; i++) {
|
||||
struct resource *res = ®ulator_res[num_intb + i];
|
||||
struct resource *res = ®ulator_res[ddata->num_intb_irqs + i];
|
||||
|
||||
*res = regulator_errb_irqs[i];
|
||||
*res = ddata->errb_irqs[i];
|
||||
res->start = res->end = irq_create_mapping(errb_domain, res->start);
|
||||
}
|
||||
|
||||
skip_errb:
|
||||
bd96801_cells[REGULATOR_CELL].resources = regulator_res;
|
||||
bd96801_cells[REGULATOR_CELL].num_resources = num_regu_irqs;
|
||||
|
||||
ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO, bd96801_cells,
|
||||
ARRAY_SIZE(bd96801_cells), NULL, 0, NULL);
|
||||
ddata->cells[REGULATOR_CELL].resources = regulator_res;
|
||||
ddata->cells[REGULATOR_CELL].num_resources = num_regu_irqs;
|
||||
ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO, ddata->cells,
|
||||
ddata->num_cells, NULL, 0, NULL);
|
||||
if (ret)
|
||||
dev_err_probe(&i2c->dev, ret, "Failed to create subdevices\n");
|
||||
|
||||
@ -448,7 +758,10 @@ skip_errb:
|
||||
}
|
||||
|
||||
static const struct of_device_id bd96801_of_match[] = {
|
||||
{ .compatible = "rohm,bd96801", },
|
||||
{ .compatible = "rohm,bd96801", .data = (void *)ROHM_CHIP_TYPE_BD96801 },
|
||||
{ .compatible = "rohm,bd96802", .data = (void *)ROHM_CHIP_TYPE_BD96802 },
|
||||
{ .compatible = "rohm,bd96805", .data = (void *)ROHM_CHIP_TYPE_BD96805 },
|
||||
{ .compatible = "rohm,bd96806", .data = (void *)ROHM_CHIP_TYPE_BD96806 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, bd96801_of_match);
|
||||
@ -476,5 +789,5 @@ static void __exit bd96801_i2c_exit(void)
|
||||
module_exit(bd96801_i2c_exit);
|
||||
|
||||
MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
|
||||
MODULE_DESCRIPTION("ROHM BD96801 Power Management IC driver");
|
||||
MODULE_DESCRIPTION("ROHM BD9680X Power Management IC driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
@ -98,7 +98,11 @@ static int rt5033_i2c_probe(struct i2c_client *i2c)
|
||||
return ret;
|
||||
}
|
||||
|
||||
device_init_wakeup(rt5033->dev, rt5033->wakeup);
|
||||
if (rt5033->wakeup) {
|
||||
ret = devm_device_init_wakeup(rt5033->dev);
|
||||
if (ret)
|
||||
return dev_err_probe(rt5033->dev, ret, "Failed to init wakeup\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
442
drivers/mfd/sec-acpm.c
Normal file
442
drivers/mfd/sec-acpm.c
Normal file
@ -0,0 +1,442 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright 2020 Google Inc
|
||||
* Copyright 2025 Linaro Ltd.
|
||||
*
|
||||
* Samsung S2MPG1x ACPM driver
|
||||
*/
|
||||
|
||||
#include <linux/array_size.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/firmware/samsung/exynos-acpm-protocol.h>
|
||||
#include <linux/mfd/samsung/core.h>
|
||||
#include <linux/mfd/samsung/rtc.h>
|
||||
#include <linux/mfd/samsung/s2mpg10.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regmap.h>
|
||||
#include "sec-core.h"
|
||||
|
||||
#define ACPM_ADDR_BITS 8
|
||||
#define ACPM_MAX_BULK_DATA 8
|
||||
|
||||
struct sec_pmic_acpm_platform_data {
|
||||
int device_type;
|
||||
|
||||
unsigned int acpm_chan_id;
|
||||
u8 speedy_channel;
|
||||
|
||||
const struct regmap_config *regmap_cfg_common;
|
||||
const struct regmap_config *regmap_cfg_pmic;
|
||||
const struct regmap_config *regmap_cfg_rtc;
|
||||
const struct regmap_config *regmap_cfg_meter;
|
||||
};
|
||||
|
||||
static const struct regmap_range s2mpg10_common_registers[] = {
|
||||
regmap_reg_range(0x00, 0x02), /* CHIP_ID_M, INT, INT_MASK */
|
||||
regmap_reg_range(0x0a, 0x0c), /* Speedy control */
|
||||
regmap_reg_range(0x1a, 0x2a), /* Debug */
|
||||
};
|
||||
|
||||
static const struct regmap_range s2mpg10_common_ro_registers[] = {
|
||||
regmap_reg_range(0x00, 0x01), /* CHIP_ID_M, INT */
|
||||
regmap_reg_range(0x28, 0x2a), /* Debug */
|
||||
};
|
||||
|
||||
static const struct regmap_range s2mpg10_common_nonvolatile_registers[] = {
|
||||
regmap_reg_range(0x00, 0x00), /* CHIP_ID_M */
|
||||
regmap_reg_range(0x02, 0x02), /* INT_MASK */
|
||||
regmap_reg_range(0x0a, 0x0c), /* Speedy control */
|
||||
};
|
||||
|
||||
static const struct regmap_range s2mpg10_common_precious_registers[] = {
|
||||
regmap_reg_range(0x01, 0x01), /* INT */
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg10_common_wr_table = {
|
||||
.yes_ranges = s2mpg10_common_registers,
|
||||
.n_yes_ranges = ARRAY_SIZE(s2mpg10_common_registers),
|
||||
.no_ranges = s2mpg10_common_ro_registers,
|
||||
.n_no_ranges = ARRAY_SIZE(s2mpg10_common_ro_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg10_common_rd_table = {
|
||||
.yes_ranges = s2mpg10_common_registers,
|
||||
.n_yes_ranges = ARRAY_SIZE(s2mpg10_common_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg10_common_volatile_table = {
|
||||
.no_ranges = s2mpg10_common_nonvolatile_registers,
|
||||
.n_no_ranges = ARRAY_SIZE(s2mpg10_common_nonvolatile_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg10_common_precious_table = {
|
||||
.yes_ranges = s2mpg10_common_precious_registers,
|
||||
.n_yes_ranges = ARRAY_SIZE(s2mpg10_common_precious_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_config s2mpg10_regmap_config_common = {
|
||||
.name = "common",
|
||||
.reg_bits = ACPM_ADDR_BITS,
|
||||
.val_bits = 8,
|
||||
.max_register = S2MPG10_COMMON_SPD_DEBUG4,
|
||||
.wr_table = &s2mpg10_common_wr_table,
|
||||
.rd_table = &s2mpg10_common_rd_table,
|
||||
.volatile_table = &s2mpg10_common_volatile_table,
|
||||
.precious_table = &s2mpg10_common_precious_table,
|
||||
.num_reg_defaults_raw = S2MPG10_COMMON_SPD_DEBUG4 + 1,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_range s2mpg10_pmic_registers[] = {
|
||||
regmap_reg_range(0x00, 0xf6), /* All PMIC registers */
|
||||
};
|
||||
|
||||
static const struct regmap_range s2mpg10_pmic_ro_registers[] = {
|
||||
regmap_reg_range(0x00, 0x05), /* INTx */
|
||||
regmap_reg_range(0x0c, 0x0f), /* STATUSx PWRONSRC OFFSRC */
|
||||
regmap_reg_range(0xc7, 0xc7), /* GPIO input */
|
||||
};
|
||||
|
||||
static const struct regmap_range s2mpg10_pmic_nonvolatile_registers[] = {
|
||||
regmap_reg_range(0x06, 0x0b), /* INTxM */
|
||||
};
|
||||
|
||||
static const struct regmap_range s2mpg10_pmic_precious_registers[] = {
|
||||
regmap_reg_range(0x00, 0x05), /* INTx */
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg10_pmic_wr_table = {
|
||||
.yes_ranges = s2mpg10_pmic_registers,
|
||||
.n_yes_ranges = ARRAY_SIZE(s2mpg10_pmic_registers),
|
||||
.no_ranges = s2mpg10_pmic_ro_registers,
|
||||
.n_no_ranges = ARRAY_SIZE(s2mpg10_pmic_ro_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg10_pmic_rd_table = {
|
||||
.yes_ranges = s2mpg10_pmic_registers,
|
||||
.n_yes_ranges = ARRAY_SIZE(s2mpg10_pmic_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg10_pmic_volatile_table = {
|
||||
.no_ranges = s2mpg10_pmic_nonvolatile_registers,
|
||||
.n_no_ranges = ARRAY_SIZE(s2mpg10_pmic_nonvolatile_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg10_pmic_precious_table = {
|
||||
.yes_ranges = s2mpg10_pmic_precious_registers,
|
||||
.n_yes_ranges = ARRAY_SIZE(s2mpg10_pmic_precious_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_config s2mpg10_regmap_config_pmic = {
|
||||
.name = "pmic",
|
||||
.reg_bits = ACPM_ADDR_BITS,
|
||||
.val_bits = 8,
|
||||
.max_register = S2MPG10_PMIC_LDO_SENSE4,
|
||||
.wr_table = &s2mpg10_pmic_wr_table,
|
||||
.rd_table = &s2mpg10_pmic_rd_table,
|
||||
.volatile_table = &s2mpg10_pmic_volatile_table,
|
||||
.precious_table = &s2mpg10_pmic_precious_table,
|
||||
.num_reg_defaults_raw = S2MPG10_PMIC_LDO_SENSE4 + 1,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_range s2mpg10_rtc_registers[] = {
|
||||
regmap_reg_range(0x00, 0x2b), /* All RTC registers */
|
||||
};
|
||||
|
||||
static const struct regmap_range s2mpg10_rtc_volatile_registers[] = {
|
||||
regmap_reg_range(0x01, 0x01), /* RTC_UPDATE */
|
||||
regmap_reg_range(0x05, 0x0c), /* Time / date */
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg10_rtc_rd_table = {
|
||||
.yes_ranges = s2mpg10_rtc_registers,
|
||||
.n_yes_ranges = ARRAY_SIZE(s2mpg10_rtc_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg10_rtc_volatile_table = {
|
||||
.yes_ranges = s2mpg10_rtc_volatile_registers,
|
||||
.n_yes_ranges = ARRAY_SIZE(s2mpg10_rtc_volatile_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_config s2mpg10_regmap_config_rtc = {
|
||||
.name = "rtc",
|
||||
.reg_bits = ACPM_ADDR_BITS,
|
||||
.val_bits = 8,
|
||||
.max_register = S2MPG10_RTC_OSC_CTRL,
|
||||
.rd_table = &s2mpg10_rtc_rd_table,
|
||||
.volatile_table = &s2mpg10_rtc_volatile_table,
|
||||
.num_reg_defaults_raw = S2MPG10_RTC_OSC_CTRL + 1,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_range s2mpg10_meter_registers[] = {
|
||||
regmap_reg_range(0x00, 0x21), /* Meter config */
|
||||
regmap_reg_range(0x40, 0x8a), /* Meter data */
|
||||
regmap_reg_range(0xee, 0xee), /* Offset */
|
||||
regmap_reg_range(0xf1, 0xf1), /* Trim */
|
||||
};
|
||||
|
||||
static const struct regmap_range s2mpg10_meter_ro_registers[] = {
|
||||
regmap_reg_range(0x40, 0x8a), /* Meter data */
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg10_meter_wr_table = {
|
||||
.yes_ranges = s2mpg10_meter_registers,
|
||||
.n_yes_ranges = ARRAY_SIZE(s2mpg10_meter_registers),
|
||||
.no_ranges = s2mpg10_meter_ro_registers,
|
||||
.n_no_ranges = ARRAY_SIZE(s2mpg10_meter_ro_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg10_meter_rd_table = {
|
||||
.yes_ranges = s2mpg10_meter_registers,
|
||||
.n_yes_ranges = ARRAY_SIZE(s2mpg10_meter_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table s2mpg10_meter_volatile_table = {
|
||||
.yes_ranges = s2mpg10_meter_ro_registers,
|
||||
.n_yes_ranges = ARRAY_SIZE(s2mpg10_meter_ro_registers),
|
||||
};
|
||||
|
||||
static const struct regmap_config s2mpg10_regmap_config_meter = {
|
||||
.name = "meter",
|
||||
.reg_bits = ACPM_ADDR_BITS,
|
||||
.val_bits = 8,
|
||||
.max_register = S2MPG10_METER_BUCK_METER_TRIM3,
|
||||
.wr_table = &s2mpg10_meter_wr_table,
|
||||
.rd_table = &s2mpg10_meter_rd_table,
|
||||
.volatile_table = &s2mpg10_meter_volatile_table,
|
||||
.num_reg_defaults_raw = S2MPG10_METER_BUCK_METER_TRIM3 + 1,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
struct sec_pmic_acpm_shared_bus_context {
|
||||
const struct acpm_handle *acpm;
|
||||
unsigned int acpm_chan_id;
|
||||
u8 speedy_channel;
|
||||
};
|
||||
|
||||
enum sec_pmic_acpm_accesstype {
|
||||
SEC_PMIC_ACPM_ACCESSTYPE_COMMON = 0x00,
|
||||
SEC_PMIC_ACPM_ACCESSTYPE_PMIC = 0x01,
|
||||
SEC_PMIC_ACPM_ACCESSTYPE_RTC = 0x02,
|
||||
SEC_PMIC_ACPM_ACCESSTYPE_METER = 0x0a,
|
||||
SEC_PMIC_ACPM_ACCESSTYPE_WLWP = 0x0b,
|
||||
SEC_PMIC_ACPM_ACCESSTYPE_TRIM = 0x0f,
|
||||
};
|
||||
|
||||
struct sec_pmic_acpm_bus_context {
|
||||
struct sec_pmic_acpm_shared_bus_context *shared;
|
||||
enum sec_pmic_acpm_accesstype type;
|
||||
};
|
||||
|
||||
static int sec_pmic_acpm_bus_write(void *context, const void *data,
|
||||
size_t count)
|
||||
{
|
||||
struct sec_pmic_acpm_bus_context *ctx = context;
|
||||
const struct acpm_handle *acpm = ctx->shared->acpm;
|
||||
const struct acpm_pmic_ops *pmic_ops = &acpm->ops.pmic_ops;
|
||||
size_t val_count = count - BITS_TO_BYTES(ACPM_ADDR_BITS);
|
||||
const u8 *d = data;
|
||||
const u8 *vals = &d[BITS_TO_BYTES(ACPM_ADDR_BITS)];
|
||||
u8 reg;
|
||||
|
||||
if (val_count < 1 || val_count > ACPM_MAX_BULK_DATA)
|
||||
return -EINVAL;
|
||||
|
||||
reg = d[0];
|
||||
|
||||
return pmic_ops->bulk_write(acpm, ctx->shared->acpm_chan_id, ctx->type, reg,
|
||||
ctx->shared->speedy_channel, val_count, vals);
|
||||
}
|
||||
|
||||
static int sec_pmic_acpm_bus_read(void *context, const void *reg_buf, size_t reg_size,
|
||||
void *val_buf, size_t val_size)
|
||||
{
|
||||
struct sec_pmic_acpm_bus_context *ctx = context;
|
||||
const struct acpm_handle *acpm = ctx->shared->acpm;
|
||||
const struct acpm_pmic_ops *pmic_ops = &acpm->ops.pmic_ops;
|
||||
const u8 *r = reg_buf;
|
||||
u8 reg;
|
||||
|
||||
if (reg_size != BITS_TO_BYTES(ACPM_ADDR_BITS) || !val_size ||
|
||||
val_size > ACPM_MAX_BULK_DATA)
|
||||
return -EINVAL;
|
||||
|
||||
reg = r[0];
|
||||
|
||||
return pmic_ops->bulk_read(acpm, ctx->shared->acpm_chan_id, ctx->type, reg,
|
||||
ctx->shared->speedy_channel, val_size, val_buf);
|
||||
}
|
||||
|
||||
static int sec_pmic_acpm_bus_reg_update_bits(void *context, unsigned int reg, unsigned int mask,
|
||||
unsigned int val)
|
||||
{
|
||||
struct sec_pmic_acpm_bus_context *ctx = context;
|
||||
const struct acpm_handle *acpm = ctx->shared->acpm;
|
||||
const struct acpm_pmic_ops *pmic_ops = &acpm->ops.pmic_ops;
|
||||
|
||||
return pmic_ops->update_reg(acpm, ctx->shared->acpm_chan_id, ctx->type, reg & 0xff,
|
||||
ctx->shared->speedy_channel, val, mask);
|
||||
}
|
||||
|
||||
static const struct regmap_bus sec_pmic_acpm_regmap_bus = {
|
||||
.write = sec_pmic_acpm_bus_write,
|
||||
.read = sec_pmic_acpm_bus_read,
|
||||
.reg_update_bits = sec_pmic_acpm_bus_reg_update_bits,
|
||||
.max_raw_read = ACPM_MAX_BULK_DATA,
|
||||
.max_raw_write = ACPM_MAX_BULK_DATA,
|
||||
};
|
||||
|
||||
static struct regmap *sec_pmic_acpm_regmap_init(struct device *dev,
|
||||
struct sec_pmic_acpm_shared_bus_context *shared_ctx,
|
||||
enum sec_pmic_acpm_accesstype type,
|
||||
const struct regmap_config *cfg, bool do_attach)
|
||||
{
|
||||
struct sec_pmic_acpm_bus_context *ctx;
|
||||
struct regmap *regmap;
|
||||
|
||||
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ctx->shared = shared_ctx;
|
||||
ctx->type = type;
|
||||
|
||||
regmap = devm_regmap_init(dev, &sec_pmic_acpm_regmap_bus, ctx, cfg);
|
||||
if (IS_ERR(regmap))
|
||||
return dev_err_cast_probe(dev, regmap, "regmap init (%s) failed\n", cfg->name);
|
||||
|
||||
if (do_attach) {
|
||||
int ret;
|
||||
|
||||
ret = regmap_attach_dev(dev, regmap, cfg);
|
||||
if (ret)
|
||||
return dev_err_ptr_probe(dev, ret, "regmap attach (%s) failed\n",
|
||||
cfg->name);
|
||||
}
|
||||
|
||||
return regmap;
|
||||
}
|
||||
|
||||
static void sec_pmic_acpm_mask_common_irqs(void *regmap_common)
|
||||
{
|
||||
regmap_write(regmap_common, S2MPG10_COMMON_INT_MASK, S2MPG10_COMMON_INT_SRC);
|
||||
}
|
||||
|
||||
static int sec_pmic_acpm_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct regmap *regmap_common, *regmap_pmic, *regmap;
|
||||
const struct sec_pmic_acpm_platform_data *pdata;
|
||||
struct sec_pmic_acpm_shared_bus_context *shared_ctx;
|
||||
const struct acpm_handle *acpm;
|
||||
struct device *dev = &pdev->dev;
|
||||
int ret, irq;
|
||||
|
||||
pdata = device_get_match_data(dev);
|
||||
if (!pdata)
|
||||
return dev_err_probe(dev, -ENODEV, "unsupported device type\n");
|
||||
|
||||
acpm = devm_acpm_get_by_node(dev, dev->parent->of_node);
|
||||
if (IS_ERR(acpm))
|
||||
return dev_err_probe(dev, PTR_ERR(acpm), "failed to get acpm\n");
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
shared_ctx = devm_kzalloc(dev, sizeof(*shared_ctx), GFP_KERNEL);
|
||||
if (!shared_ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
shared_ctx->acpm = acpm;
|
||||
shared_ctx->acpm_chan_id = pdata->acpm_chan_id;
|
||||
shared_ctx->speedy_channel = pdata->speedy_channel;
|
||||
|
||||
regmap_common = sec_pmic_acpm_regmap_init(dev, shared_ctx, SEC_PMIC_ACPM_ACCESSTYPE_COMMON,
|
||||
pdata->regmap_cfg_common, false);
|
||||
if (IS_ERR(regmap_common))
|
||||
return PTR_ERR(regmap_common);
|
||||
|
||||
/* Mask all interrupts from 'common' block, until successful init */
|
||||
ret = regmap_write(regmap_common, S2MPG10_COMMON_INT_MASK, S2MPG10_COMMON_INT_SRC);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to mask common block interrupts\n");
|
||||
|
||||
regmap_pmic = sec_pmic_acpm_regmap_init(dev, shared_ctx, SEC_PMIC_ACPM_ACCESSTYPE_PMIC,
|
||||
pdata->regmap_cfg_pmic, false);
|
||||
if (IS_ERR(regmap_pmic))
|
||||
return PTR_ERR(regmap_pmic);
|
||||
|
||||
regmap = sec_pmic_acpm_regmap_init(dev, shared_ctx, SEC_PMIC_ACPM_ACCESSTYPE_RTC,
|
||||
pdata->regmap_cfg_rtc, true);
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
regmap = sec_pmic_acpm_regmap_init(dev, shared_ctx, SEC_PMIC_ACPM_ACCESSTYPE_METER,
|
||||
pdata->regmap_cfg_meter, true);
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
ret = sec_pmic_probe(dev, pdata->device_type, irq, regmap_pmic, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (device_property_read_bool(dev, "wakeup-source"))
|
||||
devm_device_init_wakeup(dev);
|
||||
|
||||
/* Unmask PMIC interrupt from 'common' block, now that everything is in place. */
|
||||
ret = regmap_clear_bits(regmap_common, S2MPG10_COMMON_INT_MASK,
|
||||
S2MPG10_COMMON_INT_SRC_PMIC);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to unmask PMIC interrupt\n");
|
||||
|
||||
/* Mask all interrupts from 'common' block on shutdown */
|
||||
ret = devm_add_action_or_reset(dev, sec_pmic_acpm_mask_common_irqs, regmap_common);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sec_pmic_acpm_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
sec_pmic_shutdown(&pdev->dev);
|
||||
}
|
||||
|
||||
static const struct sec_pmic_acpm_platform_data s2mpg10_data = {
|
||||
.device_type = S2MPG10,
|
||||
.acpm_chan_id = 2,
|
||||
.speedy_channel = 0,
|
||||
.regmap_cfg_common = &s2mpg10_regmap_config_common,
|
||||
.regmap_cfg_pmic = &s2mpg10_regmap_config_pmic,
|
||||
.regmap_cfg_rtc = &s2mpg10_regmap_config_rtc,
|
||||
.regmap_cfg_meter = &s2mpg10_regmap_config_meter,
|
||||
};
|
||||
|
||||
static const struct of_device_id sec_pmic_acpm_of_match[] = {
|
||||
{ .compatible = "samsung,s2mpg10-pmic", .data = &s2mpg10_data, },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sec_pmic_acpm_of_match);
|
||||
|
||||
static struct platform_driver sec_pmic_acpm_driver = {
|
||||
.driver = {
|
||||
.name = "sec-pmic-acpm",
|
||||
.pm = pm_sleep_ptr(&sec_pmic_pm_ops),
|
||||
.of_match_table = sec_pmic_acpm_of_match,
|
||||
},
|
||||
.probe = sec_pmic_acpm_probe,
|
||||
.shutdown = sec_pmic_acpm_shutdown,
|
||||
};
|
||||
module_platform_driver(sec_pmic_acpm_driver);
|
||||
|
||||
MODULE_AUTHOR("André Draszik <andre.draszik@linaro.org>");
|
||||
MODULE_DESCRIPTION("ACPM driver for the Samsung S2MPG1x");
|
||||
MODULE_LICENSE("GPL");
|
||||
301
drivers/mfd/sec-common.c
Normal file
301
drivers/mfd/sec-common.c
Normal file
@ -0,0 +1,301 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2012 Samsung Electronics Co., Ltd
|
||||
* http://www.samsung.com
|
||||
* Copyright 2025 Linaro Ltd.
|
||||
*
|
||||
* Samsung SxM core driver
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/samsung/core.h>
|
||||
#include <linux/mfd/samsung/irq.h>
|
||||
#include <linux/mfd/samsung/s2mps11.h>
|
||||
#include <linux/mfd/samsung/s2mps13.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
#include "sec-core.h"
|
||||
|
||||
static const struct mfd_cell s5m8767_devs[] = {
|
||||
MFD_CELL_NAME("s5m8767-pmic"),
|
||||
MFD_CELL_NAME("s5m-rtc"),
|
||||
MFD_CELL_OF("s5m8767-clk", NULL, NULL, 0, 0, "samsung,s5m8767-clk"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2dos05_devs[] = {
|
||||
MFD_CELL_NAME("s2dos05-regulator"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mpg10_devs[] = {
|
||||
MFD_CELL_NAME("s2mpg10-meter"),
|
||||
MFD_CELL_NAME("s2mpg10-regulator"),
|
||||
MFD_CELL_NAME("s2mpg10-rtc"),
|
||||
MFD_CELL_OF("s2mpg10-clk", NULL, NULL, 0, 0, "samsung,s2mpg10-clk"),
|
||||
MFD_CELL_OF("s2mpg10-gpio", NULL, NULL, 0, 0, "samsung,s2mpg10-gpio"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mps11_devs[] = {
|
||||
MFD_CELL_NAME("s2mps11-regulator"),
|
||||
MFD_CELL_NAME("s2mps14-rtc"),
|
||||
MFD_CELL_OF("s2mps11-clk", NULL, NULL, 0, 0, "samsung,s2mps11-clk"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mps13_devs[] = {
|
||||
MFD_CELL_NAME("s2mps13-regulator"),
|
||||
MFD_CELL_NAME("s2mps13-rtc"),
|
||||
MFD_CELL_OF("s2mps13-clk", NULL, NULL, 0, 0, "samsung,s2mps13-clk"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mps14_devs[] = {
|
||||
MFD_CELL_NAME("s2mps14-regulator"),
|
||||
MFD_CELL_NAME("s2mps14-rtc"),
|
||||
MFD_CELL_OF("s2mps14-clk", NULL, NULL, 0, 0, "samsung,s2mps14-clk"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mps15_devs[] = {
|
||||
MFD_CELL_NAME("s2mps15-regulator"),
|
||||
MFD_CELL_NAME("s2mps15-rtc"),
|
||||
MFD_CELL_OF("s2mps13-clk", NULL, NULL, 0, 0, "samsung,s2mps13-clk"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mpa01_devs[] = {
|
||||
MFD_CELL_NAME("s2mpa01-pmic"),
|
||||
MFD_CELL_NAME("s2mps14-rtc"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mpu02_devs[] = {
|
||||
MFD_CELL_NAME("s2mpu02-regulator"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mpu05_devs[] = {
|
||||
MFD_CELL_NAME("s2mpu05-regulator"),
|
||||
MFD_CELL_NAME("s2mps15-rtc"),
|
||||
};
|
||||
|
||||
static void sec_pmic_dump_rev(struct sec_pmic_dev *sec_pmic)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
/* For s2mpg1x, the revision is in a different regmap */
|
||||
if (sec_pmic->device_type == S2MPG10)
|
||||
return;
|
||||
|
||||
/* For each device type, the REG_ID is always the first register */
|
||||
if (!regmap_read(sec_pmic->regmap_pmic, S2MPS11_REG_ID, &val))
|
||||
dev_dbg(sec_pmic->dev, "Revision: 0x%x\n", val);
|
||||
}
|
||||
|
||||
static void sec_pmic_configure(struct sec_pmic_dev *sec_pmic)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (sec_pmic->device_type != S2MPS13X)
|
||||
return;
|
||||
|
||||
if (sec_pmic->pdata->disable_wrstbi) {
|
||||
/*
|
||||
* If WRSTBI pin is pulled down this feature must be disabled
|
||||
* because each Suspend to RAM will trigger buck voltage reset
|
||||
* to default values.
|
||||
*/
|
||||
err = regmap_update_bits(sec_pmic->regmap_pmic,
|
||||
S2MPS13_REG_WRSTBI,
|
||||
S2MPS13_REG_WRSTBI_MASK, 0x0);
|
||||
if (err)
|
||||
dev_warn(sec_pmic->dev,
|
||||
"Cannot initialize WRSTBI config: %d\n",
|
||||
err);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Only the common platform data elements for s5m8767 are parsed here from the
|
||||
* device tree. Other sub-modules of s5m8767 such as pmic, rtc , charger and
|
||||
* others have to parse their own platform data elements from device tree.
|
||||
*
|
||||
* The s5m8767 platform data structure is instantiated here and the drivers for
|
||||
* the sub-modules need not instantiate another instance while parsing their
|
||||
* platform data.
|
||||
*/
|
||||
static struct sec_platform_data *
|
||||
sec_pmic_parse_dt_pdata(struct device *dev)
|
||||
{
|
||||
struct sec_platform_data *pd;
|
||||
|
||||
pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
|
||||
if (!pd)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
pd->manual_poweroff = of_property_read_bool(dev->of_node,
|
||||
"samsung,s2mps11-acokb-ground");
|
||||
pd->disable_wrstbi = of_property_read_bool(dev->of_node,
|
||||
"samsung,s2mps11-wrstbi-ground");
|
||||
return pd;
|
||||
}
|
||||
|
||||
int sec_pmic_probe(struct device *dev, int device_type, unsigned int irq,
|
||||
struct regmap *regmap, struct i2c_client *client)
|
||||
{
|
||||
struct sec_platform_data *pdata;
|
||||
const struct mfd_cell *sec_devs;
|
||||
struct sec_pmic_dev *sec_pmic;
|
||||
int ret, num_sec_devs;
|
||||
|
||||
sec_pmic = devm_kzalloc(dev, sizeof(*sec_pmic), GFP_KERNEL);
|
||||
if (!sec_pmic)
|
||||
return -ENOMEM;
|
||||
|
||||
dev_set_drvdata(dev, sec_pmic);
|
||||
sec_pmic->dev = dev;
|
||||
sec_pmic->device_type = device_type;
|
||||
sec_pmic->i2c = client;
|
||||
sec_pmic->irq = irq;
|
||||
sec_pmic->regmap_pmic = regmap;
|
||||
|
||||
pdata = sec_pmic_parse_dt_pdata(sec_pmic->dev);
|
||||
if (IS_ERR(pdata)) {
|
||||
ret = PTR_ERR(pdata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
sec_pmic->pdata = pdata;
|
||||
|
||||
ret = sec_irq_init(sec_pmic);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pm_runtime_set_active(sec_pmic->dev);
|
||||
|
||||
switch (sec_pmic->device_type) {
|
||||
case S5M8767X:
|
||||
sec_devs = s5m8767_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s5m8767_devs);
|
||||
break;
|
||||
case S2DOS05:
|
||||
sec_devs = s2dos05_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s2dos05_devs);
|
||||
break;
|
||||
case S2MPA01:
|
||||
sec_devs = s2mpa01_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s2mpa01_devs);
|
||||
break;
|
||||
case S2MPG10:
|
||||
sec_devs = s2mpg10_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s2mpg10_devs);
|
||||
break;
|
||||
case S2MPS11X:
|
||||
sec_devs = s2mps11_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s2mps11_devs);
|
||||
break;
|
||||
case S2MPS13X:
|
||||
sec_devs = s2mps13_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s2mps13_devs);
|
||||
break;
|
||||
case S2MPS14X:
|
||||
sec_devs = s2mps14_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s2mps14_devs);
|
||||
break;
|
||||
case S2MPS15X:
|
||||
sec_devs = s2mps15_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s2mps15_devs);
|
||||
break;
|
||||
case S2MPU02:
|
||||
sec_devs = s2mpu02_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s2mpu02_devs);
|
||||
break;
|
||||
case S2MPU05:
|
||||
sec_devs = s2mpu05_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s2mpu05_devs);
|
||||
break;
|
||||
default:
|
||||
return dev_err_probe(sec_pmic->dev, -EINVAL,
|
||||
"Unsupported device type %d\n",
|
||||
sec_pmic->device_type);
|
||||
}
|
||||
ret = devm_mfd_add_devices(sec_pmic->dev, -1, sec_devs, num_sec_devs,
|
||||
NULL, 0, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
sec_pmic_configure(sec_pmic);
|
||||
sec_pmic_dump_rev(sec_pmic);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sec_pmic_probe);
|
||||
|
||||
void sec_pmic_shutdown(struct device *dev)
|
||||
{
|
||||
struct sec_pmic_dev *sec_pmic = dev_get_drvdata(dev);
|
||||
unsigned int reg, mask;
|
||||
|
||||
if (!sec_pmic->pdata->manual_poweroff)
|
||||
return;
|
||||
|
||||
switch (sec_pmic->device_type) {
|
||||
case S2MPS11X:
|
||||
reg = S2MPS11_REG_CTRL1;
|
||||
mask = S2MPS11_CTRL1_PWRHOLD_MASK;
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* Currently only one board with S2MPS11 needs this, so just
|
||||
* ignore the rest.
|
||||
*/
|
||||
dev_warn(sec_pmic->dev,
|
||||
"Unsupported device %d for manual power off\n",
|
||||
sec_pmic->device_type);
|
||||
return;
|
||||
}
|
||||
|
||||
regmap_update_bits(sec_pmic->regmap_pmic, reg, mask, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sec_pmic_shutdown);
|
||||
|
||||
static int sec_pmic_suspend(struct device *dev)
|
||||
{
|
||||
struct sec_pmic_dev *sec_pmic = dev_get_drvdata(dev);
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
enable_irq_wake(sec_pmic->irq);
|
||||
/*
|
||||
* PMIC IRQ must be disabled during suspend for RTC alarm
|
||||
* to work properly.
|
||||
* When device is woken up from suspend, an
|
||||
* interrupt occurs before resuming I2C bus controller.
|
||||
* The interrupt is handled by regmap_irq_thread which tries
|
||||
* to read RTC registers. This read fails (I2C is still
|
||||
* suspended) and RTC Alarm interrupt is disabled.
|
||||
*/
|
||||
disable_irq(sec_pmic->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sec_pmic_resume(struct device *dev)
|
||||
{
|
||||
struct sec_pmic_dev *sec_pmic = dev_get_drvdata(dev);
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
disable_irq_wake(sec_pmic->irq);
|
||||
enable_irq(sec_pmic->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops, sec_pmic_suspend, sec_pmic_resume);
|
||||
EXPORT_SYMBOL_GPL(sec_pmic_pm_ops);
|
||||
|
||||
MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
|
||||
MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>");
|
||||
MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
|
||||
MODULE_AUTHOR("André Draszik <andre.draszik@linaro.org>");
|
||||
MODULE_DESCRIPTION("Core driver for the Samsung S5M");
|
||||
MODULE_LICENSE("GPL");
|
||||
@ -1,481 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
//
|
||||
// Copyright (c) 2012 Samsung Electronics Co., Ltd
|
||||
// http://www.samsung.com
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/samsung/core.h>
|
||||
#include <linux/mfd/samsung/irq.h>
|
||||
#include <linux/mfd/samsung/s2mpa01.h>
|
||||
#include <linux/mfd/samsung/s2mps11.h>
|
||||
#include <linux/mfd/samsung/s2mps13.h>
|
||||
#include <linux/mfd/samsung/s2mps14.h>
|
||||
#include <linux/mfd/samsung/s2mps15.h>
|
||||
#include <linux/mfd/samsung/s2mpu02.h>
|
||||
#include <linux/mfd/samsung/s5m8767.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
static const struct mfd_cell s5m8767_devs[] = {
|
||||
{ .name = "s5m8767-pmic", },
|
||||
{ .name = "s5m-rtc", },
|
||||
{
|
||||
.name = "s5m8767-clk",
|
||||
.of_compatible = "samsung,s5m8767-clk",
|
||||
},
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2dos05_devs[] = {
|
||||
{ .name = "s2dos05-regulator", },
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mps11_devs[] = {
|
||||
{ .name = "s2mps11-regulator", },
|
||||
{ .name = "s2mps14-rtc", },
|
||||
{
|
||||
.name = "s2mps11-clk",
|
||||
.of_compatible = "samsung,s2mps11-clk",
|
||||
},
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mps13_devs[] = {
|
||||
{ .name = "s2mps13-regulator", },
|
||||
{ .name = "s2mps13-rtc", },
|
||||
{
|
||||
.name = "s2mps13-clk",
|
||||
.of_compatible = "samsung,s2mps13-clk",
|
||||
},
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mps14_devs[] = {
|
||||
{ .name = "s2mps14-regulator", },
|
||||
{ .name = "s2mps14-rtc", },
|
||||
{
|
||||
.name = "s2mps14-clk",
|
||||
.of_compatible = "samsung,s2mps14-clk",
|
||||
},
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mps15_devs[] = {
|
||||
{ .name = "s2mps15-regulator", },
|
||||
{ .name = "s2mps15-rtc", },
|
||||
{
|
||||
.name = "s2mps13-clk",
|
||||
.of_compatible = "samsung,s2mps13-clk",
|
||||
},
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mpa01_devs[] = {
|
||||
{ .name = "s2mpa01-pmic", },
|
||||
{ .name = "s2mps14-rtc", },
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mpu02_devs[] = {
|
||||
{ .name = "s2mpu02-regulator", },
|
||||
};
|
||||
|
||||
static const struct mfd_cell s2mpu05_devs[] = {
|
||||
{ .name = "s2mpu05-regulator", },
|
||||
{ .name = "s2mps15-rtc", },
|
||||
};
|
||||
|
||||
static const struct of_device_id sec_dt_match[] = {
|
||||
{
|
||||
.compatible = "samsung,s5m8767-pmic",
|
||||
.data = (void *)S5M8767X,
|
||||
}, {
|
||||
.compatible = "samsung,s2dos05",
|
||||
.data = (void *)S2DOS05,
|
||||
}, {
|
||||
.compatible = "samsung,s2mps11-pmic",
|
||||
.data = (void *)S2MPS11X,
|
||||
}, {
|
||||
.compatible = "samsung,s2mps13-pmic",
|
||||
.data = (void *)S2MPS13X,
|
||||
}, {
|
||||
.compatible = "samsung,s2mps14-pmic",
|
||||
.data = (void *)S2MPS14X,
|
||||
}, {
|
||||
.compatible = "samsung,s2mps15-pmic",
|
||||
.data = (void *)S2MPS15X,
|
||||
}, {
|
||||
.compatible = "samsung,s2mpa01-pmic",
|
||||
.data = (void *)S2MPA01,
|
||||
}, {
|
||||
.compatible = "samsung,s2mpu02-pmic",
|
||||
.data = (void *)S2MPU02,
|
||||
}, {
|
||||
.compatible = "samsung,s2mpu05-pmic",
|
||||
.data = (void *)S2MPU05,
|
||||
}, {
|
||||
/* Sentinel */
|
||||
},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sec_dt_match);
|
||||
|
||||
static bool s2mpa01_volatile(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case S2MPA01_REG_INT1M:
|
||||
case S2MPA01_REG_INT2M:
|
||||
case S2MPA01_REG_INT3M:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static bool s2mps11_volatile(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case S2MPS11_REG_INT1M:
|
||||
case S2MPS11_REG_INT2M:
|
||||
case S2MPS11_REG_INT3M:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static bool s2mpu02_volatile(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case S2MPU02_REG_INT1M:
|
||||
case S2MPU02_REG_INT2M:
|
||||
case S2MPU02_REG_INT3M:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct regmap_config sec_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
};
|
||||
|
||||
static const struct regmap_config s2mpa01_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
.max_register = S2MPA01_REG_LDO_OVCB4,
|
||||
.volatile_reg = s2mpa01_volatile,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_config s2mps11_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
.max_register = S2MPS11_REG_L38CTRL,
|
||||
.volatile_reg = s2mps11_volatile,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_config s2mps13_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
.max_register = S2MPS13_REG_LDODSCH5,
|
||||
.volatile_reg = s2mps11_volatile,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_config s2mps14_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
.max_register = S2MPS14_REG_LDODSCH3,
|
||||
.volatile_reg = s2mps11_volatile,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_config s2mps15_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
.max_register = S2MPS15_REG_LDODSCH4,
|
||||
.volatile_reg = s2mps11_volatile,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_config s2mpu02_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
.max_register = S2MPU02_REG_DVSDATA,
|
||||
.volatile_reg = s2mpu02_volatile,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_config s5m8767_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
.max_register = S5M8767_REG_LDO28CTRL,
|
||||
.volatile_reg = s2mps11_volatile,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static void sec_pmic_dump_rev(struct sec_pmic_dev *sec_pmic)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
/* For each device type, the REG_ID is always the first register */
|
||||
if (!regmap_read(sec_pmic->regmap_pmic, S2MPS11_REG_ID, &val))
|
||||
dev_dbg(sec_pmic->dev, "Revision: 0x%x\n", val);
|
||||
}
|
||||
|
||||
static void sec_pmic_configure(struct sec_pmic_dev *sec_pmic)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (sec_pmic->device_type != S2MPS13X)
|
||||
return;
|
||||
|
||||
if (sec_pmic->pdata->disable_wrstbi) {
|
||||
/*
|
||||
* If WRSTBI pin is pulled down this feature must be disabled
|
||||
* because each Suspend to RAM will trigger buck voltage reset
|
||||
* to default values.
|
||||
*/
|
||||
err = regmap_update_bits(sec_pmic->regmap_pmic,
|
||||
S2MPS13_REG_WRSTBI,
|
||||
S2MPS13_REG_WRSTBI_MASK, 0x0);
|
||||
if (err)
|
||||
dev_warn(sec_pmic->dev,
|
||||
"Cannot initialize WRSTBI config: %d\n",
|
||||
err);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Only the common platform data elements for s5m8767 are parsed here from the
|
||||
* device tree. Other sub-modules of s5m8767 such as pmic, rtc , charger and
|
||||
* others have to parse their own platform data elements from device tree.
|
||||
*
|
||||
* The s5m8767 platform data structure is instantiated here and the drivers for
|
||||
* the sub-modules need not instantiate another instance while parsing their
|
||||
* platform data.
|
||||
*/
|
||||
static struct sec_platform_data *
|
||||
sec_pmic_i2c_parse_dt_pdata(struct device *dev)
|
||||
{
|
||||
struct sec_platform_data *pd;
|
||||
|
||||
pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
|
||||
if (!pd)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
pd->manual_poweroff = of_property_read_bool(dev->of_node,
|
||||
"samsung,s2mps11-acokb-ground");
|
||||
pd->disable_wrstbi = of_property_read_bool(dev->of_node,
|
||||
"samsung,s2mps11-wrstbi-ground");
|
||||
return pd;
|
||||
}
|
||||
|
||||
static int sec_pmic_probe(struct i2c_client *i2c)
|
||||
{
|
||||
const struct regmap_config *regmap;
|
||||
struct sec_platform_data *pdata;
|
||||
const struct mfd_cell *sec_devs;
|
||||
struct sec_pmic_dev *sec_pmic;
|
||||
int ret, num_sec_devs;
|
||||
|
||||
sec_pmic = devm_kzalloc(&i2c->dev, sizeof(struct sec_pmic_dev),
|
||||
GFP_KERNEL);
|
||||
if (sec_pmic == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(i2c, sec_pmic);
|
||||
sec_pmic->dev = &i2c->dev;
|
||||
sec_pmic->i2c = i2c;
|
||||
sec_pmic->irq = i2c->irq;
|
||||
|
||||
pdata = sec_pmic_i2c_parse_dt_pdata(sec_pmic->dev);
|
||||
if (IS_ERR(pdata)) {
|
||||
ret = PTR_ERR(pdata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
sec_pmic->device_type = (unsigned long)of_device_get_match_data(sec_pmic->dev);
|
||||
sec_pmic->pdata = pdata;
|
||||
|
||||
switch (sec_pmic->device_type) {
|
||||
case S2MPA01:
|
||||
regmap = &s2mpa01_regmap_config;
|
||||
break;
|
||||
case S2MPS11X:
|
||||
regmap = &s2mps11_regmap_config;
|
||||
break;
|
||||
case S2MPS13X:
|
||||
regmap = &s2mps13_regmap_config;
|
||||
break;
|
||||
case S2MPS14X:
|
||||
regmap = &s2mps14_regmap_config;
|
||||
break;
|
||||
case S2MPS15X:
|
||||
regmap = &s2mps15_regmap_config;
|
||||
break;
|
||||
case S5M8767X:
|
||||
regmap = &s5m8767_regmap_config;
|
||||
break;
|
||||
case S2MPU02:
|
||||
regmap = &s2mpu02_regmap_config;
|
||||
break;
|
||||
default:
|
||||
regmap = &sec_regmap_config;
|
||||
break;
|
||||
}
|
||||
|
||||
sec_pmic->regmap_pmic = devm_regmap_init_i2c(i2c, regmap);
|
||||
if (IS_ERR(sec_pmic->regmap_pmic)) {
|
||||
ret = PTR_ERR(sec_pmic->regmap_pmic);
|
||||
dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
sec_irq_init(sec_pmic);
|
||||
|
||||
pm_runtime_set_active(sec_pmic->dev);
|
||||
|
||||
switch (sec_pmic->device_type) {
|
||||
case S5M8767X:
|
||||
sec_devs = s5m8767_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s5m8767_devs);
|
||||
break;
|
||||
case S2DOS05:
|
||||
sec_devs = s2dos05_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s2dos05_devs);
|
||||
break;
|
||||
case S2MPA01:
|
||||
sec_devs = s2mpa01_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s2mpa01_devs);
|
||||
break;
|
||||
case S2MPS11X:
|
||||
sec_devs = s2mps11_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s2mps11_devs);
|
||||
break;
|
||||
case S2MPS13X:
|
||||
sec_devs = s2mps13_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s2mps13_devs);
|
||||
break;
|
||||
case S2MPS14X:
|
||||
sec_devs = s2mps14_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s2mps14_devs);
|
||||
break;
|
||||
case S2MPS15X:
|
||||
sec_devs = s2mps15_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s2mps15_devs);
|
||||
break;
|
||||
case S2MPU02:
|
||||
sec_devs = s2mpu02_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s2mpu02_devs);
|
||||
break;
|
||||
case S2MPU05:
|
||||
sec_devs = s2mpu05_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s2mpu05_devs);
|
||||
break;
|
||||
default:
|
||||
dev_err(&i2c->dev, "Unsupported device type (%lu)\n",
|
||||
sec_pmic->device_type);
|
||||
return -ENODEV;
|
||||
}
|
||||
ret = devm_mfd_add_devices(sec_pmic->dev, -1, sec_devs, num_sec_devs,
|
||||
NULL, 0, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
sec_pmic_configure(sec_pmic);
|
||||
sec_pmic_dump_rev(sec_pmic);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sec_pmic_shutdown(struct i2c_client *i2c)
|
||||
{
|
||||
struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
|
||||
unsigned int reg, mask;
|
||||
|
||||
if (!sec_pmic->pdata->manual_poweroff)
|
||||
return;
|
||||
|
||||
switch (sec_pmic->device_type) {
|
||||
case S2MPS11X:
|
||||
reg = S2MPS11_REG_CTRL1;
|
||||
mask = S2MPS11_CTRL1_PWRHOLD_MASK;
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* Currently only one board with S2MPS11 needs this, so just
|
||||
* ignore the rest.
|
||||
*/
|
||||
dev_warn(sec_pmic->dev,
|
||||
"Unsupported device %lu for manual power off\n",
|
||||
sec_pmic->device_type);
|
||||
return;
|
||||
}
|
||||
|
||||
regmap_update_bits(sec_pmic->regmap_pmic, reg, mask, 0);
|
||||
}
|
||||
|
||||
static int sec_pmic_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *i2c = to_i2c_client(dev);
|
||||
struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
enable_irq_wake(sec_pmic->irq);
|
||||
/*
|
||||
* PMIC IRQ must be disabled during suspend for RTC alarm
|
||||
* to work properly.
|
||||
* When device is woken up from suspend, an
|
||||
* interrupt occurs before resuming I2C bus controller.
|
||||
* The interrupt is handled by regmap_irq_thread which tries
|
||||
* to read RTC registers. This read fails (I2C is still
|
||||
* suspended) and RTC Alarm interrupt is disabled.
|
||||
*/
|
||||
disable_irq(sec_pmic->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sec_pmic_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *i2c = to_i2c_client(dev);
|
||||
struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
disable_irq_wake(sec_pmic->irq);
|
||||
enable_irq(sec_pmic->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops,
|
||||
sec_pmic_suspend, sec_pmic_resume);
|
||||
|
||||
static struct i2c_driver sec_pmic_driver = {
|
||||
.driver = {
|
||||
.name = "sec_pmic",
|
||||
.pm = pm_sleep_ptr(&sec_pmic_pm_ops),
|
||||
.of_match_table = sec_dt_match,
|
||||
},
|
||||
.probe = sec_pmic_probe,
|
||||
.shutdown = sec_pmic_shutdown,
|
||||
};
|
||||
module_i2c_driver(sec_pmic_driver);
|
||||
|
||||
MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
|
||||
MODULE_DESCRIPTION("Core support for the S5M MFD");
|
||||
MODULE_LICENSE("GPL");
|
||||
23
drivers/mfd/sec-core.h
Normal file
23
drivers/mfd/sec-core.h
Normal file
@ -0,0 +1,23 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2012 Samsung Electronics Co., Ltd
|
||||
* http://www.samsung.com
|
||||
* Copyright 2025 Linaro Ltd.
|
||||
*
|
||||
* Samsung SxM core driver internal data
|
||||
*/
|
||||
|
||||
#ifndef __SEC_CORE_INT_H
|
||||
#define __SEC_CORE_INT_H
|
||||
|
||||
struct i2c_client;
|
||||
|
||||
extern const struct dev_pm_ops sec_pmic_pm_ops;
|
||||
|
||||
int sec_pmic_probe(struct device *dev, int device_type, unsigned int irq,
|
||||
struct regmap *regmap, struct i2c_client *client);
|
||||
void sec_pmic_shutdown(struct device *dev);
|
||||
|
||||
int sec_irq_init(struct sec_pmic_dev *sec_pmic);
|
||||
|
||||
#endif /* __SEC_CORE_INT_H */
|
||||
239
drivers/mfd/sec-i2c.c
Normal file
239
drivers/mfd/sec-i2c.c
Normal file
@ -0,0 +1,239 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2012 Samsung Electronics Co., Ltd
|
||||
* http://www.samsung.com
|
||||
* Copyright 2025 Linaro Ltd.
|
||||
*
|
||||
* Samsung SxM I2C driver
|
||||
*/
|
||||
|
||||
#include <linux/dev_printk.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/mfd/samsung/core.h>
|
||||
#include <linux/mfd/samsung/s2mpa01.h>
|
||||
#include <linux/mfd/samsung/s2mps11.h>
|
||||
#include <linux/mfd/samsung/s2mps13.h>
|
||||
#include <linux/mfd/samsung/s2mps14.h>
|
||||
#include <linux/mfd/samsung/s2mps15.h>
|
||||
#include <linux/mfd/samsung/s2mpu02.h>
|
||||
#include <linux/mfd/samsung/s5m8767.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regmap.h>
|
||||
#include "sec-core.h"
|
||||
|
||||
struct sec_pmic_i2c_platform_data {
|
||||
const struct regmap_config *regmap_cfg;
|
||||
int device_type;
|
||||
};
|
||||
|
||||
static bool s2mpa01_volatile(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case S2MPA01_REG_INT1M:
|
||||
case S2MPA01_REG_INT2M:
|
||||
case S2MPA01_REG_INT3M:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static bool s2mps11_volatile(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case S2MPS11_REG_INT1M:
|
||||
case S2MPS11_REG_INT2M:
|
||||
case S2MPS11_REG_INT3M:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static bool s2mpu02_volatile(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case S2MPU02_REG_INT1M:
|
||||
case S2MPU02_REG_INT2M:
|
||||
case S2MPU02_REG_INT3M:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct regmap_config s2dos05_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
};
|
||||
|
||||
static const struct regmap_config s2mpa01_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
.max_register = S2MPA01_REG_LDO_OVCB4,
|
||||
.volatile_reg = s2mpa01_volatile,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_config s2mps11_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
.max_register = S2MPS11_REG_L38CTRL,
|
||||
.volatile_reg = s2mps11_volatile,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_config s2mps13_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
.max_register = S2MPS13_REG_LDODSCH5,
|
||||
.volatile_reg = s2mps11_volatile,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_config s2mps14_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
.max_register = S2MPS14_REG_LDODSCH3,
|
||||
.volatile_reg = s2mps11_volatile,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_config s2mps15_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
.max_register = S2MPS15_REG_LDODSCH4,
|
||||
.volatile_reg = s2mps11_volatile,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_config s2mpu02_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
.max_register = S2MPU02_REG_DVSDATA,
|
||||
.volatile_reg = s2mpu02_volatile,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_config s2mpu05_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
};
|
||||
|
||||
static const struct regmap_config s5m8767_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
.max_register = S5M8767_REG_LDO28CTRL,
|
||||
.volatile_reg = s2mps11_volatile,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static int sec_pmic_i2c_probe(struct i2c_client *client)
|
||||
{
|
||||
const struct sec_pmic_i2c_platform_data *pdata;
|
||||
struct regmap *regmap_pmic;
|
||||
|
||||
pdata = device_get_match_data(&client->dev);
|
||||
if (!pdata)
|
||||
return dev_err_probe(&client->dev, -ENODEV,
|
||||
"Unsupported device type\n");
|
||||
|
||||
regmap_pmic = devm_regmap_init_i2c(client, pdata->regmap_cfg);
|
||||
if (IS_ERR(regmap_pmic))
|
||||
return dev_err_probe(&client->dev, PTR_ERR(regmap_pmic),
|
||||
"regmap init failed\n");
|
||||
|
||||
return sec_pmic_probe(&client->dev, pdata->device_type, client->irq,
|
||||
regmap_pmic, client);
|
||||
}
|
||||
|
||||
static void sec_pmic_i2c_shutdown(struct i2c_client *i2c)
|
||||
{
|
||||
sec_pmic_shutdown(&i2c->dev);
|
||||
}
|
||||
|
||||
static const struct sec_pmic_i2c_platform_data s2dos05_data = {
|
||||
.regmap_cfg = &s2dos05_regmap_config,
|
||||
.device_type = S2DOS05
|
||||
};
|
||||
|
||||
static const struct sec_pmic_i2c_platform_data s2mpa01_data = {
|
||||
.regmap_cfg = &s2mpa01_regmap_config,
|
||||
.device_type = S2MPA01,
|
||||
};
|
||||
|
||||
static const struct sec_pmic_i2c_platform_data s2mps11_data = {
|
||||
.regmap_cfg = &s2mps11_regmap_config,
|
||||
.device_type = S2MPS11X,
|
||||
};
|
||||
|
||||
static const struct sec_pmic_i2c_platform_data s2mps13_data = {
|
||||
.regmap_cfg = &s2mps13_regmap_config,
|
||||
.device_type = S2MPS13X,
|
||||
};
|
||||
|
||||
static const struct sec_pmic_i2c_platform_data s2mps14_data = {
|
||||
.regmap_cfg = &s2mps14_regmap_config,
|
||||
.device_type = S2MPS14X,
|
||||
};
|
||||
|
||||
static const struct sec_pmic_i2c_platform_data s2mps15_data = {
|
||||
.regmap_cfg = &s2mps15_regmap_config,
|
||||
.device_type = S2MPS15X,
|
||||
};
|
||||
|
||||
static const struct sec_pmic_i2c_platform_data s2mpu02_data = {
|
||||
.regmap_cfg = &s2mpu02_regmap_config,
|
||||
.device_type = S2MPU02,
|
||||
};
|
||||
|
||||
static const struct sec_pmic_i2c_platform_data s2mpu05_data = {
|
||||
.regmap_cfg = &s2mpu05_regmap_config,
|
||||
.device_type = S2MPU05,
|
||||
};
|
||||
|
||||
static const struct sec_pmic_i2c_platform_data s5m8767_data = {
|
||||
.regmap_cfg = &s5m8767_regmap_config,
|
||||
.device_type = S5M8767X,
|
||||
};
|
||||
|
||||
static const struct of_device_id sec_pmic_i2c_of_match[] = {
|
||||
{ .compatible = "samsung,s2dos05", .data = &s2dos05_data, },
|
||||
{ .compatible = "samsung,s2mpa01-pmic", .data = &s2mpa01_data, },
|
||||
{ .compatible = "samsung,s2mps11-pmic", .data = &s2mps11_data, },
|
||||
{ .compatible = "samsung,s2mps13-pmic", .data = &s2mps13_data, },
|
||||
{ .compatible = "samsung,s2mps14-pmic", .data = &s2mps14_data, },
|
||||
{ .compatible = "samsung,s2mps15-pmic", .data = &s2mps15_data, },
|
||||
{ .compatible = "samsung,s2mpu02-pmic", .data = &s2mpu02_data, },
|
||||
{ .compatible = "samsung,s2mpu05-pmic", .data = &s2mpu05_data, },
|
||||
{ .compatible = "samsung,s5m8767-pmic", .data = &s5m8767_data, },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sec_pmic_i2c_of_match);
|
||||
|
||||
static struct i2c_driver sec_pmic_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "sec-pmic-i2c",
|
||||
.pm = pm_sleep_ptr(&sec_pmic_pm_ops),
|
||||
.of_match_table = sec_pmic_i2c_of_match,
|
||||
},
|
||||
.probe = sec_pmic_i2c_probe,
|
||||
.shutdown = sec_pmic_i2c_shutdown,
|
||||
};
|
||||
module_i2c_driver(sec_pmic_i2c_driver);
|
||||
|
||||
MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
|
||||
MODULE_AUTHOR("André Draszik <andre.draszik@linaro.org>");
|
||||
MODULE_DESCRIPTION("I2C driver for the Samsung S5M");
|
||||
MODULE_LICENSE("GPL");
|
||||
@ -3,227 +3,139 @@
|
||||
// Copyright (c) 2011-2014 Samsung Electronics Co., Ltd
|
||||
// http://www.samsung.com
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/array_size.h>
|
||||
#include <linux/build_bug.h>
|
||||
#include <linux/dev_printk.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <linux/mfd/samsung/core.h>
|
||||
#include <linux/mfd/samsung/irq.h>
|
||||
#include <linux/mfd/samsung/s2mpg10.h>
|
||||
#include <linux/mfd/samsung/s2mps11.h>
|
||||
#include <linux/mfd/samsung/s2mps14.h>
|
||||
#include <linux/mfd/samsung/s2mpu02.h>
|
||||
#include <linux/mfd/samsung/s2mpu05.h>
|
||||
#include <linux/mfd/samsung/s5m8767.h>
|
||||
#include <linux/regmap.h>
|
||||
#include "sec-core.h"
|
||||
|
||||
static const struct regmap_irq s2mpg10_irqs[] = {
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_PWRONF, 0, S2MPG10_IRQ_PWRONF_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_PWRONR, 0, S2MPG10_IRQ_PWRONR_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_JIGONBF, 0, S2MPG10_IRQ_JIGONBF_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_JIGONBR, 0, S2MPG10_IRQ_JIGONBR_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_ACOKBF, 0, S2MPG10_IRQ_ACOKBF_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_ACOKBR, 0, S2MPG10_IRQ_ACOKBR_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_PWRON1S, 0, S2MPG10_IRQ_PWRON1S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_MRB, 0, S2MPG10_IRQ_MRB_MASK),
|
||||
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_RTC60S, 1, S2MPG10_IRQ_RTC60S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_RTCA1, 1, S2MPG10_IRQ_RTCA1_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_RTCA0, 1, S2MPG10_IRQ_RTCA0_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_RTC1S, 1, S2MPG10_IRQ_RTC1S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_WTSR_COLDRST, 1, S2MPG10_IRQ_WTSR_COLDRST_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_WTSR, 1, S2MPG10_IRQ_WTSR_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_WRST, 1, S2MPG10_IRQ_WRST_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_SMPL, 1, S2MPG10_IRQ_SMPL_MASK),
|
||||
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_120C, 2, S2MPG10_IRQ_INT120C_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_140C, 2, S2MPG10_IRQ_INT140C_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_TSD, 2, S2MPG10_IRQ_TSD_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_PIF_TIMEOUT1, 2, S2MPG10_IRQ_PIF_TIMEOUT1_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_PIF_TIMEOUT2, 2, S2MPG10_IRQ_PIF_TIMEOUT2_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_SPD_PARITY_ERR, 2, S2MPG10_IRQ_SPD_PARITY_ERR_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_SPD_ABNORMAL_STOP, 2, S2MPG10_IRQ_SPD_ABNORMAL_STOP_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_PMETER_OVERF, 2, S2MPG10_IRQ_PMETER_OVERF_MASK),
|
||||
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_OCP_B1M, 3, S2MPG10_IRQ_OCP_B1M_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_OCP_B2M, 3, S2MPG10_IRQ_OCP_B2M_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_OCP_B3M, 3, S2MPG10_IRQ_OCP_B3M_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_OCP_B4M, 3, S2MPG10_IRQ_OCP_B4M_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_OCP_B5M, 3, S2MPG10_IRQ_OCP_B5M_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_OCP_B6M, 3, S2MPG10_IRQ_OCP_B6M_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_OCP_B7M, 3, S2MPG10_IRQ_OCP_B7M_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_OCP_B8M, 3, S2MPG10_IRQ_OCP_B8M_MASK),
|
||||
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_OCP_B9M, 4, S2MPG10_IRQ_OCP_B9M_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_OCP_B10M, 4, S2MPG10_IRQ_OCP_B10M_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_WLWP_ACC, 4, S2MPG10_IRQ_WLWP_ACC_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_SMPL_TIMEOUT, 4, S2MPG10_IRQ_SMPL_TIMEOUT_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_WTSR_TIMEOUT, 4, S2MPG10_IRQ_WTSR_TIMEOUT_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_SPD_SRP_PKT_RST, 4, S2MPG10_IRQ_SPD_SRP_PKT_RST_MASK),
|
||||
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_PWR_WARN_CH0, 5, S2MPG10_IRQ_PWR_WARN_CH0_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_PWR_WARN_CH1, 5, S2MPG10_IRQ_PWR_WARN_CH1_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_PWR_WARN_CH2, 5, S2MPG10_IRQ_PWR_WARN_CH2_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_PWR_WARN_CH3, 5, S2MPG10_IRQ_PWR_WARN_CH3_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_PWR_WARN_CH4, 5, S2MPG10_IRQ_PWR_WARN_CH4_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_PWR_WARN_CH5, 5, S2MPG10_IRQ_PWR_WARN_CH5_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_PWR_WARN_CH6, 5, S2MPG10_IRQ_PWR_WARN_CH6_MASK),
|
||||
REGMAP_IRQ_REG(S2MPG10_IRQ_PWR_WARN_CH7, 5, S2MPG10_IRQ_PWR_WARN_CH7_MASK),
|
||||
};
|
||||
|
||||
static const struct regmap_irq s2mps11_irqs[] = {
|
||||
[S2MPS11_IRQ_PWRONF] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_PWRONF_MASK,
|
||||
},
|
||||
[S2MPS11_IRQ_PWRONR] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_PWRONR_MASK,
|
||||
},
|
||||
[S2MPS11_IRQ_JIGONBF] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_JIGONBF_MASK,
|
||||
},
|
||||
[S2MPS11_IRQ_JIGONBR] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_JIGONBR_MASK,
|
||||
},
|
||||
[S2MPS11_IRQ_ACOKBF] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_ACOKBF_MASK,
|
||||
},
|
||||
[S2MPS11_IRQ_ACOKBR] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_ACOKBR_MASK,
|
||||
},
|
||||
[S2MPS11_IRQ_PWRON1S] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_PWRON1S_MASK,
|
||||
},
|
||||
[S2MPS11_IRQ_MRB] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_MRB_MASK,
|
||||
},
|
||||
[S2MPS11_IRQ_RTC60S] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S2MPS11_IRQ_RTC60S_MASK,
|
||||
},
|
||||
[S2MPS11_IRQ_RTCA1] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S2MPS11_IRQ_RTCA1_MASK,
|
||||
},
|
||||
[S2MPS11_IRQ_RTCA0] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S2MPS11_IRQ_RTCA0_MASK,
|
||||
},
|
||||
[S2MPS11_IRQ_SMPL] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S2MPS11_IRQ_SMPL_MASK,
|
||||
},
|
||||
[S2MPS11_IRQ_RTC1S] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S2MPS11_IRQ_RTC1S_MASK,
|
||||
},
|
||||
[S2MPS11_IRQ_WTSR] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S2MPS11_IRQ_WTSR_MASK,
|
||||
},
|
||||
[S2MPS11_IRQ_INT120C] = {
|
||||
.reg_offset = 2,
|
||||
.mask = S2MPS11_IRQ_INT120C_MASK,
|
||||
},
|
||||
[S2MPS11_IRQ_INT140C] = {
|
||||
.reg_offset = 2,
|
||||
.mask = S2MPS11_IRQ_INT140C_MASK,
|
||||
},
|
||||
REGMAP_IRQ_REG(S2MPS11_IRQ_PWRONF, 0, S2MPS11_IRQ_PWRONF_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS11_IRQ_PWRONR, 0, S2MPS11_IRQ_PWRONR_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS11_IRQ_JIGONBF, 0, S2MPS11_IRQ_JIGONBF_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS11_IRQ_JIGONBR, 0, S2MPS11_IRQ_JIGONBR_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS11_IRQ_ACOKBF, 0, S2MPS11_IRQ_ACOKBF_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS11_IRQ_ACOKBR, 0, S2MPS11_IRQ_ACOKBR_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS11_IRQ_PWRON1S, 0, S2MPS11_IRQ_PWRON1S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS11_IRQ_MRB, 0, S2MPS11_IRQ_MRB_MASK),
|
||||
|
||||
REGMAP_IRQ_REG(S2MPS11_IRQ_RTC60S, 1, S2MPS11_IRQ_RTC60S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS11_IRQ_RTCA1, 1, S2MPS11_IRQ_RTCA1_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS11_IRQ_RTCA0, 1, S2MPS11_IRQ_RTCA0_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS11_IRQ_SMPL, 1, S2MPS11_IRQ_SMPL_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS11_IRQ_RTC1S, 1, S2MPS11_IRQ_RTC1S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS11_IRQ_WTSR, 1, S2MPS11_IRQ_WTSR_MASK),
|
||||
|
||||
REGMAP_IRQ_REG(S2MPS11_IRQ_INT120C, 2, S2MPS11_IRQ_INT120C_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS11_IRQ_INT140C, 2, S2MPS11_IRQ_INT140C_MASK),
|
||||
};
|
||||
|
||||
static const struct regmap_irq s2mps14_irqs[] = {
|
||||
[S2MPS14_IRQ_PWRONF] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_PWRONF_MASK,
|
||||
},
|
||||
[S2MPS14_IRQ_PWRONR] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_PWRONR_MASK,
|
||||
},
|
||||
[S2MPS14_IRQ_JIGONBF] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_JIGONBF_MASK,
|
||||
},
|
||||
[S2MPS14_IRQ_JIGONBR] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_JIGONBR_MASK,
|
||||
},
|
||||
[S2MPS14_IRQ_ACOKBF] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_ACOKBF_MASK,
|
||||
},
|
||||
[S2MPS14_IRQ_ACOKBR] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_ACOKBR_MASK,
|
||||
},
|
||||
[S2MPS14_IRQ_PWRON1S] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_PWRON1S_MASK,
|
||||
},
|
||||
[S2MPS14_IRQ_MRB] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_MRB_MASK,
|
||||
},
|
||||
[S2MPS14_IRQ_RTC60S] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S2MPS11_IRQ_RTC60S_MASK,
|
||||
},
|
||||
[S2MPS14_IRQ_RTCA1] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S2MPS11_IRQ_RTCA1_MASK,
|
||||
},
|
||||
[S2MPS14_IRQ_RTCA0] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S2MPS11_IRQ_RTCA0_MASK,
|
||||
},
|
||||
[S2MPS14_IRQ_SMPL] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S2MPS11_IRQ_SMPL_MASK,
|
||||
},
|
||||
[S2MPS14_IRQ_RTC1S] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S2MPS11_IRQ_RTC1S_MASK,
|
||||
},
|
||||
[S2MPS14_IRQ_WTSR] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S2MPS11_IRQ_WTSR_MASK,
|
||||
},
|
||||
[S2MPS14_IRQ_INT120C] = {
|
||||
.reg_offset = 2,
|
||||
.mask = S2MPS11_IRQ_INT120C_MASK,
|
||||
},
|
||||
[S2MPS14_IRQ_INT140C] = {
|
||||
.reg_offset = 2,
|
||||
.mask = S2MPS11_IRQ_INT140C_MASK,
|
||||
},
|
||||
[S2MPS14_IRQ_TSD] = {
|
||||
.reg_offset = 2,
|
||||
.mask = S2MPS14_IRQ_TSD_MASK,
|
||||
},
|
||||
REGMAP_IRQ_REG(S2MPS14_IRQ_PWRONF, 0, S2MPS11_IRQ_PWRONF_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS14_IRQ_PWRONR, 0, S2MPS11_IRQ_PWRONR_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS14_IRQ_JIGONBF, 0, S2MPS11_IRQ_JIGONBF_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS14_IRQ_JIGONBR, 0, S2MPS11_IRQ_JIGONBR_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS14_IRQ_ACOKBF, 0, S2MPS11_IRQ_ACOKBF_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS14_IRQ_ACOKBR, 0, S2MPS11_IRQ_ACOKBR_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS14_IRQ_PWRON1S, 0, S2MPS11_IRQ_PWRON1S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS14_IRQ_MRB, 0, S2MPS11_IRQ_MRB_MASK),
|
||||
|
||||
REGMAP_IRQ_REG(S2MPS14_IRQ_RTC60S, 1, S2MPS11_IRQ_RTC60S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS14_IRQ_RTCA1, 1, S2MPS11_IRQ_RTCA1_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS14_IRQ_RTCA0, 1, S2MPS11_IRQ_RTCA0_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS14_IRQ_SMPL, 1, S2MPS11_IRQ_SMPL_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS14_IRQ_RTC1S, 1, S2MPS11_IRQ_RTC1S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS14_IRQ_WTSR, 1, S2MPS11_IRQ_WTSR_MASK),
|
||||
|
||||
REGMAP_IRQ_REG(S2MPS14_IRQ_INT120C, 2, S2MPS11_IRQ_INT120C_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS14_IRQ_INT140C, 2, S2MPS11_IRQ_INT140C_MASK),
|
||||
REGMAP_IRQ_REG(S2MPS14_IRQ_TSD, 2, S2MPS14_IRQ_TSD_MASK),
|
||||
};
|
||||
|
||||
static const struct regmap_irq s2mpu02_irqs[] = {
|
||||
[S2MPU02_IRQ_PWRONF] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_PWRONF_MASK,
|
||||
},
|
||||
[S2MPU02_IRQ_PWRONR] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_PWRONR_MASK,
|
||||
},
|
||||
[S2MPU02_IRQ_JIGONBF] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_JIGONBF_MASK,
|
||||
},
|
||||
[S2MPU02_IRQ_JIGONBR] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_JIGONBR_MASK,
|
||||
},
|
||||
[S2MPU02_IRQ_ACOKBF] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_ACOKBF_MASK,
|
||||
},
|
||||
[S2MPU02_IRQ_ACOKBR] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_ACOKBR_MASK,
|
||||
},
|
||||
[S2MPU02_IRQ_PWRON1S] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_PWRON1S_MASK,
|
||||
},
|
||||
[S2MPU02_IRQ_MRB] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S2MPS11_IRQ_MRB_MASK,
|
||||
},
|
||||
[S2MPU02_IRQ_RTC60S] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S2MPS11_IRQ_RTC60S_MASK,
|
||||
},
|
||||
[S2MPU02_IRQ_RTCA1] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S2MPS11_IRQ_RTCA1_MASK,
|
||||
},
|
||||
[S2MPU02_IRQ_RTCA0] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S2MPS11_IRQ_RTCA0_MASK,
|
||||
},
|
||||
[S2MPU02_IRQ_SMPL] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S2MPS11_IRQ_SMPL_MASK,
|
||||
},
|
||||
[S2MPU02_IRQ_RTC1S] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S2MPS11_IRQ_RTC1S_MASK,
|
||||
},
|
||||
[S2MPU02_IRQ_WTSR] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S2MPS11_IRQ_WTSR_MASK,
|
||||
},
|
||||
[S2MPU02_IRQ_INT120C] = {
|
||||
.reg_offset = 2,
|
||||
.mask = S2MPS11_IRQ_INT120C_MASK,
|
||||
},
|
||||
[S2MPU02_IRQ_INT140C] = {
|
||||
.reg_offset = 2,
|
||||
.mask = S2MPS11_IRQ_INT140C_MASK,
|
||||
},
|
||||
[S2MPU02_IRQ_TSD] = {
|
||||
.reg_offset = 2,
|
||||
.mask = S2MPS14_IRQ_TSD_MASK,
|
||||
},
|
||||
REGMAP_IRQ_REG(S2MPU02_IRQ_PWRONF, 0, S2MPS11_IRQ_PWRONF_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU02_IRQ_PWRONR, 0, S2MPS11_IRQ_PWRONR_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU02_IRQ_JIGONBF, 0, S2MPS11_IRQ_JIGONBF_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU02_IRQ_JIGONBR, 0, S2MPS11_IRQ_JIGONBR_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU02_IRQ_ACOKBF, 0, S2MPS11_IRQ_ACOKBF_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU02_IRQ_ACOKBR, 0, S2MPS11_IRQ_ACOKBR_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU02_IRQ_PWRON1S, 0, S2MPS11_IRQ_PWRON1S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU02_IRQ_MRB, 0, S2MPS11_IRQ_MRB_MASK),
|
||||
|
||||
REGMAP_IRQ_REG(S2MPU02_IRQ_RTC60S, 1, S2MPS11_IRQ_RTC60S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU02_IRQ_RTCA1, 1, S2MPS11_IRQ_RTCA1_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU02_IRQ_RTCA0, 1, S2MPS11_IRQ_RTCA0_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU02_IRQ_SMPL, 1, S2MPS11_IRQ_SMPL_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU02_IRQ_RTC1S, 1, S2MPS11_IRQ_RTC1S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU02_IRQ_WTSR, 1, S2MPS11_IRQ_WTSR_MASK),
|
||||
|
||||
REGMAP_IRQ_REG(S2MPU02_IRQ_INT120C, 2, S2MPS11_IRQ_INT120C_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU02_IRQ_INT140C, 2, S2MPS11_IRQ_INT140C_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU02_IRQ_TSD, 2, S2MPS14_IRQ_TSD_MASK),
|
||||
};
|
||||
|
||||
static const struct regmap_irq s2mpu05_irqs[] = {
|
||||
@ -247,74 +159,35 @@ static const struct regmap_irq s2mpu05_irqs[] = {
|
||||
};
|
||||
|
||||
static const struct regmap_irq s5m8767_irqs[] = {
|
||||
[S5M8767_IRQ_PWRR] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S5M8767_IRQ_PWRR_MASK,
|
||||
},
|
||||
[S5M8767_IRQ_PWRF] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S5M8767_IRQ_PWRF_MASK,
|
||||
},
|
||||
[S5M8767_IRQ_PWR1S] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S5M8767_IRQ_PWR1S_MASK,
|
||||
},
|
||||
[S5M8767_IRQ_JIGR] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S5M8767_IRQ_JIGR_MASK,
|
||||
},
|
||||
[S5M8767_IRQ_JIGF] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S5M8767_IRQ_JIGF_MASK,
|
||||
},
|
||||
[S5M8767_IRQ_LOWBAT2] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S5M8767_IRQ_LOWBAT2_MASK,
|
||||
},
|
||||
[S5M8767_IRQ_LOWBAT1] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S5M8767_IRQ_LOWBAT1_MASK,
|
||||
},
|
||||
[S5M8767_IRQ_MRB] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S5M8767_IRQ_MRB_MASK,
|
||||
},
|
||||
[S5M8767_IRQ_DVSOK2] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S5M8767_IRQ_DVSOK2_MASK,
|
||||
},
|
||||
[S5M8767_IRQ_DVSOK3] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S5M8767_IRQ_DVSOK3_MASK,
|
||||
},
|
||||
[S5M8767_IRQ_DVSOK4] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S5M8767_IRQ_DVSOK4_MASK,
|
||||
},
|
||||
[S5M8767_IRQ_RTC60S] = {
|
||||
.reg_offset = 2,
|
||||
.mask = S5M8767_IRQ_RTC60S_MASK,
|
||||
},
|
||||
[S5M8767_IRQ_RTCA1] = {
|
||||
.reg_offset = 2,
|
||||
.mask = S5M8767_IRQ_RTCA1_MASK,
|
||||
},
|
||||
[S5M8767_IRQ_RTCA2] = {
|
||||
.reg_offset = 2,
|
||||
.mask = S5M8767_IRQ_RTCA2_MASK,
|
||||
},
|
||||
[S5M8767_IRQ_SMPL] = {
|
||||
.reg_offset = 2,
|
||||
.mask = S5M8767_IRQ_SMPL_MASK,
|
||||
},
|
||||
[S5M8767_IRQ_RTC1S] = {
|
||||
.reg_offset = 2,
|
||||
.mask = S5M8767_IRQ_RTC1S_MASK,
|
||||
},
|
||||
[S5M8767_IRQ_WTSR] = {
|
||||
.reg_offset = 2,
|
||||
.mask = S5M8767_IRQ_WTSR_MASK,
|
||||
},
|
||||
REGMAP_IRQ_REG(S5M8767_IRQ_PWRR, 0, S5M8767_IRQ_PWRR_MASK),
|
||||
REGMAP_IRQ_REG(S5M8767_IRQ_PWRF, 0, S5M8767_IRQ_PWRF_MASK),
|
||||
REGMAP_IRQ_REG(S5M8767_IRQ_PWR1S, 0, S5M8767_IRQ_PWR1S_MASK),
|
||||
REGMAP_IRQ_REG(S5M8767_IRQ_JIGR, 0, S5M8767_IRQ_JIGR_MASK),
|
||||
REGMAP_IRQ_REG(S5M8767_IRQ_JIGF, 0, S5M8767_IRQ_JIGF_MASK),
|
||||
REGMAP_IRQ_REG(S5M8767_IRQ_LOWBAT2, 0, S5M8767_IRQ_LOWBAT2_MASK),
|
||||
REGMAP_IRQ_REG(S5M8767_IRQ_LOWBAT1, 0, S5M8767_IRQ_LOWBAT1_MASK),
|
||||
|
||||
REGMAP_IRQ_REG(S5M8767_IRQ_MRB, 1, S5M8767_IRQ_MRB_MASK),
|
||||
REGMAP_IRQ_REG(S5M8767_IRQ_DVSOK2, 1, S5M8767_IRQ_DVSOK2_MASK),
|
||||
REGMAP_IRQ_REG(S5M8767_IRQ_DVSOK3, 1, S5M8767_IRQ_DVSOK3_MASK),
|
||||
REGMAP_IRQ_REG(S5M8767_IRQ_DVSOK4, 1, S5M8767_IRQ_DVSOK4_MASK),
|
||||
|
||||
REGMAP_IRQ_REG(S5M8767_IRQ_RTC60S, 2, S5M8767_IRQ_RTC60S_MASK),
|
||||
REGMAP_IRQ_REG(S5M8767_IRQ_RTCA1, 2, S5M8767_IRQ_RTCA1_MASK),
|
||||
REGMAP_IRQ_REG(S5M8767_IRQ_RTCA2, 2, S5M8767_IRQ_RTCA2_MASK),
|
||||
REGMAP_IRQ_REG(S5M8767_IRQ_SMPL, 2, S5M8767_IRQ_SMPL_MASK),
|
||||
REGMAP_IRQ_REG(S5M8767_IRQ_RTC1S, 2, S5M8767_IRQ_RTC1S_MASK),
|
||||
REGMAP_IRQ_REG(S5M8767_IRQ_WTSR, 2, S5M8767_IRQ_WTSR_MASK),
|
||||
};
|
||||
|
||||
/* All S2MPG10 interrupt sources are read-only and don't require clearing */
|
||||
static const struct regmap_irq_chip s2mpg10_irq_chip = {
|
||||
.name = "s2mpg10",
|
||||
.irqs = s2mpg10_irqs,
|
||||
.num_irqs = ARRAY_SIZE(s2mpg10_irqs),
|
||||
.num_regs = 6,
|
||||
.status_base = S2MPG10_PMIC_INT1,
|
||||
.mask_base = S2MPG10_PMIC_INT1M,
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip s2mps11_irq_chip = {
|
||||
@ -382,23 +255,21 @@ static const struct regmap_irq_chip s5m8767_irq_chip = {
|
||||
|
||||
int sec_irq_init(struct sec_pmic_dev *sec_pmic)
|
||||
{
|
||||
int ret = 0;
|
||||
int type = sec_pmic->device_type;
|
||||
const struct regmap_irq_chip *sec_irq_chip;
|
||||
int ret;
|
||||
|
||||
if (!sec_pmic->irq) {
|
||||
dev_warn(sec_pmic->dev,
|
||||
"No interrupt specified, no interrupts\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
switch (sec_pmic->device_type) {
|
||||
case S5M8767X:
|
||||
sec_irq_chip = &s5m8767_irq_chip;
|
||||
break;
|
||||
case S2DOS05:
|
||||
return 0;
|
||||
case S2MPA01:
|
||||
sec_irq_chip = &s2mps14_irq_chip;
|
||||
break;
|
||||
case S2MPG10:
|
||||
sec_irq_chip = &s2mpg10_irq_chip;
|
||||
break;
|
||||
case S2MPS11X:
|
||||
sec_irq_chip = &s2mps11_irq_chip;
|
||||
break;
|
||||
@ -418,18 +289,24 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)
|
||||
sec_irq_chip = &s2mpu05_irq_chip;
|
||||
break;
|
||||
default:
|
||||
dev_err(sec_pmic->dev, "Unknown device type %lu\n",
|
||||
sec_pmic->device_type);
|
||||
return -EINVAL;
|
||||
return dev_err_probe(sec_pmic->dev, -EINVAL,
|
||||
"Unsupported device type %d\n",
|
||||
sec_pmic->device_type);
|
||||
}
|
||||
|
||||
if (!sec_pmic->irq) {
|
||||
dev_warn(sec_pmic->dev,
|
||||
"No interrupt specified, no interrupts\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = devm_regmap_add_irq_chip(sec_pmic->dev, sec_pmic->regmap_pmic,
|
||||
sec_pmic->irq, IRQF_ONESHOT,
|
||||
0, sec_irq_chip, &sec_pmic->irq_data);
|
||||
if (ret != 0) {
|
||||
dev_err(sec_pmic->dev, "Failed to register IRQ chip: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
return dev_err_probe(sec_pmic->dev, ret,
|
||||
"Failed to add %s IRQ chip\n",
|
||||
sec_irq_chip->name);
|
||||
|
||||
/*
|
||||
* The rtc-s5m driver requests S2MPS14_IRQ_RTCA0 also for S2MPS11
|
||||
@ -439,10 +316,3 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sec_irq_init);
|
||||
|
||||
MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
|
||||
MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
|
||||
MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>");
|
||||
MODULE_DESCRIPTION("Interrupt support for the S5M MFD");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
@ -631,49 +631,6 @@ unsigned long sm501_set_clock(struct device *dev,
|
||||
|
||||
EXPORT_SYMBOL_GPL(sm501_set_clock);
|
||||
|
||||
/* sm501_find_clock
|
||||
*
|
||||
* finds the closest available frequency for a given clock
|
||||
*/
|
||||
|
||||
unsigned long sm501_find_clock(struct device *dev,
|
||||
int clksrc,
|
||||
unsigned long req_freq)
|
||||
{
|
||||
struct sm501_devdata *sm = dev_get_drvdata(dev);
|
||||
unsigned long sm501_freq; /* the frequency achieveable by the 501 */
|
||||
struct sm501_clock to;
|
||||
|
||||
switch (clksrc) {
|
||||
case SM501_CLOCK_P2XCLK:
|
||||
if (sm->rev >= 0xC0) {
|
||||
/* SM502 -> use the programmable PLL */
|
||||
sm501_freq = (sm501_calc_pll(2 * req_freq,
|
||||
&to, 5) / 2);
|
||||
} else {
|
||||
sm501_freq = (sm501_select_clock(2 * req_freq,
|
||||
&to, 5) / 2);
|
||||
}
|
||||
break;
|
||||
|
||||
case SM501_CLOCK_V2XCLK:
|
||||
sm501_freq = (sm501_select_clock(2 * req_freq, &to, 3) / 2);
|
||||
break;
|
||||
|
||||
case SM501_CLOCK_MCLK:
|
||||
case SM501_CLOCK_M1XCLK:
|
||||
sm501_freq = sm501_select_clock(req_freq, &to, 3);
|
||||
break;
|
||||
|
||||
default:
|
||||
sm501_freq = 0; /* error */
|
||||
}
|
||||
|
||||
return sm501_freq;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(sm501_find_clock);
|
||||
|
||||
static struct sm501_device *to_sm_device(struct platform_device *pdev)
|
||||
{
|
||||
return container_of(pdev, struct sm501_device, pdev);
|
||||
@ -915,7 +872,8 @@ static void sm501_gpio_ensure_gpio(struct sm501_gpio_chip *smchip,
|
||||
}
|
||||
}
|
||||
|
||||
static void sm501_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
static int sm501_gpio_set(struct gpio_chip *chip, unsigned int offset,
|
||||
int value)
|
||||
|
||||
{
|
||||
struct sm501_gpio_chip *smchip = gpiochip_get_data(chip);
|
||||
@ -939,6 +897,8 @@ static void sm501_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
sm501_gpio_ensure_gpio(smchip, bit);
|
||||
|
||||
spin_unlock_irqrestore(&smgpio->lock, save);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sm501_gpio_input(struct gpio_chip *chip, unsigned offset)
|
||||
@ -1005,7 +965,7 @@ static const struct gpio_chip gpio_chip_template = {
|
||||
.ngpio = 32,
|
||||
.direction_input = sm501_gpio_input,
|
||||
.direction_output = sm501_gpio_output,
|
||||
.set = sm501_gpio_set,
|
||||
.set_rv = sm501_gpio_set,
|
||||
.get = sm501_gpio_get,
|
||||
};
|
||||
|
||||
|
||||
@ -210,7 +210,10 @@ static int sprd_pmic_probe(struct spi_device *spi)
|
||||
return ret;
|
||||
}
|
||||
|
||||
device_init_wakeup(&spi->dev, true);
|
||||
ret = devm_device_init_wakeup(&spi->dev);
|
||||
if (ret)
|
||||
return dev_err_probe(&spi->dev, ret, "Failed to init wakeup\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
* Inspired by Benjamin Gaignard's stm32-timers driver
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/mfd/stm32-lptimer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_platform.h>
|
||||
@ -49,6 +50,36 @@ static int stm32_lptimer_detect_encoder(struct stm32_lptimer *ddata)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32_lptimer_detect_hwcfgr(struct stm32_lptimer *ddata)
|
||||
{
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(ddata->regmap, STM32_LPTIM_VERR, &ddata->version);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Try to guess parameters from HWCFGR: e.g. encoder mode (STM32MP15) */
|
||||
ret = regmap_read(ddata->regmap, STM32_LPTIM_HWCFGR1, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Fallback to legacy init if HWCFGR isn't present */
|
||||
if (!val)
|
||||
return stm32_lptimer_detect_encoder(ddata);
|
||||
|
||||
ddata->has_encoder = FIELD_GET(STM32_LPTIM_HWCFGR1_ENCODER, val);
|
||||
|
||||
ret = regmap_read(ddata->regmap, STM32_LPTIM_HWCFGR2, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Number of capture/compare channels */
|
||||
ddata->num_cc_chans = FIELD_GET(STM32_LPTIM_HWCFGR2_CHAN_NUM, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32_lptimer_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
@ -73,7 +104,7 @@ static int stm32_lptimer_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(ddata->clk))
|
||||
return PTR_ERR(ddata->clk);
|
||||
|
||||
ret = stm32_lptimer_detect_encoder(ddata);
|
||||
ret = stm32_lptimer_detect_hwcfgr(ddata);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
@ -129,7 +129,7 @@ static const struct spi_device_id stmpe_spi_id[] = {
|
||||
{ "stmpe2403", STMPE2403 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, stmpe_id);
|
||||
MODULE_DEVICE_TABLE(spi, stmpe_spi_id);
|
||||
|
||||
static struct spi_driver stmpe_spi_driver = {
|
||||
.driver = {
|
||||
|
||||
@ -446,7 +446,7 @@ static irqreturn_t tps65010_irq(int irq, void *_tps)
|
||||
* offsets 4..5 == LED1/nPG, LED2 (we set one of the non-BLINK modes)
|
||||
* offset 6 == vibrator motor driver
|
||||
*/
|
||||
static void
|
||||
static int
|
||||
tps65010_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
{
|
||||
if (offset < 4)
|
||||
@ -455,6 +455,8 @@ tps65010_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
tps65010_set_led(offset - 3, value ? ON : OFF);
|
||||
else
|
||||
tps65010_set_vib(value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -512,7 +514,6 @@ static void tps65010_remove(struct i2c_client *client)
|
||||
if (client->irq > 0)
|
||||
free_irq(client->irq, tps);
|
||||
cancel_delayed_work_sync(&tps->work);
|
||||
debugfs_remove(tps->file);
|
||||
the_tps = NULL;
|
||||
}
|
||||
|
||||
@ -608,7 +609,7 @@ static int tps65010_probe(struct i2c_client *client)
|
||||
|
||||
tps65010_work(&tps->work.work);
|
||||
|
||||
tps->file = debugfs_create_file(DRIVER_NAME, S_IRUGO, NULL,
|
||||
tps->file = debugfs_create_file(DRIVER_NAME, S_IRUGO, client->debugfs,
|
||||
tps, DEBUG_FOPS);
|
||||
|
||||
/* optionally register GPIOs */
|
||||
@ -619,7 +620,7 @@ static int tps65010_probe(struct i2c_client *client)
|
||||
tps->chip.parent = &client->dev;
|
||||
tps->chip.owner = THIS_MODULE;
|
||||
|
||||
tps->chip.set = tps65010_gpio_set;
|
||||
tps->chip.set_rv = tps65010_gpio_set;
|
||||
tps->chip.direction_output = tps65010_output;
|
||||
|
||||
/* NOTE: only partial support for inputs; nyet IRQs */
|
||||
|
||||
@ -104,7 +104,8 @@ unsigned int ucb1x00_io_read(struct ucb1x00 *ucb)
|
||||
return ucb1x00_reg_read(ucb, UCB_IO_DATA);
|
||||
}
|
||||
|
||||
static void ucb1x00_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
static int ucb1x00_gpio_set(struct gpio_chip *chip, unsigned int offset,
|
||||
int value)
|
||||
{
|
||||
struct ucb1x00 *ucb = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
@ -119,6 +120,8 @@ static void ucb1x00_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
|
||||
ucb1x00_disable(ucb);
|
||||
spin_unlock_irqrestore(&ucb->io_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ucb1x00_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
@ -567,7 +570,7 @@ static int ucb1x00_probe(struct mcp *mcp)
|
||||
ucb->gpio.owner = THIS_MODULE;
|
||||
ucb->gpio.base = pdata->gpio_base;
|
||||
ucb->gpio.ngpio = 10;
|
||||
ucb->gpio.set = ucb1x00_gpio_set;
|
||||
ucb->gpio.set_rv = ucb1x00_gpio_set;
|
||||
ucb->gpio.get = ucb1x00_gpio_get;
|
||||
ucb->gpio.direction_input = ucb1x00_gpio_direction_input;
|
||||
ucb->gpio.direction_output = ucb1x00_gpio_direction_output;
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
struct stm32_pwm_lp {
|
||||
struct clk *clk;
|
||||
struct regmap *regmap;
|
||||
unsigned int num_cc_chans;
|
||||
};
|
||||
|
||||
static inline struct stm32_pwm_lp *to_stm32_pwm_lp(struct pwm_chip *chip)
|
||||
@ -30,13 +31,101 @@ static inline struct stm32_pwm_lp *to_stm32_pwm_lp(struct pwm_chip *chip)
|
||||
/* STM32 Low-Power Timer is preceded by a configurable power-of-2 prescaler */
|
||||
#define STM32_LPTIM_MAX_PRESCALER 128
|
||||
|
||||
static int stm32_pwm_lp_update_allowed(struct stm32_pwm_lp *priv, int channel)
|
||||
{
|
||||
int ret;
|
||||
u32 ccmr1;
|
||||
unsigned long ccmr;
|
||||
|
||||
/* Only one PWM on this LPTIMER: enable, prescaler and reload value can be changed */
|
||||
if (!priv->num_cc_chans)
|
||||
return true;
|
||||
|
||||
ret = regmap_read(priv->regmap, STM32_LPTIM_CCMR1, &ccmr1);
|
||||
if (ret)
|
||||
return ret;
|
||||
ccmr = ccmr1 & (STM32_LPTIM_CC1E | STM32_LPTIM_CC2E);
|
||||
|
||||
/* More than one channel enabled: enable, prescaler or ARR value can't be changed */
|
||||
if (bitmap_weight(&ccmr, sizeof(u32) * BITS_PER_BYTE) > 1)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Only one channel is enabled (or none): check status on the other channel, to
|
||||
* report if enable, prescaler or ARR value can be changed.
|
||||
*/
|
||||
if (channel)
|
||||
return !(ccmr1 & STM32_LPTIM_CC1E);
|
||||
else
|
||||
return !(ccmr1 & STM32_LPTIM_CC2E);
|
||||
}
|
||||
|
||||
static int stm32_pwm_lp_compare_channel_apply(struct stm32_pwm_lp *priv, int channel,
|
||||
bool enable, enum pwm_polarity polarity)
|
||||
{
|
||||
u32 ccmr1, val, mask;
|
||||
bool reenable;
|
||||
int ret;
|
||||
|
||||
/* No dedicated CC channel: nothing to do */
|
||||
if (!priv->num_cc_chans)
|
||||
return 0;
|
||||
|
||||
ret = regmap_read(priv->regmap, STM32_LPTIM_CCMR1, &ccmr1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (channel) {
|
||||
/* Must disable CC channel (CCxE) to modify polarity (CCxP), then re-enable */
|
||||
reenable = (enable && FIELD_GET(STM32_LPTIM_CC2E, ccmr1)) &&
|
||||
(polarity != FIELD_GET(STM32_LPTIM_CC2P, ccmr1));
|
||||
|
||||
mask = STM32_LPTIM_CC2SEL | STM32_LPTIM_CC2E | STM32_LPTIM_CC2P;
|
||||
val = FIELD_PREP(STM32_LPTIM_CC2P, polarity);
|
||||
val |= FIELD_PREP(STM32_LPTIM_CC2E, enable);
|
||||
} else {
|
||||
reenable = (enable && FIELD_GET(STM32_LPTIM_CC1E, ccmr1)) &&
|
||||
(polarity != FIELD_GET(STM32_LPTIM_CC1P, ccmr1));
|
||||
|
||||
mask = STM32_LPTIM_CC1SEL | STM32_LPTIM_CC1E | STM32_LPTIM_CC1P;
|
||||
val = FIELD_PREP(STM32_LPTIM_CC1P, polarity);
|
||||
val |= FIELD_PREP(STM32_LPTIM_CC1E, enable);
|
||||
}
|
||||
|
||||
if (reenable) {
|
||||
u32 cfgr, presc;
|
||||
unsigned long rate;
|
||||
unsigned int delay_us;
|
||||
|
||||
ret = regmap_update_bits(priv->regmap, STM32_LPTIM_CCMR1,
|
||||
channel ? STM32_LPTIM_CC2E : STM32_LPTIM_CC1E, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
/*
|
||||
* After a write to the LPTIM_CCMRx register, a new write operation can only be
|
||||
* performed after a delay of at least (PRESC × 3) clock cycles
|
||||
*/
|
||||
ret = regmap_read(priv->regmap, STM32_LPTIM_CFGR, &cfgr);
|
||||
if (ret)
|
||||
return ret;
|
||||
presc = FIELD_GET(STM32_LPTIM_PRESC, cfgr);
|
||||
rate = clk_get_rate(priv->clk) >> presc;
|
||||
if (!rate)
|
||||
return -EINVAL;
|
||||
delay_us = 3 * DIV_ROUND_UP(USEC_PER_SEC, rate);
|
||||
usleep_range(delay_us, delay_us * 2);
|
||||
}
|
||||
|
||||
return regmap_update_bits(priv->regmap, STM32_LPTIM_CCMR1, mask, val);
|
||||
}
|
||||
|
||||
static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
const struct pwm_state *state)
|
||||
{
|
||||
struct stm32_pwm_lp *priv = to_stm32_pwm_lp(chip);
|
||||
unsigned long long prd, div, dty;
|
||||
struct pwm_state cstate;
|
||||
u32 val, mask, cfgr, presc = 0;
|
||||
u32 arr, val, mask, cfgr, presc = 0;
|
||||
bool reenable;
|
||||
int ret;
|
||||
|
||||
@ -45,10 +134,28 @@ static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
||||
if (!state->enabled) {
|
||||
if (cstate.enabled) {
|
||||
/* Disable LP timer */
|
||||
ret = regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
|
||||
/* Disable CC channel if any */
|
||||
ret = stm32_pwm_lp_compare_channel_apply(priv, pwm->hwpwm, false,
|
||||
state->polarity);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = regmap_write(priv->regmap, pwm->hwpwm ?
|
||||
STM32_LPTIM_CCR2 : STM32_LPTIM_CMP, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Check if the timer can be disabled */
|
||||
ret = stm32_pwm_lp_update_allowed(priv, pwm->hwpwm);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (ret) {
|
||||
/* Disable LP timer */
|
||||
ret = regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* disable clock to PWM counter */
|
||||
clk_disable(priv->clk);
|
||||
}
|
||||
@ -79,6 +186,23 @@ static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
dty = prd * state->duty_cycle;
|
||||
do_div(dty, state->period);
|
||||
|
||||
ret = regmap_read(priv->regmap, STM32_LPTIM_CFGR, &cfgr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* When there are several channels, they share the same prescaler and reload value.
|
||||
* Check if this can be changed, or the values are the same for all channels.
|
||||
*/
|
||||
if (!stm32_pwm_lp_update_allowed(priv, pwm->hwpwm)) {
|
||||
ret = regmap_read(priv->regmap, STM32_LPTIM_ARR, &arr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if ((FIELD_GET(STM32_LPTIM_PRESC, cfgr) != presc) || (arr != prd - 1))
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (!cstate.enabled) {
|
||||
/* enable clock to drive PWM counter */
|
||||
ret = clk_enable(priv->clk);
|
||||
@ -86,15 +210,20 @@ static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_read(priv->regmap, STM32_LPTIM_CFGR, &cfgr);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
if ((FIELD_GET(STM32_LPTIM_PRESC, cfgr) != presc) ||
|
||||
(FIELD_GET(STM32_LPTIM_WAVPOL, cfgr) != state->polarity)) {
|
||||
((FIELD_GET(STM32_LPTIM_WAVPOL, cfgr) != state->polarity) && !priv->num_cc_chans)) {
|
||||
val = FIELD_PREP(STM32_LPTIM_PRESC, presc);
|
||||
val |= FIELD_PREP(STM32_LPTIM_WAVPOL, state->polarity);
|
||||
mask = STM32_LPTIM_PRESC | STM32_LPTIM_WAVPOL;
|
||||
mask = STM32_LPTIM_PRESC;
|
||||
|
||||
if (!priv->num_cc_chans) {
|
||||
/*
|
||||
* WAVPOL bit is only available when no capature compare channel is used,
|
||||
* e.g. on LPTIMER instances that have only one output channel. CCMR1 is
|
||||
* used otherwise.
|
||||
*/
|
||||
val |= FIELD_PREP(STM32_LPTIM_WAVPOL, state->polarity);
|
||||
mask |= STM32_LPTIM_WAVPOL;
|
||||
}
|
||||
|
||||
/* Must disable LP timer to modify CFGR */
|
||||
reenable = true;
|
||||
@ -120,20 +249,27 @@ static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = regmap_write(priv->regmap, STM32_LPTIM_CMP, prd - (1 + dty));
|
||||
/* Write CMP/CCRx register and ensure it's been properly written */
|
||||
ret = regmap_write(priv->regmap, pwm->hwpwm ? STM32_LPTIM_CCR2 : STM32_LPTIM_CMP,
|
||||
prd - (1 + dty));
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* ensure CMP & ARR registers are properly written */
|
||||
ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val,
|
||||
/* ensure ARR and CMP/CCRx registers are properly written */
|
||||
ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val, pwm->hwpwm ?
|
||||
(val & STM32_LPTIM_CMP2_ARROK) == STM32_LPTIM_CMP2_ARROK :
|
||||
(val & STM32_LPTIM_CMPOK_ARROK) == STM32_LPTIM_CMPOK_ARROK,
|
||||
100, 1000);
|
||||
if (ret) {
|
||||
dev_err(pwmchip_parent(chip), "ARR/CMP registers write issue\n");
|
||||
goto err;
|
||||
}
|
||||
ret = regmap_write(priv->regmap, STM32_LPTIM_ICR,
|
||||
STM32_LPTIM_CMPOKCF_ARROKCF);
|
||||
ret = regmap_write(priv->regmap, STM32_LPTIM_ICR, pwm->hwpwm ?
|
||||
STM32_LPTIM_CMP2OKCF_ARROKCF : STM32_LPTIM_CMPOKCF_ARROKCF);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = stm32_pwm_lp_compare_channel_apply(priv, pwm->hwpwm, true, state->polarity);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
@ -161,11 +297,22 @@ static int stm32_pwm_lp_get_state(struct pwm_chip *chip,
|
||||
{
|
||||
struct stm32_pwm_lp *priv = to_stm32_pwm_lp(chip);
|
||||
unsigned long rate = clk_get_rate(priv->clk);
|
||||
u32 val, presc, prd;
|
||||
u32 val, presc, prd, ccmr1;
|
||||
bool enabled;
|
||||
u64 tmp;
|
||||
|
||||
regmap_read(priv->regmap, STM32_LPTIM_CR, &val);
|
||||
state->enabled = !!FIELD_GET(STM32_LPTIM_ENABLE, val);
|
||||
enabled = !!FIELD_GET(STM32_LPTIM_ENABLE, val);
|
||||
if (priv->num_cc_chans) {
|
||||
/* There's a CC chan, need to also check if it's enabled */
|
||||
regmap_read(priv->regmap, STM32_LPTIM_CCMR1, &ccmr1);
|
||||
if (pwm->hwpwm)
|
||||
enabled &= !!FIELD_GET(STM32_LPTIM_CC2E, ccmr1);
|
||||
else
|
||||
enabled &= !!FIELD_GET(STM32_LPTIM_CC1E, ccmr1);
|
||||
}
|
||||
state->enabled = enabled;
|
||||
|
||||
/* Keep PWM counter clock refcount in sync with PWM initial state */
|
||||
if (state->enabled) {
|
||||
int ret = clk_enable(priv->clk);
|
||||
@ -176,14 +323,21 @@ static int stm32_pwm_lp_get_state(struct pwm_chip *chip,
|
||||
|
||||
regmap_read(priv->regmap, STM32_LPTIM_CFGR, &val);
|
||||
presc = FIELD_GET(STM32_LPTIM_PRESC, val);
|
||||
state->polarity = FIELD_GET(STM32_LPTIM_WAVPOL, val);
|
||||
if (priv->num_cc_chans) {
|
||||
if (pwm->hwpwm)
|
||||
state->polarity = FIELD_GET(STM32_LPTIM_CC2P, ccmr1);
|
||||
else
|
||||
state->polarity = FIELD_GET(STM32_LPTIM_CC1P, ccmr1);
|
||||
} else {
|
||||
state->polarity = FIELD_GET(STM32_LPTIM_WAVPOL, val);
|
||||
}
|
||||
|
||||
regmap_read(priv->regmap, STM32_LPTIM_ARR, &prd);
|
||||
tmp = prd + 1;
|
||||
tmp = (tmp << presc) * NSEC_PER_SEC;
|
||||
state->period = DIV_ROUND_CLOSEST_ULL(tmp, rate);
|
||||
|
||||
regmap_read(priv->regmap, STM32_LPTIM_CMP, &val);
|
||||
regmap_read(priv->regmap, pwm->hwpwm ? STM32_LPTIM_CCR2 : STM32_LPTIM_CMP, &val);
|
||||
tmp = prd - val;
|
||||
tmp = (tmp << presc) * NSEC_PER_SEC;
|
||||
state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, rate);
|
||||
@ -201,15 +355,25 @@ static int stm32_pwm_lp_probe(struct platform_device *pdev)
|
||||
struct stm32_lptimer *ddata = dev_get_drvdata(pdev->dev.parent);
|
||||
struct stm32_pwm_lp *priv;
|
||||
struct pwm_chip *chip;
|
||||
unsigned int npwm;
|
||||
int ret;
|
||||
|
||||
chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*priv));
|
||||
if (!ddata->num_cc_chans) {
|
||||
/* No dedicated CC channel, so there's only one PWM channel */
|
||||
npwm = 1;
|
||||
} else {
|
||||
/* There are dedicated CC channels, each with one PWM output */
|
||||
npwm = ddata->num_cc_chans;
|
||||
}
|
||||
|
||||
chip = devm_pwmchip_alloc(&pdev->dev, npwm, sizeof(*priv));
|
||||
if (IS_ERR(chip))
|
||||
return PTR_ERR(chip);
|
||||
priv = to_stm32_pwm_lp(chip);
|
||||
|
||||
priv->regmap = ddata->regmap;
|
||||
priv->clk = ddata->clk;
|
||||
priv->num_cc_chans = ddata->num_cc_chans;
|
||||
chip->ops = &stm32_pwm_lp_ops;
|
||||
|
||||
ret = devm_pwmchip_add(&pdev->dev, chip);
|
||||
@ -225,12 +389,15 @@ static int stm32_pwm_lp_suspend(struct device *dev)
|
||||
{
|
||||
struct pwm_chip *chip = dev_get_drvdata(dev);
|
||||
struct pwm_state state;
|
||||
unsigned int i;
|
||||
|
||||
pwm_get_state(&chip->pwms[0], &state);
|
||||
if (state.enabled) {
|
||||
dev_err(dev, "The consumer didn't stop us (%s)\n",
|
||||
chip->pwms[0].label);
|
||||
return -EBUSY;
|
||||
for (i = 0; i < chip->npwm; i++) {
|
||||
pwm_get_state(&chip->pwms[i], &state);
|
||||
if (state.enabled) {
|
||||
dev_err(dev, "The consumer didn't stop us (%s)\n",
|
||||
chip->pwms[i].label);
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
return pinctrl_pm_select_sleep_state(dev);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -83,6 +83,7 @@ enum {
|
||||
#define BD96801_LDO6_VSEL_REG 0x26
|
||||
#define BD96801_LDO7_VSEL_REG 0x27
|
||||
#define BD96801_BUCK_VSEL_MASK 0x1F
|
||||
#define BD96805_BUCK_VSEL_MASK 0x3f
|
||||
#define BD96801_LDO_VSEL_MASK 0xff
|
||||
|
||||
#define BD96801_MASK_RAMP_DELAY 0xc0
|
||||
@ -90,6 +91,7 @@ enum {
|
||||
#define BD96801_BUCK_INT_VOUT_MASK 0xff
|
||||
|
||||
#define BD96801_BUCK_VOLTS 256
|
||||
#define BD96805_BUCK_VOLTS 64
|
||||
#define BD96801_LDO_VOLTS 256
|
||||
|
||||
#define BD96801_OVP_MASK 0x03
|
||||
@ -160,6 +162,30 @@ static const struct linear_range bd96801_buck_init_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(3300000 - 150000, 0xed, 0xff, 0),
|
||||
};
|
||||
|
||||
/* BD96802 uses same voltage ranges for bucks as BD96801 */
|
||||
#define bd96802_tune_volts bd96801_tune_volts
|
||||
#define bd96802_buck_init_volts bd96801_buck_init_volts
|
||||
|
||||
/*
|
||||
* On BD96805 we have similar "negative tuning range" as on BD96801, except
|
||||
* that the max tuning is -310 ... +310 mV (instead of the 150mV). We use same
|
||||
* approach as with the BD96801 ranges.
|
||||
*/
|
||||
static const struct linear_range bd96805_tune_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(310000, 0x00, 0x1F, 10000),
|
||||
REGULATOR_LINEAR_RANGE(0, 0x20, 0x3F, 10000),
|
||||
};
|
||||
|
||||
static const struct linear_range bd96805_buck_init_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(500000 - 310000, 0x00, 0xc8, 5000),
|
||||
REGULATOR_LINEAR_RANGE(1550000 - 310000, 0xc9, 0xec, 50000),
|
||||
REGULATOR_LINEAR_RANGE(3300000 - 310000, 0xed, 0xff, 0),
|
||||
};
|
||||
|
||||
/* BD96806 uses same voltage ranges for bucks as BD96805 */
|
||||
#define bd96806_tune_volts bd96805_tune_volts
|
||||
#define bd96806_buck_init_volts bd96805_buck_init_volts
|
||||
|
||||
static const struct linear_range bd96801_ldo_int_volts[] = {
|
||||
REGULATOR_LINEAR_RANGE(300000, 0x00, 0x78, 25000),
|
||||
REGULATOR_LINEAR_RANGE(3300000, 0x79, 0xff, 0),
|
||||
@ -198,89 +224,89 @@ struct bd96801_irqinfo {
|
||||
|
||||
static const struct bd96801_irqinfo buck1_irqinfo[] = {
|
||||
BD96801_IRQINFO(BD96801_PROT_OCP, "buck1-over-curr-h", 500,
|
||||
"bd96801-buck1-overcurr-h"),
|
||||
"buck1-overcurr-h"),
|
||||
BD96801_IRQINFO(BD96801_PROT_OCP, "buck1-over-curr-l", 500,
|
||||
"bd96801-buck1-overcurr-l"),
|
||||
"buck1-overcurr-l"),
|
||||
BD96801_IRQINFO(BD96801_PROT_OCP, "buck1-over-curr-n", 500,
|
||||
"bd96801-buck1-overcurr-n"),
|
||||
"buck1-overcurr-n"),
|
||||
BD96801_IRQINFO(BD96801_PROT_OVP, "buck1-over-voltage", 500,
|
||||
"bd96801-buck1-overvolt"),
|
||||
"buck1-overvolt"),
|
||||
BD96801_IRQINFO(BD96801_PROT_UVP, "buck1-under-voltage", 500,
|
||||
"bd96801-buck1-undervolt"),
|
||||
"buck1-undervolt"),
|
||||
BD96801_IRQINFO(BD96801_PROT_TEMP, "buck1-over-temp", 500,
|
||||
"bd96801-buck1-thermal")
|
||||
"buck1-thermal")
|
||||
};
|
||||
|
||||
static const struct bd96801_irqinfo buck2_irqinfo[] = {
|
||||
BD96801_IRQINFO(BD96801_PROT_OCP, "buck2-over-curr-h", 500,
|
||||
"bd96801-buck2-overcurr-h"),
|
||||
"buck2-overcurr-h"),
|
||||
BD96801_IRQINFO(BD96801_PROT_OCP, "buck2-over-curr-l", 500,
|
||||
"bd96801-buck2-overcurr-l"),
|
||||
"buck2-overcurr-l"),
|
||||
BD96801_IRQINFO(BD96801_PROT_OCP, "buck2-over-curr-n", 500,
|
||||
"bd96801-buck2-overcurr-n"),
|
||||
"buck2-overcurr-n"),
|
||||
BD96801_IRQINFO(BD96801_PROT_OVP, "buck2-over-voltage", 500,
|
||||
"bd96801-buck2-overvolt"),
|
||||
"buck2-overvolt"),
|
||||
BD96801_IRQINFO(BD96801_PROT_UVP, "buck2-under-voltage", 500,
|
||||
"bd96801-buck2-undervolt"),
|
||||
"buck2-undervolt"),
|
||||
BD96801_IRQINFO(BD96801_PROT_TEMP, "buck2-over-temp", 500,
|
||||
"bd96801-buck2-thermal")
|
||||
"buck2-thermal")
|
||||
};
|
||||
|
||||
static const struct bd96801_irqinfo buck3_irqinfo[] = {
|
||||
BD96801_IRQINFO(BD96801_PROT_OCP, "buck3-over-curr-h", 500,
|
||||
"bd96801-buck3-overcurr-h"),
|
||||
"buck3-overcurr-h"),
|
||||
BD96801_IRQINFO(BD96801_PROT_OCP, "buck3-over-curr-l", 500,
|
||||
"bd96801-buck3-overcurr-l"),
|
||||
"buck3-overcurr-l"),
|
||||
BD96801_IRQINFO(BD96801_PROT_OCP, "buck3-over-curr-n", 500,
|
||||
"bd96801-buck3-overcurr-n"),
|
||||
"buck3-overcurr-n"),
|
||||
BD96801_IRQINFO(BD96801_PROT_OVP, "buck3-over-voltage", 500,
|
||||
"bd96801-buck3-overvolt"),
|
||||
"buck3-overvolt"),
|
||||
BD96801_IRQINFO(BD96801_PROT_UVP, "buck3-under-voltage", 500,
|
||||
"bd96801-buck3-undervolt"),
|
||||
"buck3-undervolt"),
|
||||
BD96801_IRQINFO(BD96801_PROT_TEMP, "buck3-over-temp", 500,
|
||||
"bd96801-buck3-thermal")
|
||||
"buck3-thermal")
|
||||
};
|
||||
|
||||
static const struct bd96801_irqinfo buck4_irqinfo[] = {
|
||||
BD96801_IRQINFO(BD96801_PROT_OCP, "buck4-over-curr-h", 500,
|
||||
"bd96801-buck4-overcurr-h"),
|
||||
"buck4-overcurr-h"),
|
||||
BD96801_IRQINFO(BD96801_PROT_OCP, "buck4-over-curr-l", 500,
|
||||
"bd96801-buck4-overcurr-l"),
|
||||
"buck4-overcurr-l"),
|
||||
BD96801_IRQINFO(BD96801_PROT_OCP, "buck4-over-curr-n", 500,
|
||||
"bd96801-buck4-overcurr-n"),
|
||||
"buck4-overcurr-n"),
|
||||
BD96801_IRQINFO(BD96801_PROT_OVP, "buck4-over-voltage", 500,
|
||||
"bd96801-buck4-overvolt"),
|
||||
"buck4-overvolt"),
|
||||
BD96801_IRQINFO(BD96801_PROT_UVP, "buck4-under-voltage", 500,
|
||||
"bd96801-buck4-undervolt"),
|
||||
"buck4-undervolt"),
|
||||
BD96801_IRQINFO(BD96801_PROT_TEMP, "buck4-over-temp", 500,
|
||||
"bd96801-buck4-thermal")
|
||||
"buck4-thermal")
|
||||
};
|
||||
|
||||
static const struct bd96801_irqinfo ldo5_irqinfo[] = {
|
||||
BD96801_IRQINFO(BD96801_PROT_OCP, "ldo5-overcurr", 500,
|
||||
"bd96801-ldo5-overcurr"),
|
||||
"ldo5-overcurr"),
|
||||
BD96801_IRQINFO(BD96801_PROT_OVP, "ldo5-over-voltage", 500,
|
||||
"bd96801-ldo5-overvolt"),
|
||||
"ldo5-overvolt"),
|
||||
BD96801_IRQINFO(BD96801_PROT_UVP, "ldo5-under-voltage", 500,
|
||||
"bd96801-ldo5-undervolt"),
|
||||
"ldo5-undervolt"),
|
||||
};
|
||||
|
||||
static const struct bd96801_irqinfo ldo6_irqinfo[] = {
|
||||
BD96801_IRQINFO(BD96801_PROT_OCP, "ldo6-overcurr", 500,
|
||||
"bd96801-ldo6-overcurr"),
|
||||
"ldo6-overcurr"),
|
||||
BD96801_IRQINFO(BD96801_PROT_OVP, "ldo6-over-voltage", 500,
|
||||
"bd96801-ldo6-overvolt"),
|
||||
"ldo6-overvolt"),
|
||||
BD96801_IRQINFO(BD96801_PROT_UVP, "ldo6-under-voltage", 500,
|
||||
"bd96801-ldo6-undervolt"),
|
||||
"ldo6-undervolt"),
|
||||
};
|
||||
|
||||
static const struct bd96801_irqinfo ldo7_irqinfo[] = {
|
||||
BD96801_IRQINFO(BD96801_PROT_OCP, "ldo7-overcurr", 500,
|
||||
"bd96801-ldo7-overcurr"),
|
||||
"ldo7-overcurr"),
|
||||
BD96801_IRQINFO(BD96801_PROT_OVP, "ldo7-over-voltage", 500,
|
||||
"bd96801-ldo7-overvolt"),
|
||||
"ldo7-overvolt"),
|
||||
BD96801_IRQINFO(BD96801_PROT_UVP, "ldo7-under-voltage", 500,
|
||||
"bd96801-ldo7-undervolt"),
|
||||
"ldo7-undervolt"),
|
||||
};
|
||||
|
||||
struct bd96801_irq_desc {
|
||||
@ -302,6 +328,7 @@ struct bd96801_pmic_data {
|
||||
struct bd96801_regulator_data regulator_data[BD96801_NUM_REGULATORS];
|
||||
struct regmap *regmap;
|
||||
int fatal_ind;
|
||||
int num_regulators;
|
||||
};
|
||||
|
||||
static int ldo_map_notif(int irq, struct regulator_irq_data *rid,
|
||||
@ -503,6 +530,70 @@ static int bd96801_walk_regulator_dt(struct device *dev, struct regmap *regmap,
|
||||
* case later. What we can easly do for preparing is to not use static global
|
||||
* data for regulators though.
|
||||
*/
|
||||
static const struct bd96801_pmic_data bd96802_data = {
|
||||
.regulator_data = {
|
||||
{
|
||||
.desc = {
|
||||
.name = "buck1",
|
||||
.of_match = of_match_ptr("buck1"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD96801_BUCK1,
|
||||
.ops = &bd96801_buck_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd96802_tune_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd96802_tune_volts),
|
||||
.n_voltages = BD96801_BUCK_VOLTS,
|
||||
.enable_reg = BD96801_REG_ENABLE,
|
||||
.enable_mask = BD96801_BUCK1_EN_MASK,
|
||||
.enable_is_inverted = true,
|
||||
.vsel_reg = BD96801_BUCK1_VSEL_REG,
|
||||
.vsel_mask = BD96801_BUCK_VSEL_MASK,
|
||||
.ramp_reg = BD96801_BUCK1_VSEL_REG,
|
||||
.ramp_mask = BD96801_MASK_RAMP_DELAY,
|
||||
.ramp_delay_table = &buck_ramp_table[0],
|
||||
.n_ramp_values = ARRAY_SIZE(buck_ramp_table),
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.init_ranges = bd96802_buck_init_volts,
|
||||
.num_ranges = ARRAY_SIZE(bd96802_buck_init_volts),
|
||||
.irq_desc = {
|
||||
.irqinfo = (struct bd96801_irqinfo *)&buck1_irqinfo[0],
|
||||
.num_irqs = ARRAY_SIZE(buck1_irqinfo),
|
||||
},
|
||||
},
|
||||
{
|
||||
.desc = {
|
||||
.name = "buck2",
|
||||
.of_match = of_match_ptr("buck2"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD96801_BUCK2,
|
||||
.ops = &bd96801_buck_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd96802_tune_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd96802_tune_volts),
|
||||
.n_voltages = BD96801_BUCK_VOLTS,
|
||||
.enable_reg = BD96801_REG_ENABLE,
|
||||
.enable_mask = BD96801_BUCK2_EN_MASK,
|
||||
.enable_is_inverted = true,
|
||||
.vsel_reg = BD96801_BUCK2_VSEL_REG,
|
||||
.vsel_mask = BD96801_BUCK_VSEL_MASK,
|
||||
.ramp_reg = BD96801_BUCK2_VSEL_REG,
|
||||
.ramp_mask = BD96801_MASK_RAMP_DELAY,
|
||||
.ramp_delay_table = &buck_ramp_table[0],
|
||||
.n_ramp_values = ARRAY_SIZE(buck_ramp_table),
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.irq_desc = {
|
||||
.irqinfo = (struct bd96801_irqinfo *)&buck2_irqinfo[0],
|
||||
.num_irqs = ARRAY_SIZE(buck2_irqinfo),
|
||||
},
|
||||
.init_ranges = bd96802_buck_init_volts,
|
||||
.num_ranges = ARRAY_SIZE(bd96802_buck_init_volts),
|
||||
},
|
||||
},
|
||||
.num_regulators = 2,
|
||||
};
|
||||
|
||||
static const struct bd96801_pmic_data bd96801_data = {
|
||||
.regulator_data = {
|
||||
{
|
||||
@ -688,11 +779,265 @@ static const struct bd96801_pmic_data bd96801_data = {
|
||||
.ldo_vol_lvl = BD96801_LDO7_VOL_LVL_REG,
|
||||
},
|
||||
},
|
||||
.num_regulators = 7,
|
||||
};
|
||||
|
||||
static int initialize_pmic_data(struct device *dev,
|
||||
static const struct bd96801_pmic_data bd96805_data = {
|
||||
.regulator_data = {
|
||||
{
|
||||
.desc = {
|
||||
.name = "buck1",
|
||||
.of_match = of_match_ptr("buck1"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD96801_BUCK1,
|
||||
.ops = &bd96801_buck_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd96805_tune_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd96805_tune_volts),
|
||||
.n_voltages = BD96805_BUCK_VOLTS,
|
||||
.enable_reg = BD96801_REG_ENABLE,
|
||||
.enable_mask = BD96801_BUCK1_EN_MASK,
|
||||
.enable_is_inverted = true,
|
||||
.vsel_reg = BD96801_BUCK1_VSEL_REG,
|
||||
.vsel_mask = BD96805_BUCK_VSEL_MASK,
|
||||
.ramp_reg = BD96801_BUCK1_VSEL_REG,
|
||||
.ramp_mask = BD96801_MASK_RAMP_DELAY,
|
||||
.ramp_delay_table = &buck_ramp_table[0],
|
||||
.n_ramp_values = ARRAY_SIZE(buck_ramp_table),
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.init_ranges = bd96805_buck_init_volts,
|
||||
.num_ranges = ARRAY_SIZE(bd96805_buck_init_volts),
|
||||
.irq_desc = {
|
||||
.irqinfo = (struct bd96801_irqinfo *)&buck1_irqinfo[0],
|
||||
.num_irqs = ARRAY_SIZE(buck1_irqinfo),
|
||||
},
|
||||
}, {
|
||||
.desc = {
|
||||
.name = "buck2",
|
||||
.of_match = of_match_ptr("buck2"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD96801_BUCK2,
|
||||
.ops = &bd96801_buck_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd96805_tune_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd96805_tune_volts),
|
||||
.n_voltages = BD96805_BUCK_VOLTS,
|
||||
.enable_reg = BD96801_REG_ENABLE,
|
||||
.enable_mask = BD96801_BUCK2_EN_MASK,
|
||||
.enable_is_inverted = true,
|
||||
.vsel_reg = BD96801_BUCK2_VSEL_REG,
|
||||
.vsel_mask = BD96805_BUCK_VSEL_MASK,
|
||||
.ramp_reg = BD96801_BUCK2_VSEL_REG,
|
||||
.ramp_mask = BD96801_MASK_RAMP_DELAY,
|
||||
.ramp_delay_table = &buck_ramp_table[0],
|
||||
.n_ramp_values = ARRAY_SIZE(buck_ramp_table),
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.irq_desc = {
|
||||
.irqinfo = (struct bd96801_irqinfo *)&buck2_irqinfo[0],
|
||||
.num_irqs = ARRAY_SIZE(buck2_irqinfo),
|
||||
},
|
||||
.init_ranges = bd96805_buck_init_volts,
|
||||
.num_ranges = ARRAY_SIZE(bd96805_buck_init_volts),
|
||||
}, {
|
||||
.desc = {
|
||||
.name = "buck3",
|
||||
.of_match = of_match_ptr("buck3"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD96801_BUCK3,
|
||||
.ops = &bd96801_buck_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd96805_tune_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd96805_tune_volts),
|
||||
.n_voltages = BD96805_BUCK_VOLTS,
|
||||
.enable_reg = BD96801_REG_ENABLE,
|
||||
.enable_mask = BD96801_BUCK3_EN_MASK,
|
||||
.enable_is_inverted = true,
|
||||
.vsel_reg = BD96801_BUCK3_VSEL_REG,
|
||||
.vsel_mask = BD96805_BUCK_VSEL_MASK,
|
||||
.ramp_reg = BD96801_BUCK3_VSEL_REG,
|
||||
.ramp_mask = BD96801_MASK_RAMP_DELAY,
|
||||
.ramp_delay_table = &buck_ramp_table[0],
|
||||
.n_ramp_values = ARRAY_SIZE(buck_ramp_table),
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.irq_desc = {
|
||||
.irqinfo = (struct bd96801_irqinfo *)&buck3_irqinfo[0],
|
||||
.num_irqs = ARRAY_SIZE(buck3_irqinfo),
|
||||
},
|
||||
.init_ranges = bd96805_buck_init_volts,
|
||||
.num_ranges = ARRAY_SIZE(bd96805_buck_init_volts),
|
||||
}, {
|
||||
.desc = {
|
||||
.name = "buck4",
|
||||
.of_match = of_match_ptr("buck4"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD96801_BUCK4,
|
||||
.ops = &bd96801_buck_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd96805_tune_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd96805_tune_volts),
|
||||
.n_voltages = BD96805_BUCK_VOLTS,
|
||||
.enable_reg = BD96801_REG_ENABLE,
|
||||
.enable_mask = BD96801_BUCK4_EN_MASK,
|
||||
.enable_is_inverted = true,
|
||||
.vsel_reg = BD96801_BUCK4_VSEL_REG,
|
||||
.vsel_mask = BD96805_BUCK_VSEL_MASK,
|
||||
.ramp_reg = BD96801_BUCK4_VSEL_REG,
|
||||
.ramp_mask = BD96801_MASK_RAMP_DELAY,
|
||||
.ramp_delay_table = &buck_ramp_table[0],
|
||||
.n_ramp_values = ARRAY_SIZE(buck_ramp_table),
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.irq_desc = {
|
||||
.irqinfo = (struct bd96801_irqinfo *)&buck4_irqinfo[0],
|
||||
.num_irqs = ARRAY_SIZE(buck4_irqinfo),
|
||||
},
|
||||
.init_ranges = bd96805_buck_init_volts,
|
||||
.num_ranges = ARRAY_SIZE(bd96805_buck_init_volts),
|
||||
}, {
|
||||
.desc = {
|
||||
.name = "ldo5",
|
||||
.of_match = of_match_ptr("ldo5"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD96801_LDO5,
|
||||
.ops = &bd96801_ldo_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd96801_ldo_int_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd96801_ldo_int_volts),
|
||||
.n_voltages = BD96801_LDO_VOLTS,
|
||||
.enable_reg = BD96801_REG_ENABLE,
|
||||
.enable_mask = BD96801_LDO5_EN_MASK,
|
||||
.enable_is_inverted = true,
|
||||
.vsel_reg = BD96801_LDO5_VSEL_REG,
|
||||
.vsel_mask = BD96801_LDO_VSEL_MASK,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.irq_desc = {
|
||||
.irqinfo = (struct bd96801_irqinfo *)&ldo5_irqinfo[0],
|
||||
.num_irqs = ARRAY_SIZE(ldo5_irqinfo),
|
||||
},
|
||||
.ldo_vol_lvl = BD96801_LDO5_VOL_LVL_REG,
|
||||
}, {
|
||||
.desc = {
|
||||
.name = "ldo6",
|
||||
.of_match = of_match_ptr("ldo6"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD96801_LDO6,
|
||||
.ops = &bd96801_ldo_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd96801_ldo_int_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd96801_ldo_int_volts),
|
||||
.n_voltages = BD96801_LDO_VOLTS,
|
||||
.enable_reg = BD96801_REG_ENABLE,
|
||||
.enable_mask = BD96801_LDO6_EN_MASK,
|
||||
.enable_is_inverted = true,
|
||||
.vsel_reg = BD96801_LDO6_VSEL_REG,
|
||||
.vsel_mask = BD96801_LDO_VSEL_MASK,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.irq_desc = {
|
||||
.irqinfo = (struct bd96801_irqinfo *)&ldo6_irqinfo[0],
|
||||
.num_irqs = ARRAY_SIZE(ldo6_irqinfo),
|
||||
},
|
||||
.ldo_vol_lvl = BD96801_LDO6_VOL_LVL_REG,
|
||||
}, {
|
||||
.desc = {
|
||||
.name = "ldo7",
|
||||
.of_match = of_match_ptr("ldo7"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD96801_LDO7,
|
||||
.ops = &bd96801_ldo_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd96801_ldo_int_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd96801_ldo_int_volts),
|
||||
.n_voltages = BD96801_LDO_VOLTS,
|
||||
.enable_reg = BD96801_REG_ENABLE,
|
||||
.enable_mask = BD96801_LDO7_EN_MASK,
|
||||
.enable_is_inverted = true,
|
||||
.vsel_reg = BD96801_LDO7_VSEL_REG,
|
||||
.vsel_mask = BD96801_LDO_VSEL_MASK,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.irq_desc = {
|
||||
.irqinfo = (struct bd96801_irqinfo *)&ldo7_irqinfo[0],
|
||||
.num_irqs = ARRAY_SIZE(ldo7_irqinfo),
|
||||
},
|
||||
.ldo_vol_lvl = BD96801_LDO7_VOL_LVL_REG,
|
||||
},
|
||||
},
|
||||
.num_regulators = 7,
|
||||
};
|
||||
|
||||
static const struct bd96801_pmic_data bd96806_data = {
|
||||
.regulator_data = {
|
||||
{
|
||||
.desc = {
|
||||
.name = "buck1",
|
||||
.of_match = of_match_ptr("buck1"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD96801_BUCK1,
|
||||
.ops = &bd96801_buck_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd96806_tune_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd96806_tune_volts),
|
||||
.n_voltages = BD96805_BUCK_VOLTS,
|
||||
.enable_reg = BD96801_REG_ENABLE,
|
||||
.enable_mask = BD96801_BUCK1_EN_MASK,
|
||||
.enable_is_inverted = true,
|
||||
.vsel_reg = BD96801_BUCK1_VSEL_REG,
|
||||
.vsel_mask = BD96805_BUCK_VSEL_MASK,
|
||||
.ramp_reg = BD96801_BUCK1_VSEL_REG,
|
||||
.ramp_mask = BD96801_MASK_RAMP_DELAY,
|
||||
.ramp_delay_table = &buck_ramp_table[0],
|
||||
.n_ramp_values = ARRAY_SIZE(buck_ramp_table),
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.init_ranges = bd96806_buck_init_volts,
|
||||
.num_ranges = ARRAY_SIZE(bd96806_buck_init_volts),
|
||||
.irq_desc = {
|
||||
.irqinfo = (struct bd96801_irqinfo *)&buck1_irqinfo[0],
|
||||
.num_irqs = ARRAY_SIZE(buck1_irqinfo),
|
||||
},
|
||||
},
|
||||
{
|
||||
.desc = {
|
||||
.name = "buck2",
|
||||
.of_match = of_match_ptr("buck2"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = BD96801_BUCK2,
|
||||
.ops = &bd96801_buck_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.linear_ranges = bd96806_tune_volts,
|
||||
.n_linear_ranges = ARRAY_SIZE(bd96806_tune_volts),
|
||||
.n_voltages = BD96805_BUCK_VOLTS,
|
||||
.enable_reg = BD96801_REG_ENABLE,
|
||||
.enable_mask = BD96801_BUCK2_EN_MASK,
|
||||
.enable_is_inverted = true,
|
||||
.vsel_reg = BD96801_BUCK2_VSEL_REG,
|
||||
.vsel_mask = BD96805_BUCK_VSEL_MASK,
|
||||
.ramp_reg = BD96801_BUCK2_VSEL_REG,
|
||||
.ramp_mask = BD96801_MASK_RAMP_DELAY,
|
||||
.ramp_delay_table = &buck_ramp_table[0],
|
||||
.n_ramp_values = ARRAY_SIZE(buck_ramp_table),
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.irq_desc = {
|
||||
.irqinfo = (struct bd96801_irqinfo *)&buck2_irqinfo[0],
|
||||
.num_irqs = ARRAY_SIZE(buck2_irqinfo),
|
||||
},
|
||||
.init_ranges = bd96806_buck_init_volts,
|
||||
.num_ranges = ARRAY_SIZE(bd96806_buck_init_volts),
|
||||
},
|
||||
},
|
||||
.num_regulators = 2,
|
||||
};
|
||||
|
||||
static int initialize_pmic_data(struct platform_device *pdev,
|
||||
struct bd96801_pmic_data *pdata)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
int r, i;
|
||||
|
||||
/*
|
||||
@ -700,7 +1045,7 @@ static int initialize_pmic_data(struct device *dev,
|
||||
* wish to modify IRQ information independently for each driver
|
||||
* instance.
|
||||
*/
|
||||
for (r = 0; r < BD96801_NUM_REGULATORS; r++) {
|
||||
for (r = 0; r < pdata->num_regulators; r++) {
|
||||
const struct bd96801_irqinfo *template;
|
||||
struct bd96801_irqinfo *new;
|
||||
int num_infos;
|
||||
@ -741,8 +1086,7 @@ static int bd96801_rdev_errb_irqs(struct platform_device *pdev,
|
||||
int i;
|
||||
void *retp;
|
||||
static const char * const single_out_errb_irqs[] = {
|
||||
"bd96801-%s-pvin-err", "bd96801-%s-ovp-err",
|
||||
"bd96801-%s-uvp-err", "bd96801-%s-shdn-err",
|
||||
"%s-pvin-err", "%s-ovp-err", "%s-uvp-err", "%s-shdn-err",
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(single_out_errb_irqs); i++) {
|
||||
@ -779,12 +1123,10 @@ static int bd96801_global_errb_irqs(struct platform_device *pdev,
|
||||
int i, num_irqs;
|
||||
void *retp;
|
||||
static const char * const global_errb_irqs[] = {
|
||||
"bd96801-otp-err", "bd96801-dbist-err", "bd96801-eep-err",
|
||||
"bd96801-abist-err", "bd96801-prstb-err", "bd96801-drmoserr1",
|
||||
"bd96801-drmoserr2", "bd96801-slave-err", "bd96801-vref-err",
|
||||
"bd96801-tsd", "bd96801-uvlo-err", "bd96801-ovlo-err",
|
||||
"bd96801-osc-err", "bd96801-pon-err", "bd96801-poff-err",
|
||||
"bd96801-cmd-shdn-err", "bd96801-int-shdn-err"
|
||||
"otp-err", "dbist-err", "eep-err", "abist-err", "prstb-err",
|
||||
"drmoserr1", "drmoserr2", "slave-err", "vref-err", "tsd",
|
||||
"uvlo-err", "ovlo-err", "osc-err", "pon-err", "poff-err",
|
||||
"cmd-shdn-err", "int-shdn-err"
|
||||
};
|
||||
|
||||
num_irqs = ARRAY_SIZE(global_errb_irqs);
|
||||
@ -869,6 +1211,7 @@ static int bd96801_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct regulator_dev *ldo_errs_rdev_arr[BD96801_NUM_LDOS];
|
||||
struct regulator_dev *all_rdevs[BD96801_NUM_REGULATORS];
|
||||
struct bd96801_pmic_data *pdata_template;
|
||||
struct bd96801_regulator_data *rdesc;
|
||||
struct regulator_config config = {};
|
||||
int ldo_errs_arr[BD96801_NUM_LDOS];
|
||||
@ -881,12 +1224,16 @@ static int bd96801_probe(struct platform_device *pdev)
|
||||
|
||||
parent = pdev->dev.parent;
|
||||
|
||||
pdata = devm_kmemdup(&pdev->dev, &bd96801_data, sizeof(bd96801_data),
|
||||
pdata_template = (struct bd96801_pmic_data *)platform_get_device_id(pdev)->driver_data;
|
||||
if (!pdata_template)
|
||||
return -ENODEV;
|
||||
|
||||
pdata = devm_kmemdup(&pdev->dev, pdata_template, sizeof(bd96801_data),
|
||||
GFP_KERNEL);
|
||||
if (!pdata)
|
||||
return -ENOMEM;
|
||||
|
||||
if (initialize_pmic_data(&pdev->dev, pdata))
|
||||
if (initialize_pmic_data(pdev, pdata))
|
||||
return -ENOMEM;
|
||||
|
||||
pdata->regmap = dev_get_regmap(parent, NULL);
|
||||
@ -909,11 +1256,11 @@ static int bd96801_probe(struct platform_device *pdev)
|
||||
use_errb = true;
|
||||
|
||||
ret = bd96801_walk_regulator_dt(&pdev->dev, pdata->regmap, rdesc,
|
||||
BD96801_NUM_REGULATORS);
|
||||
pdata->num_regulators);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(pdata->regulator_data); i++) {
|
||||
for (i = 0; i < pdata->num_regulators; i++) {
|
||||
struct regulator_dev *rdev;
|
||||
struct bd96801_irq_desc *idesc = &rdesc[i].irq_desc;
|
||||
int j;
|
||||
@ -926,6 +1273,7 @@ static int bd96801_probe(struct platform_device *pdev)
|
||||
rdesc[i].desc.name);
|
||||
return PTR_ERR(rdev);
|
||||
}
|
||||
|
||||
all_rdevs[i] = rdev;
|
||||
/*
|
||||
* LDOs don't have own temperature monitoring. If temperature
|
||||
@ -956,12 +1304,12 @@ static int bd96801_probe(struct platform_device *pdev)
|
||||
if (temp_notif_ldos) {
|
||||
int irq;
|
||||
struct regulator_irq_desc tw_desc = {
|
||||
.name = "bd96801-core-thermal",
|
||||
.name = "core-thermal",
|
||||
.irq_off_ms = 500,
|
||||
.map_event = ldo_map_notif,
|
||||
};
|
||||
|
||||
irq = platform_get_irq_byname(pdev, "bd96801-core-thermal");
|
||||
irq = platform_get_irq_byname(pdev, "core-thermal");
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
@ -975,14 +1323,17 @@ static int bd96801_probe(struct platform_device *pdev)
|
||||
|
||||
if (use_errb)
|
||||
return bd96801_global_errb_irqs(pdev, all_rdevs,
|
||||
ARRAY_SIZE(all_rdevs));
|
||||
pdata->num_regulators);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct platform_device_id bd96801_pmic_id[] = {
|
||||
{ "bd96801-regulator", },
|
||||
{ }
|
||||
{ "bd96801-regulator", (kernel_ulong_t)&bd96801_data },
|
||||
{ "bd96802-regulator", (kernel_ulong_t)&bd96802_data },
|
||||
{ "bd96805-regulator", (kernel_ulong_t)&bd96805_data },
|
||||
{ "bd96806-regulator", (kernel_ulong_t)&bd96806_data },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, bd96801_pmic_id);
|
||||
|
||||
|
||||
@ -133,9 +133,6 @@ struct aat2870_data {
|
||||
int (*read)(struct aat2870_data *aat2870, u8 addr, u8 *val);
|
||||
int (*write)(struct aat2870_data *aat2870, u8 addr, u8 val);
|
||||
int (*update)(struct aat2870_data *aat2870, u8 addr, u8 mask, u8 val);
|
||||
|
||||
/* for debugfs */
|
||||
struct dentry *dentry_root;
|
||||
};
|
||||
|
||||
struct aat2870_subdev_info {
|
||||
|
||||
@ -13,6 +13,26 @@
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
/* PMU ID register values; also used as device type */
|
||||
#define BCM590XX_PMUID_BCM59054 0x54
|
||||
#define BCM590XX_PMUID_BCM59056 0x56
|
||||
|
||||
/* Known chip revision IDs */
|
||||
#define BCM59054_REV_DIGITAL_A1 1
|
||||
#define BCM59054_REV_ANALOG_A1 2
|
||||
|
||||
#define BCM59056_REV_DIGITAL_A0 1
|
||||
#define BCM59056_REV_ANALOG_A0 1
|
||||
|
||||
#define BCM59056_REV_DIGITAL_B0 2
|
||||
#define BCM59056_REV_ANALOG_B0 2
|
||||
|
||||
/* regmap types */
|
||||
enum bcm590xx_regmap_type {
|
||||
BCM590XX_REGMAP_PRI,
|
||||
BCM590XX_REGMAP_SEC,
|
||||
};
|
||||
|
||||
/* max register address */
|
||||
#define BCM590XX_MAX_REGISTER_PRI 0xe7
|
||||
#define BCM590XX_MAX_REGISTER_SEC 0xf0
|
||||
@ -23,7 +43,13 @@ struct bcm590xx {
|
||||
struct i2c_client *i2c_sec;
|
||||
struct regmap *regmap_pri;
|
||||
struct regmap *regmap_sec;
|
||||
unsigned int id;
|
||||
|
||||
/* PMU ID value; also used as device type */
|
||||
u8 pmu_id;
|
||||
|
||||
/* Chip revision, read from PMUREV reg */
|
||||
u8 rev_digital;
|
||||
u8 rev_analog;
|
||||
};
|
||||
|
||||
#endif /* __LINUX_MFD_BCM590XX_H */
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/*
|
||||
* max14577-private.h - Common API for the Maxim 14577/77836 internal sub chip
|
||||
*
|
||||
* Copyright (C) 2014 Samsung Electrnoics
|
||||
* Copyright (C) 2014 Samsung Electronics
|
||||
* Chanwoo Choi <cw00.choi@samsung.com>
|
||||
* Krzysztof Kozlowski <krzk@kernel.org>
|
||||
*/
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/*
|
||||
* max14577.h - Driver for the Maxim 14577/77836
|
||||
*
|
||||
* Copyright (C) 2014 Samsung Electrnoics
|
||||
* Copyright (C) 2014 Samsung Electronics
|
||||
* Chanwoo Choi <cw00.choi@samsung.com>
|
||||
* Krzysztof Kozlowski <krzk@kernel.org>
|
||||
*
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/*
|
||||
* max77686-private.h - Voltage regulator driver for the Maxim 77686/802
|
||||
*
|
||||
* Copyright (C) 2012 Samsung Electrnoics
|
||||
* Copyright (C) 2012 Samsung Electronics
|
||||
* Chiwoong Byun <woong.byun@samsung.com>
|
||||
*/
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/*
|
||||
* max77686.h - Driver for the Maxim 77686/802
|
||||
*
|
||||
* Copyright (C) 2012 Samsung Electrnoics
|
||||
* Copyright (C) 2012 Samsung Electronics
|
||||
* Chiwoong Byun <woong.byun@samsung.com>
|
||||
*
|
||||
* This driver is based on max8997.h
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/*
|
||||
* max77693-private.h - Voltage regulator driver for the Maxim 77693
|
||||
*
|
||||
* Copyright (C) 2012 Samsung Electrnoics
|
||||
* Copyright (C) 2012 Samsung Electronics
|
||||
* SangYoung Son <hello.son@samsung.com>
|
||||
*
|
||||
* This program is not provided / owned by Maxim Integrated Products.
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/*
|
||||
* max77693.h - Driver for the Maxim 77693
|
||||
*
|
||||
* Copyright (C) 2012 Samsung Electrnoics
|
||||
* Copyright (C) 2012 Samsung Electronics
|
||||
* SangYoung Son <hello.son@samsung.com>
|
||||
*
|
||||
* This program is not provided / owned by Maxim Integrated Products.
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/*
|
||||
* max8997-private.h - Voltage regulator driver for the Maxim 8997
|
||||
*
|
||||
* Copyright (C) 2010 Samsung Electrnoics
|
||||
* Copyright (C) 2010 Samsung Electronics
|
||||
* MyungJoo Ham <myungjoo.ham@samsung.com>
|
||||
*/
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/*
|
||||
* max8997.h - Driver for the Maxim 8997/8966
|
||||
*
|
||||
* Copyright (C) 2009-2010 Samsung Electrnoics
|
||||
* Copyright (C) 2009-2010 Samsung Electronics
|
||||
* MyungJoo Ham <myungjoo.ham@samsung.com>
|
||||
*
|
||||
* This driver is based on max8998.h
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/*
|
||||
* max8998-private.h - Voltage regulator driver for the Maxim 8998
|
||||
*
|
||||
* Copyright (C) 2009-2010 Samsung Electrnoics
|
||||
* Copyright (C) 2009-2010 Samsung Electronics
|
||||
* Kyungmin Park <kyungmin.park@samsung.com>
|
||||
* Marek Szyprowski <m.szyprowski@samsung.com>
|
||||
*/
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/*
|
||||
* max8998.h - Voltage regulator driver for the Maxim 8998
|
||||
*
|
||||
* Copyright (C) 2009-2010 Samsung Electrnoics
|
||||
* Copyright (C) 2009-2010 Samsung Electronics
|
||||
* Kyungmin Park <kyungmin.park@samsung.com>
|
||||
* Marek Szyprowski <m.szyprowski@samsung.com>
|
||||
*/
|
||||
|
||||
@ -40,7 +40,9 @@
|
||||
* INTB status registers are at range 0x5c ... 0x63
|
||||
*/
|
||||
#define BD96801_REG_INT_SYS_ERRB1 0x52
|
||||
#define BD96801_REG_INT_BUCK2_ERRB 0x56
|
||||
#define BD96801_REG_INT_SYS_INTB 0x5c
|
||||
#define BD96801_REG_INT_BUCK2_INTB 0x5e
|
||||
#define BD96801_REG_INT_LDO7_INTB 0x63
|
||||
|
||||
/* MASK registers */
|
||||
|
||||
74
include/linux/mfd/rohm-bd96802.h
Normal file
74
include/linux/mfd/rohm-bd96802.h
Normal file
@ -0,0 +1,74 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (C) 2025 ROHM Semiconductors
|
||||
*
|
||||
* The digital interface of trhe BD96802 PMIC is a reduced version of the
|
||||
* BD96801. Hence the BD96801 definitions are used for registers and masks
|
||||
* while this header only holds the IRQ definitions - mainly to avoid gaps in
|
||||
* IRQ numbers caused by the lack of some BUCKs / LDOs and their respective
|
||||
* IRQs.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_MFD_BD96802_H__
|
||||
#define __LINUX_MFD_BD96802_H__
|
||||
|
||||
/* ERRB IRQs */
|
||||
enum {
|
||||
/* Reg 0x52, 0x53, 0x54 - ERRB system IRQs */
|
||||
BD96802_OTP_ERR_STAT,
|
||||
BD96802_DBIST_ERR_STAT,
|
||||
BD96802_EEP_ERR_STAT,
|
||||
BD96802_ABIST_ERR_STAT,
|
||||
BD96802_PRSTB_ERR_STAT,
|
||||
BD96802_DRMOS1_ERR_STAT,
|
||||
BD96802_DRMOS2_ERR_STAT,
|
||||
BD96802_SLAVE_ERR_STAT,
|
||||
BD96802_VREF_ERR_STAT,
|
||||
BD96802_TSD_ERR_STAT,
|
||||
BD96802_UVLO_ERR_STAT,
|
||||
BD96802_OVLO_ERR_STAT,
|
||||
BD96802_OSC_ERR_STAT,
|
||||
BD96802_PON_ERR_STAT,
|
||||
BD96802_POFF_ERR_STAT,
|
||||
BD96802_CMD_SHDN_ERR_STAT,
|
||||
BD96802_INT_SHDN_ERR_STAT,
|
||||
|
||||
/* Reg 0x55 BUCK1 ERR IRQs */
|
||||
BD96802_BUCK1_PVIN_ERR_STAT,
|
||||
BD96802_BUCK1_OVP_ERR_STAT,
|
||||
BD96802_BUCK1_UVP_ERR_STAT,
|
||||
BD96802_BUCK1_SHDN_ERR_STAT,
|
||||
|
||||
/* Reg 0x56 BUCK2 ERR IRQs */
|
||||
BD96802_BUCK2_PVIN_ERR_STAT,
|
||||
BD96802_BUCK2_OVP_ERR_STAT,
|
||||
BD96802_BUCK2_UVP_ERR_STAT,
|
||||
BD96802_BUCK2_SHDN_ERR_STAT,
|
||||
};
|
||||
|
||||
/* INTB IRQs */
|
||||
enum {
|
||||
/* Reg 0x5c (System INTB) */
|
||||
BD96802_TW_STAT,
|
||||
BD96802_WDT_ERR_STAT,
|
||||
BD96802_I2C_ERR_STAT,
|
||||
BD96802_CHIP_IF_ERR_STAT,
|
||||
|
||||
/* Reg 0x5d (BUCK1 INTB) */
|
||||
BD96802_BUCK1_OCPH_STAT,
|
||||
BD96802_BUCK1_OCPL_STAT,
|
||||
BD96802_BUCK1_OCPN_STAT,
|
||||
BD96802_BUCK1_OVD_STAT,
|
||||
BD96802_BUCK1_UVD_STAT,
|
||||
BD96802_BUCK1_TW_CH_STAT,
|
||||
|
||||
/* Reg 0x5e (BUCK2 INTB) */
|
||||
BD96802_BUCK2_OCPH_STAT,
|
||||
BD96802_BUCK2_OCPL_STAT,
|
||||
BD96802_BUCK2_OCPN_STAT,
|
||||
BD96802_BUCK2_OVD_STAT,
|
||||
BD96802_BUCK2_UVD_STAT,
|
||||
BD96802_BUCK2_TW_CH_STAT,
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -17,6 +17,9 @@ enum rohm_chip_type {
|
||||
ROHM_CHIP_TYPE_BD71837,
|
||||
ROHM_CHIP_TYPE_BD71847,
|
||||
ROHM_CHIP_TYPE_BD96801,
|
||||
ROHM_CHIP_TYPE_BD96802,
|
||||
ROHM_CHIP_TYPE_BD96805,
|
||||
ROHM_CHIP_TYPE_BD96806,
|
||||
ROHM_CHIP_TYPE_AMOUNT
|
||||
};
|
||||
|
||||
|
||||
@ -39,6 +39,7 @@ enum sec_device_type {
|
||||
S5M8767X,
|
||||
S2DOS05,
|
||||
S2MPA01,
|
||||
S2MPG10,
|
||||
S2MPS11X,
|
||||
S2MPS13X,
|
||||
S2MPS14X,
|
||||
@ -66,15 +67,11 @@ struct sec_pmic_dev {
|
||||
struct regmap *regmap_pmic;
|
||||
struct i2c_client *i2c;
|
||||
|
||||
unsigned long device_type;
|
||||
int device_type;
|
||||
int irq;
|
||||
struct regmap_irq_chip_data *irq_data;
|
||||
};
|
||||
|
||||
int sec_irq_init(struct sec_pmic_dev *sec_pmic);
|
||||
void sec_irq_exit(struct sec_pmic_dev *sec_pmic);
|
||||
int sec_irq_resume(struct sec_pmic_dev *sec_pmic);
|
||||
|
||||
struct sec_platform_data {
|
||||
struct sec_regulator_data *regulators;
|
||||
struct sec_opmode_data *opmode;
|
||||
|
||||
@ -57,6 +57,109 @@ enum s2mpa01_irq {
|
||||
#define S2MPA01_IRQ_B24_TSD_MASK (1 << 4)
|
||||
#define S2MPA01_IRQ_B35_TSD_MASK (1 << 5)
|
||||
|
||||
enum s2mpg10_irq {
|
||||
/* PMIC */
|
||||
S2MPG10_IRQ_PWRONF,
|
||||
S2MPG10_IRQ_PWRONR,
|
||||
S2MPG10_IRQ_JIGONBF,
|
||||
S2MPG10_IRQ_JIGONBR,
|
||||
S2MPG10_IRQ_ACOKBF,
|
||||
S2MPG10_IRQ_ACOKBR,
|
||||
S2MPG10_IRQ_PWRON1S,
|
||||
S2MPG10_IRQ_MRB,
|
||||
#define S2MPG10_IRQ_PWRONF_MASK BIT(0)
|
||||
#define S2MPG10_IRQ_PWRONR_MASK BIT(1)
|
||||
#define S2MPG10_IRQ_JIGONBF_MASK BIT(2)
|
||||
#define S2MPG10_IRQ_JIGONBR_MASK BIT(3)
|
||||
#define S2MPG10_IRQ_ACOKBF_MASK BIT(4)
|
||||
#define S2MPG10_IRQ_ACOKBR_MASK BIT(5)
|
||||
#define S2MPG10_IRQ_PWRON1S_MASK BIT(6)
|
||||
#define S2MPG10_IRQ_MRB_MASK BIT(7)
|
||||
|
||||
S2MPG10_IRQ_RTC60S,
|
||||
S2MPG10_IRQ_RTCA1,
|
||||
S2MPG10_IRQ_RTCA0,
|
||||
S2MPG10_IRQ_RTC1S,
|
||||
S2MPG10_IRQ_WTSR_COLDRST,
|
||||
S2MPG10_IRQ_WTSR,
|
||||
S2MPG10_IRQ_WRST,
|
||||
S2MPG10_IRQ_SMPL,
|
||||
#define S2MPG10_IRQ_RTC60S_MASK BIT(0)
|
||||
#define S2MPG10_IRQ_RTCA1_MASK BIT(1)
|
||||
#define S2MPG10_IRQ_RTCA0_MASK BIT(2)
|
||||
#define S2MPG10_IRQ_RTC1S_MASK BIT(3)
|
||||
#define S2MPG10_IRQ_WTSR_COLDRST_MASK BIT(4)
|
||||
#define S2MPG10_IRQ_WTSR_MASK BIT(5)
|
||||
#define S2MPG10_IRQ_WRST_MASK BIT(6)
|
||||
#define S2MPG10_IRQ_SMPL_MASK BIT(7)
|
||||
|
||||
S2MPG10_IRQ_120C,
|
||||
S2MPG10_IRQ_140C,
|
||||
S2MPG10_IRQ_TSD,
|
||||
S2MPG10_IRQ_PIF_TIMEOUT1,
|
||||
S2MPG10_IRQ_PIF_TIMEOUT2,
|
||||
S2MPG10_IRQ_SPD_PARITY_ERR,
|
||||
S2MPG10_IRQ_SPD_ABNORMAL_STOP,
|
||||
S2MPG10_IRQ_PMETER_OVERF,
|
||||
#define S2MPG10_IRQ_INT120C_MASK BIT(0)
|
||||
#define S2MPG10_IRQ_INT140C_MASK BIT(1)
|
||||
#define S2MPG10_IRQ_TSD_MASK BIT(2)
|
||||
#define S2MPG10_IRQ_PIF_TIMEOUT1_MASK BIT(3)
|
||||
#define S2MPG10_IRQ_PIF_TIMEOUT2_MASK BIT(4)
|
||||
#define S2MPG10_IRQ_SPD_PARITY_ERR_MASK BIT(5)
|
||||
#define S2MPG10_IRQ_SPD_ABNORMAL_STOP_MASK BIT(6)
|
||||
#define S2MPG10_IRQ_PMETER_OVERF_MASK BIT(7)
|
||||
|
||||
S2MPG10_IRQ_OCP_B1M,
|
||||
S2MPG10_IRQ_OCP_B2M,
|
||||
S2MPG10_IRQ_OCP_B3M,
|
||||
S2MPG10_IRQ_OCP_B4M,
|
||||
S2MPG10_IRQ_OCP_B5M,
|
||||
S2MPG10_IRQ_OCP_B6M,
|
||||
S2MPG10_IRQ_OCP_B7M,
|
||||
S2MPG10_IRQ_OCP_B8M,
|
||||
#define S2MPG10_IRQ_OCP_B1M_MASK BIT(0)
|
||||
#define S2MPG10_IRQ_OCP_B2M_MASK BIT(1)
|
||||
#define S2MPG10_IRQ_OCP_B3M_MASK BIT(2)
|
||||
#define S2MPG10_IRQ_OCP_B4M_MASK BIT(3)
|
||||
#define S2MPG10_IRQ_OCP_B5M_MASK BIT(4)
|
||||
#define S2MPG10_IRQ_OCP_B6M_MASK BIT(5)
|
||||
#define S2MPG10_IRQ_OCP_B7M_MASK BIT(6)
|
||||
#define S2MPG10_IRQ_OCP_B8M_MASK BIT(7)
|
||||
|
||||
S2MPG10_IRQ_OCP_B9M,
|
||||
S2MPG10_IRQ_OCP_B10M,
|
||||
S2MPG10_IRQ_WLWP_ACC,
|
||||
S2MPG10_IRQ_SMPL_TIMEOUT,
|
||||
S2MPG10_IRQ_WTSR_TIMEOUT,
|
||||
S2MPG10_IRQ_SPD_SRP_PKT_RST,
|
||||
#define S2MPG10_IRQ_OCP_B9M_MASK BIT(0)
|
||||
#define S2MPG10_IRQ_OCP_B10M_MASK BIT(1)
|
||||
#define S2MPG10_IRQ_WLWP_ACC_MASK BIT(2)
|
||||
#define S2MPG10_IRQ_SMPL_TIMEOUT_MASK BIT(5)
|
||||
#define S2MPG10_IRQ_WTSR_TIMEOUT_MASK BIT(6)
|
||||
#define S2MPG10_IRQ_SPD_SRP_PKT_RST_MASK BIT(7)
|
||||
|
||||
S2MPG10_IRQ_PWR_WARN_CH0,
|
||||
S2MPG10_IRQ_PWR_WARN_CH1,
|
||||
S2MPG10_IRQ_PWR_WARN_CH2,
|
||||
S2MPG10_IRQ_PWR_WARN_CH3,
|
||||
S2MPG10_IRQ_PWR_WARN_CH4,
|
||||
S2MPG10_IRQ_PWR_WARN_CH5,
|
||||
S2MPG10_IRQ_PWR_WARN_CH6,
|
||||
S2MPG10_IRQ_PWR_WARN_CH7,
|
||||
#define S2MPG10_IRQ_PWR_WARN_CH0_MASK BIT(0)
|
||||
#define S2MPG10_IRQ_PWR_WARN_CH1_MASK BIT(1)
|
||||
#define S2MPG10_IRQ_PWR_WARN_CH2_MASK BIT(2)
|
||||
#define S2MPG10_IRQ_PWR_WARN_CH3_MASK BIT(3)
|
||||
#define S2MPG10_IRQ_PWR_WARN_CH4_MASK BIT(4)
|
||||
#define S2MPG10_IRQ_PWR_WARN_CH5_MASK BIT(5)
|
||||
#define S2MPG10_IRQ_PWR_WARN_CH6_MASK BIT(6)
|
||||
#define S2MPG10_IRQ_PWR_WARN_CH7_MASK BIT(7)
|
||||
|
||||
S2MPG10_IRQ_NR,
|
||||
};
|
||||
|
||||
enum s2mps11_irq {
|
||||
S2MPS11_IRQ_PWRONF,
|
||||
S2MPS11_IRQ_PWRONR,
|
||||
|
||||
@ -72,6 +72,37 @@ enum s2mps_rtc_reg {
|
||||
S2MPS_RTC_REG_MAX,
|
||||
};
|
||||
|
||||
enum s2mpg10_rtc_reg {
|
||||
S2MPG10_RTC_CTRL,
|
||||
S2MPG10_RTC_UPDATE,
|
||||
S2MPG10_RTC_SMPL,
|
||||
S2MPG10_RTC_WTSR,
|
||||
S2MPG10_RTC_CAP_SEL,
|
||||
S2MPG10_RTC_MSEC,
|
||||
S2MPG10_RTC_SEC,
|
||||
S2MPG10_RTC_MIN,
|
||||
S2MPG10_RTC_HOUR,
|
||||
S2MPG10_RTC_WEEK,
|
||||
S2MPG10_RTC_DAY,
|
||||
S2MPG10_RTC_MON,
|
||||
S2MPG10_RTC_YEAR,
|
||||
S2MPG10_RTC_A0SEC,
|
||||
S2MPG10_RTC_A0MIN,
|
||||
S2MPG10_RTC_A0HOUR,
|
||||
S2MPG10_RTC_A0WEEK,
|
||||
S2MPG10_RTC_A0DAY,
|
||||
S2MPG10_RTC_A0MON,
|
||||
S2MPG10_RTC_A0YEAR,
|
||||
S2MPG10_RTC_A1SEC,
|
||||
S2MPG10_RTC_A1MIN,
|
||||
S2MPG10_RTC_A1HOUR,
|
||||
S2MPG10_RTC_A1WEEK,
|
||||
S2MPG10_RTC_A1DAY,
|
||||
S2MPG10_RTC_A1MON,
|
||||
S2MPG10_RTC_A1YEAR,
|
||||
S2MPG10_RTC_OSC_CTRL,
|
||||
};
|
||||
|
||||
#define RTC_I2C_ADDR (0x0C >> 1)
|
||||
|
||||
#define HOUR_12 (1 << 7)
|
||||
@ -124,10 +155,16 @@ enum s2mps_rtc_reg {
|
||||
#define ALARM_ENABLE_SHIFT 7
|
||||
#define ALARM_ENABLE_MASK (1 << ALARM_ENABLE_SHIFT)
|
||||
|
||||
/* WTSR & SMPL registers */
|
||||
#define SMPL_ENABLE_SHIFT 7
|
||||
#define SMPL_ENABLE_MASK (1 << SMPL_ENABLE_SHIFT)
|
||||
|
||||
#define WTSR_ENABLE_SHIFT 6
|
||||
#define WTSR_ENABLE_MASK (1 << WTSR_ENABLE_SHIFT)
|
||||
|
||||
#define S2MPG10_WTSR_COLDTIMER GENMASK(6, 5)
|
||||
#define S2MPG10_WTSR_COLDRST BIT(4)
|
||||
#define S2MPG10_WTSR_WTSRT GENMASK(3, 1)
|
||||
#define S2MPG10_WTSR_WTSR_EN BIT(0)
|
||||
|
||||
#endif /* __LINUX_MFD_SEC_RTC_H */
|
||||
|
||||
454
include/linux/mfd/samsung/s2mpg10.h
Normal file
454
include/linux/mfd/samsung/s2mpg10.h
Normal file
@ -0,0 +1,454 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2015 Samsung Electronics
|
||||
* Copyright 2020 Google Inc
|
||||
* Copyright 2025 Linaro Ltd.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_MFD_S2MPG10_H
|
||||
#define __LINUX_MFD_S2MPG10_H
|
||||
|
||||
/* Common registers (type 0x000) */
|
||||
enum s2mpg10_common_reg {
|
||||
S2MPG10_COMMON_CHIPID,
|
||||
S2MPG10_COMMON_INT,
|
||||
S2MPG10_COMMON_INT_MASK,
|
||||
S2MPG10_COMMON_SPD_CTRL1 = 0x0a,
|
||||
S2MPG10_COMMON_SPD_CTRL2,
|
||||
S2MPG10_COMMON_SPD_CTRL3,
|
||||
S2MPG10_COMMON_MON1SEL = 0x1a,
|
||||
S2MPG10_COMMON_MON2SEL,
|
||||
S2MPG10_COMMON_MONR,
|
||||
S2MPG10_COMMON_DEBUG_CTRL1,
|
||||
S2MPG10_COMMON_DEBUG_CTRL2,
|
||||
S2MPG10_COMMON_DEBUG_CTRL3,
|
||||
S2MPG10_COMMON_DEBUG_CTRL4,
|
||||
S2MPG10_COMMON_DEBUG_CTRL5,
|
||||
S2MPG10_COMMON_DEBUG_CTRL6,
|
||||
S2MPG10_COMMON_DEBUG_CTRL7,
|
||||
S2MPG10_COMMON_DEBUG_CTRL8,
|
||||
S2MPG10_COMMON_TEST_MODE1,
|
||||
S2MPG10_COMMON_TEST_MODE2,
|
||||
S2MPG10_COMMON_SPD_DEBUG1,
|
||||
S2MPG10_COMMON_SPD_DEBUG2,
|
||||
S2MPG10_COMMON_SPD_DEBUG3,
|
||||
S2MPG10_COMMON_SPD_DEBUG4,
|
||||
};
|
||||
|
||||
/* For S2MPG10_COMMON_INT and S2MPG10_COMMON_INT_MASK */
|
||||
#define S2MPG10_COMMON_INT_SRC GENMASK(7, 0)
|
||||
#define S2MPG10_COMMON_INT_SRC_PMIC BIT(0)
|
||||
|
||||
/* PMIC registers (type 0x100) */
|
||||
enum s2mpg10_pmic_reg {
|
||||
S2MPG10_PMIC_INT1,
|
||||
S2MPG10_PMIC_INT2,
|
||||
S2MPG10_PMIC_INT3,
|
||||
S2MPG10_PMIC_INT4,
|
||||
S2MPG10_PMIC_INT5,
|
||||
S2MPG10_PMIC_INT6,
|
||||
S2MPG10_PMIC_INT1M,
|
||||
S2MPG10_PMIC_INT2M,
|
||||
S2MPG10_PMIC_INT3M,
|
||||
S2MPG10_PMIC_INT4M,
|
||||
S2MPG10_PMIC_INT5M,
|
||||
S2MPG10_PMIC_INT6M,
|
||||
S2MPG10_PMIC_STATUS1,
|
||||
S2MPG10_PMIC_STATUS2,
|
||||
S2MPG10_PMIC_PWRONSRC,
|
||||
S2MPG10_PMIC_OFFSRC,
|
||||
S2MPG10_PMIC_BU_CHG,
|
||||
S2MPG10_PMIC_RTCBUF,
|
||||
S2MPG10_PMIC_COMMON_CTRL1,
|
||||
S2MPG10_PMIC_COMMON_CTRL2,
|
||||
S2MPG10_PMIC_COMMON_CTRL3,
|
||||
S2MPG10_PMIC_COMMON_CTRL4,
|
||||
S2MPG10_PMIC_SMPL_WARN_CTRL,
|
||||
S2MPG10_PMIC_MIMICKING_CTRL,
|
||||
S2MPG10_PMIC_B1M_CTRL,
|
||||
S2MPG10_PMIC_B1M_OUT1,
|
||||
S2MPG10_PMIC_B1M_OUT2,
|
||||
S2MPG10_PMIC_B2M_CTRL,
|
||||
S2MPG10_PMIC_B2M_OUT1,
|
||||
S2MPG10_PMIC_B2M_OUT2,
|
||||
S2MPG10_PMIC_B3M_CTRL,
|
||||
S2MPG10_PMIC_B3M_OUT1,
|
||||
S2MPG10_PMIC_B3M_OUT2,
|
||||
S2MPG10_PMIC_B4M_CTRL,
|
||||
S2MPG10_PMIC_B4M_OUT1,
|
||||
S2MPG10_PMIC_B4M_OUT2,
|
||||
S2MPG10_PMIC_B5M_CTRL,
|
||||
S2MPG10_PMIC_B5M_OUT1,
|
||||
S2MPG10_PMIC_B5M_OUT2,
|
||||
S2MPG10_PMIC_B6M_CTRL,
|
||||
S2MPG10_PMIC_B6M_OUT1,
|
||||
S2MPG10_PMIC_B6M_OUT2,
|
||||
S2MPG10_PMIC_B7M_CTRL,
|
||||
S2MPG10_PMIC_B7M_OUT1,
|
||||
S2MPG10_PMIC_B7M_OUT2,
|
||||
S2MPG10_PMIC_B8M_CTRL,
|
||||
S2MPG10_PMIC_B8M_OUT1,
|
||||
S2MPG10_PMIC_B8M_OUT2,
|
||||
S2MPG10_PMIC_B9M_CTRL,
|
||||
S2MPG10_PMIC_B9M_OUT1,
|
||||
S2MPG10_PMIC_B9M_OUT2,
|
||||
S2MPG10_PMIC_B10M_CTRL,
|
||||
S2MPG10_PMIC_B10M_OUT1,
|
||||
S2MPG10_PMIC_B10M_OUT2,
|
||||
S2MPG10_PMIC_BUCK1M_USONIC,
|
||||
S2MPG10_PMIC_BUCK2M_USONIC,
|
||||
S2MPG10_PMIC_BUCK3M_USONIC,
|
||||
S2MPG10_PMIC_BUCK4M_USONIC,
|
||||
S2MPG10_PMIC_BUCK5M_USONIC,
|
||||
S2MPG10_PMIC_BUCK6M_USONIC,
|
||||
S2MPG10_PMIC_BUCK7M_USONIC,
|
||||
S2MPG10_PMIC_BUCK8M_USONIC,
|
||||
S2MPG10_PMIC_BUCK9M_USONIC,
|
||||
S2MPG10_PMIC_BUCK10M_USONIC,
|
||||
S2MPG10_PMIC_L1M_CTRL,
|
||||
S2MPG10_PMIC_L2M_CTRL,
|
||||
S2MPG10_PMIC_L3M_CTRL,
|
||||
S2MPG10_PMIC_L4M_CTRL,
|
||||
S2MPG10_PMIC_L5M_CTRL,
|
||||
S2MPG10_PMIC_L6M_CTRL,
|
||||
S2MPG10_PMIC_L7M_CTRL,
|
||||
S2MPG10_PMIC_L8M_CTRL,
|
||||
S2MPG10_PMIC_L9M_CTRL,
|
||||
S2MPG10_PMIC_L10M_CTRL,
|
||||
S2MPG10_PMIC_L11M_CTRL1,
|
||||
S2MPG10_PMIC_L11M_CTRL2,
|
||||
S2MPG10_PMIC_L12M_CTRL1,
|
||||
S2MPG10_PMIC_L12M_CTRL2,
|
||||
S2MPG10_PMIC_L13M_CTRL1,
|
||||
S2MPG10_PMIC_L13M_CTRL2,
|
||||
S2MPG10_PMIC_L14M_CTRL,
|
||||
S2MPG10_PMIC_L15M_CTRL1,
|
||||
S2MPG10_PMIC_L15M_CTRL2,
|
||||
S2MPG10_PMIC_L16M_CTRL,
|
||||
S2MPG10_PMIC_L17M_CTRL,
|
||||
S2MPG10_PMIC_L18M_CTRL,
|
||||
S2MPG10_PMIC_L19M_CTRL,
|
||||
S2MPG10_PMIC_L20M_CTRL,
|
||||
S2MPG10_PMIC_L21M_CTRL,
|
||||
S2MPG10_PMIC_L22M_CTRL,
|
||||
S2MPG10_PMIC_L23M_CTRL,
|
||||
S2MPG10_PMIC_L24M_CTRL,
|
||||
S2MPG10_PMIC_L25M_CTRL,
|
||||
S2MPG10_PMIC_L26M_CTRL,
|
||||
S2MPG10_PMIC_L27M_CTRL,
|
||||
S2MPG10_PMIC_L28M_CTRL,
|
||||
S2MPG10_PMIC_L29M_CTRL,
|
||||
S2MPG10_PMIC_L30M_CTRL,
|
||||
S2MPG10_PMIC_L31M_CTRL,
|
||||
S2MPG10_PMIC_LDO_CTRL1,
|
||||
S2MPG10_PMIC_LDO_CTRL2,
|
||||
S2MPG10_PMIC_LDO_DSCH1,
|
||||
S2MPG10_PMIC_LDO_DSCH2,
|
||||
S2MPG10_PMIC_LDO_DSCH3,
|
||||
S2MPG10_PMIC_LDO_DSCH4,
|
||||
S2MPG10_PMIC_LDO_BUCK7M_HLIMIT,
|
||||
S2MPG10_PMIC_LDO_BUCK7M_LLIMIT,
|
||||
S2MPG10_PMIC_LDO_LDO21M_HLIMIT,
|
||||
S2MPG10_PMIC_LDO_LDO21M_LLIMIT,
|
||||
S2MPG10_PMIC_LDO_LDO11M_HLIMIT,
|
||||
S2MPG10_PMIC_DVS_RAMP1,
|
||||
S2MPG10_PMIC_DVS_RAMP2,
|
||||
S2MPG10_PMIC_DVS_RAMP3,
|
||||
S2MPG10_PMIC_DVS_RAMP4,
|
||||
S2MPG10_PMIC_DVS_RAMP5,
|
||||
S2MPG10_PMIC_DVS_RAMP6,
|
||||
S2MPG10_PMIC_DVS_SYNC_CTRL1,
|
||||
S2MPG10_PMIC_DVS_SYNC_CTRL2,
|
||||
S2MPG10_PMIC_DVS_SYNC_CTRL3,
|
||||
S2MPG10_PMIC_DVS_SYNC_CTRL4,
|
||||
S2MPG10_PMIC_DVS_SYNC_CTRL5,
|
||||
S2MPG10_PMIC_DVS_SYNC_CTRL6,
|
||||
S2MPG10_PMIC_OFF_CTRL1,
|
||||
S2MPG10_PMIC_OFF_CTRL2,
|
||||
S2MPG10_PMIC_OFF_CTRL3,
|
||||
S2MPG10_PMIC_OFF_CTRL4,
|
||||
S2MPG10_PMIC_SEQ_CTRL1,
|
||||
S2MPG10_PMIC_SEQ_CTRL2,
|
||||
S2MPG10_PMIC_SEQ_CTRL3,
|
||||
S2MPG10_PMIC_SEQ_CTRL4,
|
||||
S2MPG10_PMIC_SEQ_CTRL5,
|
||||
S2MPG10_PMIC_SEQ_CTRL6,
|
||||
S2MPG10_PMIC_SEQ_CTRL7,
|
||||
S2MPG10_PMIC_SEQ_CTRL8,
|
||||
S2MPG10_PMIC_SEQ_CTRL9,
|
||||
S2MPG10_PMIC_SEQ_CTRL10,
|
||||
S2MPG10_PMIC_SEQ_CTRL11,
|
||||
S2MPG10_PMIC_SEQ_CTRL12,
|
||||
S2MPG10_PMIC_SEQ_CTRL13,
|
||||
S2MPG10_PMIC_SEQ_CTRL14,
|
||||
S2MPG10_PMIC_SEQ_CTRL15,
|
||||
S2MPG10_PMIC_SEQ_CTRL16,
|
||||
S2MPG10_PMIC_SEQ_CTRL17,
|
||||
S2MPG10_PMIC_SEQ_CTRL18,
|
||||
S2MPG10_PMIC_SEQ_CTRL19,
|
||||
S2MPG10_PMIC_SEQ_CTRL20,
|
||||
S2MPG10_PMIC_SEQ_CTRL21,
|
||||
S2MPG10_PMIC_SEQ_CTRL22,
|
||||
S2MPG10_PMIC_SEQ_CTRL23,
|
||||
S2MPG10_PMIC_SEQ_CTRL24,
|
||||
S2MPG10_PMIC_SEQ_CTRL25,
|
||||
S2MPG10_PMIC_SEQ_CTRL26,
|
||||
S2MPG10_PMIC_SEQ_CTRL27,
|
||||
S2MPG10_PMIC_SEQ_CTRL28,
|
||||
S2MPG10_PMIC_SEQ_CTRL29,
|
||||
S2MPG10_PMIC_SEQ_CTRL30,
|
||||
S2MPG10_PMIC_SEQ_CTRL31,
|
||||
S2MPG10_PMIC_SEQ_CTRL32,
|
||||
S2MPG10_PMIC_SEQ_CTRL33,
|
||||
S2MPG10_PMIC_SEQ_CTRL34,
|
||||
S2MPG10_PMIC_SEQ_CTRL35,
|
||||
S2MPG10_PMIC_OFF_SEQ_CTRL1,
|
||||
S2MPG10_PMIC_OFF_SEQ_CTRL2,
|
||||
S2MPG10_PMIC_OFF_SEQ_CTRL3,
|
||||
S2MPG10_PMIC_OFF_SEQ_CTRL4,
|
||||
S2MPG10_PMIC_OFF_SEQ_CTRL5,
|
||||
S2MPG10_PMIC_OFF_SEQ_CTRL6,
|
||||
S2MPG10_PMIC_OFF_SEQ_CTRL7,
|
||||
S2MPG10_PMIC_OFF_SEQ_CTRL8,
|
||||
S2MPG10_PMIC_OFF_SEQ_CTRL9,
|
||||
S2MPG10_PMIC_OFF_SEQ_CTRL10,
|
||||
S2MPG10_PMIC_OFF_SEQ_CTRL11,
|
||||
S2MPG10_PMIC_OFF_SEQ_CTRL12,
|
||||
S2MPG10_PMIC_OFF_SEQ_CTRL13,
|
||||
S2MPG10_PMIC_OFF_SEQ_CTRL14,
|
||||
S2MPG10_PMIC_OFF_SEQ_CTRL15,
|
||||
S2MPG10_PMIC_OFF_SEQ_CTRL16,
|
||||
S2MPG10_PMIC_OFF_SEQ_CTRL17,
|
||||
S2MPG10_PMIC_OFF_SEQ_CTRL18,
|
||||
S2MPG10_PMIC_PCTRLSEL1,
|
||||
S2MPG10_PMIC_PCTRLSEL2,
|
||||
S2MPG10_PMIC_PCTRLSEL3,
|
||||
S2MPG10_PMIC_PCTRLSEL4,
|
||||
S2MPG10_PMIC_PCTRLSEL5,
|
||||
S2MPG10_PMIC_PCTRLSEL6,
|
||||
S2MPG10_PMIC_PCTRLSEL7,
|
||||
S2MPG10_PMIC_PCTRLSEL8,
|
||||
S2MPG10_PMIC_PCTRLSEL9,
|
||||
S2MPG10_PMIC_PCTRLSEL10,
|
||||
S2MPG10_PMIC_PCTRLSEL11,
|
||||
S2MPG10_PMIC_PCTRLSEL12,
|
||||
S2MPG10_PMIC_PCTRLSEL13,
|
||||
S2MPG10_PMIC_DCTRLSEL1,
|
||||
S2MPG10_PMIC_DCTRLSEL2,
|
||||
S2MPG10_PMIC_DCTRLSEL3,
|
||||
S2MPG10_PMIC_DCTRLSEL4,
|
||||
S2MPG10_PMIC_DCTRLSEL5,
|
||||
S2MPG10_PMIC_DCTRLSEL6,
|
||||
S2MPG10_PMIC_DCTRLSEL7,
|
||||
S2MPG10_PMIC_GPIO_CTRL1,
|
||||
S2MPG10_PMIC_GPIO_CTRL2,
|
||||
S2MPG10_PMIC_GPIO_CTRL3,
|
||||
S2MPG10_PMIC_GPIO_CTRL4,
|
||||
S2MPG10_PMIC_GPIO_CTRL5,
|
||||
S2MPG10_PMIC_GPIO_CTRL6,
|
||||
S2MPG10_PMIC_GPIO_CTRL7,
|
||||
S2MPG10_PMIC_B2M_OCP_WARN,
|
||||
S2MPG10_PMIC_B2M_OCP_WARN_X,
|
||||
S2MPG10_PMIC_B2M_OCP_WARN_Y,
|
||||
S2MPG10_PMIC_B2M_OCP_WARN_Z,
|
||||
S2MPG10_PMIC_B3M_OCP_WARN,
|
||||
S2MPG10_PMIC_B3M_OCP_WARN_X,
|
||||
S2MPG10_PMIC_B3M_OCP_WARN_Y,
|
||||
S2MPG10_PMIC_B3M_OCP_WARN_Z,
|
||||
S2MPG10_PMIC_B10M_OCP_WARN,
|
||||
S2MPG10_PMIC_B10M_OCP_WARN_X,
|
||||
S2MPG10_PMIC_B10M_OCP_WARN_Y,
|
||||
S2MPG10_PMIC_B10M_OCP_WARN_Z,
|
||||
S2MPG10_PMIC_B2M_SOFT_OCP_WARN,
|
||||
S2MPG10_PMIC_B2M_SOFT_OCP_WARN_X,
|
||||
S2MPG10_PMIC_B2M_SOFT_OCP_WARN_Y,
|
||||
S2MPG10_PMIC_B2M_SOFT_OCP_WARN_Z,
|
||||
S2MPG10_PMIC_B3M_SOFT_OCP_WARN,
|
||||
S2MPG10_PMIC_B3M_SOFT_OCP_WARN_X,
|
||||
S2MPG10_PMIC_B3M_SOFT_OCP_WARN_Y,
|
||||
S2MPG10_PMIC_B3M_SOFT_OCP_WARN_Z,
|
||||
S2MPG10_PMIC_B10M_SOFT_OCP_WARN,
|
||||
S2MPG10_PMIC_B10M_SOFT_OCP_WARN_X,
|
||||
S2MPG10_PMIC_B10M_SOFT_OCP_WARN_Y,
|
||||
S2MPG10_PMIC_B10M_SOFT_OCP_WARN_Z,
|
||||
S2MPG10_PMIC_BUCK_OCP_EN1,
|
||||
S2MPG10_PMIC_BUCK_OCP_EN2,
|
||||
S2MPG10_PMIC_BUCK_OCP_PD_EN1,
|
||||
S2MPG10_PMIC_BUCK_OCP_PD_EN2,
|
||||
S2MPG10_PMIC_BUCK_OCP_CTRL1,
|
||||
S2MPG10_PMIC_BUCK_OCP_CTRL2,
|
||||
S2MPG10_PMIC_BUCK_OCP_CTRL3,
|
||||
S2MPG10_PMIC_BUCK_OCP_CTRL4,
|
||||
S2MPG10_PMIC_BUCK_OCP_CTRL5,
|
||||
S2MPG10_PMIC_PIF_CTRL,
|
||||
S2MPG10_PMIC_BUCK_HR_MODE1,
|
||||
S2MPG10_PMIC_BUCK_HR_MODE2,
|
||||
S2MPG10_PMIC_FAULTOUT_CTRL,
|
||||
S2MPG10_PMIC_LDO_SENSE1,
|
||||
S2MPG10_PMIC_LDO_SENSE2,
|
||||
S2MPG10_PMIC_LDO_SENSE3,
|
||||
S2MPG10_PMIC_LDO_SENSE4,
|
||||
};
|
||||
|
||||
/* Meter registers (type 0xa00) */
|
||||
enum s2mpg10_meter_reg {
|
||||
S2MPG10_METER_CTRL1,
|
||||
S2MPG10_METER_CTRL2,
|
||||
S2MPG10_METER_CTRL3,
|
||||
S2MPG10_METER_CTRL4,
|
||||
S2MPG10_METER_BUCKEN1,
|
||||
S2MPG10_METER_BUCKEN2,
|
||||
S2MPG10_METER_MUXSEL0,
|
||||
S2MPG10_METER_MUXSEL1,
|
||||
S2MPG10_METER_MUXSEL2,
|
||||
S2MPG10_METER_MUXSEL3,
|
||||
S2MPG10_METER_MUXSEL4,
|
||||
S2MPG10_METER_MUXSEL5,
|
||||
S2MPG10_METER_MUXSEL6,
|
||||
S2MPG10_METER_MUXSEL7,
|
||||
S2MPG10_METER_LPF_C0_0,
|
||||
S2MPG10_METER_LPF_C0_1,
|
||||
S2MPG10_METER_LPF_C0_2,
|
||||
S2MPG10_METER_LPF_C0_3,
|
||||
S2MPG10_METER_LPF_C0_4,
|
||||
S2MPG10_METER_LPF_C0_5,
|
||||
S2MPG10_METER_LPF_C0_6,
|
||||
S2MPG10_METER_LPF_C0_7,
|
||||
S2MPG10_METER_PWR_WARN0,
|
||||
S2MPG10_METER_PWR_WARN1,
|
||||
S2MPG10_METER_PWR_WARN2,
|
||||
S2MPG10_METER_PWR_WARN3,
|
||||
S2MPG10_METER_PWR_WARN4,
|
||||
S2MPG10_METER_PWR_WARN5,
|
||||
S2MPG10_METER_PWR_WARN6,
|
||||
S2MPG10_METER_PWR_WARN7,
|
||||
S2MPG10_METER_PWR_HYS1,
|
||||
S2MPG10_METER_PWR_HYS2,
|
||||
S2MPG10_METER_PWR_HYS3,
|
||||
S2MPG10_METER_PWR_HYS4,
|
||||
S2MPG10_METER_ACC_DATA_CH0_1 = 0x40,
|
||||
S2MPG10_METER_ACC_DATA_CH0_2,
|
||||
S2MPG10_METER_ACC_DATA_CH0_3,
|
||||
S2MPG10_METER_ACC_DATA_CH0_4,
|
||||
S2MPG10_METER_ACC_DATA_CH0_5,
|
||||
S2MPG10_METER_ACC_DATA_CH0_6,
|
||||
S2MPG10_METER_ACC_DATA_CH1_1,
|
||||
S2MPG10_METER_ACC_DATA_CH1_2,
|
||||
S2MPG10_METER_ACC_DATA_CH1_3,
|
||||
S2MPG10_METER_ACC_DATA_CH1_4,
|
||||
S2MPG10_METER_ACC_DATA_CH1_5,
|
||||
S2MPG10_METER_ACC_DATA_CH1_6,
|
||||
S2MPG10_METER_ACC_DATA_CH2_1,
|
||||
S2MPG10_METER_ACC_DATA_CH2_2,
|
||||
S2MPG10_METER_ACC_DATA_CH2_3,
|
||||
S2MPG10_METER_ACC_DATA_CH2_4,
|
||||
S2MPG10_METER_ACC_DATA_CH2_5,
|
||||
S2MPG10_METER_ACC_DATA_CH2_6,
|
||||
S2MPG10_METER_ACC_DATA_CH3_1,
|
||||
S2MPG10_METER_ACC_DATA_CH3_2,
|
||||
S2MPG10_METER_ACC_DATA_CH3_3,
|
||||
S2MPG10_METER_ACC_DATA_CH3_4,
|
||||
S2MPG10_METER_ACC_DATA_CH3_5,
|
||||
S2MPG10_METER_ACC_DATA_CH3_6,
|
||||
S2MPG10_METER_ACC_DATA_CH4_1,
|
||||
S2MPG10_METER_ACC_DATA_CH4_2,
|
||||
S2MPG10_METER_ACC_DATA_CH4_3,
|
||||
S2MPG10_METER_ACC_DATA_CH4_4,
|
||||
S2MPG10_METER_ACC_DATA_CH4_5,
|
||||
S2MPG10_METER_ACC_DATA_CH4_6,
|
||||
S2MPG10_METER_ACC_DATA_CH5_1,
|
||||
S2MPG10_METER_ACC_DATA_CH5_2,
|
||||
S2MPG10_METER_ACC_DATA_CH5_3,
|
||||
S2MPG10_METER_ACC_DATA_CH5_4,
|
||||
S2MPG10_METER_ACC_DATA_CH5_5,
|
||||
S2MPG10_METER_ACC_DATA_CH5_6,
|
||||
S2MPG10_METER_ACC_DATA_CH6_1,
|
||||
S2MPG10_METER_ACC_DATA_CH6_2,
|
||||
S2MPG10_METER_ACC_DATA_CH6_3,
|
||||
S2MPG10_METER_ACC_DATA_CH6_4,
|
||||
S2MPG10_METER_ACC_DATA_CH6_5,
|
||||
S2MPG10_METER_ACC_DATA_CH6_6,
|
||||
S2MPG10_METER_ACC_DATA_CH7_1,
|
||||
S2MPG10_METER_ACC_DATA_CH7_2,
|
||||
S2MPG10_METER_ACC_DATA_CH7_3,
|
||||
S2MPG10_METER_ACC_DATA_CH7_4,
|
||||
S2MPG10_METER_ACC_DATA_CH7_5,
|
||||
S2MPG10_METER_ACC_DATA_CH7_6,
|
||||
S2MPG10_METER_ACC_COUNT_1,
|
||||
S2MPG10_METER_ACC_COUNT_2,
|
||||
S2MPG10_METER_ACC_COUNT_3,
|
||||
S2MPG10_METER_LPF_DATA_CH0_1,
|
||||
S2MPG10_METER_LPF_DATA_CH0_2,
|
||||
S2MPG10_METER_LPF_DATA_CH0_3,
|
||||
S2MPG10_METER_LPF_DATA_CH1_1,
|
||||
S2MPG10_METER_LPF_DATA_CH1_2,
|
||||
S2MPG10_METER_LPF_DATA_CH1_3,
|
||||
S2MPG10_METER_LPF_DATA_CH2_1,
|
||||
S2MPG10_METER_LPF_DATA_CH2_2,
|
||||
S2MPG10_METER_LPF_DATA_CH2_3,
|
||||
S2MPG10_METER_LPF_DATA_CH3_1,
|
||||
S2MPG10_METER_LPF_DATA_CH3_2,
|
||||
S2MPG10_METER_LPF_DATA_CH3_3,
|
||||
S2MPG10_METER_LPF_DATA_CH4_1,
|
||||
S2MPG10_METER_LPF_DATA_CH4_2,
|
||||
S2MPG10_METER_LPF_DATA_CH4_3,
|
||||
S2MPG10_METER_LPF_DATA_CH5_1,
|
||||
S2MPG10_METER_LPF_DATA_CH5_2,
|
||||
S2MPG10_METER_LPF_DATA_CH5_3,
|
||||
S2MPG10_METER_LPF_DATA_CH6_1,
|
||||
S2MPG10_METER_LPF_DATA_CH6_2,
|
||||
S2MPG10_METER_LPF_DATA_CH6_3,
|
||||
S2MPG10_METER_LPF_DATA_CH7_1,
|
||||
S2MPG10_METER_LPF_DATA_CH7_2,
|
||||
S2MPG10_METER_LPF_DATA_CH7_3,
|
||||
S2MPG10_METER_DSM_TRIM_OFFSET = 0xee,
|
||||
S2MPG10_METER_BUCK_METER_TRIM3 = 0xf1,
|
||||
};
|
||||
|
||||
/* S2MPG10 regulator IDs */
|
||||
enum s2mpg10_regulators {
|
||||
S2MPG10_LDO1,
|
||||
S2MPG10_LDO2,
|
||||
S2MPG10_LDO3,
|
||||
S2MPG10_LDO4,
|
||||
S2MPG10_LDO5,
|
||||
S2MPG10_LDO6,
|
||||
S2MPG10_LDO7,
|
||||
S2MPG10_LDO8,
|
||||
S2MPG10_LDO9,
|
||||
S2MPG10_LDO10,
|
||||
S2MPG10_LDO11,
|
||||
S2MPG10_LDO12,
|
||||
S2MPG10_LDO13,
|
||||
S2MPG10_LDO14,
|
||||
S2MPG10_LDO15,
|
||||
S2MPG10_LDO16,
|
||||
S2MPG10_LDO17,
|
||||
S2MPG10_LDO18,
|
||||
S2MPG10_LDO19,
|
||||
S2MPG10_LDO20,
|
||||
S2MPG10_LDO21,
|
||||
S2MPG10_LDO22,
|
||||
S2MPG10_LDO23,
|
||||
S2MPG10_LDO24,
|
||||
S2MPG10_LDO25,
|
||||
S2MPG10_LDO26,
|
||||
S2MPG10_LDO27,
|
||||
S2MPG10_LDO28,
|
||||
S2MPG10_LDO29,
|
||||
S2MPG10_LDO30,
|
||||
S2MPG10_LDO31,
|
||||
S2MPG10_BUCK1,
|
||||
S2MPG10_BUCK2,
|
||||
S2MPG10_BUCK3,
|
||||
S2MPG10_BUCK4,
|
||||
S2MPG10_BUCK5,
|
||||
S2MPG10_BUCK6,
|
||||
S2MPG10_BUCK7,
|
||||
S2MPG10_BUCK8,
|
||||
S2MPG10_BUCK9,
|
||||
S2MPG10_BUCK10,
|
||||
S2MPG10_REGULATOR_MAX,
|
||||
};
|
||||
|
||||
#endif /* __LINUX_MFD_S2MPG10_H */
|
||||
@ -17,20 +17,30 @@
|
||||
#define STM32_LPTIM_IER 0x08 /* Interrupt Enable Reg */
|
||||
#define STM32_LPTIM_CFGR 0x0C /* Configuration Reg */
|
||||
#define STM32_LPTIM_CR 0x10 /* Control Reg */
|
||||
#define STM32_LPTIM_CMP 0x14 /* Compare Reg */
|
||||
#define STM32_LPTIM_CMP 0x14 /* Compare Reg (MP25 CCR1) */
|
||||
#define STM32_LPTIM_ARR 0x18 /* Autoreload Reg */
|
||||
#define STM32_LPTIM_CNT 0x1C /* Counter Reg */
|
||||
#define STM32_LPTIM_CCMR1 0x2C /* Capture/Compare Mode MP25 */
|
||||
#define STM32_LPTIM_CCR2 0x34 /* Compare Reg2 MP25 */
|
||||
|
||||
#define STM32_LPTIM_HWCFGR2 0x3EC /* Hardware configuration register 2 - MP25 */
|
||||
#define STM32_LPTIM_HWCFGR1 0x3F0 /* Hardware configuration register 1 - MP15 */
|
||||
#define STM32_LPTIM_VERR 0x3F4 /* Version identification register - MP15 */
|
||||
|
||||
/* STM32_LPTIM_ISR - bit fields */
|
||||
#define STM32_LPTIM_DIEROK_ARROK (BIT(24) | BIT(4)) /* MP25 */
|
||||
#define STM32_LPTIM_CMP2_ARROK (BIT(19) | BIT(4))
|
||||
#define STM32_LPTIM_CMPOK_ARROK GENMASK(4, 3)
|
||||
#define STM32_LPTIM_ARROK BIT(4)
|
||||
#define STM32_LPTIM_CMPOK BIT(3)
|
||||
|
||||
/* STM32_LPTIM_ICR - bit fields */
|
||||
#define STM32_LPTIM_ARRMCF BIT(1)
|
||||
#define STM32_LPTIM_DIEROKCF_ARROKCF (BIT(24) | BIT(4)) /* MP25 */
|
||||
#define STM32_LPTIM_CMP2OKCF_ARROKCF (BIT(19) | BIT(4))
|
||||
#define STM32_LPTIM_CMPOKCF_ARROKCF GENMASK(4, 3)
|
||||
#define STM32_LPTIM_ARRMCF BIT(1)
|
||||
|
||||
/* STM32_LPTIM_IER - bit flieds */
|
||||
/* STM32_LPTIM_IER - bit fields */
|
||||
#define STM32_LPTIM_ARRMIE BIT(1)
|
||||
|
||||
/* STM32_LPTIM_CR - bit fields */
|
||||
@ -53,16 +63,37 @@
|
||||
/* STM32_LPTIM_ARR */
|
||||
#define STM32_LPTIM_MAX_ARR 0xFFFF
|
||||
|
||||
/* STM32_LPTIM_CCMR1 */
|
||||
#define STM32_LPTIM_CC2P GENMASK(19, 18)
|
||||
#define STM32_LPTIM_CC2E BIT(17)
|
||||
#define STM32_LPTIM_CC2SEL BIT(16)
|
||||
#define STM32_LPTIM_CC1P GENMASK(3, 2)
|
||||
#define STM32_LPTIM_CC1E BIT(1)
|
||||
#define STM32_LPTIM_CC1SEL BIT(0)
|
||||
|
||||
/* STM32_LPTIM_HWCFGR1 */
|
||||
#define STM32_LPTIM_HWCFGR1_ENCODER BIT(16)
|
||||
|
||||
/* STM32_LPTIM_HWCFGR2 */
|
||||
#define STM32_LPTIM_HWCFGR2_CHAN_NUM GENMASK(3, 0)
|
||||
|
||||
/* STM32_LPTIM_VERR */
|
||||
#define STM32_LPTIM_VERR_23 0x23 /* STM32MP25 */
|
||||
|
||||
/**
|
||||
* struct stm32_lptimer - STM32 Low-Power Timer data assigned by parent device
|
||||
* @clk: clock reference for this instance
|
||||
* @regmap: register map reference for this instance
|
||||
* @has_encoder: indicates this Low-Power Timer supports encoder mode
|
||||
* @num_cc_chans: indicates the number of capture/compare channels
|
||||
* @version: indicates the major and minor revision of the controller
|
||||
*/
|
||||
struct stm32_lptimer {
|
||||
struct clk *clk;
|
||||
struct regmap *regmap;
|
||||
bool has_encoder;
|
||||
unsigned int num_cc_chans;
|
||||
u32 version;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -12,9 +12,6 @@ extern int sm501_unit_power(struct device *dev,
|
||||
extern unsigned long sm501_set_clock(struct device *dev,
|
||||
int clksrc, unsigned long freq);
|
||||
|
||||
extern unsigned long sm501_find_clock(struct device *dev,
|
||||
int clksrc, unsigned long req_freq);
|
||||
|
||||
/* sm501_misc_control
|
||||
*
|
||||
* Modify the SM501's MISC_CONTROL register
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user