mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/
synced 2025-04-19 20:58:31 +09:00
* Maxim MAX77705:
* Added core MFD driver. * Added charger driver. * Added devicetree bindings for the charger and MFD core. * Added Haptic controller support via the input subsystem. * Added LED support. * Added support to simple-mfd-i2c for fuel gauge and hwmon. * Samsung S2MPU05 (Exynos7870 PMIC): * Added core MFD support. * Added Regulator support for 21 LDOs and 5 BUCKs. * Added devicetree bindings for regulators and the PMIC core. * TI TPS65215 & TPS65214: * Added support to the existing TPS65219 driver. * Added devicetree bindings. * STMicroelectronics STM32MP25: * Added support to the stm32-timers MFD driver. * Added devicetree bindings. * Congatec Board Controller (CGBC): * Added HWMON support for internal sensors. * Added support for the conga-SA8 module. * Microchip LAN969X: * Enabled the at91-usart MFD driver for this architecture. * MediaTek MT6359: * Added mfd_cell for mt6359-accdet to allow its driver to probe. * AXP20X (AXP717): Added AXP717_TS_PIN_CFG register to writeable regs for temperature sensor configuration. * SM501: Switched to using BIT() macro to mitigate potential integer overflows in GPIO functions. * ENE KB3930: Added a NULL pointer check for off_gpios during probe to prevent potential dereference. * SYSCON: Added a check for invalid resource size to prevent issues from DT misconfiguration. * CGBC: Corrected signedness issues in cgbc_session_request. * intel_soc_pmic_chtdc_ti / intel_soc_pmic_crc: Removed unneeded explicit assignment to REGCACHE_NONE. * ipaq-micro / tps65010: Switched to using str_enable_disable() helpers for clarity and potential size reduction. * upboard-fpga: Removed unnecessary ACPI_PTR() annotation. * max8997: Removed unused max8997_irq_exit() function, using devm_* helpers instead. * lp3943: Dropped unused #include <linux/pwm.h> from the header file. * db8500-prcmu: Removed needless return statements in void APIs. * qnap-mcu: Replaced commas with semicolons between expressions for correctness. * STA2X11: Removed the core MFD driver as the underlying platform support was removed. * EZX-PCAP: Removed the unused pcap_adc_sync function. * PCF50633 (OpenMoko PMIC): Removed the entire driver (core, adc, gpio, irq) as the underlying s3c24xx platform support was removed. * Converted fsl,mcu-mpc8349emitx binding to YAML. * Added qcom,msm8937-tcsr compatible. * Added microchip,sama7d65-flexcom compatible. * Added rockchip,rk3528-qos syscon compatible. * Added airoha,en7581-pbus-csr syscon compatible. * Added microchip,sama7d65-ddr3phy syscon compatible. * Added microchip,sama7d65-sfrbu syscon compatible. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEdrbJNaO+IJqU8IdIUa+KL4f8d2EFAmfmqKQACgkQUa+KL4f8 d2G+rA//UU3UixCD8FsNN+o4DS7FbxdiSUCrATOBKia9MGfor4xCl6Qk9ZyO4sE1 Rr9zUrTb1xlCmMZupZlkV8TDHHcaiUbgmnKB161d4HMxCbju10MKlm7faz2vRMz3 a73ehTmUeNDiWG3t1/2zAyRt7PHPC2zakUlnXlLhLir12uR2jsDSeGOZh4xR7Hdi 5nkOA2xWbbeW4b+ybwZ32afbLtZFkLo80QvqDx/D9lMUnQO0FqKak0Zope7IzeqC ilg+tIJOQRGEbjEVQ+pVXsPI6zfmO8eAja70F7sm+Q6TVDw2JhHU/YElHw+quiP+ aLYeE+DuSun1EYlK4ATQ0vzUdgsaOEWblF0eythctXFTfM9ZKhzWYdXEOvco7N4u R9BYRtM/zGkxiScbr6igyjWZx7NPOsKEKIi5tOv+C2BAKb53om7vsNuMgvMDL/8W gztmG0SMKwJSx2Dg7h1LLUfa3tG9QRFd0I+Yfaso3MtYmxnZVcJtM5IQbvzf6i/B 3fSiGP6PDNeJqbn9k3/7SB8Tb4XmJUN2LFdDtDuWVhgZpSDULkjpYxAXDIrbp+il QNdLPiU1x7OzPkFZQxtXLt7yRmlEc2lu9jJHkGVM1M18TMexQiFxoSY9NxkbUj3o T4s/PKGmRKHP9XxCmRSfu6Veql0MPUwtvkErlUf4GTLWK4oshag= =ntF1 -----END PGP SIGNATURE----- Merge tag 'mfd-next-6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd Pull MFD updates from Lee Jones: "Maxim MAX77705: - Added core MFD driver. - Added charger driver. - Added devicetree bindings for the charger and MFD core. - Added Haptic controller support via the input subsystem. - Added LED support. - Added support to simple-mfd-i2c for fuel gauge and hwmon. Samsung S2MPU05 (Exynos7870 PMIC): - Added core MFD support. - Added Regulator support for 21 LDOs and 5 BUCKs. - Added devicetree bindings for regulators and the PMIC core. TI TPS65215 & TPS65214: - Added support to the existing TPS65219 driver. - Added devicetree bindings. STMicroelectronics STM32MP25: - Added support to the stm32-timers MFD driver. - Added devicetree bindings. Congatec Board Controller (CGBC): - Added HWMON support for internal sensors. - Added support for the conga-SA8 module. Microchip LAN969X: - Enabled the at91-usart MFD driver for this architecture. MediaTek MT6359: - Added mfd_cell for mt6359-accdet to allow its driver to probe. Other misc driver updates: - AXP20X (AXP717): Added AXP717_TS_PIN_CFG register to writeable regs for temperature sensor configuration. - SM501: Switched to using BIT() macro to mitigate potential integer overflows in GPIO functions. - ENE KB3930: Added a NULL pointer check for off_gpios during probe to prevent potential dereference. - SYSCON: Added a check for invalid resource size to prevent issues from DT misconfiguration. - CGBC: Corrected signedness issues in cgbc_session_request - intel_soc_pmic_chtdc_ti / intel_soc_pmic_crc: Removed unneeded explicit assignment to REGCACHE_NONE. - ipaq-micro / tps65010: Switched to using str_enable_disable() helpers for clarity and potential size reduction. - upboard-fpga: Removed unnecessary ACPI_PTR() annotation. - max8997: Removed unused max8997_irq_exit() function, using devm_* helpers instead. - lp3943: Dropped unused #include <linux/pwm.h> from the header file. - db8500-prcmu: Removed needless return statements in void APIs. - qnap-mcu: Replaced commas with semicolons between expressions for correctness. - STA2X11: Removed the core MFD driver as the underlying platform support was removed. - EZX-PCAP: Removed the unused pcap_adc_sync function. - PCF50633 (OpenMoko PMIC): Removed the entire driver (core, adc, gpio, irq) as the underlying s3c24xx platform support was removed. Devicetree updates: - Converted fsl,mcu-mpc8349emitx binding to YAML - Added qcom,msm8937-tcsr compatible - Added microchip,sama7d65-flexcom compatible - Added rockchip,rk3528-qos syscon compatible - Added airoha,en7581-pbus-csr syscon compatible - Added microchip,sama7d65-ddr3phy syscon compatible - Added microchip,sama7d65-sfrbu syscon compatible" * tag 'mfd-next-6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (49 commits) mfd: cgbc-core: Add support for conga-SA8 dt-bindings: mfd: syscon: Add microchip,sama7d65-sfrbu dt-bindings: mfd: syscon: Add microchip,sama7d65-ddr3phy mfd: cgbc: Add support for HWMON dt-bindings: mfd: syscon: Add the pbus-csr node for Airoha EN7581 SoC mfd: cgbc-core: Cleanup signedness in cgbc_session_request() mfd: pcf50633: Remove remaining PCF50633 support mfd: pcf50633: Remove unused platform IRQ code mfd: pcF50633-gpio: Remove unused driver mfd: pcf50633-adc: Remove unused driver mfd: qnap-mcu: Convert commas to semicolons in qnap_mcu_exec() mfd: mt6397-core: Add mfd_cell for mt6359-accdet dt-bindings: mfd: syscon: Add rk3528 QoS register compatible dt-bindings: mfd: atmel,sama5d2-flexcom: Add microchip,sama7d65-flexcom mfd: ezx-pcap: Remove unused pcap_adc_sync mfd: db8500-prcmu: Remove needless return in three void APIs mfd: Remove STA2x11 core driver mfd: max77620: Allow building as a module mfd: ene-kb3930: Fix a potential NULL pointer dereference dt-bindings: mfd: qcom,tcsr: Add compatible for MSM8937 ...
This commit is contained in:
commit
dcab75a3c8
@ -19,12 +19,11 @@ properties:
|
||||
oneOf:
|
||||
- const: atmel,sama5d2-flexcom
|
||||
- items:
|
||||
- const: microchip,sam9x7-flexcom
|
||||
- enum:
|
||||
- microchip,sam9x7-flexcom
|
||||
- microchip,sama7d65-flexcom
|
||||
- microchip,sama7g5-flexcom
|
||||
- const: atmel,sama5d2-flexcom
|
||||
- items:
|
||||
- const: microchip,sama7g5-flexcom
|
||||
- const: atmel,sama5d2-flexcom
|
||||
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -0,0 +1,53 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mfd/fsl,mcu-mpc8349emitx.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Freescale MPC8349E-mITX-compatible Power Management Micro Controller Unit (MCU)
|
||||
|
||||
maintainers:
|
||||
- J. Neuschäfer <j.ne@posteo.net>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- fsl,mc9s08qg8-mpc8315erdb
|
||||
- fsl,mc9s08qg8-mpc8349emitx
|
||||
- fsl,mc9s08qg8-mpc8377erdb
|
||||
- fsl,mc9s08qg8-mpc8378erdb
|
||||
- fsl,mc9s08qg8-mpc8379erdb
|
||||
- const: fsl,mcu-mpc8349emitx
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#gpio-cells":
|
||||
const: 2
|
||||
|
||||
gpio-controller: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#gpio-cells"
|
||||
- gpio-controller
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mcu@a {
|
||||
#gpio-cells = <2>;
|
||||
compatible = "fsl,mc9s08qg8-mpc8349emitx",
|
||||
"fsl,mcu-mpc8349emitx";
|
||||
reg = <0x0a>;
|
||||
gpio-controller;
|
||||
};
|
||||
};
|
158
Documentation/devicetree/bindings/mfd/maxim,max77705.yaml
Normal file
158
Documentation/devicetree/bindings/mfd/maxim,max77705.yaml
Normal file
@ -0,0 +1,158 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mfd/maxim,max77705.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Maxim MAX77705 Companion Power Management and USB Type-C interface
|
||||
|
||||
maintainers:
|
||||
- Dzmitry Sankouski <dsankouski@gmail.com>
|
||||
|
||||
description: |
|
||||
This is a part of device tree bindings for Maxim MAX77705.
|
||||
|
||||
Maxim MAX77705 is a Companion Power Management and Type-C
|
||||
interface IC which includes charger, fuelgauge, LED, haptic motor driver and
|
||||
Type-C management.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: maxim,max77705
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
haptic:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: maxim,max77705-haptic
|
||||
|
||||
haptic-supply: true
|
||||
|
||||
pwms:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- haptic-supply
|
||||
- pwms
|
||||
|
||||
leds:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
description:
|
||||
Up to 4 LED channels supported.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: maxim,max77705-rgb
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
multi-led:
|
||||
type: object
|
||||
$ref: /schemas/leds/leds-class-multicolor.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
patternProperties:
|
||||
"^led@[0-3]$":
|
||||
type: object
|
||||
$ref: /schemas/leds/common.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
patternProperties:
|
||||
"^led@[0-3]$":
|
||||
type: object
|
||||
$ref: /schemas/leds/common.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pmic@66 {
|
||||
compatible = "maxim,max77705";
|
||||
reg = <0x66>;
|
||||
interrupt-parent = <&pm8998_gpios>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
pinctrl-0 = <&chg_int_default>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
leds {
|
||||
compatible = "maxim,max77705-rgb";
|
||||
|
||||
multi-led {
|
||||
color = <LED_COLOR_ID_RGB>;
|
||||
function = LED_FUNCTION_STATUS;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
led@1 {
|
||||
reg = <1>;
|
||||
color = <LED_COLOR_ID_RED>;
|
||||
};
|
||||
|
||||
led@2 {
|
||||
reg = <2>;
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
};
|
||||
|
||||
led@3 {
|
||||
reg = <3>;
|
||||
color = <LED_COLOR_ID_BLUE>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
haptic {
|
||||
compatible = "maxim,max77705-haptic";
|
||||
haptic-supply = <&vib_regulator>;
|
||||
pwms = <&vib_pwm 0 50000>;
|
||||
};
|
||||
};
|
||||
};
|
@ -52,6 +52,7 @@ properties:
|
||||
- qcom,tcsr-msm8660
|
||||
- qcom,tcsr-msm8916
|
||||
- qcom,tcsr-msm8917
|
||||
- qcom,tcsr-msm8937
|
||||
- qcom,tcsr-msm8953
|
||||
- qcom,tcsr-msm8960
|
||||
- qcom,tcsr-msm8974
|
||||
|
@ -25,6 +25,7 @@ properties:
|
||||
- samsung,s2mps14-pmic
|
||||
- samsung,s2mps15-pmic
|
||||
- samsung,s2mpu02-pmic
|
||||
- samsung,s2mpu05-pmic
|
||||
|
||||
clocks:
|
||||
$ref: /schemas/clock/samsung,s2mps11.yaml
|
||||
@ -125,6 +126,18 @@ allOf:
|
||||
samsung,s2mps11-acokb-ground: false
|
||||
samsung,s2mps11-wrstbi-ground: false
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: samsung,s2mpu05-pmic
|
||||
then:
|
||||
properties:
|
||||
regulators:
|
||||
$ref: /schemas/regulator/samsung,s2mpu05.yaml
|
||||
samsung,s2mps11-acokb-ground: false
|
||||
samsung,s2mps11-wrstbi-ground: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
@ -21,7 +21,9 @@ maintainers:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: st,stm32-timers
|
||||
enum:
|
||||
- st,stm32-timers
|
||||
- st,stm32mp25-timers
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@ -36,6 +38,9 @@ properties:
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
dmas:
|
||||
minItems: 1
|
||||
maxItems: 7
|
||||
@ -77,7 +82,9 @@ properties:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: st,stm32-pwm
|
||||
enum:
|
||||
- st,stm32-pwm
|
||||
- st,stm32mp25-pwm
|
||||
|
||||
"#pwm-cells":
|
||||
const: 3
|
||||
@ -113,7 +120,9 @@ properties:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: st,stm32-timer-counter
|
||||
enum:
|
||||
- st,stm32-timer-counter
|
||||
- st,stm32mp25-timer-counter
|
||||
|
||||
required:
|
||||
- compatible
|
||||
@ -128,12 +137,13 @@ patternProperties:
|
||||
enum:
|
||||
- st,stm32-timer-trigger
|
||||
- st,stm32h7-timer-trigger
|
||||
- st,stm32mp25-timer-trigger
|
||||
|
||||
reg:
|
||||
description: Identify trigger hardware block.
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 16
|
||||
maximum: 19
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
@ -27,6 +27,7 @@ select:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- airoha,en7581-pbus-csr
|
||||
- al,alpine-sysfabric-service
|
||||
- allwinner,sun8i-a83t-system-controller
|
||||
- allwinner,sun8i-h3-system-controller
|
||||
@ -90,6 +91,8 @@ select:
|
||||
- microchip,lan966x-cpu-syscon
|
||||
- microchip,mpfs-sysreg-scb
|
||||
- microchip,sam9x60-sfr
|
||||
- microchip,sama7d65-ddr3phy
|
||||
- microchip,sama7d65-sfrbu
|
||||
- microchip,sama7g5-ddr3phy
|
||||
- mscc,ocelot-cpu-syscon
|
||||
- mstar,msc313-pmsleep
|
||||
@ -127,6 +130,7 @@ properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- airoha,en7581-pbus-csr
|
||||
- al,alpine-sysfabric-service
|
||||
- allwinner,sun8i-a83t-system-controller
|
||||
- allwinner,sun8i-h3-system-controller
|
||||
@ -190,6 +194,8 @@ properties:
|
||||
- microchip,lan966x-cpu-syscon
|
||||
- microchip,mpfs-sysreg-scb
|
||||
- microchip,sam9x60-sfr
|
||||
- microchip,sama7d65-ddr3phy
|
||||
- microchip,sama7d65-sfrbu
|
||||
- microchip,sama7g5-ddr3phy
|
||||
- mscc,ocelot-cpu-syscon
|
||||
- mstar,msc313-pmsleep
|
||||
|
@ -0,0 +1,50 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/power/supply/maxim,max77705.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Maxim MAX777705 charger
|
||||
|
||||
maintainers:
|
||||
- Dzmitry Sankouski <dsankouski@gmail.com>
|
||||
|
||||
description: |
|
||||
This is a device tree bindings for charger found in Maxim MAX77705 chip.
|
||||
|
||||
allOf:
|
||||
- $ref: power-supply.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: maxim,max77705-charger
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- monitored-battery
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
charger@69 {
|
||||
compatible = "maxim,max77705-charger";
|
||||
reg = <0x69>;
|
||||
monitored-battery = <&battery>;
|
||||
interrupt-parent = <&pm8998_gpios>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
};
|
@ -1,17 +0,0 @@
|
||||
Freescale MPC8349E-mITX-compatible Power Management Micro Controller Unit (MCU)
|
||||
|
||||
Required properties:
|
||||
- compatible : "fsl,<mcu-chip>-<board>", "fsl,mcu-mpc8349emitx".
|
||||
- reg : should specify I2C address (0x0a).
|
||||
- #gpio-cells : should be 2.
|
||||
- gpio-controller : should be present.
|
||||
|
||||
Example:
|
||||
|
||||
mcu@a {
|
||||
#gpio-cells = <2>;
|
||||
compatible = "fsl,mc9s08qg8-mpc8349emitx",
|
||||
"fsl,mcu-mpc8349emitx";
|
||||
reg = <0x0a>;
|
||||
gpio-controller;
|
||||
};
|
@ -0,0 +1,47 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/regulator/samsung,s2mpu05.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Samsung S2MPU05 Power Management IC regulators
|
||||
|
||||
maintainers:
|
||||
- Kaustabh Chakraborty <kauschluss@disroot.org>
|
||||
|
||||
description: |
|
||||
This is a part of device tree bindings for S2M and S5M family of Power
|
||||
Management IC (PMIC).
|
||||
|
||||
The S2MPU05 provides buck and LDO regulators.
|
||||
|
||||
See also Documentation/devicetree/bindings/mfd/samsung,s2mps11.yaml for
|
||||
additional information and example.
|
||||
|
||||
patternProperties:
|
||||
# 21 LDOs
|
||||
"^ldo([1-9]|10|2[5-9]|3[0-5])$":
|
||||
type: object
|
||||
$ref: regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
description:
|
||||
Properties for single LDO regulator.
|
||||
|
||||
LDOs 11-24 are used for CP, and they're left unimplemented due to lack
|
||||
of documentation on these regulators.
|
||||
|
||||
required:
|
||||
- regulator-name
|
||||
|
||||
# 5 bucks
|
||||
"^buck[1-5]$":
|
||||
type: object
|
||||
$ref: regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
description:
|
||||
Properties for single buck regulator.
|
||||
|
||||
required:
|
||||
- regulator-name
|
||||
|
||||
additionalProperties: false
|
@ -4,7 +4,7 @@
|
||||
$id: http://devicetree.org/schemas/regulator/ti,tps65219.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: TI tps65219 Power Management Integrated Circuit regulators
|
||||
title: TI TPS65214/TPS65215/TPS65219 Power Management Integrated Circuit
|
||||
|
||||
maintainers:
|
||||
- Jerome Neanne <jerome.neanne@baylibre.com>
|
||||
@ -12,9 +12,20 @@ maintainers:
|
||||
description: |
|
||||
Regulator nodes should be named to buck<number> and ldo<number>.
|
||||
|
||||
TI TPS65219 is a Power Management IC with 3 Buck regulators, 4 Low
|
||||
Drop-out Regulators (LDOs), 1 GPIO, 2 GPOs, and power-button.
|
||||
|
||||
TI TPS65215 is a derivative of TPS65219 with 3 Buck regulators, 2 Low
|
||||
Drop-out Regulators (LDOs), 1 GPIO, 1 GPO, and power-button.
|
||||
|
||||
TI TPS65214 is a derivative of TPS65219 with 3 Buck regulators, 2 Low
|
||||
Drop-out Regulators (LDOs), 1 GPIO, 1 GPO, and power-button.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- ti,tps65214
|
||||
- ti,tps65215
|
||||
- ti,tps65219
|
||||
|
||||
reg:
|
||||
@ -90,6 +101,20 @@ required:
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- ti,tps65214
|
||||
- ti,tps65215
|
||||
then:
|
||||
properties:
|
||||
regulators:
|
||||
patternProperties:
|
||||
"^ldo[3-4]$": false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
@ -14524,12 +14524,15 @@ B: mailto:linux-samsung-soc@vger.kernel.org
|
||||
F: Documentation/devicetree/bindings/*/maxim,max14577.yaml
|
||||
F: Documentation/devicetree/bindings/*/maxim,max77686.yaml
|
||||
F: Documentation/devicetree/bindings/*/maxim,max77693.yaml
|
||||
F: Documentation/devicetree/bindings/*/maxim,max77705*.yaml
|
||||
F: Documentation/devicetree/bindings/*/maxim,max77843.yaml
|
||||
F: Documentation/devicetree/bindings/clock/maxim,max77686.txt
|
||||
F: drivers/leds/leds-max77705.c
|
||||
F: drivers/*/*max77843.c
|
||||
F: drivers/*/max14577*.c
|
||||
F: drivers/*/max77686*.c
|
||||
F: drivers/*/max77693*.c
|
||||
F: drivers/*/max77705*.c
|
||||
F: drivers/clk/clk-max77686.c
|
||||
F: drivers/extcon/extcon-max14577.c
|
||||
F: drivers/extcon/extcon-max77693.c
|
||||
@ -14537,6 +14540,7 @@ F: drivers/rtc/rtc-max77686.c
|
||||
F: include/linux/mfd/max14577*.h
|
||||
F: include/linux/mfd/max77686*.h
|
||||
F: include/linux/mfd/max77693*.h
|
||||
F: include/linux/mfd/max77705*.h
|
||||
|
||||
MAXIRADIO FM RADIO RECEIVER DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
|
@ -254,9 +254,6 @@ CONFIG_I2C_TAOS_EVM=m
|
||||
CONFIG_I2C_STUB=m
|
||||
# CONFIG_HWMON is not set
|
||||
CONFIG_THERMAL=y
|
||||
CONFIG_MFD_PCF50633=m
|
||||
CONFIG_PCF50633_ADC=m
|
||||
CONFIG_PCF50633_GPIO=m
|
||||
# CONFIG_VGA_ARB is not set
|
||||
CONFIG_LEDS_LP3944=m
|
||||
CONFIG_LEDS_PCA955X=m
|
||||
|
@ -240,12 +240,12 @@ config INPUT_MAX77650_ONKEY
|
||||
will be called max77650-onkey.
|
||||
|
||||
config INPUT_MAX77693_HAPTIC
|
||||
tristate "MAXIM MAX77693/MAX77843 haptic controller support"
|
||||
depends on (MFD_MAX77693 || MFD_MAX77843) && PWM
|
||||
tristate "MAXIM MAX77693/MAX77705/MAX77843 haptic controller support"
|
||||
depends on (MFD_MAX77693 || MFD_MAX77705 || MFD_MAX77843) && PWM
|
||||
select INPUT_FF_MEMLESS
|
||||
help
|
||||
This option enables support for the haptic controller on
|
||||
MAXIM MAX77693 and MAX77843 chips.
|
||||
MAXIM MAX77693, MAX77705 and MAX77843 chips.
|
||||
|
||||
To compile this driver as module, choose M here: the
|
||||
module will be called max77693-haptic.
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <linux/mfd/max77693.h>
|
||||
#include <linux/mfd/max77693-common.h>
|
||||
#include <linux/mfd/max77693-private.h>
|
||||
#include <linux/mfd/max77705-private.h>
|
||||
#include <linux/mfd/max77843-private.h>
|
||||
|
||||
#define MAX_MAGNITUDE_SHIFT 16
|
||||
@ -116,6 +117,13 @@ static int max77693_haptic_configure(struct max77693_haptic *haptic,
|
||||
MAX77693_HAPTIC_PWM_DIVISOR_128);
|
||||
config_reg = MAX77693_HAPTIC_REG_CONFIG2;
|
||||
break;
|
||||
case TYPE_MAX77705:
|
||||
value = ((haptic->type << MAX77693_CONFIG2_MODE) |
|
||||
(enable << MAX77693_CONFIG2_MEN) |
|
||||
(haptic->mode << MAX77693_CONFIG2_HTYP) |
|
||||
MAX77693_HAPTIC_PWM_DIVISOR_128);
|
||||
config_reg = MAX77705_PMIC_REG_MCONFIG;
|
||||
break;
|
||||
case TYPE_MAX77843:
|
||||
value = (haptic->type << MCONFIG_MODE_SHIFT) |
|
||||
(enable << MCONFIG_MEN_SHIFT) |
|
||||
@ -313,6 +321,7 @@ static int max77693_haptic_probe(struct platform_device *pdev)
|
||||
case TYPE_MAX77693:
|
||||
haptic->regmap_haptic = max77693->regmap_haptic;
|
||||
break;
|
||||
case TYPE_MAX77705:
|
||||
case TYPE_MAX77843:
|
||||
haptic->regmap_haptic = max77693->regmap;
|
||||
break;
|
||||
@ -408,6 +417,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(max77693_haptic_pm_ops,
|
||||
|
||||
static const struct platform_device_id max77693_haptic_id[] = {
|
||||
{ "max77693-haptic", },
|
||||
{ "max77705-haptic", },
|
||||
{ "max77843-haptic", },
|
||||
{},
|
||||
};
|
||||
@ -415,6 +425,7 @@ MODULE_DEVICE_TABLE(platform, max77693_haptic_id);
|
||||
|
||||
static const struct of_device_id of_max77693_haptic_dt_match[] = {
|
||||
{ .compatible = "maxim,max77693-haptic", },
|
||||
{ .compatible = "maxim,max77705-haptic", },
|
||||
{ .compatible = "maxim,max77843-haptic", },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
@ -433,5 +444,5 @@ module_platform_driver(max77693_haptic_driver);
|
||||
|
||||
MODULE_AUTHOR("Jaewon Kim <jaewon02.kim@samsung.com>");
|
||||
MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>");
|
||||
MODULE_DESCRIPTION("MAXIM 77693/77843 Haptic driver");
|
||||
MODULE_DESCRIPTION("MAXIM 77693/77705/77843 Haptic driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -778,6 +778,14 @@ config LEDS_MAX77650
|
||||
help
|
||||
LEDs driver for MAX77650 family of PMICs from Maxim Integrated.
|
||||
|
||||
config LEDS_MAX77705
|
||||
tristate "LED support for Maxim MAX77705 PMIC"
|
||||
depends on MFD_MAX77705
|
||||
depends on LEDS_CLASS
|
||||
depends on LEDS_CLASS_MULTICOLOR
|
||||
help
|
||||
LED driver for MAX77705 PMIC from Maxim Integrated.
|
||||
|
||||
config LEDS_MAX8997
|
||||
tristate "LED support for MAX8997 PMIC"
|
||||
depends on LEDS_CLASS && MFD_MAX8997
|
||||
|
@ -61,6 +61,7 @@ obj-$(CONFIG_LEDS_LP8864) += leds-lp8864.o
|
||||
obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o
|
||||
obj-$(CONFIG_LEDS_MAX5970) += leds-max5970.o
|
||||
obj-$(CONFIG_LEDS_MAX77650) += leds-max77650.o
|
||||
obj-$(CONFIG_LEDS_MAX77705) += leds-max77705.o
|
||||
obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o
|
||||
obj-$(CONFIG_LEDS_MC13783) += leds-mc13783.o
|
||||
obj-$(CONFIG_LEDS_MENF21BMC) += leds-menf21bmc.o
|
||||
|
275
drivers/leds/leds-max77705.c
Normal file
275
drivers/leds/leds-max77705.c
Normal file
@ -0,0 +1,275 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Based on leds-max77650 driver
|
||||
*
|
||||
* LED driver for MAXIM 77705 PMIC.
|
||||
* Copyright (C) 2025 Dzmitry Sankouski <dsankouski@gmail.org>
|
||||
*/
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/led-class-multicolor.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/mfd/max77705-private.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define MAX77705_LED_NUM_LEDS 4
|
||||
#define MAX77705_LED_EN_MASK GENMASK(1, 0)
|
||||
#define MAX77705_LED_MAX_BRIGHTNESS 0xff
|
||||
#define MAX77705_LED_EN_SHIFT(reg) (reg * MAX77705_RGBLED_EN_WIDTH)
|
||||
#define MAX77705_LED_REG_BRIGHTNESS(reg) (reg + MAX77705_RGBLED_REG_LED0BRT)
|
||||
|
||||
struct max77705_led {
|
||||
struct led_classdev cdev;
|
||||
struct led_classdev_mc mcdev;
|
||||
struct regmap *regmap;
|
||||
|
||||
struct mc_subled *subled_info;
|
||||
};
|
||||
|
||||
static const struct regmap_config max77705_leds_regmap_config = {
|
||||
.reg_base = MAX77705_RGBLED_REG_BASE,
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = MAX77705_LED_REG_END,
|
||||
};
|
||||
|
||||
static int max77705_rgb_blink(struct led_classdev *cdev,
|
||||
unsigned long *delay_on,
|
||||
unsigned long *delay_off)
|
||||
{
|
||||
struct max77705_led *led = container_of(cdev, struct max77705_led, cdev);
|
||||
int value, on_value, off_value;
|
||||
|
||||
if (*delay_on < MAX77705_RGB_DELAY_100_STEP)
|
||||
on_value = 0;
|
||||
else if (*delay_on < MAX77705_RGB_DELAY_100_STEP_LIM)
|
||||
on_value = *delay_on / MAX77705_RGB_DELAY_100_STEP - 1;
|
||||
else if (*delay_on < MAX77705_RGB_DELAY_250_STEP_LIM)
|
||||
on_value = (*delay_on - MAX77705_RGB_DELAY_100_STEP_LIM) /
|
||||
MAX77705_RGB_DELAY_250_STEP +
|
||||
MAX77705_RGB_DELAY_100_STEP_COUNT;
|
||||
else
|
||||
on_value = 15;
|
||||
|
||||
on_value <<= 4;
|
||||
|
||||
if (*delay_off < 1)
|
||||
off_value = 0;
|
||||
else if (*delay_off < MAX77705_RGB_DELAY_500_STEP)
|
||||
off_value = 1;
|
||||
else if (*delay_off < MAX77705_RGB_DELAY_500_STEP_LIM)
|
||||
off_value = *delay_off / MAX77705_RGB_DELAY_500_STEP;
|
||||
else if (*delay_off < MAX77705_RGB_DELAY_1000_STEP_LIM)
|
||||
off_value = (*delay_off - MAX77705_RGB_DELAY_1000_STEP_LIM) /
|
||||
MAX77705_RGB_DELAY_1000_STEP +
|
||||
MAX77705_RGB_DELAY_500_STEP_COUNT;
|
||||
else if (*delay_off < MAX77705_RGB_DELAY_2000_STEP_LIM)
|
||||
off_value = (*delay_off - MAX77705_RGB_DELAY_2000_STEP_LIM) /
|
||||
MAX77705_RGB_DELAY_2000_STEP +
|
||||
MAX77705_RGB_DELAY_1000_STEP_COUNT;
|
||||
else
|
||||
off_value = 15;
|
||||
|
||||
value = on_value | off_value;
|
||||
return regmap_write(led->regmap, MAX77705_RGBLED_REG_LEDBLNK, value);
|
||||
}
|
||||
|
||||
static int max77705_led_brightness_set(struct regmap *regmap, struct mc_subled *subled,
|
||||
int num_colors)
|
||||
{
|
||||
int ret;
|
||||
|
||||
for (int i = 0; i < num_colors; i++) {
|
||||
unsigned int channel, brightness;
|
||||
|
||||
channel = subled[i].channel;
|
||||
brightness = subled[i].brightness;
|
||||
|
||||
if (brightness == LED_OFF) {
|
||||
/* Flash OFF */
|
||||
ret = regmap_update_bits(regmap,
|
||||
MAX77705_RGBLED_REG_LEDEN,
|
||||
MAX77705_LED_EN_MASK << MAX77705_LED_EN_SHIFT(channel), 0);
|
||||
} else {
|
||||
/* Set current */
|
||||
ret = regmap_write(regmap, MAX77705_LED_REG_BRIGHTNESS(channel),
|
||||
brightness);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = regmap_update_bits(regmap,
|
||||
MAX77705_RGBLED_REG_LEDEN,
|
||||
LED_ON << MAX77705_LED_EN_SHIFT(channel),
|
||||
MAX77705_LED_EN_MASK << MAX77705_LED_EN_SHIFT(channel));
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max77705_led_brightness_set_single(struct led_classdev *cdev,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
struct max77705_led *led = container_of(cdev, struct max77705_led, cdev);
|
||||
|
||||
led->subled_info->brightness = brightness;
|
||||
|
||||
return max77705_led_brightness_set(led->regmap, led->subled_info, 1);
|
||||
}
|
||||
|
||||
static int max77705_led_brightness_set_multi(struct led_classdev *cdev,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
struct led_classdev_mc *mcdev = lcdev_to_mccdev(cdev);
|
||||
struct max77705_led *led = container_of(mcdev, struct max77705_led, mcdev);
|
||||
|
||||
led_mc_calc_color_components(mcdev, brightness);
|
||||
|
||||
return max77705_led_brightness_set(led->regmap, led->mcdev.subled_info, mcdev->num_colors);
|
||||
}
|
||||
|
||||
static int max77705_parse_subled(struct device *dev, struct fwnode_handle *np,
|
||||
struct mc_subled *info)
|
||||
{
|
||||
u32 color = LED_COLOR_ID_GREEN;
|
||||
u32 reg;
|
||||
int ret;
|
||||
|
||||
ret = fwnode_property_read_u32(np, "reg", ®);
|
||||
if (ret || !reg || reg >= MAX77705_LED_NUM_LEDS)
|
||||
return dev_err_probe(dev, -EINVAL, "invalid \"reg\" of %pOFn\n", np);
|
||||
|
||||
info->channel = reg;
|
||||
|
||||
ret = fwnode_property_read_u32(np, "color", &color);
|
||||
if (ret < 0 && ret != -EINVAL)
|
||||
return dev_err_probe(dev, ret,
|
||||
"failed to parse \"color\" of %pOF\n", np);
|
||||
|
||||
info->color_index = color;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max77705_add_led(struct device *dev, struct regmap *regmap, struct fwnode_handle *np)
|
||||
{
|
||||
int ret, i = 0;
|
||||
unsigned int color, reg;
|
||||
struct max77705_led *led;
|
||||
struct led_classdev *cdev;
|
||||
struct mc_subled *info;
|
||||
struct fwnode_handle *child;
|
||||
struct led_init_data init_data = {};
|
||||
|
||||
led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
|
||||
if (!led)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = fwnode_property_read_u32(np, "color", &color);
|
||||
if (ret < 0 && ret != -EINVAL)
|
||||
return dev_err_probe(dev, ret,
|
||||
"failed to parse \"color\" of %pOF\n", np);
|
||||
|
||||
led->regmap = regmap;
|
||||
init_data.fwnode = np;
|
||||
|
||||
if (color == LED_COLOR_ID_RGB) {
|
||||
int num_channels = of_get_available_child_count(to_of_node(np));
|
||||
|
||||
ret = fwnode_property_read_u32(np, "reg", ®);
|
||||
if (ret || reg >= MAX77705_LED_NUM_LEDS)
|
||||
ret = -EINVAL;
|
||||
|
||||
info = devm_kcalloc(dev, num_channels, sizeof(*info), GFP_KERNEL);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
cdev = &led->mcdev.led_cdev;
|
||||
cdev->max_brightness = MAX77705_LED_MAX_BRIGHTNESS;
|
||||
cdev->brightness_set_blocking = max77705_led_brightness_set_multi;
|
||||
cdev->blink_set = max77705_rgb_blink;
|
||||
|
||||
fwnode_for_each_available_child_node(np, child) {
|
||||
ret = max77705_parse_subled(dev, child, &info[i]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
info[i].intensity = 0;
|
||||
i++;
|
||||
}
|
||||
|
||||
led->mcdev.subled_info = info;
|
||||
led->mcdev.num_colors = num_channels;
|
||||
led->cdev = *cdev;
|
||||
|
||||
ret = devm_led_classdev_multicolor_register_ext(dev, &led->mcdev, &init_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = max77705_led_brightness_set_multi(&led->cdev, LED_OFF);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
max77705_parse_subled(dev, np, info);
|
||||
|
||||
led->subled_info = info;
|
||||
led->cdev.brightness_set_blocking = max77705_led_brightness_set_single;
|
||||
led->cdev.blink_set = max77705_rgb_blink;
|
||||
led->cdev.max_brightness = MAX77705_LED_MAX_BRIGHTNESS;
|
||||
|
||||
ret = devm_led_classdev_register_ext(dev, &led->cdev, &init_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = max77705_led_brightness_set_single(&led->cdev, LED_OFF);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max77705_led_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct i2c_client *i2c = to_i2c_client(pdev->dev.parent);
|
||||
struct regmap *regmap;
|
||||
int ret;
|
||||
|
||||
regmap = devm_regmap_init_i2c(i2c, &max77705_leds_regmap_config);
|
||||
if (IS_ERR(regmap))
|
||||
return dev_err_probe(dev, PTR_ERR(regmap), "Failed to register LEDs regmap\n");
|
||||
|
||||
device_for_each_child_node_scoped(dev, child) {
|
||||
ret = max77705_add_led(dev, regmap, child);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id max77705_led_of_match[] = {
|
||||
{ .compatible = "maxim,max77705-rgb" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, max77705_led_of_match);
|
||||
|
||||
static struct platform_driver max77705_led_driver = {
|
||||
.driver = {
|
||||
.name = "max77705-led",
|
||||
.of_match_table = max77705_led_of_match,
|
||||
},
|
||||
.probe = max77705_led_probe,
|
||||
};
|
||||
module_platform_driver(max77705_led_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Maxim MAX77705 LED driver");
|
||||
MODULE_AUTHOR("Dzmitry Sankouski <dsankouski@gmail.com>");
|
||||
MODULE_LICENSE("GPL");
|
@ -138,7 +138,7 @@ config MFD_AAT2870_CORE
|
||||
config MFD_AT91_USART
|
||||
tristate "AT91 USART Driver"
|
||||
select MFD_CORE
|
||||
depends on ARCH_AT91 || COMPILE_TEST
|
||||
depends on ARCH_AT91 || ARCH_LAN969X || COMPILE_TEST
|
||||
help
|
||||
Select this to get support for AT91 USART IP. This is a wrapper
|
||||
over at91-usart-serial driver and usart-spi-driver. Only one function
|
||||
@ -858,7 +858,7 @@ config MFD_MAX77541
|
||||
There are regulators and adc.
|
||||
|
||||
config MFD_MAX77620
|
||||
bool "Maxim Semiconductor MAX77620 and MAX20024 PMIC Support"
|
||||
tristate "Maxim Semiconductor MAX77620 and MAX20024 PMIC Support"
|
||||
depends on I2C=y
|
||||
depends on OF
|
||||
select MFD_CORE
|
||||
@ -916,6 +916,19 @@ config MFD_MAX77693
|
||||
additional drivers must be enabled in order to use the functionality
|
||||
of the device.
|
||||
|
||||
config MFD_MAX77705
|
||||
tristate "Maxim MAX77705 PMIC Support"
|
||||
depends on I2C
|
||||
select MFD_CORE
|
||||
select MFD_SIMPLE_MFD_I2C
|
||||
help
|
||||
Say yes here to add support for Maxim Integrated MAX77705 PMIC.
|
||||
This is a Power Management IC with Charger, safe LDOs, Flash, Haptic
|
||||
and MUIC controls on chip.
|
||||
This driver provides common support for accessing the device;
|
||||
additional drivers must be enabled in order to use the functionality
|
||||
of the device.
|
||||
|
||||
config MFD_MAX77714
|
||||
tristate "Maxim Semiconductor MAX77714 PMIC Support"
|
||||
depends on I2C
|
||||
@ -1119,30 +1132,6 @@ config MFD_RETU
|
||||
Retu and Tahvo are a multi-function devices found on Nokia
|
||||
Internet Tablets (770, N800 and N810).
|
||||
|
||||
config MFD_PCF50633
|
||||
tristate "NXP PCF50633"
|
||||
depends on I2C
|
||||
select REGMAP_I2C
|
||||
help
|
||||
Say yes here if you have NXP PCF50633 chip on your board.
|
||||
This core driver provides register access and IRQ handling
|
||||
facilities, and registers devices for the various functions
|
||||
so that function-specific drivers can bind to them.
|
||||
|
||||
config PCF50633_ADC
|
||||
tristate "NXP PCF50633 ADC"
|
||||
depends on MFD_PCF50633
|
||||
help
|
||||
Say yes here if you want to include support for ADC in the
|
||||
NXP PCF50633 chip.
|
||||
|
||||
config PCF50633_GPIO
|
||||
tristate "NXP PCF50633 GPIO"
|
||||
depends on MFD_PCF50633
|
||||
help
|
||||
Say yes here if you want to include support GPIO for pins on
|
||||
the PCF50633 chip.
|
||||
|
||||
config MFD_PM8XXX
|
||||
tristate "Qualcomm PM8xxx PMIC chips driver"
|
||||
depends on ARM || HEXAGON || COMPILE_TEST
|
||||
@ -1495,12 +1484,6 @@ config STMPE_SPI
|
||||
This is used to enable SPI interface of STMPE
|
||||
endmenu
|
||||
|
||||
config MFD_STA2X11
|
||||
bool "STMicroelectronics STA2X11"
|
||||
depends on STA2X11
|
||||
select MFD_CORE
|
||||
select REGMAP_MMIO
|
||||
|
||||
config MFD_SUN6I_PRCM
|
||||
bool "Allwinner A31/A23/A33 PRCM controller"
|
||||
depends on ARCH_SUNXI || COMPILE_TEST
|
||||
|
@ -26,7 +26,6 @@ obj-$(CONFIG_MFD_TI_LP873X) += lp873x.o
|
||||
obj-$(CONFIG_MFD_TI_LP87565) += lp87565.o
|
||||
obj-$(CONFIG_MFD_TI_AM335X_TSCADC) += ti_am335x_tscadc.o
|
||||
|
||||
obj-$(CONFIG_MFD_STA2X11) += sta2x11-mfd.o
|
||||
obj-$(CONFIG_MFD_STMPE) += stmpe.o
|
||||
obj-$(CONFIG_STMPE_I2C) += stmpe-i2c.o
|
||||
obj-$(CONFIG_STMPE_SPI) += stmpe-spi.o
|
||||
@ -168,6 +167,7 @@ obj-$(CONFIG_MFD_MAX77620) += max77620.o
|
||||
obj-$(CONFIG_MFD_MAX77650) += max77650.o
|
||||
obj-$(CONFIG_MFD_MAX77686) += max77686.o
|
||||
obj-$(CONFIG_MFD_MAX77693) += max77693.o
|
||||
obj-$(CONFIG_MFD_MAX77705) += max77705.o
|
||||
obj-$(CONFIG_MFD_MAX77714) += max77714.o
|
||||
obj-$(CONFIG_MFD_MAX77843) += max77843.o
|
||||
obj-$(CONFIG_MFD_MAX8907) += max8907.o
|
||||
@ -183,10 +183,6 @@ obj-$(CONFIG_MFD_MT6370) += mt6370.o
|
||||
mt6397-objs := mt6397-core.o mt6397-irq.o mt6358-irq.o
|
||||
obj-$(CONFIG_MFD_MT6397) += mt6397.o
|
||||
|
||||
pcf50633-objs := pcf50633-core.o pcf50633-irq.o
|
||||
obj-$(CONFIG_MFD_PCF50633) += pcf50633.o
|
||||
obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o
|
||||
obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o
|
||||
obj-$(CONFIG_RZ_MTU3) += rz-mtu3.o
|
||||
obj-$(CONFIG_ABX500_CORE) += abx500-core.o
|
||||
obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o
|
||||
|
@ -224,6 +224,7 @@ static const struct regmap_range axp717_writeable_ranges[] = {
|
||||
regmap_reg_range(AXP717_VSYS_V_POWEROFF, AXP717_VSYS_V_POWEROFF),
|
||||
regmap_reg_range(AXP717_IRQ0_EN, AXP717_IRQ4_EN),
|
||||
regmap_reg_range(AXP717_IRQ0_STATE, AXP717_IRQ4_STATE),
|
||||
regmap_reg_range(AXP717_TS_PIN_CFG, AXP717_TS_PIN_CFG),
|
||||
regmap_reg_range(AXP717_ICC_CHG_SET, AXP717_CV_CHG_SET),
|
||||
regmap_reg_range(AXP717_DCDC_OUTPUT_CONTROL, AXP717_CPUSLDO_CONTROL),
|
||||
regmap_reg_range(AXP717_ADC_CH_EN_CONTROL, AXP717_ADC_CH_EN_CONTROL),
|
||||
|
@ -96,7 +96,7 @@ static int cgbc_session_command(struct cgbc_device_data *cgbc, u8 cmd)
|
||||
|
||||
static int cgbc_session_request(struct cgbc_device_data *cgbc)
|
||||
{
|
||||
unsigned int ret;
|
||||
int ret;
|
||||
|
||||
ret = cgbc_wait_device(cgbc);
|
||||
|
||||
@ -236,6 +236,7 @@ static struct mfd_cell cgbc_devs[] = {
|
||||
{ .name = "cgbc-gpio" },
|
||||
{ .name = "cgbc-i2c", .id = 1 },
|
||||
{ .name = "cgbc-i2c", .id = 2 },
|
||||
{ .name = "cgbc-hwmon" },
|
||||
};
|
||||
|
||||
static int cgbc_map(struct cgbc_device_data *cgbc)
|
||||
@ -384,6 +385,13 @@ static const struct dmi_system_id cgbc_dmi_table[] __initconst = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "conga-SA7"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "SA8",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "congatec"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "conga-SA8"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(dmi, cgbc_dmi_table);
|
||||
|
@ -162,7 +162,7 @@ static int kb3930_probe(struct i2c_client *client)
|
||||
devm_gpiod_get_array_optional(dev, "off", GPIOD_IN);
|
||||
if (IS_ERR(ddata->off_gpios))
|
||||
return PTR_ERR(ddata->off_gpios);
|
||||
if (ddata->off_gpios->ndescs < 2) {
|
||||
if (ddata->off_gpios && ddata->off_gpios->ndescs < 2) {
|
||||
dev_err(dev, "invalid off-gpios property\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -25,11 +25,6 @@ struct pcap_adc_request {
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct pcap_adc_sync_request {
|
||||
u16 res[2];
|
||||
struct completion completion;
|
||||
};
|
||||
|
||||
struct pcap_chip {
|
||||
struct spi_device *spi;
|
||||
|
||||
@ -335,34 +330,6 @@ int pcap_adc_async(struct pcap_chip *pcap, u8 bank, u32 flags, u8 ch[],
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pcap_adc_async);
|
||||
|
||||
static void pcap_adc_sync_cb(void *param, u16 res[])
|
||||
{
|
||||
struct pcap_adc_sync_request *req = param;
|
||||
|
||||
req->res[0] = res[0];
|
||||
req->res[1] = res[1];
|
||||
complete(&req->completion);
|
||||
}
|
||||
|
||||
int pcap_adc_sync(struct pcap_chip *pcap, u8 bank, u32 flags, u8 ch[],
|
||||
u16 res[])
|
||||
{
|
||||
struct pcap_adc_sync_request sync_data;
|
||||
int ret;
|
||||
|
||||
init_completion(&sync_data.completion);
|
||||
ret = pcap_adc_async(pcap, bank, flags, ch, pcap_adc_sync_cb,
|
||||
&sync_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
wait_for_completion(&sync_data.completion);
|
||||
res[0] = sync_data.res[0];
|
||||
res[1] = sync_data.res[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pcap_adc_sync);
|
||||
|
||||
/* subdevs */
|
||||
static int pcap_remove_subdev(struct device *dev, void *unused)
|
||||
{
|
||||
|
@ -82,7 +82,6 @@ static const struct regmap_config chtdc_ti_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = 0xff,
|
||||
.cache_type = REGCACHE_NONE,
|
||||
};
|
||||
|
||||
static const struct regmap_irq chtdc_ti_irqs[] = {
|
||||
|
@ -113,7 +113,6 @@ static const struct regmap_config crystal_cove_regmap_config = {
|
||||
.val_bits = 8,
|
||||
|
||||
.max_register = CRYSTAL_COVE_MAX_REGISTER,
|
||||
.cache_type = REGCACHE_NONE,
|
||||
};
|
||||
|
||||
static const struct regmap_irq crystal_cove_irqs[] = {
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/ipaq-micro.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/string_choices.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/list.h>
|
||||
@ -267,7 +268,7 @@ static void __init ipaq_micro_eeprom_dump(struct ipaq_micro *micro)
|
||||
dev_info(micro->dev, "page mode: %u\n", ipaq_micro_to_u16(dump+84));
|
||||
dev_info(micro->dev, "country ID: %u\n", ipaq_micro_to_u16(dump+86));
|
||||
dev_info(micro->dev, "color display: %s\n",
|
||||
ipaq_micro_to_u16(dump+88) ? "yes" : "no");
|
||||
str_yes_no(ipaq_micro_to_u16(dump + 88)));
|
||||
dev_info(micro->dev, "ROM size: %u MiB\n", ipaq_micro_to_u16(dump+90));
|
||||
dev_info(micro->dev, "RAM size: %u KiB\n", ipaq_micro_to_u16(dump+92));
|
||||
dev_info(micro->dev, "screen: %u x %u\n",
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/max77620.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
@ -700,3 +701,7 @@ static struct i2c_driver max77620_driver = {
|
||||
.id_table = max77620_id,
|
||||
};
|
||||
builtin_i2c_driver(max77620_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Maxim Semiconductor MAX77620 and MAX20024 PMIC Support");
|
||||
MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
182
drivers/mfd/max77705.c
Normal file
182
drivers/mfd/max77705.c
Normal file
@ -0,0 +1,182 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Maxim MAX77705 PMIC core driver
|
||||
*
|
||||
* Copyright (C) 2025 Dzmitry Sankouski <dsankouski@gmail.com>
|
||||
**/
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/max77705-private.h>
|
||||
#include <linux/mfd/max77693-common.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/power/max17042_battery.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
static struct mfd_cell max77705_devs[] = {
|
||||
MFD_CELL_OF("max77705-rgb", NULL, NULL, 0, 0, "maxim,max77705-rgb"),
|
||||
MFD_CELL_OF("max77705-charger", NULL, NULL, 0, 0, "maxim,max77705-charger"),
|
||||
MFD_CELL_OF("max77705-haptic", NULL, NULL, 0, 0, "maxim,max77705-haptic"),
|
||||
};
|
||||
|
||||
static const struct regmap_range max77705_readable_ranges[] = {
|
||||
regmap_reg_range(MAX77705_PMIC_REG_PMICID1, MAX77705_PMIC_REG_BSTOUT_MASK),
|
||||
regmap_reg_range(MAX77705_PMIC_REG_INTSRC, MAX77705_PMIC_REG_RESERVED_29),
|
||||
regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL1, MAX77705_PMIC_REG_BOOSTCONTROL1),
|
||||
regmap_reg_range(MAX77705_PMIC_REG_MCONFIG, MAX77705_PMIC_REG_MCONFIG2),
|
||||
regmap_reg_range(MAX77705_PMIC_REG_FORCE_EN_MASK, MAX77705_PMIC_REG_FORCE_EN_MASK),
|
||||
regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL1, MAX77705_PMIC_REG_BOOSTCONTROL1),
|
||||
regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL2, MAX77705_PMIC_REG_BOOSTCONTROL2),
|
||||
regmap_reg_range(MAX77705_PMIC_REG_SW_RESET, MAX77705_PMIC_REG_USBC_RESET),
|
||||
};
|
||||
|
||||
static const struct regmap_range max77705_writable_ranges[] = {
|
||||
regmap_reg_range(MAX77705_PMIC_REG_MAINCTRL1, MAX77705_PMIC_REG_BSTOUT_MASK),
|
||||
regmap_reg_range(MAX77705_PMIC_REG_INTSRC, MAX77705_PMIC_REG_RESERVED_29),
|
||||
regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL1, MAX77705_PMIC_REG_BOOSTCONTROL1),
|
||||
regmap_reg_range(MAX77705_PMIC_REG_MCONFIG, MAX77705_PMIC_REG_MCONFIG2),
|
||||
regmap_reg_range(MAX77705_PMIC_REG_FORCE_EN_MASK, MAX77705_PMIC_REG_FORCE_EN_MASK),
|
||||
regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL1, MAX77705_PMIC_REG_BOOSTCONTROL1),
|
||||
regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL2, MAX77705_PMIC_REG_BOOSTCONTROL2),
|
||||
regmap_reg_range(MAX77705_PMIC_REG_SW_RESET, MAX77705_PMIC_REG_USBC_RESET),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table max77705_readable_table = {
|
||||
.yes_ranges = max77705_readable_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(max77705_readable_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table max77705_writable_table = {
|
||||
.yes_ranges = max77705_writable_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(max77705_writable_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_config max77705_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.rd_table = &max77705_readable_table,
|
||||
.wr_table = &max77705_writable_table,
|
||||
.max_register = MAX77705_PMIC_REG_USBC_RESET,
|
||||
};
|
||||
|
||||
static const struct regmap_irq max77705_topsys_irqs[] = {
|
||||
{ .mask = MAX77705_SYSTEM_IRQ_BSTEN_INT, },
|
||||
{ .mask = MAX77705_SYSTEM_IRQ_SYSUVLO_INT, },
|
||||
{ .mask = MAX77705_SYSTEM_IRQ_SYSOVLO_INT, },
|
||||
{ .mask = MAX77705_SYSTEM_IRQ_TSHDN_INT, },
|
||||
{ .mask = MAX77705_SYSTEM_IRQ_TM_INT, },
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip max77705_topsys_irq_chip = {
|
||||
.name = "max77705-topsys",
|
||||
.status_base = MAX77705_PMIC_REG_SYSTEM_INT,
|
||||
.mask_base = MAX77705_PMIC_REG_SYSTEM_INT_MASK,
|
||||
.num_regs = 1,
|
||||
.irqs = max77705_topsys_irqs,
|
||||
.num_irqs = ARRAY_SIZE(max77705_topsys_irqs),
|
||||
};
|
||||
|
||||
static int max77705_i2c_probe(struct i2c_client *i2c)
|
||||
{
|
||||
struct device *dev = &i2c->dev;
|
||||
struct max77693_dev *max77705;
|
||||
struct regmap_irq_chip_data *irq_data;
|
||||
struct irq_domain *domain;
|
||||
enum max77705_hw_rev pmic_rev;
|
||||
unsigned int pmic_rev_value;
|
||||
int ret;
|
||||
|
||||
max77705 = devm_kzalloc(dev, sizeof(*max77705), GFP_KERNEL);
|
||||
if (!max77705)
|
||||
return -ENOMEM;
|
||||
|
||||
max77705->i2c = i2c;
|
||||
max77705->type = TYPE_MAX77705;
|
||||
i2c_set_clientdata(i2c, max77705);
|
||||
|
||||
max77705->regmap = devm_regmap_init_i2c(i2c, &max77705_regmap_config);
|
||||
if (IS_ERR(max77705->regmap))
|
||||
return PTR_ERR(max77705->regmap);
|
||||
|
||||
ret = regmap_read(max77705->regmap, MAX77705_PMIC_REG_PMICREV, &pmic_rev_value);
|
||||
if (ret < 0)
|
||||
return -ENODEV;
|
||||
|
||||
pmic_rev = pmic_rev_value & MAX77705_REVISION_MASK;
|
||||
if (pmic_rev != MAX77705_PASS3)
|
||||
return dev_err_probe(dev, -ENODEV, "Rev.0x%x is not tested\n", pmic_rev);
|
||||
|
||||
ret = devm_regmap_add_irq_chip(dev, max77705->regmap,
|
||||
i2c->irq,
|
||||
IRQF_ONESHOT | IRQF_SHARED, 0,
|
||||
&max77705_topsys_irq_chip,
|
||||
&irq_data);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to add IRQ chip\n");
|
||||
|
||||
/* Unmask interrupts from all blocks in interrupt source register */
|
||||
ret = regmap_update_bits(max77705->regmap,
|
||||
MAX77705_PMIC_REG_INTSRC_MASK,
|
||||
MAX77705_SRC_IRQ_ALL, (unsigned int)~MAX77705_SRC_IRQ_ALL);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(dev, ret, "Could not unmask interrupts in INTSRC\n");
|
||||
|
||||
domain = regmap_irq_get_domain(irq_data);
|
||||
|
||||
ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
|
||||
max77705_devs, ARRAY_SIZE(max77705_devs),
|
||||
NULL, 0, domain);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to register child devices\n");
|
||||
|
||||
device_init_wakeup(dev, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max77705_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *i2c = to_i2c_client(dev);
|
||||
|
||||
disable_irq(i2c->irq);
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
enable_irq_wake(i2c->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max77705_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *i2c = to_i2c_client(dev);
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
disable_irq_wake(i2c->irq);
|
||||
|
||||
enable_irq(i2c->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
DEFINE_SIMPLE_DEV_PM_OPS(max77705_pm_ops, max77705_suspend, max77705_resume);
|
||||
|
||||
static const struct of_device_id max77705_i2c_of_match[] = {
|
||||
{ .compatible = "maxim,max77705" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, max77705_i2c_of_match);
|
||||
|
||||
static struct i2c_driver max77705_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "max77705",
|
||||
.of_match_table = max77705_i2c_of_match,
|
||||
.pm = pm_sleep_ptr(&max77705_pm_ops),
|
||||
},
|
||||
.probe = max77705_i2c_probe
|
||||
};
|
||||
module_i2c_driver(max77705_i2c_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Maxim MAX77705 PMIC core driver");
|
||||
MODULE_AUTHOR("Dzmitry Sankouski <dsankouski@gmail.com>");
|
||||
MODULE_LICENSE("GPL");
|
@ -335,7 +335,8 @@ int max8997_irq_init(struct max8997_dev *max8997)
|
||||
}
|
||||
max8997->irq_domain = domain;
|
||||
|
||||
ret = request_threaded_irq(max8997->irq, NULL, max8997_irq_thread,
|
||||
ret = devm_request_threaded_irq(max8997->dev, max8997->irq, NULL,
|
||||
max8997_irq_thread,
|
||||
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
|
||||
"max8997-irq", max8997);
|
||||
|
||||
@ -348,7 +349,8 @@ int max8997_irq_init(struct max8997_dev *max8997)
|
||||
if (!max8997->ono)
|
||||
return 0;
|
||||
|
||||
ret = request_threaded_irq(max8997->ono, NULL, max8997_irq_thread,
|
||||
ret = devm_request_threaded_irq(max8997->dev, max8997->ono, NULL,
|
||||
max8997_irq_thread,
|
||||
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
|
||||
IRQF_ONESHOT, "max8997-ono", max8997);
|
||||
|
||||
@ -358,12 +360,3 @@ int max8997_irq_init(struct max8997_dev *max8997)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void max8997_irq_exit(struct max8997_dev *max8997)
|
||||
{
|
||||
if (max8997->ono)
|
||||
free_irq(max8997->ono, max8997);
|
||||
|
||||
if (max8997->irq)
|
||||
free_irq(max8997->irq, max8997);
|
||||
}
|
||||
|
@ -84,6 +84,12 @@ static const struct resource mt6359_keys_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(MT6359_IRQ_HOMEKEY_R, "homekey_r"),
|
||||
};
|
||||
|
||||
static const struct resource mt6359_accdet_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(MT6359_IRQ_ACCDET, "accdet_irq"),
|
||||
DEFINE_RES_IRQ_NAMED(MT6359_IRQ_ACCDET_EINT0, "accdet_eint0"),
|
||||
DEFINE_RES_IRQ_NAMED(MT6359_IRQ_ACCDET_EINT1, "accdet_eint1"),
|
||||
};
|
||||
|
||||
static const struct resource mt6323_keys_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(MT6323_IRQ_STATUS_PWRKEY, "powerkey"),
|
||||
DEFINE_RES_IRQ_NAMED(MT6323_IRQ_STATUS_FCHRKEY, "homekey"),
|
||||
@ -239,6 +245,12 @@ static const struct mfd_cell mt6359_devs[] = {
|
||||
.resources = mt6359_keys_resources,
|
||||
.of_compatible = "mediatek,mt6359-keys"
|
||||
},
|
||||
{
|
||||
.name = "mt6359-accdet",
|
||||
.of_compatible = "mediatek,mt6359-accdet",
|
||||
.num_resources = ARRAY_SIZE(mt6359_accdet_resources),
|
||||
.resources = mt6359_accdet_resources,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct mfd_cell mt6397_devs[] = {
|
||||
|
@ -1,255 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/* NXP PCF50633 ADC Driver
|
||||
*
|
||||
* (C) 2006-2008 by Openmoko, Inc.
|
||||
* Author: Balaji Rao <balajirrao@openmoko.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Broken down from monstrous PCF50633 driver mainly by
|
||||
* Harald Welte, Andy Green and Werner Almesberger
|
||||
*
|
||||
* NOTE: This driver does not yet support subtractive ADC mode, which means
|
||||
* you can do only one measurement per read request.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/completion.h>
|
||||
|
||||
#include <linux/mfd/pcf50633/core.h>
|
||||
#include <linux/mfd/pcf50633/adc.h>
|
||||
|
||||
struct pcf50633_adc_request {
|
||||
int mux;
|
||||
int avg;
|
||||
void (*callback)(struct pcf50633 *, void *, int);
|
||||
void *callback_param;
|
||||
};
|
||||
|
||||
struct pcf50633_adc_sync_request {
|
||||
int result;
|
||||
struct completion completion;
|
||||
};
|
||||
|
||||
#define PCF50633_MAX_ADC_FIFO_DEPTH 8
|
||||
|
||||
struct pcf50633_adc {
|
||||
struct pcf50633 *pcf;
|
||||
|
||||
/* Private stuff */
|
||||
struct pcf50633_adc_request *queue[PCF50633_MAX_ADC_FIFO_DEPTH];
|
||||
int queue_head;
|
||||
int queue_tail;
|
||||
struct mutex queue_mutex;
|
||||
};
|
||||
|
||||
static inline struct pcf50633_adc *__to_adc(struct pcf50633 *pcf)
|
||||
{
|
||||
return platform_get_drvdata(pcf->adc_pdev);
|
||||
}
|
||||
|
||||
static void adc_setup(struct pcf50633 *pcf, int channel, int avg)
|
||||
{
|
||||
channel &= PCF50633_ADCC1_ADCMUX_MASK;
|
||||
|
||||
/* kill ratiometric, but enable ACCSW biasing */
|
||||
pcf50633_reg_write(pcf, PCF50633_REG_ADCC2, 0x00);
|
||||
pcf50633_reg_write(pcf, PCF50633_REG_ADCC3, 0x01);
|
||||
|
||||
/* start ADC conversion on selected channel */
|
||||
pcf50633_reg_write(pcf, PCF50633_REG_ADCC1, channel | avg |
|
||||
PCF50633_ADCC1_ADCSTART | PCF50633_ADCC1_RES_10BIT);
|
||||
}
|
||||
|
||||
static void trigger_next_adc_job_if_any(struct pcf50633 *pcf)
|
||||
{
|
||||
struct pcf50633_adc *adc = __to_adc(pcf);
|
||||
int head;
|
||||
|
||||
head = adc->queue_head;
|
||||
|
||||
if (!adc->queue[head])
|
||||
return;
|
||||
|
||||
adc_setup(pcf, adc->queue[head]->mux, adc->queue[head]->avg);
|
||||
}
|
||||
|
||||
static int
|
||||
adc_enqueue_request(struct pcf50633 *pcf, struct pcf50633_adc_request *req)
|
||||
{
|
||||
struct pcf50633_adc *adc = __to_adc(pcf);
|
||||
int head, tail;
|
||||
|
||||
mutex_lock(&adc->queue_mutex);
|
||||
|
||||
head = adc->queue_head;
|
||||
tail = adc->queue_tail;
|
||||
|
||||
if (adc->queue[tail]) {
|
||||
mutex_unlock(&adc->queue_mutex);
|
||||
dev_err(pcf->dev, "ADC queue is full, dropping request\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
adc->queue[tail] = req;
|
||||
if (head == tail)
|
||||
trigger_next_adc_job_if_any(pcf);
|
||||
adc->queue_tail = (tail + 1) & (PCF50633_MAX_ADC_FIFO_DEPTH - 1);
|
||||
|
||||
mutex_unlock(&adc->queue_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pcf50633_adc_sync_read_callback(struct pcf50633 *pcf, void *param,
|
||||
int result)
|
||||
{
|
||||
struct pcf50633_adc_sync_request *req = param;
|
||||
|
||||
req->result = result;
|
||||
complete(&req->completion);
|
||||
}
|
||||
|
||||
int pcf50633_adc_sync_read(struct pcf50633 *pcf, int mux, int avg)
|
||||
{
|
||||
struct pcf50633_adc_sync_request req;
|
||||
int ret;
|
||||
|
||||
init_completion(&req.completion);
|
||||
|
||||
ret = pcf50633_adc_async_read(pcf, mux, avg,
|
||||
pcf50633_adc_sync_read_callback, &req);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
wait_for_completion(&req.completion);
|
||||
|
||||
return req.result;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pcf50633_adc_sync_read);
|
||||
|
||||
int pcf50633_adc_async_read(struct pcf50633 *pcf, int mux, int avg,
|
||||
void (*callback)(struct pcf50633 *, void *, int),
|
||||
void *callback_param)
|
||||
{
|
||||
struct pcf50633_adc_request *req;
|
||||
int ret;
|
||||
|
||||
/* req is freed when the result is ready, in interrupt handler */
|
||||
req = kmalloc(sizeof(*req), GFP_KERNEL);
|
||||
if (!req)
|
||||
return -ENOMEM;
|
||||
|
||||
req->mux = mux;
|
||||
req->avg = avg;
|
||||
req->callback = callback;
|
||||
req->callback_param = callback_param;
|
||||
|
||||
ret = adc_enqueue_request(pcf, req);
|
||||
if (ret)
|
||||
kfree(req);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pcf50633_adc_async_read);
|
||||
|
||||
static int adc_result(struct pcf50633 *pcf)
|
||||
{
|
||||
u8 adcs1, adcs3;
|
||||
u16 result;
|
||||
|
||||
adcs1 = pcf50633_reg_read(pcf, PCF50633_REG_ADCS1);
|
||||
adcs3 = pcf50633_reg_read(pcf, PCF50633_REG_ADCS3);
|
||||
result = (adcs1 << 2) | (adcs3 & PCF50633_ADCS3_ADCDAT1L_MASK);
|
||||
|
||||
dev_dbg(pcf->dev, "adc result = %d\n", result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void pcf50633_adc_irq(int irq, void *data)
|
||||
{
|
||||
struct pcf50633_adc *adc = data;
|
||||
struct pcf50633 *pcf = adc->pcf;
|
||||
struct pcf50633_adc_request *req;
|
||||
int head, res;
|
||||
|
||||
mutex_lock(&adc->queue_mutex);
|
||||
head = adc->queue_head;
|
||||
|
||||
req = adc->queue[head];
|
||||
if (WARN_ON(!req)) {
|
||||
dev_err(pcf->dev, "pcf50633-adc irq: ADC queue empty!\n");
|
||||
mutex_unlock(&adc->queue_mutex);
|
||||
return;
|
||||
}
|
||||
adc->queue[head] = NULL;
|
||||
adc->queue_head = (head + 1) &
|
||||
(PCF50633_MAX_ADC_FIFO_DEPTH - 1);
|
||||
|
||||
res = adc_result(pcf);
|
||||
trigger_next_adc_job_if_any(pcf);
|
||||
|
||||
mutex_unlock(&adc->queue_mutex);
|
||||
|
||||
req->callback(pcf, req->callback_param, res);
|
||||
kfree(req);
|
||||
}
|
||||
|
||||
static int pcf50633_adc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct pcf50633_adc *adc;
|
||||
|
||||
adc = devm_kzalloc(&pdev->dev, sizeof(*adc), GFP_KERNEL);
|
||||
if (!adc)
|
||||
return -ENOMEM;
|
||||
|
||||
adc->pcf = dev_to_pcf50633(pdev->dev.parent);
|
||||
platform_set_drvdata(pdev, adc);
|
||||
|
||||
pcf50633_register_irq(adc->pcf, PCF50633_IRQ_ADCRDY,
|
||||
pcf50633_adc_irq, adc);
|
||||
|
||||
mutex_init(&adc->queue_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pcf50633_adc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct pcf50633_adc *adc = platform_get_drvdata(pdev);
|
||||
int i, head;
|
||||
|
||||
pcf50633_free_irq(adc->pcf, PCF50633_IRQ_ADCRDY);
|
||||
|
||||
mutex_lock(&adc->queue_mutex);
|
||||
head = adc->queue_head;
|
||||
|
||||
if (WARN_ON(adc->queue[head]))
|
||||
dev_err(adc->pcf->dev,
|
||||
"adc driver removed with request pending\n");
|
||||
|
||||
for (i = 0; i < PCF50633_MAX_ADC_FIFO_DEPTH; i++)
|
||||
kfree(adc->queue[i]);
|
||||
|
||||
mutex_unlock(&adc->queue_mutex);
|
||||
}
|
||||
|
||||
static struct platform_driver pcf50633_adc_driver = {
|
||||
.driver = {
|
||||
.name = "pcf50633-adc",
|
||||
},
|
||||
.probe = pcf50633_adc_probe,
|
||||
.remove = pcf50633_adc_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(pcf50633_adc_driver);
|
||||
|
||||
MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>");
|
||||
MODULE_DESCRIPTION("PCF50633 adc driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:pcf50633-adc");
|
||||
|
@ -1,304 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/* NXP PCF50633 Power Management Unit (PMU) driver
|
||||
*
|
||||
* (C) 2006-2008 by Openmoko, Inc.
|
||||
* Author: Harald Welte <laforge@openmoko.org>
|
||||
* Balaji Rao <balajirrao@openmoko.org>
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include <linux/mfd/pcf50633/core.h>
|
||||
|
||||
/* Read a block of up to 32 regs */
|
||||
int pcf50633_read_block(struct pcf50633 *pcf, u8 reg,
|
||||
int nr_regs, u8 *data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = regmap_raw_read(pcf->regmap, reg, data, nr_regs);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
return nr_regs;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pcf50633_read_block);
|
||||
|
||||
/* Write a block of up to 32 regs */
|
||||
int pcf50633_write_block(struct pcf50633 *pcf , u8 reg,
|
||||
int nr_regs, u8 *data)
|
||||
{
|
||||
return regmap_raw_write(pcf->regmap, reg, data, nr_regs);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pcf50633_write_block);
|
||||
|
||||
u8 pcf50633_reg_read(struct pcf50633 *pcf, u8 reg)
|
||||
{
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(pcf->regmap, reg, &val);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
return val;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pcf50633_reg_read);
|
||||
|
||||
int pcf50633_reg_write(struct pcf50633 *pcf, u8 reg, u8 val)
|
||||
{
|
||||
return regmap_write(pcf->regmap, reg, val);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pcf50633_reg_write);
|
||||
|
||||
int pcf50633_reg_set_bit_mask(struct pcf50633 *pcf, u8 reg, u8 mask, u8 val)
|
||||
{
|
||||
return regmap_update_bits(pcf->regmap, reg, mask, val);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pcf50633_reg_set_bit_mask);
|
||||
|
||||
int pcf50633_reg_clear_bits(struct pcf50633 *pcf, u8 reg, u8 val)
|
||||
{
|
||||
return regmap_update_bits(pcf->regmap, reg, val, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pcf50633_reg_clear_bits);
|
||||
|
||||
/* sysfs attributes */
|
||||
static ssize_t dump_regs_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct pcf50633 *pcf = dev_get_drvdata(dev);
|
||||
u8 dump[16];
|
||||
int n, n1, idx = 0;
|
||||
char *buf1 = buf;
|
||||
static u8 address_no_read[] = { /* must be ascending */
|
||||
PCF50633_REG_INT1,
|
||||
PCF50633_REG_INT2,
|
||||
PCF50633_REG_INT3,
|
||||
PCF50633_REG_INT4,
|
||||
PCF50633_REG_INT5,
|
||||
0 /* terminator */
|
||||
};
|
||||
|
||||
for (n = 0; n < 256; n += sizeof(dump)) {
|
||||
for (n1 = 0; n1 < sizeof(dump); n1++)
|
||||
if (n == address_no_read[idx]) {
|
||||
idx++;
|
||||
dump[n1] = 0x00;
|
||||
} else
|
||||
dump[n1] = pcf50633_reg_read(pcf, n + n1);
|
||||
|
||||
buf1 += sprintf(buf1, "%*ph\n", (int)sizeof(dump), dump);
|
||||
}
|
||||
|
||||
return buf1 - buf;
|
||||
}
|
||||
static DEVICE_ATTR_ADMIN_RO(dump_regs);
|
||||
|
||||
static ssize_t resume_reason_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct pcf50633 *pcf = dev_get_drvdata(dev);
|
||||
int n;
|
||||
|
||||
n = sprintf(buf, "%02x%02x%02x%02x%02x\n",
|
||||
pcf->resume_reason[0],
|
||||
pcf->resume_reason[1],
|
||||
pcf->resume_reason[2],
|
||||
pcf->resume_reason[3],
|
||||
pcf->resume_reason[4]);
|
||||
|
||||
return n;
|
||||
}
|
||||
static DEVICE_ATTR_ADMIN_RO(resume_reason);
|
||||
|
||||
static struct attribute *pcf_sysfs_entries[] = {
|
||||
&dev_attr_dump_regs.attr,
|
||||
&dev_attr_resume_reason.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group pcf_attr_group = {
|
||||
.name = NULL, /* put in device directory */
|
||||
.attrs = pcf_sysfs_entries,
|
||||
};
|
||||
|
||||
static void
|
||||
pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name,
|
||||
struct platform_device **pdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
*pdev = platform_device_alloc(name, -1);
|
||||
if (!*pdev) {
|
||||
dev_err(pcf->dev, "Failed to allocate %s\n", name);
|
||||
return;
|
||||
}
|
||||
|
||||
(*pdev)->dev.parent = pcf->dev;
|
||||
|
||||
ret = platform_device_add(*pdev);
|
||||
if (ret) {
|
||||
dev_err(pcf->dev, "Failed to register %s: %d\n", name, ret);
|
||||
platform_device_put(*pdev);
|
||||
*pdev = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct regmap_config pcf50633_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
};
|
||||
|
||||
static int pcf50633_probe(struct i2c_client *client)
|
||||
{
|
||||
struct pcf50633 *pcf;
|
||||
struct platform_device *pdev;
|
||||
struct pcf50633_platform_data *pdata = dev_get_platdata(&client->dev);
|
||||
int i, j, ret;
|
||||
int version, variant;
|
||||
|
||||
if (!client->irq) {
|
||||
dev_err(&client->dev, "Missing IRQ\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
pcf = devm_kzalloc(&client->dev, sizeof(*pcf), GFP_KERNEL);
|
||||
if (!pcf)
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(client, pcf);
|
||||
pcf->dev = &client->dev;
|
||||
pcf->pdata = pdata;
|
||||
|
||||
mutex_init(&pcf->lock);
|
||||
|
||||
pcf->regmap = devm_regmap_init_i2c(client, &pcf50633_regmap_config);
|
||||
if (IS_ERR(pcf->regmap)) {
|
||||
ret = PTR_ERR(pcf->regmap);
|
||||
dev_err(pcf->dev, "Failed to allocate register map: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
version = pcf50633_reg_read(pcf, 0);
|
||||
variant = pcf50633_reg_read(pcf, 1);
|
||||
if (version < 0 || variant < 0) {
|
||||
dev_err(pcf->dev, "Unable to probe pcf50633\n");
|
||||
ret = -ENODEV;
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_info(pcf->dev, "Probed device version %d variant %d\n",
|
||||
version, variant);
|
||||
|
||||
pcf50633_irq_init(pcf, client->irq);
|
||||
|
||||
/* Create sub devices */
|
||||
pcf50633_client_dev_register(pcf, "pcf50633-input", &pcf->input_pdev);
|
||||
pcf50633_client_dev_register(pcf, "pcf50633-rtc", &pcf->rtc_pdev);
|
||||
pcf50633_client_dev_register(pcf, "pcf50633-mbc", &pcf->mbc_pdev);
|
||||
pcf50633_client_dev_register(pcf, "pcf50633-adc", &pcf->adc_pdev);
|
||||
pcf50633_client_dev_register(pcf, "pcf50633-backlight", &pcf->bl_pdev);
|
||||
|
||||
|
||||
for (i = 0; i < PCF50633_NUM_REGULATORS; i++) {
|
||||
pdev = platform_device_alloc("pcf50633-regulator", i);
|
||||
if (!pdev) {
|
||||
ret = -ENOMEM;
|
||||
goto err2;
|
||||
}
|
||||
|
||||
pdev->dev.parent = pcf->dev;
|
||||
ret = platform_device_add_data(pdev, &pdata->reg_init_data[i],
|
||||
sizeof(pdata->reg_init_data[i]));
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = platform_device_add(pdev);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
pcf->regulator_pdev[i] = pdev;
|
||||
}
|
||||
|
||||
ret = sysfs_create_group(&client->dev.kobj, &pcf_attr_group);
|
||||
if (ret)
|
||||
dev_warn(pcf->dev, "error creating sysfs entries\n");
|
||||
|
||||
if (pdata->probe_done)
|
||||
pdata->probe_done(pcf);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
platform_device_put(pdev);
|
||||
err2:
|
||||
for (j = 0; j < i; j++)
|
||||
platform_device_put(pcf->regulator_pdev[j]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void pcf50633_remove(struct i2c_client *client)
|
||||
{
|
||||
struct pcf50633 *pcf = i2c_get_clientdata(client);
|
||||
int i;
|
||||
|
||||
sysfs_remove_group(&client->dev.kobj, &pcf_attr_group);
|
||||
pcf50633_irq_free(pcf);
|
||||
|
||||
platform_device_unregister(pcf->input_pdev);
|
||||
platform_device_unregister(pcf->rtc_pdev);
|
||||
platform_device_unregister(pcf->mbc_pdev);
|
||||
platform_device_unregister(pcf->adc_pdev);
|
||||
platform_device_unregister(pcf->bl_pdev);
|
||||
|
||||
for (i = 0; i < PCF50633_NUM_REGULATORS; i++)
|
||||
platform_device_unregister(pcf->regulator_pdev[i]);
|
||||
}
|
||||
|
||||
static const struct i2c_device_id pcf50633_id_table[] = {
|
||||
{"pcf50633", 0x73},
|
||||
{/* end of list */}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, pcf50633_id_table);
|
||||
|
||||
static struct i2c_driver pcf50633_driver = {
|
||||
.driver = {
|
||||
.name = "pcf50633",
|
||||
.pm = pm_sleep_ptr(&pcf50633_pm),
|
||||
},
|
||||
.id_table = pcf50633_id_table,
|
||||
.probe = pcf50633_probe,
|
||||
.remove = pcf50633_remove,
|
||||
};
|
||||
|
||||
static int __init pcf50633_init(void)
|
||||
{
|
||||
return i2c_add_driver(&pcf50633_driver);
|
||||
}
|
||||
|
||||
static void __exit pcf50633_exit(void)
|
||||
{
|
||||
i2c_del_driver(&pcf50633_driver);
|
||||
}
|
||||
|
||||
MODULE_DESCRIPTION("I2C chip driver for NXP PCF50633 PMU");
|
||||
MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
subsys_initcall(pcf50633_init);
|
||||
module_exit(pcf50633_exit);
|
@ -1,92 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/* NXP PCF50633 GPIO Driver
|
||||
*
|
||||
* (C) 2006-2008 by Openmoko, Inc.
|
||||
* Author: Balaji Rao <balajirrao@openmoko.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Broken down from monstrous PCF50633 driver mainly by
|
||||
* Harald Welte, Andy Green and Werner Almesberger
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <linux/mfd/pcf50633/core.h>
|
||||
#include <linux/mfd/pcf50633/gpio.h>
|
||||
#include <linux/mfd/pcf50633/pmic.h>
|
||||
|
||||
static const u8 pcf50633_regulator_registers[PCF50633_NUM_REGULATORS] = {
|
||||
[PCF50633_REGULATOR_AUTO] = PCF50633_REG_AUTOOUT,
|
||||
[PCF50633_REGULATOR_DOWN1] = PCF50633_REG_DOWN1OUT,
|
||||
[PCF50633_REGULATOR_DOWN2] = PCF50633_REG_DOWN2OUT,
|
||||
[PCF50633_REGULATOR_MEMLDO] = PCF50633_REG_MEMLDOOUT,
|
||||
[PCF50633_REGULATOR_LDO1] = PCF50633_REG_LDO1OUT,
|
||||
[PCF50633_REGULATOR_LDO2] = PCF50633_REG_LDO2OUT,
|
||||
[PCF50633_REGULATOR_LDO3] = PCF50633_REG_LDO3OUT,
|
||||
[PCF50633_REGULATOR_LDO4] = PCF50633_REG_LDO4OUT,
|
||||
[PCF50633_REGULATOR_LDO5] = PCF50633_REG_LDO5OUT,
|
||||
[PCF50633_REGULATOR_LDO6] = PCF50633_REG_LDO6OUT,
|
||||
[PCF50633_REGULATOR_HCLDO] = PCF50633_REG_HCLDOOUT,
|
||||
};
|
||||
|
||||
int pcf50633_gpio_set(struct pcf50633 *pcf, int gpio, u8 val)
|
||||
{
|
||||
u8 reg;
|
||||
|
||||
reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG;
|
||||
|
||||
return pcf50633_reg_set_bit_mask(pcf, reg, 0x07, val);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pcf50633_gpio_set);
|
||||
|
||||
u8 pcf50633_gpio_get(struct pcf50633 *pcf, int gpio)
|
||||
{
|
||||
u8 reg, val;
|
||||
|
||||
reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG;
|
||||
val = pcf50633_reg_read(pcf, reg) & 0x07;
|
||||
|
||||
return val;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pcf50633_gpio_get);
|
||||
|
||||
int pcf50633_gpio_invert_set(struct pcf50633 *pcf, int gpio, int invert)
|
||||
{
|
||||
u8 val, reg;
|
||||
|
||||
reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG;
|
||||
val = !!invert << 3;
|
||||
|
||||
return pcf50633_reg_set_bit_mask(pcf, reg, 1 << 3, val);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pcf50633_gpio_invert_set);
|
||||
|
||||
int pcf50633_gpio_invert_get(struct pcf50633 *pcf, int gpio)
|
||||
{
|
||||
u8 reg, val;
|
||||
|
||||
reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG;
|
||||
val = pcf50633_reg_read(pcf, reg);
|
||||
|
||||
return val & (1 << 3);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pcf50633_gpio_invert_get);
|
||||
|
||||
int pcf50633_gpio_power_supply_set(struct pcf50633 *pcf,
|
||||
int gpio, int regulator, int on)
|
||||
{
|
||||
u8 reg, val, mask;
|
||||
|
||||
/* the *ENA register is always one after the *OUT register */
|
||||
reg = pcf50633_regulator_registers[regulator] + 1;
|
||||
|
||||
val = !!on << (gpio - PCF50633_GPIO1);
|
||||
mask = 1 << (gpio - PCF50633_GPIO1);
|
||||
|
||||
return pcf50633_reg_set_bit_mask(pcf, reg, mask, val);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pcf50633_gpio_power_supply_set);
|
||||
|
||||
MODULE_DESCRIPTION("NXP PCF50633 GPIO Driver");
|
||||
MODULE_LICENSE("GPL");
|
@ -1,312 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/* NXP PCF50633 Power Management Unit (PMU) driver
|
||||
*
|
||||
* (C) 2006-2008 by Openmoko, Inc.
|
||||
* Author: Harald Welte <laforge@openmoko.org>
|
||||
* Balaji Rao <balajirrao@openmoko.org>
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <linux/mfd/pcf50633/core.h>
|
||||
#include <linux/mfd/pcf50633/mbc.h>
|
||||
|
||||
int pcf50633_register_irq(struct pcf50633 *pcf, int irq,
|
||||
void (*handler) (int, void *), void *data)
|
||||
{
|
||||
if (irq < 0 || irq >= PCF50633_NUM_IRQ || !handler)
|
||||
return -EINVAL;
|
||||
|
||||
if (WARN_ON(pcf->irq_handler[irq].handler))
|
||||
return -EBUSY;
|
||||
|
||||
mutex_lock(&pcf->lock);
|
||||
pcf->irq_handler[irq].handler = handler;
|
||||
pcf->irq_handler[irq].data = data;
|
||||
mutex_unlock(&pcf->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pcf50633_register_irq);
|
||||
|
||||
int pcf50633_free_irq(struct pcf50633 *pcf, int irq)
|
||||
{
|
||||
if (irq < 0 || irq >= PCF50633_NUM_IRQ)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&pcf->lock);
|
||||
pcf->irq_handler[irq].handler = NULL;
|
||||
mutex_unlock(&pcf->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pcf50633_free_irq);
|
||||
|
||||
static int __pcf50633_irq_mask_set(struct pcf50633 *pcf, int irq, u8 mask)
|
||||
{
|
||||
u8 reg, bit;
|
||||
int idx;
|
||||
|
||||
idx = irq >> 3;
|
||||
reg = PCF50633_REG_INT1M + idx;
|
||||
bit = 1 << (irq & 0x07);
|
||||
|
||||
pcf50633_reg_set_bit_mask(pcf, reg, bit, mask ? bit : 0);
|
||||
|
||||
mutex_lock(&pcf->lock);
|
||||
|
||||
if (mask)
|
||||
pcf->mask_regs[idx] |= bit;
|
||||
else
|
||||
pcf->mask_regs[idx] &= ~bit;
|
||||
|
||||
mutex_unlock(&pcf->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pcf50633_irq_mask(struct pcf50633 *pcf, int irq)
|
||||
{
|
||||
dev_dbg(pcf->dev, "Masking IRQ %d\n", irq);
|
||||
|
||||
return __pcf50633_irq_mask_set(pcf, irq, 1);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pcf50633_irq_mask);
|
||||
|
||||
int pcf50633_irq_unmask(struct pcf50633 *pcf, int irq)
|
||||
{
|
||||
dev_dbg(pcf->dev, "Unmasking IRQ %d\n", irq);
|
||||
|
||||
return __pcf50633_irq_mask_set(pcf, irq, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pcf50633_irq_unmask);
|
||||
|
||||
int pcf50633_irq_mask_get(struct pcf50633 *pcf, int irq)
|
||||
{
|
||||
u8 reg, bits;
|
||||
|
||||
reg = irq >> 3;
|
||||
bits = 1 << (irq & 0x07);
|
||||
|
||||
return pcf->mask_regs[reg] & bits;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pcf50633_irq_mask_get);
|
||||
|
||||
static void pcf50633_irq_call_handler(struct pcf50633 *pcf, int irq)
|
||||
{
|
||||
if (pcf->irq_handler[irq].handler)
|
||||
pcf->irq_handler[irq].handler(irq, pcf->irq_handler[irq].data);
|
||||
}
|
||||
|
||||
/* Maximum amount of time ONKEY is held before emergency action is taken */
|
||||
#define PCF50633_ONKEY1S_TIMEOUT 8
|
||||
|
||||
static irqreturn_t pcf50633_irq(int irq, void *data)
|
||||
{
|
||||
struct pcf50633 *pcf = data;
|
||||
int ret, i, j;
|
||||
u8 pcf_int[5], chgstat;
|
||||
|
||||
/* Read the 5 INT regs in one transaction */
|
||||
ret = pcf50633_read_block(pcf, PCF50633_REG_INT1,
|
||||
ARRAY_SIZE(pcf_int), pcf_int);
|
||||
if (ret != ARRAY_SIZE(pcf_int)) {
|
||||
dev_err(pcf->dev, "Error reading INT registers\n");
|
||||
|
||||
/*
|
||||
* If this doesn't ACK the interrupt to the chip, we'll be
|
||||
* called once again as we're level triggered.
|
||||
*/
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* defeat 8s death from lowsys on A5 */
|
||||
pcf50633_reg_write(pcf, PCF50633_REG_OOCSHDWN, 0x04);
|
||||
|
||||
/* We immediately read the usb and adapter status. We thus make sure
|
||||
* only of USBINS/USBREM IRQ handlers are called */
|
||||
if (pcf_int[0] & (PCF50633_INT1_USBINS | PCF50633_INT1_USBREM)) {
|
||||
chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2);
|
||||
if (chgstat & (0x3 << 4))
|
||||
pcf_int[0] &= ~PCF50633_INT1_USBREM;
|
||||
else
|
||||
pcf_int[0] &= ~PCF50633_INT1_USBINS;
|
||||
}
|
||||
|
||||
/* Make sure only one of ADPINS or ADPREM is set */
|
||||
if (pcf_int[0] & (PCF50633_INT1_ADPINS | PCF50633_INT1_ADPREM)) {
|
||||
chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2);
|
||||
if (chgstat & (0x3 << 4))
|
||||
pcf_int[0] &= ~PCF50633_INT1_ADPREM;
|
||||
else
|
||||
pcf_int[0] &= ~PCF50633_INT1_ADPINS;
|
||||
}
|
||||
|
||||
dev_dbg(pcf->dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x "
|
||||
"INT4=0x%02x INT5=0x%02x\n", pcf_int[0],
|
||||
pcf_int[1], pcf_int[2], pcf_int[3], pcf_int[4]);
|
||||
|
||||
/* Some revisions of the chip don't have a 8s standby mode on
|
||||
* ONKEY1S press. We try to manually do it in such cases. */
|
||||
if ((pcf_int[0] & PCF50633_INT1_SECOND) && pcf->onkey1s_held) {
|
||||
dev_info(pcf->dev, "ONKEY1S held for %d secs\n",
|
||||
pcf->onkey1s_held);
|
||||
if (pcf->onkey1s_held++ == PCF50633_ONKEY1S_TIMEOUT)
|
||||
if (pcf->pdata->force_shutdown)
|
||||
pcf->pdata->force_shutdown(pcf);
|
||||
}
|
||||
|
||||
if (pcf_int[2] & PCF50633_INT3_ONKEY1S) {
|
||||
dev_info(pcf->dev, "ONKEY1S held\n");
|
||||
pcf->onkey1s_held = 1 ;
|
||||
|
||||
/* Unmask IRQ_SECOND */
|
||||
pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT1M,
|
||||
PCF50633_INT1_SECOND);
|
||||
|
||||
/* Unmask IRQ_ONKEYR */
|
||||
pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT2M,
|
||||
PCF50633_INT2_ONKEYR);
|
||||
}
|
||||
|
||||
if ((pcf_int[1] & PCF50633_INT2_ONKEYR) && pcf->onkey1s_held) {
|
||||
pcf->onkey1s_held = 0;
|
||||
|
||||
/* Mask SECOND and ONKEYR interrupts */
|
||||
if (pcf->mask_regs[0] & PCF50633_INT1_SECOND)
|
||||
pcf50633_reg_set_bit_mask(pcf,
|
||||
PCF50633_REG_INT1M,
|
||||
PCF50633_INT1_SECOND,
|
||||
PCF50633_INT1_SECOND);
|
||||
|
||||
if (pcf->mask_regs[1] & PCF50633_INT2_ONKEYR)
|
||||
pcf50633_reg_set_bit_mask(pcf,
|
||||
PCF50633_REG_INT2M,
|
||||
PCF50633_INT2_ONKEYR,
|
||||
PCF50633_INT2_ONKEYR);
|
||||
}
|
||||
|
||||
/* Have we just resumed ? */
|
||||
if (pcf->is_suspended) {
|
||||
pcf->is_suspended = 0;
|
||||
|
||||
/* Set the resume reason filtering out non resumers */
|
||||
for (i = 0; i < ARRAY_SIZE(pcf_int); i++)
|
||||
pcf->resume_reason[i] = pcf_int[i] &
|
||||
pcf->pdata->resumers[i];
|
||||
|
||||
/* Make sure we don't pass on any ONKEY events to
|
||||
* userspace now */
|
||||
pcf_int[1] &= ~(PCF50633_INT2_ONKEYR | PCF50633_INT2_ONKEYF);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(pcf_int); i++) {
|
||||
/* Unset masked interrupts */
|
||||
pcf_int[i] &= ~pcf->mask_regs[i];
|
||||
|
||||
for (j = 0; j < 8 ; j++)
|
||||
if (pcf_int[i] & (1 << j))
|
||||
pcf50633_irq_call_handler(pcf, (i * 8) + j);
|
||||
}
|
||||
|
||||
out:
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int pcf50633_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct pcf50633 *pcf = i2c_get_clientdata(client);
|
||||
int ret;
|
||||
int i;
|
||||
u8 res[5];
|
||||
|
||||
|
||||
/* Make sure our interrupt handlers are not called
|
||||
* henceforth */
|
||||
disable_irq(pcf->irq);
|
||||
|
||||
/* Save the masks */
|
||||
ret = pcf50633_read_block(pcf, PCF50633_REG_INT1M,
|
||||
ARRAY_SIZE(pcf->suspend_irq_masks),
|
||||
pcf->suspend_irq_masks);
|
||||
if (ret < 0) {
|
||||
dev_err(pcf->dev, "error saving irq masks\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Write wakeup irq masks */
|
||||
for (i = 0; i < ARRAY_SIZE(res); i++)
|
||||
res[i] = ~pcf->pdata->resumers[i];
|
||||
|
||||
ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M,
|
||||
ARRAY_SIZE(res), &res[0]);
|
||||
if (ret < 0) {
|
||||
dev_err(pcf->dev, "error writing wakeup irq masks\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
pcf->is_suspended = 1;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pcf50633_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct pcf50633 *pcf = i2c_get_clientdata(client);
|
||||
int ret;
|
||||
|
||||
/* Write the saved mask registers */
|
||||
ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M,
|
||||
ARRAY_SIZE(pcf->suspend_irq_masks),
|
||||
pcf->suspend_irq_masks);
|
||||
if (ret < 0)
|
||||
dev_err(pcf->dev, "Error restoring saved suspend masks\n");
|
||||
|
||||
enable_irq(pcf->irq);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
EXPORT_GPL_SIMPLE_DEV_PM_OPS(pcf50633_pm, pcf50633_suspend, pcf50633_resume);
|
||||
|
||||
int pcf50633_irq_init(struct pcf50633 *pcf, int irq)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pcf->irq = irq;
|
||||
|
||||
/* Enable all interrupts except RTC SECOND */
|
||||
pcf->mask_regs[0] = 0x80;
|
||||
pcf50633_reg_write(pcf, PCF50633_REG_INT1M, pcf->mask_regs[0]);
|
||||
pcf50633_reg_write(pcf, PCF50633_REG_INT2M, 0x00);
|
||||
pcf50633_reg_write(pcf, PCF50633_REG_INT3M, 0x00);
|
||||
pcf50633_reg_write(pcf, PCF50633_REG_INT4M, 0x00);
|
||||
pcf50633_reg_write(pcf, PCF50633_REG_INT5M, 0x00);
|
||||
|
||||
ret = request_threaded_irq(irq, NULL, pcf50633_irq,
|
||||
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
|
||||
"pcf50633", pcf);
|
||||
|
||||
if (ret)
|
||||
dev_err(pcf->dev, "Failed to request IRQ %d\n", ret);
|
||||
|
||||
if (enable_irq_wake(irq) < 0)
|
||||
dev_err(pcf->dev, "IRQ %u cannot be enabled as wake-up source"
|
||||
"in this hardware revision", irq);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void pcf50633_irq_free(struct pcf50633 *pcf)
|
||||
{
|
||||
free_irq(pcf->irq, pcf);
|
||||
}
|
@ -158,9 +158,9 @@ int qnap_mcu_exec(struct qnap_mcu *mcu,
|
||||
|
||||
mutex_lock(&mcu->bus_lock);
|
||||
|
||||
reply->data = rx,
|
||||
reply->length = length,
|
||||
reply->received = 0,
|
||||
reply->data = rx;
|
||||
reply->length = length;
|
||||
reply->received = 0;
|
||||
reinit_completion(&reply->done);
|
||||
|
||||
qnap_mcu_write(mcu, cmd_data, cmd_data_size);
|
||||
|
@ -83,6 +83,11 @@ 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",
|
||||
@ -108,6 +113,9 @@ static const struct of_device_id sec_dt_match[] = {
|
||||
}, {
|
||||
.compatible = "samsung,s2mpu02-pmic",
|
||||
.data = (void *)S2MPU02,
|
||||
}, {
|
||||
.compatible = "samsung,s2mpu05-pmic",
|
||||
.data = (void *)S2MPU05,
|
||||
}, {
|
||||
/* Sentinel */
|
||||
},
|
||||
@ -374,6 +382,10 @@ static int sec_pmic_probe(struct i2c_client *i2c)
|
||||
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);
|
||||
|
@ -14,6 +14,7 @@
|
||||
#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>
|
||||
|
||||
static const struct regmap_irq s2mps11_irqs[] = {
|
||||
@ -225,6 +226,26 @@ static const struct regmap_irq s2mpu02_irqs[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct regmap_irq s2mpu05_irqs[] = {
|
||||
REGMAP_IRQ_REG(S2MPU05_IRQ_PWRONF, 0, S2MPU05_IRQ_PWRONF_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU05_IRQ_PWRONR, 0, S2MPU05_IRQ_PWRONR_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU05_IRQ_JIGONBF, 0, S2MPU05_IRQ_JIGONBF_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU05_IRQ_JIGONBR, 0, S2MPU05_IRQ_JIGONBR_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU05_IRQ_ACOKF, 0, S2MPU05_IRQ_ACOKF_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU05_IRQ_ACOKR, 0, S2MPU05_IRQ_ACOKR_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU05_IRQ_PWRON1S, 0, S2MPU05_IRQ_PWRON1S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU05_IRQ_MRB, 0, S2MPU05_IRQ_MRB_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU05_IRQ_RTC60S, 1, S2MPU05_IRQ_RTC60S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU05_IRQ_RTCA1, 1, S2MPU05_IRQ_RTCA1_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU05_IRQ_RTCA0, 1, S2MPU05_IRQ_RTCA0_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU05_IRQ_SMPL, 1, S2MPU05_IRQ_SMPL_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU05_IRQ_RTC1S, 1, S2MPU05_IRQ_RTC1S_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU05_IRQ_WTSR, 1, S2MPU05_IRQ_WTSR_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU05_IRQ_INT120C, 2, S2MPU05_IRQ_INT120C_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU05_IRQ_INT140C, 2, S2MPU05_IRQ_INT140C_MASK),
|
||||
REGMAP_IRQ_REG(S2MPU05_IRQ_TSD, 2, S2MPU05_IRQ_TSD_MASK),
|
||||
};
|
||||
|
||||
static const struct regmap_irq s5m8767_irqs[] = {
|
||||
[S5M8767_IRQ_PWRR] = {
|
||||
.reg_offset = 0,
|
||||
@ -339,6 +360,16 @@ static const struct regmap_irq_chip s2mpu02_irq_chip = {
|
||||
.ack_base = S2MPU02_REG_INT1,
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip s2mpu05_irq_chip = {
|
||||
.name = "s2mpu05",
|
||||
.irqs = s2mpu05_irqs,
|
||||
.num_irqs = ARRAY_SIZE(s2mpu05_irqs),
|
||||
.num_regs = 3,
|
||||
.status_base = S2MPU05_REG_INT1,
|
||||
.mask_base = S2MPU05_REG_INT1M,
|
||||
.ack_base = S2MPU05_REG_INT1,
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip s5m8767_irq_chip = {
|
||||
.name = "s5m8767",
|
||||
.irqs = s5m8767_irqs,
|
||||
@ -383,6 +414,9 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)
|
||||
case S2MPU02:
|
||||
sec_irq_chip = &s2mpu02_irq_chip;
|
||||
break;
|
||||
case S2MPU05:
|
||||
sec_irq_chip = &s2mpu05_irq_chip;
|
||||
break;
|
||||
default:
|
||||
dev_err(sec_pmic->dev, "Unknown device type %lu\n",
|
||||
sec_pmic->device_type);
|
||||
|
@ -83,11 +83,22 @@ static const struct simple_mfd_data maxim_max5970 = {
|
||||
.mfd_cell_size = ARRAY_SIZE(max5970_cells),
|
||||
};
|
||||
|
||||
static const struct mfd_cell max77705_sensor_cells[] = {
|
||||
{ .name = "max77705-battery" },
|
||||
{ .name = "max77705-hwmon", },
|
||||
};
|
||||
|
||||
static const struct simple_mfd_data maxim_mon_max77705 = {
|
||||
.mfd_cell = max77705_sensor_cells,
|
||||
.mfd_cell_size = ARRAY_SIZE(max77705_sensor_cells),
|
||||
};
|
||||
|
||||
static const struct of_device_id simple_mfd_i2c_of_match[] = {
|
||||
{ .compatible = "kontron,sl28cpld" },
|
||||
{ .compatible = "silergy,sy7636a", .data = &silergy_sy7636a},
|
||||
{ .compatible = "maxim,max5970", .data = &maxim_max5970},
|
||||
{ .compatible = "maxim,max5978", .data = &maxim_max5970},
|
||||
{ .compatible = "maxim,max77705-battery", .data = &maxim_mon_max77705},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, simple_mfd_i2c_of_match);
|
||||
|
@ -920,7 +920,7 @@ static void sm501_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
{
|
||||
struct sm501_gpio_chip *smchip = gpiochip_get_data(chip);
|
||||
struct sm501_gpio *smgpio = smchip->ourgpio;
|
||||
unsigned long bit = 1 << offset;
|
||||
unsigned long bit = BIT(offset);
|
||||
void __iomem *regs = smchip->regbase;
|
||||
unsigned long save;
|
||||
unsigned long val;
|
||||
@ -946,7 +946,7 @@ static int sm501_gpio_input(struct gpio_chip *chip, unsigned offset)
|
||||
struct sm501_gpio_chip *smchip = gpiochip_get_data(chip);
|
||||
struct sm501_gpio *smgpio = smchip->ourgpio;
|
||||
void __iomem *regs = smchip->regbase;
|
||||
unsigned long bit = 1 << offset;
|
||||
unsigned long bit = BIT(offset);
|
||||
unsigned long save;
|
||||
unsigned long ddr;
|
||||
|
||||
@ -971,7 +971,7 @@ static int sm501_gpio_output(struct gpio_chip *chip,
|
||||
{
|
||||
struct sm501_gpio_chip *smchip = gpiochip_get_data(chip);
|
||||
struct sm501_gpio *smgpio = smchip->ourgpio;
|
||||
unsigned long bit = 1 << offset;
|
||||
unsigned long bit = BIT(offset);
|
||||
void __iomem *regs = smchip->regbase;
|
||||
unsigned long save;
|
||||
unsigned long val;
|
||||
|
@ -1,645 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* STA2x11 mfd for GPIO, SCTL and APBREG
|
||||
*
|
||||
* Copyright (c) 2009-2011 Wind River Systems, Inc.
|
||||
* Copyright (c) 2011 ST Microelectronics (Alessandro Rubini, Davide Ciminaghi)
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/sta2x11-mfd.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <asm/sta2x11.h>
|
||||
|
||||
static inline int __reg_within_range(unsigned int r,
|
||||
unsigned int start,
|
||||
unsigned int end)
|
||||
{
|
||||
return ((r >= start) && (r <= end));
|
||||
}
|
||||
|
||||
/* This describes STA2X11 MFD chip for us, we may have several */
|
||||
struct sta2x11_mfd {
|
||||
struct sta2x11_instance *instance;
|
||||
struct regmap *regmap[sta2x11_n_mfd_plat_devs];
|
||||
spinlock_t lock[sta2x11_n_mfd_plat_devs];
|
||||
struct list_head list;
|
||||
void __iomem *regs[sta2x11_n_mfd_plat_devs];
|
||||
};
|
||||
|
||||
static LIST_HEAD(sta2x11_mfd_list);
|
||||
|
||||
/* Three functions to act on the list */
|
||||
static struct sta2x11_mfd *sta2x11_mfd_find(struct pci_dev *pdev)
|
||||
{
|
||||
struct sta2x11_instance *instance;
|
||||
struct sta2x11_mfd *mfd;
|
||||
|
||||
if (!pdev && !list_empty(&sta2x11_mfd_list)) {
|
||||
pr_warn("%s: Unspecified device, using first instance\n",
|
||||
__func__);
|
||||
return list_entry(sta2x11_mfd_list.next,
|
||||
struct sta2x11_mfd, list);
|
||||
}
|
||||
|
||||
instance = sta2x11_get_instance(pdev);
|
||||
if (!instance)
|
||||
return NULL;
|
||||
list_for_each_entry(mfd, &sta2x11_mfd_list, list) {
|
||||
if (mfd->instance == instance)
|
||||
return mfd;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int sta2x11_mfd_add(struct pci_dev *pdev, gfp_t flags)
|
||||
{
|
||||
int i;
|
||||
struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev);
|
||||
struct sta2x11_instance *instance;
|
||||
|
||||
if (mfd)
|
||||
return -EBUSY;
|
||||
instance = sta2x11_get_instance(pdev);
|
||||
if (!instance)
|
||||
return -EINVAL;
|
||||
mfd = kzalloc(sizeof(*mfd), flags);
|
||||
if (!mfd)
|
||||
return -ENOMEM;
|
||||
INIT_LIST_HEAD(&mfd->list);
|
||||
for (i = 0; i < ARRAY_SIZE(mfd->lock); i++)
|
||||
spin_lock_init(&mfd->lock[i]);
|
||||
mfd->instance = instance;
|
||||
list_add(&mfd->list, &sta2x11_mfd_list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This function is exported and is not expected to fail */
|
||||
u32 __sta2x11_mfd_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val,
|
||||
enum sta2x11_mfd_plat_dev index)
|
||||
{
|
||||
struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev);
|
||||
u32 r;
|
||||
unsigned long flags;
|
||||
void __iomem *regs;
|
||||
|
||||
if (!mfd) {
|
||||
dev_warn(&pdev->dev, ": can't access sctl regs\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
regs = mfd->regs[index];
|
||||
if (!regs) {
|
||||
dev_warn(&pdev->dev, ": system ctl not initialized\n");
|
||||
return 0;
|
||||
}
|
||||
spin_lock_irqsave(&mfd->lock[index], flags);
|
||||
r = readl(regs + reg);
|
||||
r &= ~mask;
|
||||
r |= val;
|
||||
if (mask)
|
||||
writel(r, regs + reg);
|
||||
spin_unlock_irqrestore(&mfd->lock[index], flags);
|
||||
return r;
|
||||
}
|
||||
EXPORT_SYMBOL(__sta2x11_mfd_mask);
|
||||
|
||||
int sta2x11_mfd_get_regs_data(struct platform_device *dev,
|
||||
enum sta2x11_mfd_plat_dev index,
|
||||
void __iomem **regs,
|
||||
spinlock_t **lock)
|
||||
{
|
||||
struct pci_dev *pdev = *(struct pci_dev **)dev_get_platdata(&dev->dev);
|
||||
struct sta2x11_mfd *mfd;
|
||||
|
||||
if (!pdev)
|
||||
return -ENODEV;
|
||||
mfd = sta2x11_mfd_find(pdev);
|
||||
if (!mfd)
|
||||
return -ENODEV;
|
||||
if (index >= sta2x11_n_mfd_plat_devs)
|
||||
return -ENODEV;
|
||||
*regs = mfd->regs[index];
|
||||
*lock = &mfd->lock[index];
|
||||
pr_debug("%s %d *regs = %p\n", __func__, __LINE__, *regs);
|
||||
return *regs ? 0 : -ENODEV;
|
||||
}
|
||||
EXPORT_SYMBOL(sta2x11_mfd_get_regs_data);
|
||||
|
||||
/*
|
||||
* Special sta2x11-mfd regmap lock/unlock functions
|
||||
*/
|
||||
|
||||
static void sta2x11_regmap_lock(void *__lock)
|
||||
{
|
||||
spinlock_t *lock = __lock;
|
||||
spin_lock(lock);
|
||||
}
|
||||
|
||||
static void sta2x11_regmap_unlock(void *__lock)
|
||||
{
|
||||
spinlock_t *lock = __lock;
|
||||
spin_unlock(lock);
|
||||
}
|
||||
|
||||
/* OTP (one time programmable registers do not require locking */
|
||||
static void sta2x11_regmap_nolock(void *__lock)
|
||||
{
|
||||
}
|
||||
|
||||
static const char *sta2x11_mfd_names[sta2x11_n_mfd_plat_devs] = {
|
||||
[sta2x11_sctl] = STA2X11_MFD_SCTL_NAME,
|
||||
[sta2x11_apbreg] = STA2X11_MFD_APBREG_NAME,
|
||||
[sta2x11_apb_soc_regs] = STA2X11_MFD_APB_SOC_REGS_NAME,
|
||||
[sta2x11_scr] = STA2X11_MFD_SCR_NAME,
|
||||
};
|
||||
|
||||
static bool sta2x11_sctl_writeable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
return !__reg_within_range(reg, SCTL_SCPCIECSBRST, SCTL_SCRSTSTA);
|
||||
}
|
||||
|
||||
static struct regmap_config sta2x11_sctl_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.lock = sta2x11_regmap_lock,
|
||||
.unlock = sta2x11_regmap_unlock,
|
||||
.max_register = SCTL_SCRSTSTA,
|
||||
.writeable_reg = sta2x11_sctl_writeable_reg,
|
||||
};
|
||||
|
||||
static bool sta2x11_scr_readable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
return (reg == STA2X11_SECR_CR) ||
|
||||
__reg_within_range(reg, STA2X11_SECR_FVR0, STA2X11_SECR_FVR1);
|
||||
}
|
||||
|
||||
static bool sta2x11_scr_writeable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct regmap_config sta2x11_scr_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.lock = sta2x11_regmap_nolock,
|
||||
.unlock = sta2x11_regmap_nolock,
|
||||
.max_register = STA2X11_SECR_FVR1,
|
||||
.readable_reg = sta2x11_scr_readable_reg,
|
||||
.writeable_reg = sta2x11_scr_writeable_reg,
|
||||
};
|
||||
|
||||
static bool sta2x11_apbreg_readable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
/* Two blocks (CAN and MLB, SARAC) 0x100 bytes apart */
|
||||
if (reg >= APBREG_BSR_SARAC)
|
||||
reg -= APBREG_BSR_SARAC;
|
||||
switch (reg) {
|
||||
case APBREG_BSR:
|
||||
case APBREG_PAER:
|
||||
case APBREG_PWAC:
|
||||
case APBREG_PRAC:
|
||||
case APBREG_PCG:
|
||||
case APBREG_PUR:
|
||||
case APBREG_EMU_PCG:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool sta2x11_apbreg_writeable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
if (reg >= APBREG_BSR_SARAC)
|
||||
reg -= APBREG_BSR_SARAC;
|
||||
if (!sta2x11_apbreg_readable_reg(dev, reg))
|
||||
return false;
|
||||
return reg != APBREG_PAER;
|
||||
}
|
||||
|
||||
static struct regmap_config sta2x11_apbreg_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.lock = sta2x11_regmap_lock,
|
||||
.unlock = sta2x11_regmap_unlock,
|
||||
.max_register = APBREG_EMU_PCG_SARAC,
|
||||
.readable_reg = sta2x11_apbreg_readable_reg,
|
||||
.writeable_reg = sta2x11_apbreg_writeable_reg,
|
||||
};
|
||||
|
||||
static bool sta2x11_apb_soc_regs_readable_reg(struct device *dev,
|
||||
unsigned int reg)
|
||||
{
|
||||
return reg <= PCIE_SoC_INT_ROUTER_STATUS3_REG ||
|
||||
__reg_within_range(reg, DMA_IP_CTRL_REG, SPARE3_RESERVED) ||
|
||||
__reg_within_range(reg, MASTER_LOCK_REG,
|
||||
SYSTEM_CONFIG_STATUS_REG) ||
|
||||
reg == MSP_CLK_CTRL_REG ||
|
||||
__reg_within_range(reg, COMPENSATION_REG1, TEST_CTL_REG);
|
||||
}
|
||||
|
||||
static bool sta2x11_apb_soc_regs_writeable_reg(struct device *dev,
|
||||
unsigned int reg)
|
||||
{
|
||||
if (!sta2x11_apb_soc_regs_readable_reg(dev, reg))
|
||||
return false;
|
||||
switch (reg) {
|
||||
case PCIE_COMMON_CLOCK_CONFIG_0_4_0:
|
||||
case SYSTEM_CONFIG_STATUS_REG:
|
||||
case COMPENSATION_REG1:
|
||||
case PCIE_SoC_INT_ROUTER_STATUS0_REG...PCIE_SoC_INT_ROUTER_STATUS3_REG:
|
||||
case PCIE_PM_STATUS_0_PORT_0_4...PCIE_PM_STATUS_7_0_EP4:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static struct regmap_config sta2x11_apb_soc_regs_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.lock = sta2x11_regmap_lock,
|
||||
.unlock = sta2x11_regmap_unlock,
|
||||
.max_register = TEST_CTL_REG,
|
||||
.readable_reg = sta2x11_apb_soc_regs_readable_reg,
|
||||
.writeable_reg = sta2x11_apb_soc_regs_writeable_reg,
|
||||
};
|
||||
|
||||
static struct regmap_config *
|
||||
sta2x11_mfd_regmap_configs[sta2x11_n_mfd_plat_devs] = {
|
||||
[sta2x11_sctl] = &sta2x11_sctl_regmap_config,
|
||||
[sta2x11_apbreg] = &sta2x11_apbreg_regmap_config,
|
||||
[sta2x11_apb_soc_regs] = &sta2x11_apb_soc_regs_regmap_config,
|
||||
[sta2x11_scr] = &sta2x11_scr_regmap_config,
|
||||
};
|
||||
|
||||
/* Probe for the four platform devices */
|
||||
|
||||
static int sta2x11_mfd_platform_probe(struct platform_device *dev,
|
||||
enum sta2x11_mfd_plat_dev index)
|
||||
{
|
||||
struct pci_dev **pdev;
|
||||
struct sta2x11_mfd *mfd;
|
||||
struct resource *res;
|
||||
const char *name = sta2x11_mfd_names[index];
|
||||
struct regmap_config *regmap_config = sta2x11_mfd_regmap_configs[index];
|
||||
|
||||
pdev = dev_get_platdata(&dev->dev);
|
||||
mfd = sta2x11_mfd_find(*pdev);
|
||||
if (!mfd)
|
||||
return -ENODEV;
|
||||
if (!regmap_config)
|
||||
return -ENODEV;
|
||||
|
||||
res = platform_get_resource(dev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!request_mem_region(res->start, resource_size(res), name))
|
||||
return -EBUSY;
|
||||
|
||||
mfd->regs[index] = ioremap(res->start, resource_size(res));
|
||||
if (!mfd->regs[index]) {
|
||||
release_mem_region(res->start, resource_size(res));
|
||||
return -ENOMEM;
|
||||
}
|
||||
regmap_config->lock_arg = &mfd->lock;
|
||||
/*
|
||||
No caching, registers could be reached both via regmap and via
|
||||
void __iomem *
|
||||
*/
|
||||
regmap_config->cache_type = REGCACHE_NONE;
|
||||
mfd->regmap[index] = devm_regmap_init_mmio(&dev->dev, mfd->regs[index],
|
||||
regmap_config);
|
||||
WARN_ON(IS_ERR(mfd->regmap[index]));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sta2x11_sctl_probe(struct platform_device *dev)
|
||||
{
|
||||
return sta2x11_mfd_platform_probe(dev, sta2x11_sctl);
|
||||
}
|
||||
|
||||
static int sta2x11_apbreg_probe(struct platform_device *dev)
|
||||
{
|
||||
return sta2x11_mfd_platform_probe(dev, sta2x11_apbreg);
|
||||
}
|
||||
|
||||
static int sta2x11_apb_soc_regs_probe(struct platform_device *dev)
|
||||
{
|
||||
return sta2x11_mfd_platform_probe(dev, sta2x11_apb_soc_regs);
|
||||
}
|
||||
|
||||
static int sta2x11_scr_probe(struct platform_device *dev)
|
||||
{
|
||||
return sta2x11_mfd_platform_probe(dev, sta2x11_scr);
|
||||
}
|
||||
|
||||
/* The three platform drivers */
|
||||
static struct platform_driver sta2x11_sctl_platform_driver = {
|
||||
.driver = {
|
||||
.name = STA2X11_MFD_SCTL_NAME,
|
||||
},
|
||||
.probe = sta2x11_sctl_probe,
|
||||
};
|
||||
|
||||
static struct platform_driver sta2x11_platform_driver = {
|
||||
.driver = {
|
||||
.name = STA2X11_MFD_APBREG_NAME,
|
||||
},
|
||||
.probe = sta2x11_apbreg_probe,
|
||||
};
|
||||
|
||||
static struct platform_driver sta2x11_apb_soc_regs_platform_driver = {
|
||||
.driver = {
|
||||
.name = STA2X11_MFD_APB_SOC_REGS_NAME,
|
||||
},
|
||||
.probe = sta2x11_apb_soc_regs_probe,
|
||||
};
|
||||
|
||||
static struct platform_driver sta2x11_scr_platform_driver = {
|
||||
.driver = {
|
||||
.name = STA2X11_MFD_SCR_NAME,
|
||||
},
|
||||
.probe = sta2x11_scr_probe,
|
||||
};
|
||||
|
||||
static struct platform_driver * const drivers[] = {
|
||||
&sta2x11_platform_driver,
|
||||
&sta2x11_sctl_platform_driver,
|
||||
&sta2x11_apb_soc_regs_platform_driver,
|
||||
&sta2x11_scr_platform_driver,
|
||||
};
|
||||
|
||||
static int __init sta2x11_drivers_init(void)
|
||||
{
|
||||
return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
|
||||
}
|
||||
|
||||
/*
|
||||
* What follows are the PCI devices that host the above pdevs.
|
||||
* Each logic block is 4kB and they are all consecutive: we use this info.
|
||||
*/
|
||||
|
||||
/* Mfd 0 device */
|
||||
|
||||
/* Mfd 0, Bar 0 */
|
||||
enum mfd0_bar0_cells {
|
||||
STA2X11_GPIO_0 = 0,
|
||||
STA2X11_GPIO_1,
|
||||
STA2X11_GPIO_2,
|
||||
STA2X11_GPIO_3,
|
||||
STA2X11_SCTL,
|
||||
STA2X11_SCR,
|
||||
STA2X11_TIME,
|
||||
};
|
||||
/* Mfd 0 , Bar 1 */
|
||||
enum mfd0_bar1_cells {
|
||||
STA2X11_APBREG = 0,
|
||||
};
|
||||
#define CELL_4K(_name, _cell) { \
|
||||
.name = _name, \
|
||||
.start = _cell * 4096, .end = _cell * 4096 + 4095, \
|
||||
.flags = IORESOURCE_MEM, \
|
||||
}
|
||||
|
||||
static const struct resource gpio_resources[] = {
|
||||
{
|
||||
/* 4 consecutive cells, 1 driver */
|
||||
.name = STA2X11_MFD_GPIO_NAME,
|
||||
.start = 0,
|
||||
.end = (4 * 4096) - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}
|
||||
};
|
||||
static const struct resource sctl_resources[] = {
|
||||
CELL_4K(STA2X11_MFD_SCTL_NAME, STA2X11_SCTL),
|
||||
};
|
||||
static const struct resource scr_resources[] = {
|
||||
CELL_4K(STA2X11_MFD_SCR_NAME, STA2X11_SCR),
|
||||
};
|
||||
static const struct resource time_resources[] = {
|
||||
CELL_4K(STA2X11_MFD_TIME_NAME, STA2X11_TIME),
|
||||
};
|
||||
|
||||
static const struct resource apbreg_resources[] = {
|
||||
CELL_4K(STA2X11_MFD_APBREG_NAME, STA2X11_APBREG),
|
||||
};
|
||||
|
||||
#define DEV(_name, _r) \
|
||||
{ .name = _name, .num_resources = ARRAY_SIZE(_r), .resources = _r, }
|
||||
|
||||
static struct mfd_cell sta2x11_mfd0_bar0[] = {
|
||||
/* offset 0: we add pdata later */
|
||||
DEV(STA2X11_MFD_GPIO_NAME, gpio_resources),
|
||||
DEV(STA2X11_MFD_SCTL_NAME, sctl_resources),
|
||||
DEV(STA2X11_MFD_SCR_NAME, scr_resources),
|
||||
DEV(STA2X11_MFD_TIME_NAME, time_resources),
|
||||
};
|
||||
|
||||
static struct mfd_cell sta2x11_mfd0_bar1[] = {
|
||||
DEV(STA2X11_MFD_APBREG_NAME, apbreg_resources),
|
||||
};
|
||||
|
||||
/* Mfd 1 devices */
|
||||
|
||||
/* Mfd 1, Bar 0 */
|
||||
enum mfd1_bar0_cells {
|
||||
STA2X11_VIC = 0,
|
||||
};
|
||||
|
||||
/* Mfd 1, Bar 1 */
|
||||
enum mfd1_bar1_cells {
|
||||
STA2X11_APB_SOC_REGS = 0,
|
||||
};
|
||||
|
||||
static const struct resource vic_resources[] = {
|
||||
CELL_4K(STA2X11_MFD_VIC_NAME, STA2X11_VIC),
|
||||
};
|
||||
|
||||
static const struct resource apb_soc_regs_resources[] = {
|
||||
CELL_4K(STA2X11_MFD_APB_SOC_REGS_NAME, STA2X11_APB_SOC_REGS),
|
||||
};
|
||||
|
||||
static struct mfd_cell sta2x11_mfd1_bar0[] = {
|
||||
DEV(STA2X11_MFD_VIC_NAME, vic_resources),
|
||||
};
|
||||
|
||||
static struct mfd_cell sta2x11_mfd1_bar1[] = {
|
||||
DEV(STA2X11_MFD_APB_SOC_REGS_NAME, apb_soc_regs_resources),
|
||||
};
|
||||
|
||||
|
||||
static int sta2x11_mfd_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
{
|
||||
pci_save_state(pdev);
|
||||
pci_disable_device(pdev);
|
||||
pci_set_power_state(pdev, pci_choose_state(pdev, state));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sta2x11_mfd_resume(struct pci_dev *pdev)
|
||||
{
|
||||
int err;
|
||||
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
err = pci_enable_device(pdev);
|
||||
if (err)
|
||||
return err;
|
||||
pci_restore_state(pdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct sta2x11_mfd_bar_setup_data {
|
||||
struct mfd_cell *cells;
|
||||
int ncells;
|
||||
};
|
||||
|
||||
struct sta2x11_mfd_setup_data {
|
||||
struct sta2x11_mfd_bar_setup_data bars[2];
|
||||
};
|
||||
|
||||
#define STA2X11_MFD0 0
|
||||
#define STA2X11_MFD1 1
|
||||
|
||||
static struct sta2x11_mfd_setup_data mfd_setup_data[] = {
|
||||
/* Mfd 0: gpio, sctl, scr, timers / apbregs */
|
||||
[STA2X11_MFD0] = {
|
||||
.bars = {
|
||||
[0] = {
|
||||
.cells = sta2x11_mfd0_bar0,
|
||||
.ncells = ARRAY_SIZE(sta2x11_mfd0_bar0),
|
||||
},
|
||||
[1] = {
|
||||
.cells = sta2x11_mfd0_bar1,
|
||||
.ncells = ARRAY_SIZE(sta2x11_mfd0_bar1),
|
||||
},
|
||||
},
|
||||
},
|
||||
/* Mfd 1: vic / apb-soc-regs */
|
||||
[STA2X11_MFD1] = {
|
||||
.bars = {
|
||||
[0] = {
|
||||
.cells = sta2x11_mfd1_bar0,
|
||||
.ncells = ARRAY_SIZE(sta2x11_mfd1_bar0),
|
||||
},
|
||||
[1] = {
|
||||
.cells = sta2x11_mfd1_bar1,
|
||||
.ncells = ARRAY_SIZE(sta2x11_mfd1_bar1),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static void sta2x11_mfd_setup(struct pci_dev *pdev,
|
||||
struct sta2x11_mfd_setup_data *sd)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < ARRAY_SIZE(sd->bars); i++)
|
||||
for (j = 0; j < sd->bars[i].ncells; j++) {
|
||||
sd->bars[i].cells[j].pdata_size = sizeof(pdev);
|
||||
sd->bars[i].cells[j].platform_data = &pdev;
|
||||
}
|
||||
}
|
||||
|
||||
static int sta2x11_mfd_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *pci_id)
|
||||
{
|
||||
int err, i;
|
||||
struct sta2x11_mfd_setup_data *setup_data;
|
||||
|
||||
dev_info(&pdev->dev, "%s\n", __func__);
|
||||
|
||||
err = pci_enable_device(pdev);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "Can't enable device.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
err = pci_enable_msi(pdev);
|
||||
if (err)
|
||||
dev_info(&pdev->dev, "Enable msi failed\n");
|
||||
|
||||
setup_data = pci_id->device == PCI_DEVICE_ID_STMICRO_GPIO ?
|
||||
&mfd_setup_data[STA2X11_MFD0] :
|
||||
&mfd_setup_data[STA2X11_MFD1];
|
||||
|
||||
/* platform data is the pci device for all of them */
|
||||
sta2x11_mfd_setup(pdev, setup_data);
|
||||
|
||||
/* Record this pdev before mfd_add_devices: their probe looks for it */
|
||||
if (!sta2x11_mfd_find(pdev))
|
||||
sta2x11_mfd_add(pdev, GFP_KERNEL);
|
||||
|
||||
/* Just 2 bars for all mfd's at present */
|
||||
for (i = 0; i < 2; i++) {
|
||||
err = mfd_add_devices(&pdev->dev, -1,
|
||||
setup_data->bars[i].cells,
|
||||
setup_data->bars[i].ncells,
|
||||
&pdev->resource[i],
|
||||
0, NULL);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev,
|
||||
"mfd_add_devices[%d] failed: %d\n", i, err);
|
||||
goto err_disable;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_disable:
|
||||
mfd_remove_devices(&pdev->dev);
|
||||
pci_disable_device(pdev);
|
||||
pci_disable_msi(pdev);
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct pci_device_id sta2x11_mfd_tbl[] = {
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_GPIO)},
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_VIC)},
|
||||
{0,},
|
||||
};
|
||||
|
||||
static struct pci_driver sta2x11_mfd_driver = {
|
||||
.name = "sta2x11-mfd",
|
||||
.id_table = sta2x11_mfd_tbl,
|
||||
.probe = sta2x11_mfd_probe,
|
||||
.suspend = sta2x11_mfd_suspend,
|
||||
.resume = sta2x11_mfd_resume,
|
||||
};
|
||||
|
||||
static int __init sta2x11_mfd_init(void)
|
||||
{
|
||||
pr_info("%s\n", __func__);
|
||||
return pci_register_driver(&sta2x11_mfd_driver);
|
||||
}
|
||||
|
||||
/*
|
||||
* All of this must be ready before "normal" devices like MMCI appear.
|
||||
* But MFD (the pci device) can't be too early. The following choice
|
||||
* prepares platform drivers very early and probe the PCI device later,
|
||||
* but before other PCI devices.
|
||||
*/
|
||||
subsys_initcall(sta2x11_drivers_init);
|
||||
rootfs_initcall(sta2x11_mfd_init);
|
@ -9,6 +9,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/reset.h>
|
||||
|
||||
#define STM32_TIMERS_MAX_REGISTERS 0x3fc
|
||||
@ -173,6 +174,31 @@ static void stm32_timers_get_arr_size(struct stm32_timers *ddata)
|
||||
regmap_write(ddata->regmap, TIM_ARR, arr);
|
||||
}
|
||||
|
||||
static int stm32_timers_probe_hwcfgr(struct device *dev, struct stm32_timers *ddata)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
ddata->ipidr = (uintptr_t)device_get_match_data(dev);
|
||||
if (!ddata->ipidr) {
|
||||
/* Fallback to legacy method for probing counter width */
|
||||
stm32_timers_get_arr_size(ddata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
regmap_read(ddata->regmap, TIM_IPIDR, &val);
|
||||
if (val != ddata->ipidr) {
|
||||
dev_err(dev, "Unsupported device detected: %u\n", val);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
regmap_read(ddata->regmap, TIM_HWCFGR2, &val);
|
||||
|
||||
/* Counter width in bits, max reload value is BIT(width) - 1 */
|
||||
ddata->max_arr = BIT(FIELD_GET(TIM_HWCFGR2_CNT_WIDTH, val)) - 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32_timers_dma_probe(struct device *dev,
|
||||
struct stm32_timers *ddata)
|
||||
{
|
||||
@ -285,7 +311,9 @@ static int stm32_timers_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(ddata->clk))
|
||||
return PTR_ERR(ddata->clk);
|
||||
|
||||
stm32_timers_get_arr_size(ddata);
|
||||
ret = stm32_timers_probe_hwcfgr(dev, ddata);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = stm32_timers_irq_probe(pdev, ddata);
|
||||
if (ret)
|
||||
@ -320,6 +348,7 @@ static void stm32_timers_remove(struct platform_device *pdev)
|
||||
|
||||
static const struct of_device_id stm32_timers_of_match[] = {
|
||||
{ .compatible = "st,stm32-timers", },
|
||||
{ .compatible = "st,stm32mp25-timers", .data = (void *)STM32MP25_TIM_IPIDR },
|
||||
{ /* end node */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, stm32_timers_of_match);
|
||||
|
@ -47,6 +47,7 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_res)
|
||||
struct regmap_config syscon_config = syscon_regmap_config;
|
||||
struct resource res;
|
||||
struct reset_control *reset;
|
||||
resource_size_t res_size;
|
||||
|
||||
WARN_ON(!mutex_is_locked(&syscon_list_lock));
|
||||
|
||||
@ -96,6 +97,12 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_res)
|
||||
}
|
||||
}
|
||||
|
||||
res_size = resource_size(&res);
|
||||
if (res_size < reg_io_width) {
|
||||
ret = -EFAULT;
|
||||
goto err_regmap;
|
||||
}
|
||||
|
||||
syscon_config.name = kasprintf(GFP_KERNEL, "%pOFn@%pa", np, &res.start);
|
||||
if (!syscon_config.name) {
|
||||
ret = -ENOMEM;
|
||||
@ -103,7 +110,7 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_res)
|
||||
}
|
||||
syscon_config.reg_stride = reg_io_width;
|
||||
syscon_config.val_bits = reg_io_width * 8;
|
||||
syscon_config.max_register = resource_size(&res) - reg_io_width;
|
||||
syscon_config.max_register = res_size - reg_io_width;
|
||||
if (!syscon_config.max_register)
|
||||
syscon_config.max_register_is_0 = true;
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/string_choices.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
@ -250,7 +251,7 @@ static int dbg_show(struct seq_file *s, void *_)
|
||||
v2 = i2c_smbus_read_byte_data(tps->client, TPS_LED1_PER);
|
||||
seq_printf(s, "led1 %s, on=%02x, per=%02x, %d/%d msec\n",
|
||||
(value & 0x80)
|
||||
? ((v2 & 0x80) ? "on" : "off")
|
||||
? str_on_off(v2 & 0x80)
|
||||
: ((v2 & 0x80) ? "blink" : "(nPG)"),
|
||||
value, v2,
|
||||
(value & 0x7f) * 10, (v2 & 0x7f) * 100);
|
||||
@ -259,7 +260,7 @@ static int dbg_show(struct seq_file *s, void *_)
|
||||
v2 = i2c_smbus_read_byte_data(tps->client, TPS_LED2_PER);
|
||||
seq_printf(s, "led2 %s, on=%02x, per=%02x, %d/%d msec\n",
|
||||
(value & 0x80)
|
||||
? ((v2 & 0x80) ? "on" : "off")
|
||||
? str_on_off(v2 & 0x80)
|
||||
: ((v2 & 0x80) ? "blink" : "off"),
|
||||
value, v2,
|
||||
(value & 0x7f) * 10, (v2 & 0x7f) * 100);
|
||||
@ -738,7 +739,7 @@ int tps65010_set_gpio_out_value(unsigned gpio, unsigned value)
|
||||
TPS_DEFGPIO, defgpio);
|
||||
|
||||
pr_debug("%s: gpio%dout = %s, defgpio 0x%02x\n", DRIVER_NAME,
|
||||
gpio, value ? "high" : "low",
|
||||
gpio, str_high_low(value),
|
||||
i2c_smbus_read_byte_data(the_tps->client, TPS_DEFGPIO));
|
||||
|
||||
mutex_unlock(&the_tps->lock);
|
||||
@ -850,7 +851,7 @@ int tps65010_set_vib(unsigned value)
|
||||
status = i2c_smbus_write_byte_data(the_tps->client,
|
||||
TPS_VDCDC2, vdcdc2);
|
||||
|
||||
pr_debug("%s: vibrator %s\n", DRIVER_NAME, value ? "on" : "off");
|
||||
pr_debug("%s: vibrator %s\n", DRIVER_NAME, str_on_off(value));
|
||||
|
||||
mutex_unlock(&the_tps->lock);
|
||||
return status;
|
||||
@ -872,7 +873,7 @@ int tps65010_set_low_pwr(unsigned mode)
|
||||
mutex_lock(&the_tps->lock);
|
||||
|
||||
pr_debug("%s: %s low_pwr, vdcdc1 0x%02x\n", DRIVER_NAME,
|
||||
mode ? "enable" : "disable",
|
||||
str_enable_disable(mode),
|
||||
i2c_smbus_read_byte_data(the_tps->client, TPS_VDCDC1));
|
||||
|
||||
vdcdc1 = i2c_smbus_read_byte_data(the_tps->client, TPS_VDCDC1);
|
||||
@ -984,7 +985,7 @@ int tps65013_set_low_pwr(unsigned mode)
|
||||
|
||||
pr_debug("%s: %s low_pwr, chgconfig 0x%02x vdcdc1 0x%02x\n",
|
||||
DRIVER_NAME,
|
||||
mode ? "enable" : "disable",
|
||||
str_enable_disable(mode),
|
||||
i2c_smbus_read_byte_data(the_tps->client, TPS_CHGCONFIG),
|
||||
i2c_smbus_read_byte_data(the_tps->client, TPS_VDCDC1));
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Driver for TPS65219 Integrated Power Management Integrated Chips (PMIC)
|
||||
// Driver for TPS65214/TPS65215/TPS65219 Power Management Integrated Chips
|
||||
//
|
||||
// Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
|
||||
// Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/reboot.h>
|
||||
@ -59,6 +60,84 @@ static const struct resource tps65219_pwrbutton_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_PB_RISING_EDGE_DETECT, "rising"),
|
||||
};
|
||||
|
||||
static const struct resource tps65214_regulator_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_SCG, "LDO1_SCG"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_OC, "LDO1_OC"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_UV, "LDO1_UV"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_SCG, "LDO2_SCG"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_OC, "LDO2_OC"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_UV, "LDO2_UV"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_SCG, "BUCK3_SCG"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_OC, "BUCK3_OC"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_NEG_OC, "BUCK3_NEG_OC"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_UV, "BUCK3_UV"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_SCG, "BUCK1_SCG"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_OC, "BUCK1_OC"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_NEG_OC, "BUCK1_NEG_OC"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_UV, "BUCK1_UV"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_SCG, "BUCK2_SCG"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_OC, "BUCK2_OC"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_NEG_OC, "BUCK2_NEG_OC"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_UV, "BUCK2_UV"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_RV, "BUCK1_RV"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_RV, "BUCK2_RV"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_RV, "BUCK3_RV"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_RV, "LDO1_RV"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65214_INT_LDO2_RV, "LDO2_RV"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_RV_SD, "BUCK1_RV_SD"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_RV_SD, "BUCK2_RV_SD"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_RV_SD, "BUCK3_RV_SD"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65214_INT_LDO1_RV_SD, "LDO1_RV_SD"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO2_RV_SD, "LDO2_RV_SD"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_TIMEOUT, "TIMEOUT"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_2_WARM, "SENSOR_2_WARM"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_1_WARM, "SENSOR_1_WARM"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_0_WARM, "SENSOR_0_WARM"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_2_HOT, "SENSOR_2_HOT"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_1_HOT, "SENSOR_1_HOT"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_0_HOT, "SENSOR_0_HOT"),
|
||||
};
|
||||
|
||||
static const struct resource tps65215_regulator_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(TPS65215_INT_LDO1_SCG, "LDO1_SCG"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65215_INT_LDO1_OC, "LDO1_OC"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65215_INT_LDO1_UV, "LDO1_UV"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65215_INT_LDO2_SCG, "LDO2_SCG"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65215_INT_LDO2_OC, "LDO2_OC"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65215_INT_LDO2_UV, "LDO2_UV"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_SCG, "BUCK3_SCG"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_OC, "BUCK3_OC"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_NEG_OC, "BUCK3_NEG_OC"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_UV, "BUCK3_UV"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_SCG, "BUCK1_SCG"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_OC, "BUCK1_OC"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_NEG_OC, "BUCK1_NEG_OC"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_UV, "BUCK1_UV"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_SCG, "BUCK2_SCG"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_OC, "BUCK2_OC"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_NEG_OC, "BUCK2_NEG_OC"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_UV, "BUCK2_UV"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_RV, "BUCK1_RV"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_RV, "BUCK2_RV"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_RV, "BUCK3_RV"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_RV, "LDO1_RV"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65215_INT_LDO2_RV, "LDO2_RV"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK1_RV_SD, "BUCK1_RV_SD"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK2_RV_SD, "BUCK2_RV_SD"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_BUCK3_RV_SD, "BUCK3_RV_SD"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO1_RV_SD, "LDO1_RV_SD"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65215_INT_LDO2_RV_SD, "LDO2_RV_SD"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_TIMEOUT, "TIMEOUT"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_3_WARM, "SENSOR_3_WARM"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_2_WARM, "SENSOR_2_WARM"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_1_WARM, "SENSOR_1_WARM"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_0_WARM, "SENSOR_0_WARM"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_3_HOT, "SENSOR_3_HOT"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_2_HOT, "SENSOR_2_HOT"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_1_HOT, "SENSOR_1_HOT"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_0_HOT, "SENSOR_0_HOT"),
|
||||
};
|
||||
|
||||
static const struct resource tps65219_regulator_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_SCG, "LDO3_SCG"),
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_LDO3_OC, "LDO3_OC"),
|
||||
@ -109,6 +188,16 @@ static const struct resource tps65219_regulator_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(TPS65219_INT_SENSOR_0_HOT, "SENSOR_0_HOT"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell tps65214_cells[] = {
|
||||
MFD_CELL_RES("tps65214-regulator", tps65214_regulator_resources),
|
||||
MFD_CELL_NAME("tps65215-gpio"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell tps65215_cells[] = {
|
||||
MFD_CELL_RES("tps65215-regulator", tps65215_regulator_resources),
|
||||
MFD_CELL_NAME("tps65215-gpio"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell tps65219_cells[] = {
|
||||
MFD_CELL_RES("tps65219-regulator", tps65219_regulator_resources),
|
||||
MFD_CELL_NAME("tps65219-gpio"),
|
||||
@ -136,8 +225,19 @@ static unsigned int bit3_offsets[] = { TPS65219_REG_INT_BUCK_1_2_POS }; /* Buck
|
||||
static unsigned int bit4_offsets[] = { TPS65219_REG_INT_BUCK_3_POS }; /* Buck 3 */
|
||||
static unsigned int bit5_offsets[] = { TPS65219_REG_INT_LDO_1_2_POS }; /* LDO 1-2 */
|
||||
static unsigned int bit6_offsets[] = { TPS65219_REG_INT_LDO_3_4_POS }; /* LDO 3-4 */
|
||||
static unsigned int tps65215_bit5_offsets[] = { TPS65215_REG_INT_LDO_1_POS };
|
||||
static unsigned int tps65215_bit6_offsets[] = { TPS65215_REG_INT_LDO_2_POS };
|
||||
static unsigned int bit7_offsets[] = { TPS65219_REG_INT_PB_POS }; /* Power Button */
|
||||
|
||||
/* TPS65214 INT_SOURCE bit 6 is 'RESERVED'*/
|
||||
static unsigned int tps65214_bit0_offsets[] = { TPS65214_REG_INT_TO_RV_POS };
|
||||
static unsigned int tps65214_bit1_offsets[] = { TPS65214_REG_INT_RV_POS };
|
||||
static unsigned int tps65214_bit2_offsets[] = { TPS65214_REG_INT_SYS_POS };
|
||||
static unsigned int tps65214_bit3_offsets[] = { TPS65214_REG_INT_BUCK_1_2_POS };
|
||||
static unsigned int tps65214_bit4_offsets[] = { TPS65214_REG_INT_BUCK_3_POS };
|
||||
static unsigned int tps65214_bit5_offsets[] = { TPS65214_REG_INT_LDO_1_2_POS };
|
||||
static unsigned int tps65214_bit7_offsets[] = { TPS65214_REG_INT_PB_POS };
|
||||
|
||||
static struct regmap_irq_sub_irq_map tps65219_sub_irq_offsets[] = {
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets),
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(bit1_offsets),
|
||||
@ -149,9 +249,112 @@ static struct regmap_irq_sub_irq_map tps65219_sub_irq_offsets[] = {
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(bit7_offsets),
|
||||
};
|
||||
|
||||
static struct regmap_irq_sub_irq_map tps65215_sub_irq_offsets[] = {
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets),
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(bit1_offsets),
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(bit2_offsets),
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(bit3_offsets),
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(bit4_offsets),
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(tps65215_bit5_offsets),
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(tps65215_bit6_offsets),
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(bit7_offsets),
|
||||
};
|
||||
|
||||
static struct regmap_irq_sub_irq_map tps65214_sub_irq_offsets[] = {
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(tps65214_bit0_offsets),
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(tps65214_bit1_offsets),
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(tps65214_bit2_offsets),
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(tps65214_bit3_offsets),
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(tps65214_bit4_offsets),
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(tps65214_bit5_offsets),
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(tps65214_bit7_offsets),
|
||||
};
|
||||
|
||||
#define TPS65219_REGMAP_IRQ_REG(int_name, register_position) \
|
||||
REGMAP_IRQ_REG(int_name, register_position, int_name##_MASK)
|
||||
|
||||
static const struct regmap_irq tps65214_irqs[] = {
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO1_SCG, TPS65214_REG_INT_LDO_1_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO1_OC, TPS65214_REG_INT_LDO_1_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO1_UV, TPS65214_REG_INT_LDO_1_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO2_SCG, TPS65214_REG_INT_LDO_1_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO2_OC, TPS65214_REG_INT_LDO_1_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO2_UV, TPS65214_REG_INT_LDO_1_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_SCG, TPS65214_REG_INT_BUCK_3_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_OC, TPS65214_REG_INT_BUCK_3_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_NEG_OC, TPS65214_REG_INT_BUCK_3_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_UV, TPS65214_REG_INT_BUCK_3_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_SCG, TPS65214_REG_INT_BUCK_1_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_OC, TPS65214_REG_INT_BUCK_1_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_NEG_OC, TPS65214_REG_INT_BUCK_1_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_UV, TPS65214_REG_INT_BUCK_1_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_SCG, TPS65214_REG_INT_BUCK_1_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_OC, TPS65214_REG_INT_BUCK_1_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_NEG_OC, TPS65214_REG_INT_BUCK_1_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_UV, TPS65214_REG_INT_BUCK_1_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_2_WARM, TPS65214_REG_INT_SYS_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_1_WARM, TPS65214_REG_INT_SYS_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_0_WARM, TPS65214_REG_INT_SYS_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_2_HOT, TPS65214_REG_INT_SYS_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_1_HOT, TPS65214_REG_INT_SYS_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_0_HOT, TPS65214_REG_INT_SYS_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_RV, TPS65214_REG_INT_RV_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_RV, TPS65214_REG_INT_RV_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_RV, TPS65214_REG_INT_RV_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO1_RV, TPS65214_REG_INT_RV_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65214_INT_LDO2_RV, TPS65214_REG_INT_RV_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_RV_SD, TPS65214_REG_INT_TO_RV_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_RV_SD, TPS65214_REG_INT_TO_RV_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_RV_SD, TPS65214_REG_INT_TO_RV_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65214_INT_LDO1_RV_SD, TPS65214_REG_INT_TO_RV_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO2_RV_SD, TPS65214_REG_INT_TO_RV_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_TIMEOUT, TPS65214_REG_INT_TO_RV_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_PB_FALLING_EDGE_DETECT, TPS65214_REG_INT_PB_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_PB_RISING_EDGE_DETECT, TPS65214_REG_INT_PB_POS),
|
||||
};
|
||||
|
||||
static const struct regmap_irq tps65215_irqs[] = {
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65215_INT_LDO1_SCG, TPS65215_REG_INT_LDO_1_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65215_INT_LDO1_OC, TPS65215_REG_INT_LDO_1_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65215_INT_LDO1_UV, TPS65215_REG_INT_LDO_1_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65215_INT_LDO2_SCG, TPS65215_REG_INT_LDO_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65215_INT_LDO2_OC, TPS65215_REG_INT_LDO_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65215_INT_LDO2_UV, TPS65215_REG_INT_LDO_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_SCG, TPS65219_REG_INT_BUCK_3_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_OC, TPS65219_REG_INT_BUCK_3_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_NEG_OC, TPS65219_REG_INT_BUCK_3_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_UV, TPS65219_REG_INT_BUCK_3_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_SCG, TPS65219_REG_INT_BUCK_1_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_OC, TPS65219_REG_INT_BUCK_1_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_NEG_OC, TPS65219_REG_INT_BUCK_1_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_UV, TPS65219_REG_INT_BUCK_1_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_SCG, TPS65219_REG_INT_BUCK_1_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_OC, TPS65219_REG_INT_BUCK_1_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_NEG_OC, TPS65219_REG_INT_BUCK_1_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_UV, TPS65219_REG_INT_BUCK_1_2_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_3_WARM, TPS65219_REG_INT_SYS_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_2_WARM, TPS65219_REG_INT_SYS_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_1_WARM, TPS65219_REG_INT_SYS_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_0_WARM, TPS65219_REG_INT_SYS_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_3_HOT, TPS65219_REG_INT_SYS_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_2_HOT, TPS65219_REG_INT_SYS_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_1_HOT, TPS65219_REG_INT_SYS_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_SENSOR_0_HOT, TPS65219_REG_INT_SYS_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_RV, TPS65219_REG_INT_RV_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_RV, TPS65219_REG_INT_RV_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_RV, TPS65219_REG_INT_RV_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO1_RV, TPS65219_REG_INT_RV_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65215_INT_LDO2_RV, TPS65219_REG_INT_RV_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK1_RV_SD, TPS65219_REG_INT_TO_RV_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK2_RV_SD, TPS65219_REG_INT_TO_RV_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_BUCK3_RV_SD, TPS65219_REG_INT_TO_RV_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO1_RV_SD, TPS65219_REG_INT_TO_RV_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65215_INT_LDO2_RV_SD, TPS65219_REG_INT_TO_RV_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_TIMEOUT, TPS65219_REG_INT_TO_RV_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_PB_FALLING_EDGE_DETECT, TPS65219_REG_INT_PB_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_PB_RISING_EDGE_DETECT, TPS65219_REG_INT_PB_POS),
|
||||
};
|
||||
|
||||
static const struct regmap_irq tps65219_irqs[] = {
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO3_SCG, TPS65219_REG_INT_LDO_3_4_POS),
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_LDO3_OC, TPS65219_REG_INT_LDO_3_4_POS),
|
||||
@ -204,6 +407,34 @@ static const struct regmap_irq tps65219_irqs[] = {
|
||||
TPS65219_REGMAP_IRQ_REG(TPS65219_INT_PB_RISING_EDGE_DETECT, TPS65219_REG_INT_PB_POS),
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip tps65214_irq_chip = {
|
||||
.name = "tps65214_irq",
|
||||
.main_status = TPS65219_REG_INT_SOURCE,
|
||||
.num_main_regs = 1,
|
||||
.num_main_status_bits = 8,
|
||||
.irqs = tps65214_irqs,
|
||||
.num_irqs = ARRAY_SIZE(tps65214_irqs),
|
||||
.status_base = TPS65214_REG_INT_LDO_1_2,
|
||||
.ack_base = TPS65214_REG_INT_LDO_1_2,
|
||||
.clear_ack = 1,
|
||||
.num_regs = 8,
|
||||
.sub_reg_offsets = tps65214_sub_irq_offsets,
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip tps65215_irq_chip = {
|
||||
.name = "tps65215_irq",
|
||||
.main_status = TPS65219_REG_INT_SOURCE,
|
||||
.num_main_regs = 1,
|
||||
.num_main_status_bits = 8,
|
||||
.irqs = tps65215_irqs,
|
||||
.num_irqs = ARRAY_SIZE(tps65215_irqs),
|
||||
.status_base = TPS65215_REG_INT_LDO_2,
|
||||
.ack_base = TPS65215_REG_INT_LDO_2,
|
||||
.clear_ack = 1,
|
||||
.num_regs = 8,
|
||||
.sub_reg_offsets = tps65215_sub_irq_offsets,
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip tps65219_irq_chip = {
|
||||
.name = "tps65219_irq",
|
||||
.main_status = TPS65219_REG_INT_SOURCE,
|
||||
@ -218,10 +449,34 @@ static const struct regmap_irq_chip tps65219_irq_chip = {
|
||||
.sub_reg_offsets = tps65219_sub_irq_offsets,
|
||||
};
|
||||
|
||||
struct tps65219_chip_data {
|
||||
const struct regmap_irq_chip *irq_chip;
|
||||
const struct mfd_cell *cells;
|
||||
int n_cells;
|
||||
};
|
||||
|
||||
static struct tps65219_chip_data chip_info_table[] = {
|
||||
[TPS65214] = {
|
||||
.irq_chip = &tps65214_irq_chip,
|
||||
.cells = tps65214_cells,
|
||||
.n_cells = ARRAY_SIZE(tps65214_cells),
|
||||
},
|
||||
[TPS65215] = {
|
||||
.irq_chip = &tps65215_irq_chip,
|
||||
.cells = tps65215_cells,
|
||||
.n_cells = ARRAY_SIZE(tps65215_cells),
|
||||
},
|
||||
[TPS65219] = {
|
||||
.irq_chip = &tps65219_irq_chip,
|
||||
.cells = tps65219_cells,
|
||||
.n_cells = ARRAY_SIZE(tps65219_cells),
|
||||
},
|
||||
};
|
||||
|
||||
static int tps65219_probe(struct i2c_client *client)
|
||||
{
|
||||
struct tps65219 *tps;
|
||||
unsigned int chipid;
|
||||
struct tps65219_chip_data *pmic;
|
||||
bool pwr_button;
|
||||
int ret;
|
||||
|
||||
@ -232,6 +487,8 @@ static int tps65219_probe(struct i2c_client *client)
|
||||
i2c_set_clientdata(client, tps);
|
||||
|
||||
tps->dev = &client->dev;
|
||||
tps->chip_id = (uintptr_t)i2c_get_match_data(client);
|
||||
pmic = &chip_info_table[tps->chip_id];
|
||||
|
||||
tps->regmap = devm_regmap_init_i2c(client, &tps65219_regmap_config);
|
||||
if (IS_ERR(tps->regmap)) {
|
||||
@ -240,20 +497,14 @@ static int tps65219_probe(struct i2c_client *client)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_regmap_add_irq_chip(&client->dev, tps->regmap, client->irq,
|
||||
IRQF_ONESHOT, 0, &tps65219_irq_chip,
|
||||
ret = devm_regmap_add_irq_chip(tps->dev, tps->regmap, client->irq,
|
||||
IRQF_ONESHOT, 0, pmic->irq_chip,
|
||||
&tps->irq_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_read(tps->regmap, TPS65219_REG_TI_DEV_ID, &chipid);
|
||||
if (ret) {
|
||||
dev_err(tps->dev, "Failed to read device ID: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO,
|
||||
tps65219_cells, ARRAY_SIZE(tps65219_cells),
|
||||
pmic->cells, pmic->n_cells,
|
||||
NULL, 0, regmap_irq_get_domain(tps->irq_data));
|
||||
if (ret) {
|
||||
dev_err(tps->dev, "Failed to add child devices: %d\n", ret);
|
||||
@ -291,7 +542,9 @@ static int tps65219_probe(struct i2c_client *client)
|
||||
}
|
||||
|
||||
static const struct of_device_id of_tps65219_match_table[] = {
|
||||
{ .compatible = "ti,tps65219", },
|
||||
{ .compatible = "ti,tps65214", .data = (void *)TPS65214, },
|
||||
{ .compatible = "ti,tps65215", .data = (void *)TPS65215, },
|
||||
{ .compatible = "ti,tps65219", .data = (void *)TPS65219, },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_tps65219_match_table);
|
||||
@ -306,5 +559,5 @@ static struct i2c_driver tps65219_driver = {
|
||||
module_i2c_driver(tps65219_driver);
|
||||
|
||||
MODULE_AUTHOR("Jerome Neanne <jneanne@baylibre.com>");
|
||||
MODULE_DESCRIPTION("TPS65219 power management IC driver");
|
||||
MODULE_DESCRIPTION("TPS65214/TPS65215/TPS65219 PMIC driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -11,7 +11,6 @@
|
||||
* Author: Thomas Richard <thomas.richard@bootlin.com>
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
@ -311,7 +310,7 @@ MODULE_DEVICE_TABLE(acpi, upboard_fpga_acpi_match);
|
||||
static struct platform_driver upboard_fpga_driver = {
|
||||
.driver = {
|
||||
.name = "upboard-fpga",
|
||||
.acpi_match_table = ACPI_PTR(upboard_fpga_acpi_match),
|
||||
.acpi_match_table = upboard_fpga_acpi_match,
|
||||
.dev_groups = upboard_fpga_groups,
|
||||
},
|
||||
.probe = upboard_fpga_probe,
|
||||
|
@ -583,6 +583,12 @@ config CHARGER_MAX77693
|
||||
help
|
||||
Say Y to enable support for the Maxim MAX77693 battery charger.
|
||||
|
||||
config CHARGER_MAX77705
|
||||
tristate "Maxim MAX77705 battery charger driver"
|
||||
depends on MFD_MAX77705
|
||||
help
|
||||
Say Y to enable support for the Maxim MAX77705 battery charger.
|
||||
|
||||
config CHARGER_MAX77976
|
||||
tristate "Maxim MAX77976 battery charger driver"
|
||||
depends on I2C
|
||||
|
@ -80,6 +80,7 @@ obj-$(CONFIG_CHARGER_MAX14577) += max14577_charger.o
|
||||
obj-$(CONFIG_CHARGER_DETECTOR_MAX14656) += max14656_charger_detector.o
|
||||
obj-$(CONFIG_CHARGER_MAX77650) += max77650-charger.o
|
||||
obj-$(CONFIG_CHARGER_MAX77693) += max77693_charger.o
|
||||
obj-$(CONFIG_CHARGER_MAX77705) += max77705_charger.o
|
||||
obj-$(CONFIG_CHARGER_MAX77976) += max77976_charger.o
|
||||
obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o
|
||||
obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o
|
||||
|
581
drivers/power/supply/max77705_charger.c
Normal file
581
drivers/power/supply/max77705_charger.c
Normal file
@ -0,0 +1,581 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Based on max77650-charger.c
|
||||
*
|
||||
* Copyright (C) 2025 Dzmitry Sankouski <dsankouski@gmail.org>
|
||||
*
|
||||
* Battery charger driver for MAXIM 77705 charger/power-supply.
|
||||
*/
|
||||
|
||||
#include <linux/devm-helpers.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mfd/max77693-common.h>
|
||||
#include <linux/mfd/max77705-private.h>
|
||||
#include <linux/power/max77705_charger.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
static const char *max77705_charger_model = "max77705";
|
||||
static const char *max77705_charger_manufacturer = "Maxim Integrated";
|
||||
|
||||
static const struct regmap_config max77705_chg_regmap_config = {
|
||||
.reg_base = MAX77705_CHG_REG_BASE,
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = MAX77705_CHG_REG_SAFEOUT_CTRL,
|
||||
};
|
||||
|
||||
static enum power_supply_property max77705_charger_props[] = {
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
POWER_SUPPLY_PROP_STATUS,
|
||||
POWER_SUPPLY_PROP_CHARGE_TYPE,
|
||||
POWER_SUPPLY_PROP_HEALTH,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
|
||||
POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
|
||||
POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
|
||||
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
|
||||
};
|
||||
|
||||
static int max77705_chgin_irq(void *irq_drv_data)
|
||||
{
|
||||
struct max77705_charger_data *charger = irq_drv_data;
|
||||
|
||||
queue_work(charger->wqueue, &charger->chgin_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct regmap_irq max77705_charger_irqs[] = {
|
||||
{ .mask = MAX77705_BYP_IM, },
|
||||
{ .mask = MAX77705_INP_LIMIT_IM, },
|
||||
{ .mask = MAX77705_BATP_IM, },
|
||||
{ .mask = MAX77705_BAT_IM, },
|
||||
{ .mask = MAX77705_CHG_IM, },
|
||||
{ .mask = MAX77705_WCIN_IM, },
|
||||
{ .mask = MAX77705_CHGIN_IM, },
|
||||
{ .mask = MAX77705_AICL_IM, },
|
||||
};
|
||||
|
||||
static struct regmap_irq_chip max77705_charger_irq_chip = {
|
||||
.name = "max77705-charger",
|
||||
.status_base = MAX77705_CHG_REG_INT,
|
||||
.mask_base = MAX77705_CHG_REG_INT_MASK,
|
||||
.handle_post_irq = max77705_chgin_irq,
|
||||
.num_regs = 1,
|
||||
.irqs = max77705_charger_irqs,
|
||||
.num_irqs = ARRAY_SIZE(max77705_charger_irqs),
|
||||
};
|
||||
|
||||
static int max77705_charger_enable(struct max77705_charger_data *chg)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = regmap_update_bits(chg->regmap, MAX77705_CHG_REG_CNFG_09,
|
||||
MAX77705_CHG_EN_MASK, MAX77705_CHG_EN_MASK);
|
||||
if (rv)
|
||||
dev_err(chg->dev, "unable to enable the charger: %d\n", rv);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void max77705_charger_disable(void *data)
|
||||
{
|
||||
struct max77705_charger_data *chg = data;
|
||||
int rv;
|
||||
|
||||
rv = regmap_update_bits(chg->regmap,
|
||||
MAX77705_CHG_REG_CNFG_09,
|
||||
MAX77705_CHG_EN_MASK,
|
||||
MAX77705_CHG_DISABLE);
|
||||
if (rv)
|
||||
dev_err(chg->dev, "unable to disable the charger: %d\n", rv);
|
||||
}
|
||||
|
||||
static int max77705_get_online(struct regmap *regmap, int *val)
|
||||
{
|
||||
unsigned int data;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(regmap, MAX77705_CHG_REG_INT_OK, &data);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
*val = !!(data & MAX77705_CHGIN_OK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max77705_check_battery(struct max77705_charger_data *charger, int *val)
|
||||
{
|
||||
unsigned int reg_data;
|
||||
unsigned int reg_data2;
|
||||
struct regmap *regmap = charger->regmap;
|
||||
|
||||
regmap_read(regmap, MAX77705_CHG_REG_INT_OK, ®_data);
|
||||
|
||||
dev_dbg(charger->dev, "CHG_INT_OK(0x%x)\n", reg_data);
|
||||
|
||||
regmap_read(regmap, MAX77705_CHG_REG_DETAILS_00, ®_data2);
|
||||
|
||||
dev_dbg(charger->dev, "CHG_DETAILS00(0x%x)\n", reg_data2);
|
||||
|
||||
if ((reg_data & MAX77705_BATP_OK) || !(reg_data2 & MAX77705_BATP_DTLS))
|
||||
*val = true;
|
||||
else
|
||||
*val = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max77705_get_charge_type(struct max77705_charger_data *charger, int *val)
|
||||
{
|
||||
struct regmap *regmap = charger->regmap;
|
||||
unsigned int reg_data;
|
||||
|
||||
regmap_read(regmap, MAX77705_CHG_REG_CNFG_09, ®_data);
|
||||
if (!MAX77705_CHARGER_CHG_CHARGING(reg_data)) {
|
||||
*val = POWER_SUPPLY_CHARGE_TYPE_NONE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
regmap_read(regmap, MAX77705_CHG_REG_DETAILS_01, ®_data);
|
||||
reg_data &= MAX77705_CHG_DTLS;
|
||||
|
||||
switch (reg_data) {
|
||||
case 0x0:
|
||||
case MAX77705_CHARGER_CONSTANT_CURRENT:
|
||||
case MAX77705_CHARGER_CONSTANT_VOLTAGE:
|
||||
*val = POWER_SUPPLY_CHARGE_TYPE_FAST;
|
||||
return 0;
|
||||
default:
|
||||
*val = POWER_SUPPLY_CHARGE_TYPE_NONE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max77705_get_status(struct max77705_charger_data *charger, int *val)
|
||||
{
|
||||
struct regmap *regmap = charger->regmap;
|
||||
unsigned int reg_data;
|
||||
|
||||
regmap_read(regmap, MAX77705_CHG_REG_CNFG_09, ®_data);
|
||||
if (!MAX77705_CHARGER_CHG_CHARGING(reg_data)) {
|
||||
*val = POWER_SUPPLY_CHARGE_TYPE_NONE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
regmap_read(regmap, MAX77705_CHG_REG_DETAILS_01, ®_data);
|
||||
reg_data &= MAX77705_CHG_DTLS;
|
||||
|
||||
switch (reg_data) {
|
||||
case 0x0:
|
||||
case MAX77705_CHARGER_CONSTANT_CURRENT:
|
||||
case MAX77705_CHARGER_CONSTANT_VOLTAGE:
|
||||
*val = POWER_SUPPLY_STATUS_CHARGING;
|
||||
return 0;
|
||||
case MAX77705_CHARGER_END_OF_CHARGE:
|
||||
case MAX77705_CHARGER_DONE:
|
||||
*val = POWER_SUPPLY_STATUS_FULL;
|
||||
return 0;
|
||||
/* those values hard coded as in vendor kernel, because of */
|
||||
/* failure to determine it's actual meaning. */
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
case 0x07:
|
||||
*val = POWER_SUPPLY_STATUS_NOT_CHARGING;
|
||||
return 0;
|
||||
case 0x08:
|
||||
case 0xA:
|
||||
case 0xB:
|
||||
*val = POWER_SUPPLY_STATUS_DISCHARGING;
|
||||
return 0;
|
||||
default:
|
||||
*val = POWER_SUPPLY_STATUS_UNKNOWN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max77705_get_vbus_state(struct regmap *regmap, int *value)
|
||||
{
|
||||
int ret;
|
||||
unsigned int charge_dtls;
|
||||
|
||||
ret = regmap_read(regmap, MAX77705_CHG_REG_DETAILS_00, &charge_dtls);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
charge_dtls = ((charge_dtls & MAX77705_CHGIN_DTLS) >>
|
||||
MAX77705_CHGIN_DTLS_SHIFT);
|
||||
|
||||
switch (charge_dtls) {
|
||||
case 0x00:
|
||||
*value = POWER_SUPPLY_HEALTH_UNDERVOLTAGE;
|
||||
break;
|
||||
case 0x01:
|
||||
*value = POWER_SUPPLY_HEALTH_UNDERVOLTAGE;
|
||||
break;
|
||||
case 0x02:
|
||||
*value = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
|
||||
break;
|
||||
case 0x03:
|
||||
*value = POWER_SUPPLY_HEALTH_GOOD;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max77705_get_battery_health(struct max77705_charger_data *charger,
|
||||
int *value)
|
||||
{
|
||||
struct regmap *regmap = charger->regmap;
|
||||
unsigned int bat_dtls;
|
||||
|
||||
regmap_read(regmap, MAX77705_CHG_REG_DETAILS_01, &bat_dtls);
|
||||
bat_dtls = ((bat_dtls & MAX77705_BAT_DTLS) >> MAX77705_BAT_DTLS_SHIFT);
|
||||
|
||||
switch (bat_dtls) {
|
||||
case MAX77705_BATTERY_NOBAT:
|
||||
dev_dbg(charger->dev, "%s: No battery and the charger is suspended\n",
|
||||
__func__);
|
||||
*value = POWER_SUPPLY_HEALTH_NO_BATTERY;
|
||||
break;
|
||||
case MAX77705_BATTERY_PREQUALIFICATION:
|
||||
dev_dbg(charger->dev, "%s: battery is okay but its voltage is low(~VPQLB)\n",
|
||||
__func__);
|
||||
break;
|
||||
case MAX77705_BATTERY_DEAD:
|
||||
dev_dbg(charger->dev, "%s: battery dead\n", __func__);
|
||||
*value = POWER_SUPPLY_HEALTH_DEAD;
|
||||
break;
|
||||
case MAX77705_BATTERY_GOOD:
|
||||
case MAX77705_BATTERY_LOWVOLTAGE:
|
||||
*value = POWER_SUPPLY_HEALTH_GOOD;
|
||||
break;
|
||||
case MAX77705_BATTERY_OVERVOLTAGE:
|
||||
dev_dbg(charger->dev, "%s: battery ovp\n", __func__);
|
||||
*value = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
|
||||
break;
|
||||
default:
|
||||
dev_dbg(charger->dev, "%s: battery unknown\n", __func__);
|
||||
*value = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max77705_get_health(struct max77705_charger_data *charger, int *val)
|
||||
{
|
||||
struct regmap *regmap = charger->regmap;
|
||||
int ret, is_online = 0;
|
||||
|
||||
ret = max77705_get_online(regmap, &is_online);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (is_online) {
|
||||
ret = max77705_get_vbus_state(regmap, val);
|
||||
if (ret || (*val != POWER_SUPPLY_HEALTH_GOOD))
|
||||
return ret;
|
||||
}
|
||||
return max77705_get_battery_health(charger, val);
|
||||
}
|
||||
|
||||
static int max77705_get_input_current(struct max77705_charger_data *charger,
|
||||
int *val)
|
||||
{
|
||||
unsigned int reg_data;
|
||||
int get_current = 0;
|
||||
struct regmap *regmap = charger->regmap;
|
||||
|
||||
regmap_read(regmap, MAX77705_CHG_REG_CNFG_09, ®_data);
|
||||
|
||||
reg_data &= MAX77705_CHG_CHGIN_LIM_MASK;
|
||||
|
||||
if (reg_data <= 3)
|
||||
get_current = MAX77705_CURRENT_CHGIN_MIN;
|
||||
else if (reg_data >= MAX77705_CHG_CHGIN_LIM_MASK)
|
||||
get_current = MAX77705_CURRENT_CHGIN_MAX;
|
||||
else
|
||||
get_current = (reg_data + 1) * MAX77705_CURRENT_CHGIN_STEP;
|
||||
|
||||
*val = get_current;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max77705_get_charge_current(struct max77705_charger_data *charger,
|
||||
int *val)
|
||||
{
|
||||
unsigned int reg_data;
|
||||
struct regmap *regmap = charger->regmap;
|
||||
|
||||
regmap_read(regmap, MAX77705_CHG_REG_CNFG_02, ®_data);
|
||||
reg_data &= MAX77705_CHG_CC;
|
||||
|
||||
*val = reg_data <= 0x2 ? MAX77705_CURRENT_CHGIN_MIN : reg_data * MAX77705_CURRENT_CHG_STEP;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max77705_set_float_voltage(struct max77705_charger_data *charger,
|
||||
int float_voltage)
|
||||
{
|
||||
int float_voltage_mv;
|
||||
unsigned int reg_data = 0;
|
||||
struct regmap *regmap = charger->regmap;
|
||||
|
||||
float_voltage_mv = float_voltage / 1000;
|
||||
reg_data = float_voltage_mv <= 4000 ? 0x0 :
|
||||
float_voltage_mv >= 4500 ? 0x23 :
|
||||
(float_voltage_mv <= 4200) ? (float_voltage_mv - 4000) / 50 :
|
||||
(((float_voltage_mv - 4200) / 10) + 0x04);
|
||||
|
||||
return regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_04,
|
||||
MAX77705_CHG_CV_PRM_MASK,
|
||||
(reg_data << MAX77705_CHG_CV_PRM_SHIFT));
|
||||
}
|
||||
|
||||
static int max77705_get_float_voltage(struct max77705_charger_data *charger,
|
||||
int *val)
|
||||
{
|
||||
unsigned int reg_data = 0;
|
||||
int voltage_mv;
|
||||
struct regmap *regmap = charger->regmap;
|
||||
|
||||
regmap_read(regmap, MAX77705_CHG_REG_CNFG_04, ®_data);
|
||||
reg_data &= MAX77705_CHG_PRM_MASK;
|
||||
voltage_mv = reg_data <= 0x04 ? reg_data * 50 + 4000 :
|
||||
(reg_data - 4) * 10 + 4200;
|
||||
*val = voltage_mv * 1000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max77705_chg_get_property(struct power_supply *psy,
|
||||
enum power_supply_property psp,
|
||||
union power_supply_propval *val)
|
||||
{
|
||||
struct max77705_charger_data *charger = power_supply_get_drvdata(psy);
|
||||
struct regmap *regmap = charger->regmap;
|
||||
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_ONLINE:
|
||||
return max77705_get_online(regmap, &val->intval);
|
||||
case POWER_SUPPLY_PROP_PRESENT:
|
||||
return max77705_check_battery(charger, &val->intval);
|
||||
case POWER_SUPPLY_PROP_STATUS:
|
||||
return max77705_get_status(charger, &val->intval);
|
||||
case POWER_SUPPLY_PROP_CHARGE_TYPE:
|
||||
return max77705_get_charge_type(charger, &val->intval);
|
||||
case POWER_SUPPLY_PROP_HEALTH:
|
||||
return max77705_get_health(charger, &val->intval);
|
||||
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
|
||||
return max77705_get_input_current(charger, &val->intval);
|
||||
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
|
||||
return max77705_get_charge_current(charger, &val->intval);
|
||||
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
|
||||
return max77705_get_float_voltage(charger, &val->intval);
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
|
||||
val->intval = charger->bat_info->voltage_max_design_uv;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_MODEL_NAME:
|
||||
val->strval = max77705_charger_model;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_MANUFACTURER:
|
||||
val->strval = max77705_charger_manufacturer;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct power_supply_desc max77705_charger_psy_desc = {
|
||||
.name = "max77705-charger",
|
||||
.type = POWER_SUPPLY_TYPE_USB,
|
||||
.properties = max77705_charger_props,
|
||||
.num_properties = ARRAY_SIZE(max77705_charger_props),
|
||||
.get_property = max77705_chg_get_property,
|
||||
};
|
||||
|
||||
static void max77705_chgin_isr_work(struct work_struct *work)
|
||||
{
|
||||
struct max77705_charger_data *charger =
|
||||
container_of(work, struct max77705_charger_data, chgin_work);
|
||||
|
||||
power_supply_changed(charger->psy_chg);
|
||||
}
|
||||
|
||||
static void max77705_charger_initialize(struct max77705_charger_data *chg)
|
||||
{
|
||||
u8 reg_data;
|
||||
struct power_supply_battery_info *info;
|
||||
struct regmap *regmap = chg->regmap;
|
||||
|
||||
if (power_supply_get_battery_info(chg->psy_chg, &info) < 0)
|
||||
return;
|
||||
|
||||
chg->bat_info = info;
|
||||
|
||||
/* unlock charger setting protect */
|
||||
/* slowest LX slope */
|
||||
reg_data = MAX77705_CHGPROT_MASK | MAX77705_SLOWEST_LX_SLOPE;
|
||||
regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_06, reg_data,
|
||||
reg_data);
|
||||
|
||||
/* fast charge timer disable */
|
||||
/* restart threshold disable */
|
||||
/* pre-qual charge disable */
|
||||
reg_data = (MAX77705_FCHGTIME_DISABLE << MAX77705_FCHGTIME_SHIFT) |
|
||||
(MAX77705_CHG_RSTRT_DISABLE << MAX77705_CHG_RSTRT_SHIFT) |
|
||||
(MAX77705_CHG_PQEN_DISABLE << MAX77705_PQEN_SHIFT);
|
||||
regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_01,
|
||||
(MAX77705_FCHGTIME_MASK |
|
||||
MAX77705_CHG_RSTRT_MASK |
|
||||
MAX77705_PQEN_MASK),
|
||||
reg_data);
|
||||
|
||||
/* OTG off(UNO on), boost off */
|
||||
regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_00,
|
||||
MAX77705_OTG_CTRL, 0);
|
||||
|
||||
/* charge current 450mA(default) */
|
||||
/* otg current limit 900mA */
|
||||
regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_02,
|
||||
MAX77705_OTG_ILIM_MASK,
|
||||
MAX77705_OTG_ILIM_900 << MAX77705_OTG_ILIM_SHIFT);
|
||||
|
||||
/* BAT to SYS OCP 4.80A */
|
||||
regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_05,
|
||||
MAX77705_REG_B2SOVRC_MASK,
|
||||
MAX77705_B2SOVRC_4_8A << MAX77705_REG_B2SOVRC_SHIFT);
|
||||
/* top off current 150mA */
|
||||
/* top off timer 30min */
|
||||
reg_data = (MAX77705_TO_ITH_150MA << MAX77705_TO_ITH_SHIFT) |
|
||||
(MAX77705_TO_TIME_30M << MAX77705_TO_TIME_SHIFT) |
|
||||
(MAX77705_SYS_TRACK_DISABLE << MAX77705_SYS_TRACK_DIS_SHIFT);
|
||||
regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_03,
|
||||
(MAX77705_TO_ITH_MASK |
|
||||
MAX77705_TO_TIME_MASK |
|
||||
MAX77705_SYS_TRACK_DIS_MASK), reg_data);
|
||||
|
||||
/* cv voltage 4.2V or 4.35V */
|
||||
/* MINVSYS 3.6V(default) */
|
||||
if (info->voltage_max_design_uv < 0) {
|
||||
dev_warn(chg->dev, "missing battery:voltage-max-design-microvolt\n");
|
||||
max77705_set_float_voltage(chg, 4200000);
|
||||
} else {
|
||||
max77705_set_float_voltage(chg, info->voltage_max_design_uv);
|
||||
}
|
||||
|
||||
regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_12,
|
||||
MAX77705_VCHGIN_REG_MASK, MAX77705_VCHGIN_4_5);
|
||||
regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_12,
|
||||
MAX77705_WCIN_REG_MASK, MAX77705_WCIN_4_5);
|
||||
|
||||
/* Watchdog timer */
|
||||
regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_00,
|
||||
MAX77705_WDTEN_MASK, 0);
|
||||
|
||||
/* Active Discharge Enable */
|
||||
regmap_update_bits(regmap, MAX77705_PMIC_REG_MAINCTRL1, 1, 1);
|
||||
|
||||
/* VBYPSET=5.0V */
|
||||
regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_11, MAX77705_VBYPSET_MASK, 0);
|
||||
|
||||
/* Switching Frequency : 1.5MHz */
|
||||
regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_08, MAX77705_REG_FSW_MASK,
|
||||
(MAX77705_CHG_FSW_1_5MHz << MAX77705_REG_FSW_SHIFT));
|
||||
|
||||
/* Auto skip mode */
|
||||
regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_12, MAX77705_REG_DISKIP_MASK,
|
||||
(MAX77705_AUTO_SKIP << MAX77705_REG_DISKIP_SHIFT));
|
||||
}
|
||||
|
||||
static int max77705_charger_probe(struct i2c_client *i2c)
|
||||
{
|
||||
struct power_supply_config pscfg = {};
|
||||
struct max77705_charger_data *chg;
|
||||
struct device *dev;
|
||||
struct regmap_irq_chip_data *irq_data;
|
||||
int ret;
|
||||
|
||||
dev = &i2c->dev;
|
||||
|
||||
chg = devm_kzalloc(dev, sizeof(*chg), GFP_KERNEL);
|
||||
if (!chg)
|
||||
return -ENOMEM;
|
||||
|
||||
chg->dev = dev;
|
||||
i2c_set_clientdata(i2c, chg);
|
||||
|
||||
chg->regmap = devm_regmap_init_i2c(i2c, &max77705_chg_regmap_config);
|
||||
if (IS_ERR(chg->regmap))
|
||||
return PTR_ERR(chg->regmap);
|
||||
|
||||
ret = regmap_update_bits(chg->regmap,
|
||||
MAX77705_CHG_REG_INT_MASK,
|
||||
MAX77705_CHGIN_IM, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pscfg.fwnode = dev_fwnode(dev);
|
||||
pscfg.drv_data = chg;
|
||||
|
||||
chg->psy_chg = devm_power_supply_register(dev, &max77705_charger_psy_desc, &pscfg);
|
||||
if (IS_ERR(chg->psy_chg))
|
||||
return PTR_ERR(chg->psy_chg);
|
||||
|
||||
max77705_charger_irq_chip.irq_drv_data = chg;
|
||||
ret = devm_regmap_add_irq_chip(chg->dev, chg->regmap, i2c->irq,
|
||||
IRQF_ONESHOT | IRQF_SHARED, 0,
|
||||
&max77705_charger_irq_chip,
|
||||
&irq_data);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to add irq chip\n");
|
||||
|
||||
chg->wqueue = create_singlethread_workqueue(dev_name(dev));
|
||||
if (IS_ERR(chg->wqueue))
|
||||
return dev_err_probe(dev, PTR_ERR(chg->wqueue), "failed to create workqueue\n");
|
||||
|
||||
ret = devm_work_autocancel(dev, &chg->chgin_work, max77705_chgin_isr_work);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to initialize interrupt work\n");
|
||||
|
||||
max77705_charger_initialize(chg);
|
||||
|
||||
ret = max77705_charger_enable(chg);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to enable charge\n");
|
||||
|
||||
return devm_add_action_or_reset(dev, max77705_charger_disable, chg);
|
||||
}
|
||||
|
||||
static const struct of_device_id max77705_charger_of_match[] = {
|
||||
{ .compatible = "maxim,max77705-charger" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, max77705_charger_of_match);
|
||||
|
||||
static struct i2c_driver max77705_charger_driver = {
|
||||
.driver = {
|
||||
.name = "max77705-charger",
|
||||
.of_match_table = max77705_charger_of_match,
|
||||
},
|
||||
.probe = max77705_charger_probe,
|
||||
};
|
||||
module_i2c_driver(max77705_charger_driver);
|
||||
|
||||
MODULE_AUTHOR("Dzmitry Sankouski <dsankouski@gmail.com>");
|
||||
MODULE_DESCRIPTION("Maxim MAX77705 charger driver");
|
||||
MODULE_LICENSE("GPL");
|
@ -1330,10 +1330,10 @@ config REGULATOR_S2MPA01
|
||||
via I2C bus. S2MPA01 has 10 Bucks and 26 LDO outputs.
|
||||
|
||||
config REGULATOR_S2MPS11
|
||||
tristate "Samsung S2MPS11/13/14/15/S2MPU02 voltage regulator"
|
||||
tristate "Samsung S2MPS11/13/14/15/S2MPU02/05 voltage regulator"
|
||||
depends on MFD_SEC_CORE || COMPILE_TEST
|
||||
help
|
||||
This driver supports a Samsung S2MPS11/13/14/15/S2MPU02 voltage
|
||||
This driver supports a Samsung S2MPS11/13/14/15/S2MPU02/05 voltage
|
||||
output regulator via I2C bus. The chip is comprised of high efficient
|
||||
Buck converters including Dual-Phase Buck converter, Buck-Boost
|
||||
converter, various LDOs.
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <linux/mfd/samsung/s2mps14.h>
|
||||
#include <linux/mfd/samsung/s2mps15.h>
|
||||
#include <linux/mfd/samsung/s2mpu02.h>
|
||||
#include <linux/mfd/samsung/s2mpu05.h>
|
||||
|
||||
/* The highest number of possible regulators for supported devices. */
|
||||
#define S2MPS_REGULATOR_MAX S2MPS13_REGULATOR_MAX
|
||||
@ -254,6 +255,9 @@ static int s2mps11_regulator_enable(struct regulator_dev *rdev)
|
||||
else
|
||||
val = rdev->desc->enable_mask;
|
||||
break;
|
||||
case S2MPU05:
|
||||
val = rdev->desc->enable_mask;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -1118,6 +1122,86 @@ static const struct regulator_desc s2mpu02_regulators[] = {
|
||||
regulator_desc_s2mpu02_buck7(7),
|
||||
};
|
||||
|
||||
#define regulator_desc_s2mpu05_ldo_reg(num, min, step, reg) { \
|
||||
.name = "ldo"#num, \
|
||||
.id = S2MPU05_LDO##num, \
|
||||
.ops = &s2mpu02_ldo_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
.min_uV = min, \
|
||||
.uV_step = step, \
|
||||
.n_voltages = S2MPU05_LDO_N_VOLTAGES, \
|
||||
.vsel_reg = reg, \
|
||||
.vsel_mask = S2MPU05_LDO_VSEL_MASK, \
|
||||
.enable_reg = reg, \
|
||||
.enable_mask = S2MPU05_ENABLE_MASK, \
|
||||
.enable_time = S2MPU05_ENABLE_TIME_LDO \
|
||||
}
|
||||
|
||||
#define regulator_desc_s2mpu05_ldo(num, reg, min, step) \
|
||||
regulator_desc_s2mpu05_ldo_reg(num, min, step, S2MPU05_REG_L##num##reg)
|
||||
|
||||
#define regulator_desc_s2mpu05_ldo1(num, reg) \
|
||||
regulator_desc_s2mpu05_ldo(num, reg, S2MPU05_LDO_MIN1, S2MPU05_LDO_STEP1)
|
||||
|
||||
#define regulator_desc_s2mpu05_ldo2(num, reg) \
|
||||
regulator_desc_s2mpu05_ldo(num, reg, S2MPU05_LDO_MIN1, S2MPU05_LDO_STEP2)
|
||||
|
||||
#define regulator_desc_s2mpu05_ldo3(num, reg) \
|
||||
regulator_desc_s2mpu05_ldo(num, reg, S2MPU05_LDO_MIN2, S2MPU05_LDO_STEP2)
|
||||
|
||||
#define regulator_desc_s2mpu05_ldo4(num, reg) \
|
||||
regulator_desc_s2mpu05_ldo(num, reg, S2MPU05_LDO_MIN3, S2MPU05_LDO_STEP2)
|
||||
|
||||
#define regulator_desc_s2mpu05_buck(num, which) { \
|
||||
.name = "buck"#num, \
|
||||
.id = S2MPU05_BUCK##num, \
|
||||
.ops = &s2mpu02_buck_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE, \
|
||||
.min_uV = S2MPU05_BUCK_MIN##which, \
|
||||
.uV_step = S2MPU05_BUCK_STEP##which, \
|
||||
.n_voltages = S2MPU05_BUCK_N_VOLTAGES, \
|
||||
.vsel_reg = S2MPU05_REG_B##num##CTRL2, \
|
||||
.vsel_mask = S2MPU05_BUCK_VSEL_MASK, \
|
||||
.enable_reg = S2MPU05_REG_B##num##CTRL1, \
|
||||
.enable_mask = S2MPU05_ENABLE_MASK, \
|
||||
.enable_time = S2MPU05_ENABLE_TIME_BUCK##num \
|
||||
}
|
||||
|
||||
#define regulator_desc_s2mpu05_buck123(num) regulator_desc_s2mpu05_buck(num, 1)
|
||||
#define regulator_desc_s2mpu05_buck45(num) regulator_desc_s2mpu05_buck(num, 2)
|
||||
|
||||
static const struct regulator_desc s2mpu05_regulators[] = {
|
||||
regulator_desc_s2mpu05_ldo4(1, CTRL),
|
||||
regulator_desc_s2mpu05_ldo3(2, CTRL),
|
||||
regulator_desc_s2mpu05_ldo2(3, CTRL),
|
||||
regulator_desc_s2mpu05_ldo1(4, CTRL),
|
||||
regulator_desc_s2mpu05_ldo1(5, CTRL),
|
||||
regulator_desc_s2mpu05_ldo1(6, CTRL),
|
||||
regulator_desc_s2mpu05_ldo2(7, CTRL),
|
||||
regulator_desc_s2mpu05_ldo3(8, CTRL),
|
||||
regulator_desc_s2mpu05_ldo4(9, CTRL1),
|
||||
regulator_desc_s2mpu05_ldo4(10, CTRL),
|
||||
/* LDOs 11-24 are used for CP. They aren't documented. */
|
||||
regulator_desc_s2mpu05_ldo2(25, CTRL),
|
||||
regulator_desc_s2mpu05_ldo3(26, CTRL),
|
||||
regulator_desc_s2mpu05_ldo2(27, CTRL),
|
||||
regulator_desc_s2mpu05_ldo3(28, CTRL),
|
||||
regulator_desc_s2mpu05_ldo3(29, CTRL),
|
||||
regulator_desc_s2mpu05_ldo2(30, CTRL),
|
||||
regulator_desc_s2mpu05_ldo3(31, CTRL),
|
||||
regulator_desc_s2mpu05_ldo3(32, CTRL),
|
||||
regulator_desc_s2mpu05_ldo3(33, CTRL),
|
||||
regulator_desc_s2mpu05_ldo3(34, CTRL),
|
||||
regulator_desc_s2mpu05_ldo3(35, CTRL),
|
||||
regulator_desc_s2mpu05_buck123(1),
|
||||
regulator_desc_s2mpu05_buck123(2),
|
||||
regulator_desc_s2mpu05_buck123(3),
|
||||
regulator_desc_s2mpu05_buck45(4),
|
||||
regulator_desc_s2mpu05_buck45(5),
|
||||
};
|
||||
|
||||
static int s2mps11_pmic_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
|
||||
@ -1159,6 +1243,11 @@ static int s2mps11_pmic_probe(struct platform_device *pdev)
|
||||
regulators = s2mpu02_regulators;
|
||||
BUILD_BUG_ON(S2MPS_REGULATOR_MAX < ARRAY_SIZE(s2mpu02_regulators));
|
||||
break;
|
||||
case S2MPU05:
|
||||
rdev_num = ARRAY_SIZE(s2mpu05_regulators);
|
||||
regulators = s2mpu05_regulators;
|
||||
BUILD_BUG_ON(S2MPS_REGULATOR_MAX < ARRAY_SIZE(s2mpu05_regulators));
|
||||
break;
|
||||
default:
|
||||
dev_err(&pdev->dev, "Invalid device type: %u\n",
|
||||
s2mps11->dev_type);
|
||||
@ -1228,6 +1317,7 @@ static const struct platform_device_id s2mps11_pmic_id[] = {
|
||||
{ "s2mps14-regulator", S2MPS14X},
|
||||
{ "s2mps15-regulator", S2MPS15X},
|
||||
{ "s2mpu02-regulator", S2MPU02},
|
||||
{ "s2mpu05-regulator", S2MPU05},
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, s2mps11_pmic_id);
|
||||
@ -1245,5 +1335,5 @@ module_platform_driver(s2mps11_pmic_driver);
|
||||
|
||||
/* Module information */
|
||||
MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
|
||||
MODULE_DESCRIPTION("Samsung S2MPS11/S2MPS14/S2MPS15/S2MPU02 Regulator Driver");
|
||||
MODULE_DESCRIPTION("Samsung S2MPS11/14/15/S2MPU02/05 Regulator Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -137,6 +137,7 @@ enum axp20x_variants {
|
||||
#define AXP717_IRQ2_STATE 0x4a
|
||||
#define AXP717_IRQ3_STATE 0x4b
|
||||
#define AXP717_IRQ4_STATE 0x4c
|
||||
#define AXP717_TS_PIN_CFG 0x50
|
||||
#define AXP717_ICC_CHG_SET 0x62
|
||||
#define AXP717_ITERM_CHG_SET 0x63
|
||||
#define AXP717_CV_CHG_SET 0x64
|
||||
|
@ -215,7 +215,7 @@ struct prcmu_fw_version {
|
||||
|
||||
static inline void prcmu_early_init(void)
|
||||
{
|
||||
return db8500_prcmu_early_init();
|
||||
db8500_prcmu_early_init();
|
||||
}
|
||||
|
||||
static inline int prcmu_set_power_state(u8 state, bool keep_ulp_clk,
|
||||
@ -302,7 +302,7 @@ static inline int prcmu_request_ape_opp_100_voltage(bool enable)
|
||||
|
||||
static inline void prcmu_system_reset(u16 reset_code)
|
||||
{
|
||||
return db8500_prcmu_system_reset(reset_code);
|
||||
db8500_prcmu_system_reset(reset_code);
|
||||
}
|
||||
|
||||
static inline u16 prcmu_get_reset_code(void)
|
||||
@ -314,7 +314,7 @@ int prcmu_ac_wake_req(void);
|
||||
void prcmu_ac_sleep_req(void);
|
||||
static inline void prcmu_modem_reset(void)
|
||||
{
|
||||
return db8500_prcmu_modem_reset();
|
||||
db8500_prcmu_modem_reset();
|
||||
}
|
||||
|
||||
static inline bool prcmu_is_ac_wake_requested(void)
|
||||
|
@ -31,7 +31,6 @@ int ezx_pcap_set_bits(struct pcap_chip *, u8, u32, u32);
|
||||
int pcap_to_irq(struct pcap_chip *, int);
|
||||
int irq_to_pcap(struct pcap_chip *, int);
|
||||
int pcap_adc_async(struct pcap_chip *, u8, u32, u8[], void *, void *);
|
||||
int pcap_adc_sync(struct pcap_chip *, u8, u32, u8[], u16[]);
|
||||
void pcap_set_ts_bits(struct pcap_chip *, u32);
|
||||
|
||||
#define PCAP_SECOND_PORT 1
|
||||
|
@ -11,7 +11,6 @@
|
||||
#define __MFD_LP3943_H__
|
||||
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/pwm.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
/* Registers */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Common data shared between Maxim 77693 and 77843 drivers
|
||||
* Common data shared between Maxim 77693, 77705 and 77843 drivers
|
||||
*
|
||||
* Copyright (C) 2015 Samsung Electronics
|
||||
*/
|
||||
@ -11,6 +11,7 @@
|
||||
enum max77693_types {
|
||||
TYPE_MAX77693_UNKNOWN,
|
||||
TYPE_MAX77693,
|
||||
TYPE_MAX77705,
|
||||
TYPE_MAX77843,
|
||||
|
||||
TYPE_MAX77693_NUM,
|
||||
@ -32,6 +33,7 @@ struct max77693_dev {
|
||||
struct regmap *regmap_muic;
|
||||
struct regmap *regmap_haptic; /* Only MAX77693 */
|
||||
struct regmap *regmap_chg; /* Only MAX77843 */
|
||||
struct regmap *regmap_leds; /* Only MAX77705 */
|
||||
|
||||
struct regmap_irq_chip_data *irq_data_led;
|
||||
struct regmap_irq_chip_data *irq_data_topsys;
|
||||
|
195
include/linux/mfd/max77705-private.h
Normal file
195
include/linux/mfd/max77705-private.h
Normal file
@ -0,0 +1,195 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Maxim MAX77705 definitions.
|
||||
*
|
||||
* Copyright (C) 2015 Samsung Electronics, Inc.
|
||||
* Copyright (C) 2025 Dzmitry Sankouski <dsankouski@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_MFD_MAX77705_PRIV_H
|
||||
#define __LINUX_MFD_MAX77705_PRIV_H
|
||||
|
||||
#define MAX77705_SRC_IRQ_CHG BIT(0)
|
||||
#define MAX77705_SRC_IRQ_TOP BIT(1)
|
||||
#define MAX77705_SRC_IRQ_FG BIT(2)
|
||||
#define MAX77705_SRC_IRQ_USBC BIT(3)
|
||||
#define MAX77705_SRC_IRQ_ALL (MAX77705_SRC_IRQ_CHG | MAX77705_SRC_IRQ_TOP | \
|
||||
MAX77705_SRC_IRQ_FG | MAX77705_SRC_IRQ_USBC)
|
||||
|
||||
/* MAX77705_PMIC_REG_PMICREV register */
|
||||
#define MAX77705_VERSION_SHIFT 3
|
||||
#define MAX77705_REVISION_MASK GENMASK(2, 0)
|
||||
#define MAX77705_VERSION_MASK GENMASK(7, MAX77705_VERSION_SHIFT)
|
||||
/* MAX77705_PMIC_REG_MAINCTRL1 register */
|
||||
#define MAX77705_MAINCTRL1_BIASEN_SHIFT 7
|
||||
#define MAX77705_MAINCTRL1_BIASEN_MASK BIT(MAX77705_MAINCTRL1_BIASEN_SHIFT)
|
||||
/* MAX77705_PMIC_REG_MCONFIG2 (haptics) register */
|
||||
#define MAX77705_CONFIG2_MEN_SHIFT 6
|
||||
#define MAX77705_CONFIG2_MODE_SHIFT 7
|
||||
#define MAX77705_CONFIG2_HTYP_SHIFT 5
|
||||
/* MAX77705_PMIC_REG_SYSTEM_INT_MASK register */
|
||||
#define MAX77705_SYSTEM_IRQ_BSTEN_INT BIT(3)
|
||||
#define MAX77705_SYSTEM_IRQ_SYSUVLO_INT BIT(4)
|
||||
#define MAX77705_SYSTEM_IRQ_SYSOVLO_INT BIT(5)
|
||||
#define MAX77705_SYSTEM_IRQ_TSHDN_INT BIT(6)
|
||||
#define MAX77705_SYSTEM_IRQ_TM_INT BIT(7)
|
||||
/* MAX77705_RGBLED_REG_LEDEN register */
|
||||
#define MAX77705_RGBLED_EN_WIDTH 2
|
||||
/* MAX77705_RGBLED_REG_LEDBLNK register */
|
||||
#define MAX77705_RGB_DELAY_100_STEP_LIM 500
|
||||
#define MAX77705_RGB_DELAY_100_STEP_COUNT 4
|
||||
#define MAX77705_RGB_DELAY_100_STEP 100
|
||||
#define MAX77705_RGB_DELAY_250_STEP_LIM 3250
|
||||
#define MAX77705_RGB_DELAY_250_STEP 250
|
||||
#define MAX77705_RGB_DELAY_500_STEP 500
|
||||
#define MAX77705_RGB_DELAY_500_STEP_COUNT 10
|
||||
#define MAX77705_RGB_DELAY_500_STEP_LIM 5000
|
||||
#define MAX77705_RGB_DELAY_1000_STEP_LIM 8000
|
||||
#define MAX77705_RGB_DELAY_1000_STEP_COUNT 13
|
||||
#define MAX77705_RGB_DELAY_1000_STEP 1000
|
||||
#define MAX77705_RGB_DELAY_2000_STEP 2000
|
||||
#define MAX77705_RGB_DELAY_2000_STEP_COUNT 13
|
||||
#define MAX77705_RGB_DELAY_2000_STEP_LIM 12000
|
||||
|
||||
enum max77705_hw_rev {
|
||||
MAX77705_PASS1 = 1,
|
||||
MAX77705_PASS2,
|
||||
MAX77705_PASS3
|
||||
};
|
||||
|
||||
enum max77705_reg {
|
||||
MAX77705_PMIC_REG_PMICID1 = 0x00,
|
||||
MAX77705_PMIC_REG_PMICREV = 0x01,
|
||||
MAX77705_PMIC_REG_MAINCTRL1 = 0x02,
|
||||
MAX77705_PMIC_REG_BSTOUT_MASK = 0x03,
|
||||
MAX77705_PMIC_REG_FORCE_EN_MASK = 0x08,
|
||||
MAX77705_PMIC_REG_MCONFIG = 0x10,
|
||||
MAX77705_PMIC_REG_MCONFIG2 = 0x11,
|
||||
MAX77705_PMIC_REG_INTSRC = 0x22,
|
||||
MAX77705_PMIC_REG_INTSRC_MASK = 0x23,
|
||||
MAX77705_PMIC_REG_SYSTEM_INT = 0x24,
|
||||
MAX77705_PMIC_REG_RESERVED_25 = 0x25,
|
||||
MAX77705_PMIC_REG_SYSTEM_INT_MASK = 0x26,
|
||||
MAX77705_PMIC_REG_RESERVED_27 = 0x27,
|
||||
MAX77705_PMIC_REG_RESERVED_28 = 0x28,
|
||||
MAX77705_PMIC_REG_RESERVED_29 = 0x29,
|
||||
MAX77705_PMIC_REG_BOOSTCONTROL1 = 0x4C,
|
||||
MAX77705_PMIC_REG_BOOSTCONTROL2 = 0x4F,
|
||||
MAX77705_PMIC_REG_SW_RESET = 0x50,
|
||||
MAX77705_PMIC_REG_USBC_RESET = 0x51,
|
||||
|
||||
MAX77705_PMIC_REG_END
|
||||
};
|
||||
|
||||
enum max77705_chg_reg {
|
||||
MAX77705_CHG_REG_BASE = 0xB0,
|
||||
MAX77705_CHG_REG_INT = 0,
|
||||
MAX77705_CHG_REG_INT_MASK,
|
||||
MAX77705_CHG_REG_INT_OK,
|
||||
MAX77705_CHG_REG_DETAILS_00,
|
||||
MAX77705_CHG_REG_DETAILS_01,
|
||||
MAX77705_CHG_REG_DETAILS_02,
|
||||
MAX77705_CHG_REG_DTLS_03,
|
||||
MAX77705_CHG_REG_CNFG_00,
|
||||
MAX77705_CHG_REG_CNFG_01,
|
||||
MAX77705_CHG_REG_CNFG_02,
|
||||
MAX77705_CHG_REG_CNFG_03,
|
||||
MAX77705_CHG_REG_CNFG_04,
|
||||
MAX77705_CHG_REG_CNFG_05,
|
||||
MAX77705_CHG_REG_CNFG_06,
|
||||
MAX77705_CHG_REG_CNFG_07,
|
||||
MAX77705_CHG_REG_CNFG_08,
|
||||
MAX77705_CHG_REG_CNFG_09,
|
||||
MAX77705_CHG_REG_CNFG_10,
|
||||
MAX77705_CHG_REG_CNFG_11,
|
||||
|
||||
MAX77705_CHG_REG_CNFG_12,
|
||||
MAX77705_CHG_REG_CNFG_13,
|
||||
MAX77705_CHG_REG_CNFG_14,
|
||||
MAX77705_CHG_REG_SAFEOUT_CTRL
|
||||
};
|
||||
|
||||
enum max77705_fuelgauge_reg {
|
||||
STATUS_REG = 0x00,
|
||||
VALRT_THRESHOLD_REG = 0x01,
|
||||
TALRT_THRESHOLD_REG = 0x02,
|
||||
SALRT_THRESHOLD_REG = 0x03,
|
||||
REMCAP_REP_REG = 0x05,
|
||||
SOCREP_REG = 0x06,
|
||||
TEMPERATURE_REG = 0x08,
|
||||
VCELL_REG = 0x09,
|
||||
TIME_TO_EMPTY_REG = 0x11,
|
||||
FULLSOCTHR_REG = 0x13,
|
||||
CURRENT_REG = 0x0A,
|
||||
AVG_CURRENT_REG = 0x0B,
|
||||
SOCMIX_REG = 0x0D,
|
||||
SOCAV_REG = 0x0E,
|
||||
REMCAP_MIX_REG = 0x0F,
|
||||
FULLCAP_REG = 0x10,
|
||||
RFAST_REG = 0x15,
|
||||
AVR_TEMPERATURE_REG = 0x16,
|
||||
CYCLES_REG = 0x17,
|
||||
DESIGNCAP_REG = 0x18,
|
||||
AVR_VCELL_REG = 0x19,
|
||||
TIME_TO_FULL_REG = 0x20,
|
||||
CONFIG_REG = 0x1D,
|
||||
ICHGTERM_REG = 0x1E,
|
||||
REMCAP_AV_REG = 0x1F,
|
||||
FULLCAP_NOM_REG = 0x23,
|
||||
LEARN_CFG_REG = 0x28,
|
||||
FILTER_CFG_REG = 0x29,
|
||||
MISCCFG_REG = 0x2B,
|
||||
QRTABLE20_REG = 0x32,
|
||||
FULLCAP_REP_REG = 0x35,
|
||||
RCOMP_REG = 0x38,
|
||||
VEMPTY_REG = 0x3A,
|
||||
FSTAT_REG = 0x3D,
|
||||
DISCHARGE_THRESHOLD_REG = 0x40,
|
||||
QRTABLE30_REG = 0x42,
|
||||
ISYS_REG = 0x43,
|
||||
DQACC_REG = 0x45,
|
||||
DPACC_REG = 0x46,
|
||||
AVGISYS_REG = 0x4B,
|
||||
QH_REG = 0x4D,
|
||||
VSYS_REG = 0xB1,
|
||||
TALRTTH2_REG = 0xB2,
|
||||
VBYP_REG = 0xB3,
|
||||
CONFIG2_REG = 0xBB,
|
||||
IIN_REG = 0xD0,
|
||||
OCV_REG = 0xEE,
|
||||
VFOCV_REG = 0xFB,
|
||||
VFSOC_REG = 0xFF,
|
||||
|
||||
MAX77705_FG_END
|
||||
};
|
||||
|
||||
enum max77705_led_reg {
|
||||
MAX77705_RGBLED_REG_BASE = 0x30,
|
||||
MAX77705_RGBLED_REG_LEDEN = 0,
|
||||
MAX77705_RGBLED_REG_LED0BRT,
|
||||
MAX77705_RGBLED_REG_LED1BRT,
|
||||
MAX77705_RGBLED_REG_LED2BRT,
|
||||
MAX77705_RGBLED_REG_LED3BRT,
|
||||
MAX77705_RGBLED_REG_LEDRMP,
|
||||
MAX77705_RGBLED_REG_LEDBLNK,
|
||||
MAX77705_LED_REG_END
|
||||
};
|
||||
|
||||
enum max77705_charger_battery_state {
|
||||
MAX77705_BATTERY_NOBAT,
|
||||
MAX77705_BATTERY_PREQUALIFICATION,
|
||||
MAX77705_BATTERY_DEAD,
|
||||
MAX77705_BATTERY_GOOD,
|
||||
MAX77705_BATTERY_LOWVOLTAGE,
|
||||
MAX77705_BATTERY_OVERVOLTAGE,
|
||||
MAX77705_BATTERY_RESERVED
|
||||
};
|
||||
|
||||
enum max77705_charger_charge_type {
|
||||
MAX77705_CHARGER_CONSTANT_CURRENT = 1,
|
||||
MAX77705_CHARGER_CONSTANT_VOLTAGE,
|
||||
MAX77705_CHARGER_END_OF_CHARGE,
|
||||
MAX77705_CHARGER_DONE
|
||||
};
|
||||
|
||||
#endif /* __LINUX_MFD_MAX77705_PRIV_H */
|
@ -397,7 +397,6 @@ enum max8997_types {
|
||||
};
|
||||
|
||||
extern int max8997_irq_init(struct max8997_dev *max8997);
|
||||
extern void max8997_irq_exit(struct max8997_dev *max8997);
|
||||
extern int max8997_irq_resume(struct max8997_dev *max8997);
|
||||
|
||||
extern int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest);
|
||||
|
@ -1,69 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* adc.h -- Driver for NXP PCF50633 ADC
|
||||
*
|
||||
* (C) 2006-2008 by Openmoko, Inc.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_MFD_PCF50633_ADC_H
|
||||
#define __LINUX_MFD_PCF50633_ADC_H
|
||||
|
||||
#include <linux/mfd/pcf50633/core.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
/* ADC Registers */
|
||||
#define PCF50633_REG_ADCC3 0x52
|
||||
#define PCF50633_REG_ADCC2 0x53
|
||||
#define PCF50633_REG_ADCC1 0x54
|
||||
#define PCF50633_REG_ADCS1 0x55
|
||||
#define PCF50633_REG_ADCS2 0x56
|
||||
#define PCF50633_REG_ADCS3 0x57
|
||||
|
||||
#define PCF50633_ADCC1_ADCSTART 0x01
|
||||
#define PCF50633_ADCC1_RES_8BIT 0x02
|
||||
#define PCF50633_ADCC1_RES_10BIT 0x00
|
||||
#define PCF50633_ADCC1_AVERAGE_NO 0x00
|
||||
#define PCF50633_ADCC1_AVERAGE_4 0x04
|
||||
#define PCF50633_ADCC1_AVERAGE_8 0x08
|
||||
#define PCF50633_ADCC1_AVERAGE_16 0x0c
|
||||
#define PCF50633_ADCC1_MUX_BATSNS_RES 0x00
|
||||
#define PCF50633_ADCC1_MUX_BATSNS_SUBTR 0x10
|
||||
#define PCF50633_ADCC1_MUX_ADCIN2_RES 0x20
|
||||
#define PCF50633_ADCC1_MUX_ADCIN2_SUBTR 0x30
|
||||
#define PCF50633_ADCC1_MUX_BATTEMP 0x60
|
||||
#define PCF50633_ADCC1_MUX_ADCIN1 0x70
|
||||
#define PCF50633_ADCC1_AVERAGE_MASK 0x0c
|
||||
#define PCF50633_ADCC1_ADCMUX_MASK 0xf0
|
||||
|
||||
#define PCF50633_ADCC2_RATIO_NONE 0x00
|
||||
#define PCF50633_ADCC2_RATIO_BATTEMP 0x01
|
||||
#define PCF50633_ADCC2_RATIO_ADCIN1 0x02
|
||||
#define PCF50633_ADCC2_RATIO_BOTH 0x03
|
||||
#define PCF50633_ADCC2_RATIOSETTL_100US 0x04
|
||||
|
||||
#define PCF50633_ADCC3_ACCSW_EN 0x01
|
||||
#define PCF50633_ADCC3_NTCSW_EN 0x04
|
||||
#define PCF50633_ADCC3_RES_DIV_TWO 0x10
|
||||
#define PCF50633_ADCC3_RES_DIV_THREE 0x00
|
||||
|
||||
#define PCF50633_ADCS3_REF_NTCSW 0x00
|
||||
#define PCF50633_ADCS3_REF_ACCSW 0x10
|
||||
#define PCF50633_ADCS3_REF_2V0 0x20
|
||||
#define PCF50633_ADCS3_REF_VISA 0x30
|
||||
#define PCF50633_ADCS3_REF_2V0_2 0x70
|
||||
#define PCF50633_ADCS3_ADCRDY 0x80
|
||||
|
||||
#define PCF50633_ADCS3_ADCDAT1L_MASK 0x03
|
||||
#define PCF50633_ADCS3_ADCDAT2L_MASK 0x0c
|
||||
#define PCF50633_ADCS3_ADCDAT2L_SHIFT 2
|
||||
#define PCF50633_ASCS3_REF_MASK 0x70
|
||||
|
||||
extern int
|
||||
pcf50633_adc_async_read(struct pcf50633 *pcf, int mux, int avg,
|
||||
void (*callback)(struct pcf50633 *, void *, int),
|
||||
void *callback_param);
|
||||
extern int
|
||||
pcf50633_adc_sync_read(struct pcf50633 *pcf, int mux, int avg);
|
||||
|
||||
#endif /* __LINUX_PCF50633_ADC_H */
|
@ -1,48 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* gpio.h -- GPIO driver for NXP PCF50633
|
||||
*
|
||||
* (C) 2006-2008 by Openmoko, Inc.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_MFD_PCF50633_GPIO_H
|
||||
#define __LINUX_MFD_PCF50633_GPIO_H
|
||||
|
||||
#include <linux/mfd/pcf50633/core.h>
|
||||
|
||||
#define PCF50633_GPIO1 1
|
||||
#define PCF50633_GPIO2 2
|
||||
#define PCF50633_GPIO3 3
|
||||
#define PCF50633_GPO 4
|
||||
|
||||
#define PCF50633_REG_GPIO1CFG 0x14
|
||||
#define PCF50633_REG_GPIO2CFG 0x15
|
||||
#define PCF50633_REG_GPIO3CFG 0x16
|
||||
#define PCF50633_REG_GPOCFG 0x17
|
||||
|
||||
#define PCF50633_GPOCFG_GPOSEL_MASK 0x07
|
||||
|
||||
enum pcf50633_reg_gpocfg {
|
||||
PCF50633_GPOCFG_GPOSEL_0 = 0x00,
|
||||
PCF50633_GPOCFG_GPOSEL_LED_NFET = 0x01,
|
||||
PCF50633_GPOCFG_GPOSEL_SYSxOK = 0x02,
|
||||
PCF50633_GPOCFG_GPOSEL_CLK32K = 0x03,
|
||||
PCF50633_GPOCFG_GPOSEL_ADAPUSB = 0x04,
|
||||
PCF50633_GPOCFG_GPOSEL_USBxOK = 0x05,
|
||||
PCF50633_GPOCFG_GPOSEL_ACTPH4 = 0x06,
|
||||
PCF50633_GPOCFG_GPOSEL_1 = 0x07,
|
||||
PCF50633_GPOCFG_GPOSEL_INVERSE = 0x08,
|
||||
};
|
||||
|
||||
int pcf50633_gpio_set(struct pcf50633 *pcf, int gpio, u8 val);
|
||||
u8 pcf50633_gpio_get(struct pcf50633 *pcf, int gpio);
|
||||
|
||||
int pcf50633_gpio_invert_set(struct pcf50633 *, int gpio, int invert);
|
||||
int pcf50633_gpio_invert_get(struct pcf50633 *pcf, int gpio);
|
||||
|
||||
int pcf50633_gpio_power_supply_set(struct pcf50633 *,
|
||||
int gpio, int regulator, int on);
|
||||
#endif /* __LINUX_MFD_PCF50633_GPIO_H */
|
||||
|
||||
|
@ -1,130 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* mbc.h -- Driver for NXP PCF50633 Main Battery Charger
|
||||
*
|
||||
* (C) 2006-2008 by Openmoko, Inc.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_MFD_PCF50633_MBC_H
|
||||
#define __LINUX_MFD_PCF50633_MBC_H
|
||||
|
||||
#include <linux/mfd/pcf50633/core.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#define PCF50633_REG_MBCC1 0x43
|
||||
#define PCF50633_REG_MBCC2 0x44
|
||||
#define PCF50633_REG_MBCC3 0x45
|
||||
#define PCF50633_REG_MBCC4 0x46
|
||||
#define PCF50633_REG_MBCC5 0x47
|
||||
#define PCF50633_REG_MBCC6 0x48
|
||||
#define PCF50633_REG_MBCC7 0x49
|
||||
#define PCF50633_REG_MBCC8 0x4a
|
||||
#define PCF50633_REG_MBCS1 0x4b
|
||||
#define PCF50633_REG_MBCS2 0x4c
|
||||
#define PCF50633_REG_MBCS3 0x4d
|
||||
|
||||
enum pcf50633_reg_mbcc1 {
|
||||
PCF50633_MBCC1_CHGENA = 0x01, /* Charger enable */
|
||||
PCF50633_MBCC1_AUTOSTOP = 0x02,
|
||||
PCF50633_MBCC1_AUTORES = 0x04, /* automatic resume */
|
||||
PCF50633_MBCC1_RESUME = 0x08, /* explicit resume cmd */
|
||||
PCF50633_MBCC1_RESTART = 0x10, /* restart charging */
|
||||
PCF50633_MBCC1_PREWDTIME_60M = 0x20, /* max. precharging time */
|
||||
PCF50633_MBCC1_WDTIME_1H = 0x00,
|
||||
PCF50633_MBCC1_WDTIME_2H = 0x40,
|
||||
PCF50633_MBCC1_WDTIME_4H = 0x80,
|
||||
PCF50633_MBCC1_WDTIME_6H = 0xc0,
|
||||
};
|
||||
#define PCF50633_MBCC1_WDTIME_MASK 0xc0
|
||||
|
||||
enum pcf50633_reg_mbcc2 {
|
||||
PCF50633_MBCC2_VBATCOND_2V7 = 0x00,
|
||||
PCF50633_MBCC2_VBATCOND_2V85 = 0x01,
|
||||
PCF50633_MBCC2_VBATCOND_3V0 = 0x02,
|
||||
PCF50633_MBCC2_VBATCOND_3V15 = 0x03,
|
||||
PCF50633_MBCC2_VMAX_4V = 0x00,
|
||||
PCF50633_MBCC2_VMAX_4V20 = 0x28,
|
||||
PCF50633_MBCC2_VRESDEBTIME_64S = 0x80, /* debounce time (32/64sec) */
|
||||
};
|
||||
|
||||
enum pcf50633_reg_mbcc7 {
|
||||
PCF50633_MBCC7_USB_100mA = 0x00,
|
||||
PCF50633_MBCC7_USB_500mA = 0x01,
|
||||
PCF50633_MBCC7_USB_1000mA = 0x02,
|
||||
PCF50633_MBCC7_USB_SUSPEND = 0x03,
|
||||
PCF50633_MBCC7_BATTEMP_EN = 0x04,
|
||||
PCF50633_MBCC7_BATSYSIMAX_1A6 = 0x00,
|
||||
PCF50633_MBCC7_BATSYSIMAX_1A8 = 0x40,
|
||||
PCF50633_MBCC7_BATSYSIMAX_2A0 = 0x80,
|
||||
PCF50633_MBCC7_BATSYSIMAX_2A2 = 0xc0,
|
||||
};
|
||||
#define PCF50633_MBCC7_USB_MASK 0x03
|
||||
|
||||
enum pcf50633_reg_mbcc8 {
|
||||
PCF50633_MBCC8_USBENASUS = 0x10,
|
||||
};
|
||||
|
||||
enum pcf50633_reg_mbcs1 {
|
||||
PCF50633_MBCS1_USBPRES = 0x01,
|
||||
PCF50633_MBCS1_USBOK = 0x02,
|
||||
PCF50633_MBCS1_ADAPTPRES = 0x04,
|
||||
PCF50633_MBCS1_ADAPTOK = 0x08,
|
||||
PCF50633_MBCS1_TBAT_OK = 0x00,
|
||||
PCF50633_MBCS1_TBAT_ABOVE = 0x10,
|
||||
PCF50633_MBCS1_TBAT_BELOW = 0x20,
|
||||
PCF50633_MBCS1_TBAT_UNDEF = 0x30,
|
||||
PCF50633_MBCS1_PREWDTEXP = 0x40,
|
||||
PCF50633_MBCS1_WDTEXP = 0x80,
|
||||
};
|
||||
|
||||
enum pcf50633_reg_mbcs2_mbcmod {
|
||||
PCF50633_MBCS2_MBC_PLAY = 0x00,
|
||||
PCF50633_MBCS2_MBC_USB_PRE = 0x01,
|
||||
PCF50633_MBCS2_MBC_USB_PRE_WAIT = 0x02,
|
||||
PCF50633_MBCS2_MBC_USB_FAST = 0x03,
|
||||
PCF50633_MBCS2_MBC_USB_FAST_WAIT = 0x04,
|
||||
PCF50633_MBCS2_MBC_USB_SUSPEND = 0x05,
|
||||
PCF50633_MBCS2_MBC_ADP_PRE = 0x06,
|
||||
PCF50633_MBCS2_MBC_ADP_PRE_WAIT = 0x07,
|
||||
PCF50633_MBCS2_MBC_ADP_FAST = 0x08,
|
||||
PCF50633_MBCS2_MBC_ADP_FAST_WAIT = 0x09,
|
||||
PCF50633_MBCS2_MBC_BAT_FULL = 0x0a,
|
||||
PCF50633_MBCS2_MBC_HALT = 0x0b,
|
||||
};
|
||||
#define PCF50633_MBCS2_MBC_MASK 0x0f
|
||||
enum pcf50633_reg_mbcs2_chgstat {
|
||||
PCF50633_MBCS2_CHGS_NONE = 0x00,
|
||||
PCF50633_MBCS2_CHGS_ADAPTER = 0x10,
|
||||
PCF50633_MBCS2_CHGS_USB = 0x20,
|
||||
PCF50633_MBCS2_CHGS_BOTH = 0x30,
|
||||
};
|
||||
#define PCF50633_MBCS2_RESSTAT_AUTO 0x40
|
||||
|
||||
enum pcf50633_reg_mbcs3 {
|
||||
PCF50633_MBCS3_USBLIM_PLAY = 0x01,
|
||||
PCF50633_MBCS3_USBLIM_CGH = 0x02,
|
||||
PCF50633_MBCS3_TLIM_PLAY = 0x04,
|
||||
PCF50633_MBCS3_TLIM_CHG = 0x08,
|
||||
PCF50633_MBCS3_ILIM = 0x10, /* 1: Ibat > Icutoff */
|
||||
PCF50633_MBCS3_VLIM = 0x20, /* 1: Vbat == Vmax */
|
||||
PCF50633_MBCS3_VBATSTAT = 0x40, /* 1: Vbat > Vbatcond */
|
||||
PCF50633_MBCS3_VRES = 0x80, /* 1: Vbat > Vth(RES) */
|
||||
};
|
||||
|
||||
#define PCF50633_MBCC2_VBATCOND_MASK 0x03
|
||||
#define PCF50633_MBCC2_VMAX_MASK 0x3c
|
||||
|
||||
/* Charger status */
|
||||
#define PCF50633_MBC_USB_ONLINE 0x01
|
||||
#define PCF50633_MBC_USB_ACTIVE 0x02
|
||||
#define PCF50633_MBC_ADAPTER_ONLINE 0x04
|
||||
#define PCF50633_MBC_ADAPTER_ACTIVE 0x08
|
||||
|
||||
int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma);
|
||||
|
||||
int pcf50633_mbc_get_status(struct pcf50633 *);
|
||||
int pcf50633_mbc_get_usb_online_status(struct pcf50633 *);
|
||||
|
||||
#endif
|
||||
|
@ -1,68 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __LINUX_MFD_PCF50633_PMIC_H
|
||||
#define __LINUX_MFD_PCF50633_PMIC_H
|
||||
|
||||
#include <linux/mfd/pcf50633/core.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#define PCF50633_REG_AUTOOUT 0x1a
|
||||
#define PCF50633_REG_AUTOENA 0x1b
|
||||
#define PCF50633_REG_AUTOCTL 0x1c
|
||||
#define PCF50633_REG_AUTOMXC 0x1d
|
||||
#define PCF50633_REG_DOWN1OUT 0x1e
|
||||
#define PCF50633_REG_DOWN1ENA 0x1f
|
||||
#define PCF50633_REG_DOWN1CTL 0x20
|
||||
#define PCF50633_REG_DOWN1MXC 0x21
|
||||
#define PCF50633_REG_DOWN2OUT 0x22
|
||||
#define PCF50633_REG_DOWN2ENA 0x23
|
||||
#define PCF50633_REG_DOWN2CTL 0x24
|
||||
#define PCF50633_REG_DOWN2MXC 0x25
|
||||
#define PCF50633_REG_MEMLDOOUT 0x26
|
||||
#define PCF50633_REG_MEMLDOENA 0x27
|
||||
#define PCF50633_REG_LDO1OUT 0x2d
|
||||
#define PCF50633_REG_LDO1ENA 0x2e
|
||||
#define PCF50633_REG_LDO2OUT 0x2f
|
||||
#define PCF50633_REG_LDO2ENA 0x30
|
||||
#define PCF50633_REG_LDO3OUT 0x31
|
||||
#define PCF50633_REG_LDO3ENA 0x32
|
||||
#define PCF50633_REG_LDO4OUT 0x33
|
||||
#define PCF50633_REG_LDO4ENA 0x34
|
||||
#define PCF50633_REG_LDO5OUT 0x35
|
||||
#define PCF50633_REG_LDO5ENA 0x36
|
||||
#define PCF50633_REG_LDO6OUT 0x37
|
||||
#define PCF50633_REG_LDO6ENA 0x38
|
||||
#define PCF50633_REG_HCLDOOUT 0x39
|
||||
#define PCF50633_REG_HCLDOENA 0x3a
|
||||
#define PCF50633_REG_HCLDOOVL 0x40
|
||||
|
||||
enum pcf50633_regulator_enable {
|
||||
PCF50633_REGULATOR_ON = 0x01,
|
||||
PCF50633_REGULATOR_ON_GPIO1 = 0x02,
|
||||
PCF50633_REGULATOR_ON_GPIO2 = 0x04,
|
||||
PCF50633_REGULATOR_ON_GPIO3 = 0x08,
|
||||
};
|
||||
#define PCF50633_REGULATOR_ON_MASK 0x0f
|
||||
|
||||
enum pcf50633_regulator_phase {
|
||||
PCF50633_REGULATOR_ACTPH1 = 0x00,
|
||||
PCF50633_REGULATOR_ACTPH2 = 0x10,
|
||||
PCF50633_REGULATOR_ACTPH3 = 0x20,
|
||||
PCF50633_REGULATOR_ACTPH4 = 0x30,
|
||||
};
|
||||
#define PCF50633_REGULATOR_ACTPH_MASK 0x30
|
||||
|
||||
enum pcf50633_regulator_id {
|
||||
PCF50633_REGULATOR_AUTO,
|
||||
PCF50633_REGULATOR_DOWN1,
|
||||
PCF50633_REGULATOR_DOWN2,
|
||||
PCF50633_REGULATOR_LDO1,
|
||||
PCF50633_REGULATOR_LDO2,
|
||||
PCF50633_REGULATOR_LDO3,
|
||||
PCF50633_REGULATOR_LDO4,
|
||||
PCF50633_REGULATOR_LDO5,
|
||||
PCF50633_REGULATOR_LDO6,
|
||||
PCF50633_REGULATOR_HCLDO,
|
||||
PCF50633_REGULATOR_MEMLDO,
|
||||
};
|
||||
#endif
|
||||
|
@ -44,6 +44,7 @@ enum sec_device_type {
|
||||
S2MPS14X,
|
||||
S2MPS15X,
|
||||
S2MPU02,
|
||||
S2MPU05,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -150,6 +150,50 @@ enum s2mpu02_irq {
|
||||
/* Masks for interrupts are the same as in s2mps11 */
|
||||
#define S2MPS14_IRQ_TSD_MASK (1 << 2)
|
||||
|
||||
enum s2mpu05_irq {
|
||||
S2MPU05_IRQ_PWRONF,
|
||||
S2MPU05_IRQ_PWRONR,
|
||||
S2MPU05_IRQ_JIGONBF,
|
||||
S2MPU05_IRQ_JIGONBR,
|
||||
S2MPU05_IRQ_ACOKF,
|
||||
S2MPU05_IRQ_ACOKR,
|
||||
S2MPU05_IRQ_PWRON1S,
|
||||
S2MPU05_IRQ_MRB,
|
||||
|
||||
S2MPU05_IRQ_RTC60S,
|
||||
S2MPU05_IRQ_RTCA1,
|
||||
S2MPU05_IRQ_RTCA0,
|
||||
S2MPU05_IRQ_SMPL,
|
||||
S2MPU05_IRQ_RTC1S,
|
||||
S2MPU05_IRQ_WTSR,
|
||||
|
||||
S2MPU05_IRQ_INT120C,
|
||||
S2MPU05_IRQ_INT140C,
|
||||
S2MPU05_IRQ_TSD,
|
||||
|
||||
S2MPU05_IRQ_NR,
|
||||
};
|
||||
|
||||
#define S2MPU05_IRQ_PWRONF_MASK BIT(0)
|
||||
#define S2MPU05_IRQ_PWRONR_MASK BIT(1)
|
||||
#define S2MPU05_IRQ_JIGONBF_MASK BIT(2)
|
||||
#define S2MPU05_IRQ_JIGONBR_MASK BIT(3)
|
||||
#define S2MPU05_IRQ_ACOKF_MASK BIT(4)
|
||||
#define S2MPU05_IRQ_ACOKR_MASK BIT(5)
|
||||
#define S2MPU05_IRQ_PWRON1S_MASK BIT(6)
|
||||
#define S2MPU05_IRQ_MRB_MASK BIT(7)
|
||||
|
||||
#define S2MPU05_IRQ_RTC60S_MASK BIT(0)
|
||||
#define S2MPU05_IRQ_RTCA1_MASK BIT(1)
|
||||
#define S2MPU05_IRQ_RTCA0_MASK BIT(2)
|
||||
#define S2MPU05_IRQ_SMPL_MASK BIT(3)
|
||||
#define S2MPU05_IRQ_RTC1S_MASK BIT(4)
|
||||
#define S2MPU05_IRQ_WTSR_MASK BIT(5)
|
||||
|
||||
#define S2MPU05_IRQ_INT120C_MASK BIT(0)
|
||||
#define S2MPU05_IRQ_INT140C_MASK BIT(1)
|
||||
#define S2MPU05_IRQ_TSD_MASK BIT(2)
|
||||
|
||||
enum s5m8767_irq {
|
||||
S5M8767_IRQ_PWRR,
|
||||
S5M8767_IRQ_PWRF,
|
||||
|
183
include/linux/mfd/samsung/s2mpu05.h
Normal file
183
include/linux/mfd/samsung/s2mpu05.h
Normal file
@ -0,0 +1,183 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2015 Samsung Electronics Co., Ltd
|
||||
* Copyright (c) 2025 Kaustabh Chakraborty <kauschluss@disroot.org>
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_MFD_S2MPU05_H
|
||||
#define __LINUX_MFD_S2MPU05_H
|
||||
|
||||
/* S2MPU05 registers */
|
||||
enum S2MPU05_reg {
|
||||
S2MPU05_REG_ID,
|
||||
S2MPU05_REG_INT1,
|
||||
S2MPU05_REG_INT2,
|
||||
S2MPU05_REG_INT3,
|
||||
S2MPU05_REG_INT1M,
|
||||
S2MPU05_REG_INT2M,
|
||||
S2MPU05_REG_INT3M,
|
||||
S2MPU05_REG_ST1,
|
||||
S2MPU05_REG_ST2,
|
||||
S2MPU05_REG_PWRONSRC,
|
||||
S2MPU05_REG_OFFSRC,
|
||||
S2MPU05_REG_BU_CHG,
|
||||
S2MPU05_REG_RTC_BUF,
|
||||
S2MPU05_REG_CTRL1,
|
||||
S2MPU05_REG_CTRL2,
|
||||
S2MPU05_REG_ETC_TEST,
|
||||
S2MPU05_REG_OTP_ADRL,
|
||||
S2MPU05_REG_OTP_ADRH,
|
||||
S2MPU05_REG_OTP_DATA,
|
||||
S2MPU05_REG_MON1SEL,
|
||||
S2MPU05_REG_MON2SEL,
|
||||
S2MPU05_REG_CTRL3,
|
||||
S2MPU05_REG_ETC_OTP,
|
||||
S2MPU05_REG_UVLO,
|
||||
S2MPU05_REG_TIME_CTRL1,
|
||||
S2MPU05_REG_TIME_CTRL2,
|
||||
S2MPU05_REG_B1CTRL1,
|
||||
S2MPU05_REG_B1CTRL2,
|
||||
S2MPU05_REG_B2CTRL1,
|
||||
S2MPU05_REG_B2CTRL2,
|
||||
S2MPU05_REG_B2CTRL3,
|
||||
S2MPU05_REG_B2CTRL4,
|
||||
S2MPU05_REG_B3CTRL1,
|
||||
S2MPU05_REG_B3CTRL2,
|
||||
S2MPU05_REG_B3CTRL3,
|
||||
S2MPU05_REG_B4CTRL1,
|
||||
S2MPU05_REG_B4CTRL2,
|
||||
S2MPU05_REG_B5CTRL1,
|
||||
S2MPU05_REG_B5CTRL2,
|
||||
S2MPU05_REG_BUCK_RAMP,
|
||||
S2MPU05_REG_LDO_DVS1,
|
||||
S2MPU05_REG_LDO_DVS9,
|
||||
S2MPU05_REG_LDO_DVS10,
|
||||
S2MPU05_REG_L1CTRL,
|
||||
S2MPU05_REG_L2CTRL,
|
||||
S2MPU05_REG_L3CTRL,
|
||||
S2MPU05_REG_L4CTRL,
|
||||
S2MPU05_REG_L5CTRL,
|
||||
S2MPU05_REG_L6CTRL,
|
||||
S2MPU05_REG_L7CTRL,
|
||||
S2MPU05_REG_L8CTRL,
|
||||
S2MPU05_REG_L9CTRL1,
|
||||
S2MPU05_REG_L9CTRL2,
|
||||
S2MPU05_REG_L10CTRL,
|
||||
S2MPU05_REG_L11CTRL1,
|
||||
S2MPU05_REG_L11CTRL2,
|
||||
S2MPU05_REG_L12CTRL,
|
||||
S2MPU05_REG_L13CTRL,
|
||||
S2MPU05_REG_L14CTRL,
|
||||
S2MPU05_REG_L15CTRL,
|
||||
S2MPU05_REG_L16CTRL,
|
||||
S2MPU05_REG_L17CTRL1,
|
||||
S2MPU05_REG_L17CTRL2,
|
||||
S2MPU05_REG_L18CTRL1,
|
||||
S2MPU05_REG_L18CTRL2,
|
||||
S2MPU05_REG_L19CTRL,
|
||||
S2MPU05_REG_L20CTRL,
|
||||
S2MPU05_REG_L21CTRL,
|
||||
S2MPU05_REG_L22CTRL,
|
||||
S2MPU05_REG_L23CTRL,
|
||||
S2MPU05_REG_L24CTRL,
|
||||
S2MPU05_REG_L25CTRL,
|
||||
S2MPU05_REG_L26CTRL,
|
||||
S2MPU05_REG_L27CTRL,
|
||||
S2MPU05_REG_L28CTRL,
|
||||
S2MPU05_REG_L29CTRL,
|
||||
S2MPU05_REG_L30CTRL,
|
||||
S2MPU05_REG_L31CTRL,
|
||||
S2MPU05_REG_L32CTRL,
|
||||
S2MPU05_REG_L33CTRL,
|
||||
S2MPU05_REG_L34CTRL,
|
||||
S2MPU05_REG_L35CTRL,
|
||||
S2MPU05_REG_LDO_DSCH1,
|
||||
S2MPU05_REG_LDO_DSCH2,
|
||||
S2MPU05_REG_LDO_DSCH3,
|
||||
S2MPU05_REG_LDO_DSCH4,
|
||||
S2MPU05_REG_LDO_DSCH5,
|
||||
S2MPU05_REG_LDO_CTRL1,
|
||||
S2MPU05_REG_LDO_CTRL2,
|
||||
S2MPU05_REG_TCXO_CTRL,
|
||||
S2MPU05_REG_SELMIF,
|
||||
};
|
||||
|
||||
/* S2MPU05 regulator ids */
|
||||
enum S2MPU05_regulators {
|
||||
S2MPU05_LDO1,
|
||||
S2MPU05_LDO2,
|
||||
S2MPU05_LDO3,
|
||||
S2MPU05_LDO4,
|
||||
S2MPU05_LDO5,
|
||||
S2MPU05_LDO6,
|
||||
S2MPU05_LDO7,
|
||||
S2MPU05_LDO8,
|
||||
S2MPU05_LDO9,
|
||||
S2MPU05_LDO10,
|
||||
S2MPU05_LDO11,
|
||||
S2MPU05_LDO12,
|
||||
S2MPU05_LDO13,
|
||||
S2MPU05_LDO14,
|
||||
S2MPU05_LDO15,
|
||||
S2MPU05_LDO16,
|
||||
S2MPU05_LDO17,
|
||||
S2MPU05_LDO18,
|
||||
S2MPU05_LDO19,
|
||||
S2MPU05_LDO20,
|
||||
S2MPU05_LDO21,
|
||||
S2MPU05_LDO22,
|
||||
S2MPU05_LDO23,
|
||||
S2MPU05_LDO24,
|
||||
S2MPU05_LDO25,
|
||||
S2MPU05_LDO26,
|
||||
S2MPU05_LDO27,
|
||||
S2MPU05_LDO28,
|
||||
S2MPU05_LDO29,
|
||||
S2MPU05_LDO30,
|
||||
S2MPU05_LDO31,
|
||||
S2MPU05_LDO32,
|
||||
S2MPU05_LDO33,
|
||||
S2MPU05_LDO34,
|
||||
S2MPU05_LDO35,
|
||||
S2MPU05_BUCK1,
|
||||
S2MPU05_BUCK2,
|
||||
S2MPU05_BUCK3,
|
||||
S2MPU05_BUCK4,
|
||||
S2MPU05_BUCK5,
|
||||
|
||||
S2MPU05_REGULATOR_MAX,
|
||||
};
|
||||
|
||||
#define S2MPU05_SW_ENABLE_MASK 0x03
|
||||
|
||||
#define S2MPU05_ENABLE_TIME_LDO 128
|
||||
#define S2MPU05_ENABLE_TIME_BUCK1 110
|
||||
#define S2MPU05_ENABLE_TIME_BUCK2 110
|
||||
#define S2MPU05_ENABLE_TIME_BUCK3 110
|
||||
#define S2MPU05_ENABLE_TIME_BUCK4 150
|
||||
#define S2MPU05_ENABLE_TIME_BUCK5 150
|
||||
|
||||
#define S2MPU05_LDO_MIN1 800000
|
||||
#define S2MPU05_LDO_MIN2 1800000
|
||||
#define S2MPU05_LDO_MIN3 400000
|
||||
#define S2MPU05_LDO_STEP1 12500
|
||||
#define S2MPU05_LDO_STEP2 25000
|
||||
|
||||
#define S2MPU05_BUCK_MIN1 400000
|
||||
#define S2MPU05_BUCK_MIN2 600000
|
||||
#define S2MPU05_BUCK_STEP1 6250
|
||||
#define S2MPU05_BUCK_STEP2 12500
|
||||
|
||||
#define S2MPU05_RAMP_DELAY 12000 /* uV/uS */
|
||||
|
||||
#define S2MPU05_ENABLE_SHIFT 6
|
||||
#define S2MPU05_ENABLE_MASK (0x03 << S2MPU05_ENABLE_SHIFT)
|
||||
|
||||
#define S2MPU05_LDO_VSEL_MASK 0x3F
|
||||
#define S2MPU05_BUCK_VSEL_MASK 0xFF
|
||||
#define S2MPU05_LDO_N_VOLTAGES (S2MPU05_LDO_VSEL_MASK + 1)
|
||||
#define S2MPU05_BUCK_N_VOLTAGES (S2MPU05_BUCK_VSEL_MASK + 1)
|
||||
|
||||
#define S2MPU05_PMIC_EN_SHIFT 6
|
||||
|
||||
#endif /* __LINUX_MFD_S2MPU05_H */
|
@ -1,506 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2009-2011 Wind River Systems, Inc.
|
||||
* Copyright (c) 2011 ST Microelectronics (Alessandro Rubini)
|
||||
*
|
||||
* The STMicroelectronics ConneXt (STA2X11) chip has several unrelated
|
||||
* functions in one PCI endpoint functions. This driver simply
|
||||
* registers the platform devices in this iomemregion and exports a few
|
||||
* functions to access common registers
|
||||
*/
|
||||
|
||||
#ifndef __STA2X11_MFD_H
|
||||
#define __STA2X11_MFD_H
|
||||
#include <linux/types.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
enum sta2x11_mfd_plat_dev {
|
||||
sta2x11_sctl = 0,
|
||||
sta2x11_gpio,
|
||||
sta2x11_scr,
|
||||
sta2x11_time,
|
||||
sta2x11_apbreg,
|
||||
sta2x11_apb_soc_regs,
|
||||
sta2x11_vic,
|
||||
sta2x11_n_mfd_plat_devs,
|
||||
};
|
||||
|
||||
#define STA2X11_MFD_SCTL_NAME "sta2x11-sctl"
|
||||
#define STA2X11_MFD_GPIO_NAME "sta2x11-gpio"
|
||||
#define STA2X11_MFD_SCR_NAME "sta2x11-scr"
|
||||
#define STA2X11_MFD_TIME_NAME "sta2x11-time"
|
||||
#define STA2X11_MFD_APBREG_NAME "sta2x11-apbreg"
|
||||
#define STA2X11_MFD_APB_SOC_REGS_NAME "sta2x11-apb-soc-regs"
|
||||
#define STA2X11_MFD_VIC_NAME "sta2x11-vic"
|
||||
|
||||
extern u32
|
||||
__sta2x11_mfd_mask(struct pci_dev *, u32, u32, u32, enum sta2x11_mfd_plat_dev);
|
||||
|
||||
/*
|
||||
* The MFD PCI block includes the GPIO peripherals and other register blocks.
|
||||
* For GPIO, we have 32*4 bits (I use "gsta" for "gpio sta2x11".)
|
||||
*/
|
||||
#define GSTA_GPIO_PER_BLOCK 32
|
||||
#define GSTA_NR_BLOCKS 4
|
||||
#define GSTA_NR_GPIO (GSTA_GPIO_PER_BLOCK * GSTA_NR_BLOCKS)
|
||||
|
||||
/* Pinconfig is set by the board definition: altfunc, pull-up, pull-down */
|
||||
struct sta2x11_gpio_pdata {
|
||||
unsigned pinconfig[GSTA_NR_GPIO];
|
||||
};
|
||||
|
||||
/* Macros below lifted from sh_pfc.h, with minor differences */
|
||||
#define PINMUX_TYPE_NONE 0
|
||||
#define PINMUX_TYPE_FUNCTION 1
|
||||
#define PINMUX_TYPE_OUTPUT_LOW 2
|
||||
#define PINMUX_TYPE_OUTPUT_HIGH 3
|
||||
#define PINMUX_TYPE_INPUT 4
|
||||
#define PINMUX_TYPE_INPUT_PULLUP 5
|
||||
#define PINMUX_TYPE_INPUT_PULLDOWN 6
|
||||
|
||||
/* Give names to GPIO pins, like PXA does, taken from the manual */
|
||||
#define STA2X11_GPIO0 0
|
||||
#define STA2X11_GPIO1 1
|
||||
#define STA2X11_GPIO2 2
|
||||
#define STA2X11_GPIO3 3
|
||||
#define STA2X11_GPIO4 4
|
||||
#define STA2X11_GPIO5 5
|
||||
#define STA2X11_GPIO6 6
|
||||
#define STA2X11_GPIO7 7
|
||||
#define STA2X11_GPIO8_RGBOUT_RED7 8
|
||||
#define STA2X11_GPIO9_RGBOUT_RED6 9
|
||||
#define STA2X11_GPIO10_RGBOUT_RED5 10
|
||||
#define STA2X11_GPIO11_RGBOUT_RED4 11
|
||||
#define STA2X11_GPIO12_RGBOUT_RED3 12
|
||||
#define STA2X11_GPIO13_RGBOUT_RED2 13
|
||||
#define STA2X11_GPIO14_RGBOUT_RED1 14
|
||||
#define STA2X11_GPIO15_RGBOUT_RED0 15
|
||||
#define STA2X11_GPIO16_RGBOUT_GREEN7 16
|
||||
#define STA2X11_GPIO17_RGBOUT_GREEN6 17
|
||||
#define STA2X11_GPIO18_RGBOUT_GREEN5 18
|
||||
#define STA2X11_GPIO19_RGBOUT_GREEN4 19
|
||||
#define STA2X11_GPIO20_RGBOUT_GREEN3 20
|
||||
#define STA2X11_GPIO21_RGBOUT_GREEN2 21
|
||||
#define STA2X11_GPIO22_RGBOUT_GREEN1 22
|
||||
#define STA2X11_GPIO23_RGBOUT_GREEN0 23
|
||||
#define STA2X11_GPIO24_RGBOUT_BLUE7 24
|
||||
#define STA2X11_GPIO25_RGBOUT_BLUE6 25
|
||||
#define STA2X11_GPIO26_RGBOUT_BLUE5 26
|
||||
#define STA2X11_GPIO27_RGBOUT_BLUE4 27
|
||||
#define STA2X11_GPIO28_RGBOUT_BLUE3 28
|
||||
#define STA2X11_GPIO29_RGBOUT_BLUE2 29
|
||||
#define STA2X11_GPIO30_RGBOUT_BLUE1 30
|
||||
#define STA2X11_GPIO31_RGBOUT_BLUE0 31
|
||||
#define STA2X11_GPIO32_RGBOUT_VSYNCH 32
|
||||
#define STA2X11_GPIO33_RGBOUT_HSYNCH 33
|
||||
#define STA2X11_GPIO34_RGBOUT_DEN 34
|
||||
#define STA2X11_GPIO35_ETH_CRS_DV 35
|
||||
#define STA2X11_GPIO36_ETH_TXD1 36
|
||||
#define STA2X11_GPIO37_ETH_TXD0 37
|
||||
#define STA2X11_GPIO38_ETH_TX_EN 38
|
||||
#define STA2X11_GPIO39_MDIO 39
|
||||
#define STA2X11_GPIO40_ETH_REF_CLK 40
|
||||
#define STA2X11_GPIO41_ETH_RXD1 41
|
||||
#define STA2X11_GPIO42_ETH_RXD0 42
|
||||
#define STA2X11_GPIO43_MDC 43
|
||||
#define STA2X11_GPIO44_CAN_TX 44
|
||||
#define STA2X11_GPIO45_CAN_RX 45
|
||||
#define STA2X11_GPIO46_MLB_DAT 46
|
||||
#define STA2X11_GPIO47_MLB_SIG 47
|
||||
#define STA2X11_GPIO48_SPI0_CLK 48
|
||||
#define STA2X11_GPIO49_SPI0_TXD 49
|
||||
#define STA2X11_GPIO50_SPI0_RXD 50
|
||||
#define STA2X11_GPIO51_SPI0_FRM 51
|
||||
#define STA2X11_GPIO52_SPI1_CLK 52
|
||||
#define STA2X11_GPIO53_SPI1_TXD 53
|
||||
#define STA2X11_GPIO54_SPI1_RXD 54
|
||||
#define STA2X11_GPIO55_SPI1_FRM 55
|
||||
#define STA2X11_GPIO56_SPI2_CLK 56
|
||||
#define STA2X11_GPIO57_SPI2_TXD 57
|
||||
#define STA2X11_GPIO58_SPI2_RXD 58
|
||||
#define STA2X11_GPIO59_SPI2_FRM 59
|
||||
#define STA2X11_GPIO60_I2C0_SCL 60
|
||||
#define STA2X11_GPIO61_I2C0_SDA 61
|
||||
#define STA2X11_GPIO62_I2C1_SCL 62
|
||||
#define STA2X11_GPIO63_I2C1_SDA 63
|
||||
#define STA2X11_GPIO64_I2C2_SCL 64
|
||||
#define STA2X11_GPIO65_I2C2_SDA 65
|
||||
#define STA2X11_GPIO66_I2C3_SCL 66
|
||||
#define STA2X11_GPIO67_I2C3_SDA 67
|
||||
#define STA2X11_GPIO68_MSP0_RCK 68
|
||||
#define STA2X11_GPIO69_MSP0_RXD 69
|
||||
#define STA2X11_GPIO70_MSP0_RFS 70
|
||||
#define STA2X11_GPIO71_MSP0_TCK 71
|
||||
#define STA2X11_GPIO72_MSP0_TXD 72
|
||||
#define STA2X11_GPIO73_MSP0_TFS 73
|
||||
#define STA2X11_GPIO74_MSP0_SCK 74
|
||||
#define STA2X11_GPIO75_MSP1_CK 75
|
||||
#define STA2X11_GPIO76_MSP1_RXD 76
|
||||
#define STA2X11_GPIO77_MSP1_FS 77
|
||||
#define STA2X11_GPIO78_MSP1_TXD 78
|
||||
#define STA2X11_GPIO79_MSP2_CK 79
|
||||
#define STA2X11_GPIO80_MSP2_RXD 80
|
||||
#define STA2X11_GPIO81_MSP2_FS 81
|
||||
#define STA2X11_GPIO82_MSP2_TXD 82
|
||||
#define STA2X11_GPIO83_MSP3_CK 83
|
||||
#define STA2X11_GPIO84_MSP3_RXD 84
|
||||
#define STA2X11_GPIO85_MSP3_FS 85
|
||||
#define STA2X11_GPIO86_MSP3_TXD 86
|
||||
#define STA2X11_GPIO87_MSP4_CK 87
|
||||
#define STA2X11_GPIO88_MSP4_RXD 88
|
||||
#define STA2X11_GPIO89_MSP4_FS 89
|
||||
#define STA2X11_GPIO90_MSP4_TXD 90
|
||||
#define STA2X11_GPIO91_MSP5_CK 91
|
||||
#define STA2X11_GPIO92_MSP5_RXD 92
|
||||
#define STA2X11_GPIO93_MSP5_FS 93
|
||||
#define STA2X11_GPIO94_MSP5_TXD 94
|
||||
#define STA2X11_GPIO95_SDIO3_DAT3 95
|
||||
#define STA2X11_GPIO96_SDIO3_DAT2 96
|
||||
#define STA2X11_GPIO97_SDIO3_DAT1 97
|
||||
#define STA2X11_GPIO98_SDIO3_DAT0 98
|
||||
#define STA2X11_GPIO99_SDIO3_CLK 99
|
||||
#define STA2X11_GPIO100_SDIO3_CMD 100
|
||||
#define STA2X11_GPIO101 101
|
||||
#define STA2X11_GPIO102 102
|
||||
#define STA2X11_GPIO103 103
|
||||
#define STA2X11_GPIO104 104
|
||||
#define STA2X11_GPIO105_SDIO2_DAT3 105
|
||||
#define STA2X11_GPIO106_SDIO2_DAT2 106
|
||||
#define STA2X11_GPIO107_SDIO2_DAT1 107
|
||||
#define STA2X11_GPIO108_SDIO2_DAT0 108
|
||||
#define STA2X11_GPIO109_SDIO2_CLK 109
|
||||
#define STA2X11_GPIO110_SDIO2_CMD 110
|
||||
#define STA2X11_GPIO111 111
|
||||
#define STA2X11_GPIO112 112
|
||||
#define STA2X11_GPIO113 113
|
||||
#define STA2X11_GPIO114 114
|
||||
#define STA2X11_GPIO115_SDIO1_DAT3 115
|
||||
#define STA2X11_GPIO116_SDIO1_DAT2 116
|
||||
#define STA2X11_GPIO117_SDIO1_DAT1 117
|
||||
#define STA2X11_GPIO118_SDIO1_DAT0 118
|
||||
#define STA2X11_GPIO119_SDIO1_CLK 119
|
||||
#define STA2X11_GPIO120_SDIO1_CMD 120
|
||||
#define STA2X11_GPIO121 121
|
||||
#define STA2X11_GPIO122 122
|
||||
#define STA2X11_GPIO123 123
|
||||
#define STA2X11_GPIO124 124
|
||||
#define STA2X11_GPIO125_UART2_TXD 125
|
||||
#define STA2X11_GPIO126_UART2_RXD 126
|
||||
#define STA2X11_GPIO127_UART3_TXD 127
|
||||
|
||||
/*
|
||||
* The APB bridge has its own registers, needed by our users as well.
|
||||
* They are accessed with the following read/mask/write function.
|
||||
*/
|
||||
static inline u32
|
||||
sta2x11_apbreg_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val)
|
||||
{
|
||||
return __sta2x11_mfd_mask(pdev, reg, mask, val, sta2x11_apbreg);
|
||||
}
|
||||
|
||||
/* CAN and MLB */
|
||||
#define APBREG_BSR 0x00 /* Bridge Status Reg */
|
||||
#define APBREG_PAER 0x08 /* Peripherals Address Error Reg */
|
||||
#define APBREG_PWAC 0x20 /* Peripheral Write Access Control reg */
|
||||
#define APBREG_PRAC 0x40 /* Peripheral Read Access Control reg */
|
||||
#define APBREG_PCG 0x60 /* Peripheral Clock Gating Reg */
|
||||
#define APBREG_PUR 0x80 /* Peripheral Under Reset Reg */
|
||||
#define APBREG_EMU_PCG 0xA0 /* Emulator Peripheral Clock Gating Reg */
|
||||
|
||||
#define APBREG_CAN (1 << 1)
|
||||
#define APBREG_MLB (1 << 3)
|
||||
|
||||
/* SARAC */
|
||||
#define APBREG_BSR_SARAC 0x100 /* Bridge Status Reg */
|
||||
#define APBREG_PAER_SARAC 0x108 /* Peripherals Address Error Reg */
|
||||
#define APBREG_PWAC_SARAC 0x120 /* Peripheral Write Access Control reg */
|
||||
#define APBREG_PRAC_SARAC 0x140 /* Peripheral Read Access Control reg */
|
||||
#define APBREG_PCG_SARAC 0x160 /* Peripheral Clock Gating Reg */
|
||||
#define APBREG_PUR_SARAC 0x180 /* Peripheral Under Reset Reg */
|
||||
#define APBREG_EMU_PCG_SARAC 0x1A0 /* Emulator Peripheral Clock Gating Reg */
|
||||
|
||||
#define APBREG_SARAC (1 << 2)
|
||||
|
||||
/*
|
||||
* The system controller has its own registers. Some of these are accessed
|
||||
* by out users as well, using the following read/mask/write/function
|
||||
*/
|
||||
static inline
|
||||
u32 sta2x11_sctl_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val)
|
||||
{
|
||||
return __sta2x11_mfd_mask(pdev, reg, mask, val, sta2x11_sctl);
|
||||
}
|
||||
|
||||
#define SCTL_SCCTL 0x00 /* System controller control register */
|
||||
#define SCTL_ARMCFG 0x04 /* ARM configuration register */
|
||||
#define SCTL_SCPLLCTL 0x08 /* PLL control status register */
|
||||
|
||||
#define SCTL_SCPLLCTL_AUDIO_PLL_PD BIT(1)
|
||||
#define SCTL_SCPLLCTL_FRAC_CONTROL BIT(3)
|
||||
#define SCTL_SCPLLCTL_STRB_BYPASS BIT(6)
|
||||
#define SCTL_SCPLLCTL_STRB_INPUT BIT(8)
|
||||
|
||||
#define SCTL_SCPLLFCTRL 0x0c /* PLL frequency control register */
|
||||
|
||||
#define SCTL_SCPLLFCTRL_AUDIO_PLL_NDIV_MASK 0xff
|
||||
#define SCTL_SCPLLFCTRL_AUDIO_PLL_NDIV_SHIFT 10
|
||||
#define SCTL_SCPLLFCTRL_AUDIO_PLL_IDF_MASK 7
|
||||
#define SCTL_SCPLLFCTRL_AUDIO_PLL_IDF_SHIFT 21
|
||||
#define SCTL_SCPLLFCTRL_AUDIO_PLL_ODF_MASK 7
|
||||
#define SCTL_SCPLLFCTRL_AUDIO_PLL_ODF_SHIFT 18
|
||||
#define SCTL_SCPLLFCTRL_DITHER_DISABLE_MASK 0x03
|
||||
#define SCTL_SCPLLFCTRL_DITHER_DISABLE_SHIFT 4
|
||||
|
||||
|
||||
#define SCTL_SCRESFRACT 0x10 /* PLL fractional input register */
|
||||
|
||||
#define SCTL_SCRESFRACT_MASK 0x0000ffff
|
||||
|
||||
|
||||
#define SCTL_SCRESCTRL1 0x14 /* Peripheral reset control 1 */
|
||||
#define SCTL_SCRESXTRL2 0x18 /* Peripheral reset control 2 */
|
||||
#define SCTL_SCPEREN0 0x1c /* Peripheral clock enable register 0 */
|
||||
#define SCTL_SCPEREN1 0x20 /* Peripheral clock enable register 1 */
|
||||
#define SCTL_SCPEREN2 0x24 /* Peripheral clock enable register 2 */
|
||||
#define SCTL_SCGRST 0x28 /* Peripheral global reset */
|
||||
#define SCTL_SCPCIECSBRST 0x2c /* PCIe PAB CSB reset status register */
|
||||
#define SCTL_SCPCIPMCR1 0x30 /* PCI power management control 1 */
|
||||
#define SCTL_SCPCIPMCR2 0x34 /* PCI power management control 2 */
|
||||
#define SCTL_SCPCIPMSR1 0x38 /* PCI power management status 1 */
|
||||
#define SCTL_SCPCIPMSR2 0x3c /* PCI power management status 2 */
|
||||
#define SCTL_SCPCIPMSR3 0x40 /* PCI power management status 3 */
|
||||
#define SCTL_SCINTREN 0x44 /* Interrupt enable */
|
||||
#define SCTL_SCRISR 0x48 /* RAW interrupt status */
|
||||
#define SCTL_SCCLKSTAT0 0x4c /* Peripheral clocks status 0 */
|
||||
#define SCTL_SCCLKSTAT1 0x50 /* Peripheral clocks status 1 */
|
||||
#define SCTL_SCCLKSTAT2 0x54 /* Peripheral clocks status 2 */
|
||||
#define SCTL_SCRSTSTA 0x58 /* Reset status register */
|
||||
|
||||
#define SCTL_SCRESCTRL1_USB_PHY_POR (1 << 0)
|
||||
#define SCTL_SCRESCTRL1_USB_OTG (1 << 1)
|
||||
#define SCTL_SCRESCTRL1_USB_HRST (1 << 2)
|
||||
#define SCTL_SCRESCTRL1_USB_PHY_HOST (1 << 3)
|
||||
#define SCTL_SCRESCTRL1_SATAII (1 << 4)
|
||||
#define SCTL_SCRESCTRL1_VIP (1 << 5)
|
||||
#define SCTL_SCRESCTRL1_PER_MMC0 (1 << 6)
|
||||
#define SCTL_SCRESCTRL1_PER_MMC1 (1 << 7)
|
||||
#define SCTL_SCRESCTRL1_PER_GPIO0 (1 << 8)
|
||||
#define SCTL_SCRESCTRL1_PER_GPIO1 (1 << 9)
|
||||
#define SCTL_SCRESCTRL1_PER_GPIO2 (1 << 10)
|
||||
#define SCTL_SCRESCTRL1_PER_GPIO3 (1 << 11)
|
||||
#define SCTL_SCRESCTRL1_PER_MTU0 (1 << 12)
|
||||
#define SCTL_SCRESCTRL1_KER_SPI0 (1 << 13)
|
||||
#define SCTL_SCRESCTRL1_KER_SPI1 (1 << 14)
|
||||
#define SCTL_SCRESCTRL1_KER_SPI2 (1 << 15)
|
||||
#define SCTL_SCRESCTRL1_KER_MCI0 (1 << 16)
|
||||
#define SCTL_SCRESCTRL1_KER_MCI1 (1 << 17)
|
||||
#define SCTL_SCRESCTRL1_PRE_HSI2C0 (1 << 18)
|
||||
#define SCTL_SCRESCTRL1_PER_HSI2C1 (1 << 19)
|
||||
#define SCTL_SCRESCTRL1_PER_HSI2C2 (1 << 20)
|
||||
#define SCTL_SCRESCTRL1_PER_HSI2C3 (1 << 21)
|
||||
#define SCTL_SCRESCTRL1_PER_MSP0 (1 << 22)
|
||||
#define SCTL_SCRESCTRL1_PER_MSP1 (1 << 23)
|
||||
#define SCTL_SCRESCTRL1_PER_MSP2 (1 << 24)
|
||||
#define SCTL_SCRESCTRL1_PER_MSP3 (1 << 25)
|
||||
#define SCTL_SCRESCTRL1_PER_MSP4 (1 << 26)
|
||||
#define SCTL_SCRESCTRL1_PER_MSP5 (1 << 27)
|
||||
#define SCTL_SCRESCTRL1_PER_MMC (1 << 28)
|
||||
#define SCTL_SCRESCTRL1_KER_MSP0 (1 << 29)
|
||||
#define SCTL_SCRESCTRL1_KER_MSP1 (1 << 30)
|
||||
#define SCTL_SCRESCTRL1_KER_MSP2 (1 << 31)
|
||||
|
||||
#define SCTL_SCPEREN0_UART0 (1 << 0)
|
||||
#define SCTL_SCPEREN0_UART1 (1 << 1)
|
||||
#define SCTL_SCPEREN0_UART2 (1 << 2)
|
||||
#define SCTL_SCPEREN0_UART3 (1 << 3)
|
||||
#define SCTL_SCPEREN0_MSP0 (1 << 4)
|
||||
#define SCTL_SCPEREN0_MSP1 (1 << 5)
|
||||
#define SCTL_SCPEREN0_MSP2 (1 << 6)
|
||||
#define SCTL_SCPEREN0_MSP3 (1 << 7)
|
||||
#define SCTL_SCPEREN0_MSP4 (1 << 8)
|
||||
#define SCTL_SCPEREN0_MSP5 (1 << 9)
|
||||
#define SCTL_SCPEREN0_SPI0 (1 << 10)
|
||||
#define SCTL_SCPEREN0_SPI1 (1 << 11)
|
||||
#define SCTL_SCPEREN0_SPI2 (1 << 12)
|
||||
#define SCTL_SCPEREN0_I2C0 (1 << 13)
|
||||
#define SCTL_SCPEREN0_I2C1 (1 << 14)
|
||||
#define SCTL_SCPEREN0_I2C2 (1 << 15)
|
||||
#define SCTL_SCPEREN0_I2C3 (1 << 16)
|
||||
#define SCTL_SCPEREN0_SVDO_LVDS (1 << 17)
|
||||
#define SCTL_SCPEREN0_USB_HOST (1 << 18)
|
||||
#define SCTL_SCPEREN0_USB_OTG (1 << 19)
|
||||
#define SCTL_SCPEREN0_MCI0 (1 << 20)
|
||||
#define SCTL_SCPEREN0_MCI1 (1 << 21)
|
||||
#define SCTL_SCPEREN0_MCI2 (1 << 22)
|
||||
#define SCTL_SCPEREN0_MCI3 (1 << 23)
|
||||
#define SCTL_SCPEREN0_SATA (1 << 24)
|
||||
#define SCTL_SCPEREN0_ETHERNET (1 << 25)
|
||||
#define SCTL_SCPEREN0_VIC (1 << 26)
|
||||
#define SCTL_SCPEREN0_DMA_AUDIO (1 << 27)
|
||||
#define SCTL_SCPEREN0_DMA_SOC (1 << 28)
|
||||
#define SCTL_SCPEREN0_RAM (1 << 29)
|
||||
#define SCTL_SCPEREN0_VIP (1 << 30)
|
||||
#define SCTL_SCPEREN0_ARM (1 << 31)
|
||||
|
||||
#define SCTL_SCPEREN1_UART0 (1 << 0)
|
||||
#define SCTL_SCPEREN1_UART1 (1 << 1)
|
||||
#define SCTL_SCPEREN1_UART2 (1 << 2)
|
||||
#define SCTL_SCPEREN1_UART3 (1 << 3)
|
||||
#define SCTL_SCPEREN1_MSP0 (1 << 4)
|
||||
#define SCTL_SCPEREN1_MSP1 (1 << 5)
|
||||
#define SCTL_SCPEREN1_MSP2 (1 << 6)
|
||||
#define SCTL_SCPEREN1_MSP3 (1 << 7)
|
||||
#define SCTL_SCPEREN1_MSP4 (1 << 8)
|
||||
#define SCTL_SCPEREN1_MSP5 (1 << 9)
|
||||
#define SCTL_SCPEREN1_SPI0 (1 << 10)
|
||||
#define SCTL_SCPEREN1_SPI1 (1 << 11)
|
||||
#define SCTL_SCPEREN1_SPI2 (1 << 12)
|
||||
#define SCTL_SCPEREN1_I2C0 (1 << 13)
|
||||
#define SCTL_SCPEREN1_I2C1 (1 << 14)
|
||||
#define SCTL_SCPEREN1_I2C2 (1 << 15)
|
||||
#define SCTL_SCPEREN1_I2C3 (1 << 16)
|
||||
#define SCTL_SCPEREN1_USB_PHY (1 << 17)
|
||||
|
||||
/*
|
||||
* APB-SOC registers
|
||||
*/
|
||||
static inline
|
||||
u32 sta2x11_apb_soc_regs_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val)
|
||||
{
|
||||
return __sta2x11_mfd_mask(pdev, reg, mask, val, sta2x11_apb_soc_regs);
|
||||
}
|
||||
|
||||
#define PCIE_EP1_FUNC3_0_INTR_REG 0x000
|
||||
#define PCIE_EP1_FUNC7_4_INTR_REG 0x004
|
||||
#define PCIE_EP2_FUNC3_0_INTR_REG 0x008
|
||||
#define PCIE_EP2_FUNC7_4_INTR_REG 0x00c
|
||||
#define PCIE_EP3_FUNC3_0_INTR_REG 0x010
|
||||
#define PCIE_EP3_FUNC7_4_INTR_REG 0x014
|
||||
#define PCIE_EP4_FUNC3_0_INTR_REG 0x018
|
||||
#define PCIE_EP4_FUNC7_4_INTR_REG 0x01c
|
||||
#define PCIE_INTR_ENABLE0_REG 0x020
|
||||
#define PCIE_INTR_ENABLE1_REG 0x024
|
||||
#define PCIE_EP1_FUNC_TC_REG 0x028
|
||||
#define PCIE_EP2_FUNC_TC_REG 0x02c
|
||||
#define PCIE_EP3_FUNC_TC_REG 0x030
|
||||
#define PCIE_EP4_FUNC_TC_REG 0x034
|
||||
#define PCIE_EP1_FUNC_F_REG 0x038
|
||||
#define PCIE_EP2_FUNC_F_REG 0x03c
|
||||
#define PCIE_EP3_FUNC_F_REG 0x040
|
||||
#define PCIE_EP4_FUNC_F_REG 0x044
|
||||
#define PCIE_PAB_AMBA_SW_RST_REG 0x048
|
||||
#define PCIE_PM_STATUS_0_PORT_0_4 0x04c
|
||||
#define PCIE_PM_STATUS_7_0_EP1 0x050
|
||||
#define PCIE_PM_STATUS_7_0_EP2 0x054
|
||||
#define PCIE_PM_STATUS_7_0_EP3 0x058
|
||||
#define PCIE_PM_STATUS_7_0_EP4 0x05c
|
||||
#define PCIE_DEV_ID_0_EP1_REG 0x060
|
||||
#define PCIE_CC_REV_ID_0_EP1_REG 0x064
|
||||
#define PCIE_DEV_ID_1_EP1_REG 0x068
|
||||
#define PCIE_CC_REV_ID_1_EP1_REG 0x06c
|
||||
#define PCIE_DEV_ID_2_EP1_REG 0x070
|
||||
#define PCIE_CC_REV_ID_2_EP1_REG 0x074
|
||||
#define PCIE_DEV_ID_3_EP1_REG 0x078
|
||||
#define PCIE_CC_REV_ID_3_EP1_REG 0x07c
|
||||
#define PCIE_DEV_ID_4_EP1_REG 0x080
|
||||
#define PCIE_CC_REV_ID_4_EP1_REG 0x084
|
||||
#define PCIE_DEV_ID_5_EP1_REG 0x088
|
||||
#define PCIE_CC_REV_ID_5_EP1_REG 0x08c
|
||||
#define PCIE_DEV_ID_6_EP1_REG 0x090
|
||||
#define PCIE_CC_REV_ID_6_EP1_REG 0x094
|
||||
#define PCIE_DEV_ID_7_EP1_REG 0x098
|
||||
#define PCIE_CC_REV_ID_7_EP1_REG 0x09c
|
||||
#define PCIE_DEV_ID_0_EP2_REG 0x0a0
|
||||
#define PCIE_CC_REV_ID_0_EP2_REG 0x0a4
|
||||
#define PCIE_DEV_ID_1_EP2_REG 0x0a8
|
||||
#define PCIE_CC_REV_ID_1_EP2_REG 0x0ac
|
||||
#define PCIE_DEV_ID_2_EP2_REG 0x0b0
|
||||
#define PCIE_CC_REV_ID_2_EP2_REG 0x0b4
|
||||
#define PCIE_DEV_ID_3_EP2_REG 0x0b8
|
||||
#define PCIE_CC_REV_ID_3_EP2_REG 0x0bc
|
||||
#define PCIE_DEV_ID_4_EP2_REG 0x0c0
|
||||
#define PCIE_CC_REV_ID_4_EP2_REG 0x0c4
|
||||
#define PCIE_DEV_ID_5_EP2_REG 0x0c8
|
||||
#define PCIE_CC_REV_ID_5_EP2_REG 0x0cc
|
||||
#define PCIE_DEV_ID_6_EP2_REG 0x0d0
|
||||
#define PCIE_CC_REV_ID_6_EP2_REG 0x0d4
|
||||
#define PCIE_DEV_ID_7_EP2_REG 0x0d8
|
||||
#define PCIE_CC_REV_ID_7_EP2_REG 0x0dC
|
||||
#define PCIE_DEV_ID_0_EP3_REG 0x0e0
|
||||
#define PCIE_CC_REV_ID_0_EP3_REG 0x0e4
|
||||
#define PCIE_DEV_ID_1_EP3_REG 0x0e8
|
||||
#define PCIE_CC_REV_ID_1_EP3_REG 0x0ec
|
||||
#define PCIE_DEV_ID_2_EP3_REG 0x0f0
|
||||
#define PCIE_CC_REV_ID_2_EP3_REG 0x0f4
|
||||
#define PCIE_DEV_ID_3_EP3_REG 0x0f8
|
||||
#define PCIE_CC_REV_ID_3_EP3_REG 0x0fc
|
||||
#define PCIE_DEV_ID_4_EP3_REG 0x100
|
||||
#define PCIE_CC_REV_ID_4_EP3_REG 0x104
|
||||
#define PCIE_DEV_ID_5_EP3_REG 0x108
|
||||
#define PCIE_CC_REV_ID_5_EP3_REG 0x10c
|
||||
#define PCIE_DEV_ID_6_EP3_REG 0x110
|
||||
#define PCIE_CC_REV_ID_6_EP3_REG 0x114
|
||||
#define PCIE_DEV_ID_7_EP3_REG 0x118
|
||||
#define PCIE_CC_REV_ID_7_EP3_REG 0x11c
|
||||
#define PCIE_DEV_ID_0_EP4_REG 0x120
|
||||
#define PCIE_CC_REV_ID_0_EP4_REG 0x124
|
||||
#define PCIE_DEV_ID_1_EP4_REG 0x128
|
||||
#define PCIE_CC_REV_ID_1_EP4_REG 0x12c
|
||||
#define PCIE_DEV_ID_2_EP4_REG 0x130
|
||||
#define PCIE_CC_REV_ID_2_EP4_REG 0x134
|
||||
#define PCIE_DEV_ID_3_EP4_REG 0x138
|
||||
#define PCIE_CC_REV_ID_3_EP4_REG 0x13c
|
||||
#define PCIE_DEV_ID_4_EP4_REG 0x140
|
||||
#define PCIE_CC_REV_ID_4_EP4_REG 0x144
|
||||
#define PCIE_DEV_ID_5_EP4_REG 0x148
|
||||
#define PCIE_CC_REV_ID_5_EP4_REG 0x14c
|
||||
#define PCIE_DEV_ID_6_EP4_REG 0x150
|
||||
#define PCIE_CC_REV_ID_6_EP4_REG 0x154
|
||||
#define PCIE_DEV_ID_7_EP4_REG 0x158
|
||||
#define PCIE_CC_REV_ID_7_EP4_REG 0x15c
|
||||
#define PCIE_SUBSYS_VEN_ID_REG 0x160
|
||||
#define PCIE_COMMON_CLOCK_CONFIG_0_4_0 0x164
|
||||
#define PCIE_MIPHYP_SSC_EN_REG 0x168
|
||||
#define PCIE_MIPHYP_ADDR_REG 0x16c
|
||||
#define PCIE_L1_ASPM_READY_REG 0x170
|
||||
#define PCIE_EXT_CFG_RDY_REG 0x174
|
||||
#define PCIE_SoC_INT_ROUTER_STATUS0_REG 0x178
|
||||
#define PCIE_SoC_INT_ROUTER_STATUS1_REG 0x17c
|
||||
#define PCIE_SoC_INT_ROUTER_STATUS2_REG 0x180
|
||||
#define PCIE_SoC_INT_ROUTER_STATUS3_REG 0x184
|
||||
#define DMA_IP_CTRL_REG 0x324
|
||||
#define DISP_BRIDGE_PU_PD_CTRL_REG 0x328
|
||||
#define VIP_PU_PD_CTRL_REG 0x32c
|
||||
#define USB_MLB_PU_PD_CTRL_REG 0x330
|
||||
#define SDIO_PU_PD_MISCFUNC_CTRL_REG1 0x334
|
||||
#define SDIO_PU_PD_MISCFUNC_CTRL_REG2 0x338
|
||||
#define UART_PU_PD_CTRL_REG 0x33c
|
||||
#define ARM_Lock 0x340
|
||||
#define SYS_IO_CHAR_REG1 0x344
|
||||
#define SYS_IO_CHAR_REG2 0x348
|
||||
#define SATA_CORE_ID_REG 0x34c
|
||||
#define SATA_CTRL_REG 0x350
|
||||
#define I2C_HSFIX_MISC_REG 0x354
|
||||
#define SPARE2_RESERVED 0x358
|
||||
#define SPARE3_RESERVED 0x35c
|
||||
#define MASTER_LOCK_REG 0x368
|
||||
#define SYSTEM_CONFIG_STATUS_REG 0x36c
|
||||
#define MSP_CLK_CTRL_REG 0x39c
|
||||
#define COMPENSATION_REG1 0x3c4
|
||||
#define COMPENSATION_REG2 0x3c8
|
||||
#define COMPENSATION_REG3 0x3cc
|
||||
#define TEST_CTL_REG 0x3d0
|
||||
|
||||
/*
|
||||
* SECR (OTP) registers
|
||||
*/
|
||||
#define STA2X11_SECR_CR 0x00
|
||||
#define STA2X11_SECR_FVR0 0x10
|
||||
#define STA2X11_SECR_FVR1 0x14
|
||||
|
||||
extern int sta2x11_mfd_get_regs_data(struct platform_device *pdev,
|
||||
enum sta2x11_mfd_plat_dev index,
|
||||
void __iomem **regs,
|
||||
spinlock_t **lock);
|
||||
|
||||
#endif /* __STA2X11_MFD_H */
|
@ -33,6 +33,9 @@
|
||||
#define TIM_DCR 0x48 /* DMA control register */
|
||||
#define TIM_DMAR 0x4C /* DMA register for transfer */
|
||||
#define TIM_TISEL 0x68 /* Input Selection */
|
||||
#define TIM_HWCFGR2 0x3EC /* hardware configuration 2 Reg (MP25) */
|
||||
#define TIM_HWCFGR1 0x3F0 /* hardware configuration 1 Reg (MP25) */
|
||||
#define TIM_IPIDR 0x3F8 /* IP identification Reg (MP25) */
|
||||
|
||||
#define TIM_CR1_CEN BIT(0) /* Counter Enable */
|
||||
#define TIM_CR1_DIR BIT(4) /* Counter Direction */
|
||||
@ -100,6 +103,9 @@
|
||||
#define TIM_BDTR_BKF(x) (0xf << (16 + (x) * 4))
|
||||
#define TIM_DCR_DBA GENMASK(4, 0) /* DMA base addr */
|
||||
#define TIM_DCR_DBL GENMASK(12, 8) /* DMA burst len */
|
||||
#define TIM_HWCFGR1_NB_OF_CC GENMASK(3, 0) /* Capture/compare channels */
|
||||
#define TIM_HWCFGR1_NB_OF_DT GENMASK(7, 4) /* Complementary outputs & dead-time generators */
|
||||
#define TIM_HWCFGR2_CNT_WIDTH GENMASK(15, 8) /* Counter width */
|
||||
|
||||
#define MAX_TIM_PSC 0xFFFF
|
||||
#define MAX_TIM_ICPSC 0x3
|
||||
@ -113,6 +119,8 @@
|
||||
#define TIM_BDTR_BKF_MASK 0xF
|
||||
#define TIM_BDTR_BKF_SHIFT(x) (16 + (x) * 4)
|
||||
|
||||
#define STM32MP25_TIM_IPIDR 0x00120002
|
||||
|
||||
enum stm32_timers_dmas {
|
||||
STM32_TIMERS_DMA_CH1,
|
||||
STM32_TIMERS_DMA_CH2,
|
||||
@ -151,6 +159,7 @@ struct stm32_timers_dma {
|
||||
|
||||
struct stm32_timers {
|
||||
struct clk *clk;
|
||||
u32 ipidr;
|
||||
struct regmap *regmap;
|
||||
u32 max_arr;
|
||||
struct stm32_timers_dma dma; /* Only to be used by the parent */
|
||||
|
@ -1,8 +1,9 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Functions to access TPS65219 Power Management IC.
|
||||
* Functions to access TPS65215/TPS65219 Power Management Integrated Chips
|
||||
*
|
||||
* Copyright (C) 2022 BayLibre Incorporated - https://www.baylibre.com/
|
||||
* Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
|
||||
*/
|
||||
|
||||
#ifndef MFD_TPS65219_H
|
||||
@ -13,8 +14,12 @@
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
|
||||
/* TPS chip id list */
|
||||
#define TPS65219 0xF0
|
||||
/* Chip id list*/
|
||||
enum pmic_id {
|
||||
TPS65214,
|
||||
TPS65215,
|
||||
TPS65219,
|
||||
};
|
||||
|
||||
/* I2C ID for TPS65219 part */
|
||||
#define TPS65219_I2C_ID 0x24
|
||||
@ -24,15 +29,23 @@
|
||||
#define TPS65219_REG_NVM_ID 0x01
|
||||
#define TPS65219_REG_ENABLE_CTRL 0x02
|
||||
#define TPS65219_REG_BUCKS_CONFIG 0x03
|
||||
#define TPS65214_REG_LOCK 0x03
|
||||
#define TPS65219_REG_LDO4_VOUT 0x04
|
||||
#define TPS65214_REG_LDO1_VOUT_STBY 0x04
|
||||
#define TPS65219_REG_LDO3_VOUT 0x05
|
||||
#define TPS65215_REG_LDO2_VOUT 0x05
|
||||
#define TPS65214_REG_LDO1_VOUT 0x05
|
||||
#define TPS65219_REG_LDO2_VOUT 0x06
|
||||
#define TPS65214_REG_LDO2_VOUT 0x06
|
||||
#define TPS65219_REG_LDO1_VOUT 0x07
|
||||
#define TPS65214_REG_LDO2_VOUT_STBY 0x07
|
||||
#define TPS65219_REG_BUCK3_VOUT 0x8
|
||||
#define TPS65219_REG_BUCK2_VOUT 0x9
|
||||
#define TPS65219_REG_BUCK1_VOUT 0xA
|
||||
#define TPS65219_REG_LDO4_SEQUENCE_SLOT 0xB
|
||||
#define TPS65219_REG_LDO3_SEQUENCE_SLOT 0xC
|
||||
#define TPS65215_REG_LDO2_SEQUENCE_SLOT 0xC
|
||||
#define TPS65214_REG_LDO1_SEQUENCE_SLOT 0xC
|
||||
#define TPS65219_REG_LDO2_SEQUENCE_SLOT 0xD
|
||||
#define TPS65219_REG_LDO1_SEQUENCE_SLOT 0xE
|
||||
#define TPS65219_REG_BUCK3_SEQUENCE_SLOT 0xF
|
||||
@ -41,15 +54,21 @@
|
||||
#define TPS65219_REG_nRST_SEQUENCE_SLOT 0x12
|
||||
#define TPS65219_REG_GPIO_SEQUENCE_SLOT 0x13
|
||||
#define TPS65219_REG_GPO2_SEQUENCE_SLOT 0x14
|
||||
#define TPS65214_REG_GPIO_GPI_SEQUENCE_SLOT 0x14
|
||||
#define TPS65219_REG_GPO1_SEQUENCE_SLOT 0x15
|
||||
#define TPS65214_REG_GPO_SEQUENCE_SLOT 0x15
|
||||
#define TPS65219_REG_POWER_UP_SLOT_DURATION_1 0x16
|
||||
#define TPS65219_REG_POWER_UP_SLOT_DURATION_2 0x17
|
||||
/* _SLOT_DURATION_3 doesn't apply to TPS65215*/
|
||||
#define TPS65219_REG_POWER_UP_SLOT_DURATION_3 0x18
|
||||
#define TPS65219_REG_POWER_UP_SLOT_DURATION_4 0x19
|
||||
#define TPS65214_REG_BUCK3_VOUT_STBY 0x19
|
||||
#define TPS65219_REG_POWER_DOWN_SLOT_DURATION_1 0x1A
|
||||
#define TPS65219_REG_POWER_DOWN_SLOT_DURATION_2 0x1B
|
||||
#define TPS65219_REG_POWER_DOWN_SLOT_DURATION_3 0x1C
|
||||
#define TPS65214_REG_BUCK2_VOUT_STBY 0x1C
|
||||
#define TPS65219_REG_POWER_DOWN_SLOT_DURATION_4 0x1D
|
||||
#define TPS65214_REG_BUCK1_VOUT_STBY 0x1D
|
||||
#define TPS65219_REG_GENERAL_CONFIG 0x1E
|
||||
#define TPS65219_REG_MFP_1_CONFIG 0x1F
|
||||
#define TPS65219_REG_MFP_2_CONFIG 0x20
|
||||
@ -67,9 +86,19 @@
|
||||
#define TPS65219_REG_DISCHARGE_CONFIG 0x2A
|
||||
/* main irq registers */
|
||||
#define TPS65219_REG_INT_SOURCE 0x2B
|
||||
/* 'sub irq' registers */
|
||||
|
||||
/* TPS65219 'sub irq' registers */
|
||||
#define TPS65219_REG_INT_LDO_3_4 0x2C
|
||||
#define TPS65219_REG_INT_LDO_1_2 0x2D
|
||||
|
||||
/* TPS65215 specific 'sub irq' registers */
|
||||
#define TPS65215_REG_INT_LDO_2 0x2C
|
||||
#define TPS65215_REG_INT_LDO_1 0x2D
|
||||
|
||||
/* TPS65214 specific 'sub irq' register */
|
||||
#define TPS65214_REG_INT_LDO_1_2 0x2D
|
||||
|
||||
/* Common TPS65215 & TPS65219 'sub irq' registers */
|
||||
#define TPS65219_REG_INT_BUCK_3 0x2E
|
||||
#define TPS65219_REG_INT_BUCK_1_2 0x2F
|
||||
#define TPS65219_REG_INT_SYSTEM 0x30
|
||||
@ -86,6 +115,17 @@
|
||||
#define TPS65219_REG_INT_TO_RV_POS 6
|
||||
#define TPS65219_REG_INT_PB_POS 7
|
||||
|
||||
#define TPS65215_REG_INT_LDO_2_POS 0
|
||||
#define TPS65215_REG_INT_LDO_1_POS 1
|
||||
|
||||
#define TPS65214_REG_INT_LDO_1_2_POS 0
|
||||
#define TPS65214_REG_INT_BUCK_3_POS 1
|
||||
#define TPS65214_REG_INT_BUCK_1_2_POS 2
|
||||
#define TPS65214_REG_INT_SYS_POS 3
|
||||
#define TPS65214_REG_INT_RV_POS 4
|
||||
#define TPS65214_REG_INT_TO_RV_POS 5
|
||||
#define TPS65214_REG_INT_PB_POS 6
|
||||
|
||||
#define TPS65219_REG_USER_NVM_CMD 0x34
|
||||
#define TPS65219_REG_POWER_UP_STATUS 0x35
|
||||
#define TPS65219_REG_SPARE_2 0x36
|
||||
@ -107,6 +147,8 @@
|
||||
#define TPS65219_ENABLE_LDO1_EN_MASK BIT(3)
|
||||
#define TPS65219_ENABLE_LDO2_EN_MASK BIT(4)
|
||||
#define TPS65219_ENABLE_LDO3_EN_MASK BIT(5)
|
||||
#define TPS65215_ENABLE_LDO2_EN_MASK BIT(5)
|
||||
#define TPS65214_ENABLE_LDO1_EN_MASK BIT(5)
|
||||
#define TPS65219_ENABLE_LDO4_EN_MASK BIT(6)
|
||||
/* power ON-OFF sequence slot */
|
||||
#define TPS65219_BUCKS_LDOS_SEQUENCE_OFF_SLOT_MASK GENMASK(3, 0)
|
||||
@ -158,20 +200,27 @@
|
||||
#define TPS65219_REG_MASK_EFFECT_MASK GENMASK(2, 1)
|
||||
#define TPS65219_REG_MASK_INT_FOR_PB_MASK BIT(7)
|
||||
/* UnderVoltage - Short to GND - OverCurrent*/
|
||||
/* LDO3-4 */
|
||||
/* LDO3-4: only for TPS65219*/
|
||||
#define TPS65219_INT_LDO3_SCG_MASK BIT(0)
|
||||
#define TPS65219_INT_LDO3_OC_MASK BIT(1)
|
||||
#define TPS65219_INT_LDO3_UV_MASK BIT(2)
|
||||
#define TPS65219_INT_LDO4_SCG_MASK BIT(3)
|
||||
#define TPS65219_INT_LDO4_OC_MASK BIT(4)
|
||||
#define TPS65219_INT_LDO4_UV_MASK BIT(5)
|
||||
/* LDO1-2 */
|
||||
/* LDO1-2: TPS65214 & TPS65219 */
|
||||
#define TPS65219_INT_LDO1_SCG_MASK BIT(0)
|
||||
#define TPS65219_INT_LDO1_OC_MASK BIT(1)
|
||||
#define TPS65219_INT_LDO1_UV_MASK BIT(2)
|
||||
#define TPS65219_INT_LDO2_SCG_MASK BIT(3)
|
||||
#define TPS65219_INT_LDO2_OC_MASK BIT(4)
|
||||
#define TPS65219_INT_LDO2_UV_MASK BIT(5)
|
||||
/* TPS65215 LDO1-2*/
|
||||
#define TPS65215_INT_LDO1_SCG_MASK BIT(0)
|
||||
#define TPS65215_INT_LDO1_OC_MASK BIT(1)
|
||||
#define TPS65215_INT_LDO1_UV_MASK BIT(2)
|
||||
#define TPS65215_INT_LDO2_SCG_MASK BIT(0)
|
||||
#define TPS65215_INT_LDO2_OC_MASK BIT(1)
|
||||
#define TPS65215_INT_LDO2_UV_MASK BIT(2)
|
||||
/* BUCK3 */
|
||||
#define TPS65219_INT_BUCK3_SCG_MASK BIT(0)
|
||||
#define TPS65219_INT_BUCK3_OC_MASK BIT(1)
|
||||
@ -186,12 +235,13 @@
|
||||
#define TPS65219_INT_BUCK2_OC_MASK BIT(5)
|
||||
#define TPS65219_INT_BUCK2_NEG_OC_MASK BIT(6)
|
||||
#define TPS65219_INT_BUCK2_UV_MASK BIT(7)
|
||||
/* Thermal Sensor */
|
||||
/* Thermal Sensor: TPS65219/TPS65215 */
|
||||
#define TPS65219_INT_SENSOR_3_WARM_MASK BIT(0)
|
||||
#define TPS65219_INT_SENSOR_3_HOT_MASK BIT(4)
|
||||
/* Thermal Sensor: TPS65219/TPS65215/TPS65214 */
|
||||
#define TPS65219_INT_SENSOR_2_WARM_MASK BIT(1)
|
||||
#define TPS65219_INT_SENSOR_1_WARM_MASK BIT(2)
|
||||
#define TPS65219_INT_SENSOR_0_WARM_MASK BIT(3)
|
||||
#define TPS65219_INT_SENSOR_3_HOT_MASK BIT(4)
|
||||
#define TPS65219_INT_SENSOR_2_HOT_MASK BIT(5)
|
||||
#define TPS65219_INT_SENSOR_1_HOT_MASK BIT(6)
|
||||
#define TPS65219_INT_SENSOR_0_HOT_MASK BIT(7)
|
||||
@ -202,6 +252,8 @@
|
||||
#define TPS65219_INT_LDO1_RV_MASK BIT(3)
|
||||
#define TPS65219_INT_LDO2_RV_MASK BIT(4)
|
||||
#define TPS65219_INT_LDO3_RV_MASK BIT(5)
|
||||
#define TPS65215_INT_LDO2_RV_MASK BIT(5)
|
||||
#define TPS65214_INT_LDO2_RV_MASK BIT(5)
|
||||
#define TPS65219_INT_LDO4_RV_MASK BIT(6)
|
||||
/* Residual Voltage ShutDown */
|
||||
#define TPS65219_INT_BUCK1_RV_SD_MASK BIT(0)
|
||||
@ -210,6 +262,8 @@
|
||||
#define TPS65219_INT_LDO1_RV_SD_MASK BIT(3)
|
||||
#define TPS65219_INT_LDO2_RV_SD_MASK BIT(4)
|
||||
#define TPS65219_INT_LDO3_RV_SD_MASK BIT(5)
|
||||
#define TPS65215_INT_LDO2_RV_SD_MASK BIT(5)
|
||||
#define TPS65214_INT_LDO1_RV_SD_MASK BIT(5)
|
||||
#define TPS65219_INT_LDO4_RV_SD_MASK BIT(6)
|
||||
#define TPS65219_INT_TIMEOUT_MASK BIT(7)
|
||||
/* Power Button */
|
||||
@ -235,7 +289,15 @@ enum {
|
||||
TPS65219_INT_LDO4_SCG,
|
||||
TPS65219_INT_LDO4_OC,
|
||||
TPS65219_INT_LDO4_UV,
|
||||
/* LDO1-2 */
|
||||
/* TPS65215 LDO1*/
|
||||
TPS65215_INT_LDO1_SCG,
|
||||
TPS65215_INT_LDO1_OC,
|
||||
TPS65215_INT_LDO1_UV,
|
||||
/* TPS65215 LDO2*/
|
||||
TPS65215_INT_LDO2_SCG,
|
||||
TPS65215_INT_LDO2_OC,
|
||||
TPS65215_INT_LDO2_UV,
|
||||
/* LDO1-2: TPS65219/TPS65214 */
|
||||
TPS65219_INT_LDO1_SCG,
|
||||
TPS65219_INT_LDO1_OC,
|
||||
TPS65219_INT_LDO1_UV,
|
||||
@ -271,6 +333,8 @@ enum {
|
||||
TPS65219_INT_BUCK3_RV,
|
||||
TPS65219_INT_LDO1_RV,
|
||||
TPS65219_INT_LDO2_RV,
|
||||
TPS65215_INT_LDO2_RV,
|
||||
TPS65214_INT_LDO2_RV,
|
||||
TPS65219_INT_LDO3_RV,
|
||||
TPS65219_INT_LDO4_RV,
|
||||
/* Residual Voltage ShutDown */
|
||||
@ -278,6 +342,8 @@ enum {
|
||||
TPS65219_INT_BUCK2_RV_SD,
|
||||
TPS65219_INT_BUCK3_RV_SD,
|
||||
TPS65219_INT_LDO1_RV_SD,
|
||||
TPS65214_INT_LDO1_RV_SD,
|
||||
TPS65215_INT_LDO2_RV_SD,
|
||||
TPS65219_INT_LDO2_RV_SD,
|
||||
TPS65219_INT_LDO3_RV_SD,
|
||||
TPS65219_INT_LDO4_RV_SD,
|
||||
@ -287,6 +353,23 @@ enum {
|
||||
TPS65219_INT_PB_RISING_EDGE_DETECT,
|
||||
};
|
||||
|
||||
enum tps65214_regulator_id {
|
||||
/*
|
||||
* DCDC's same as TPS65219
|
||||
* LDO1 maps to TPS65219's LDO3
|
||||
* LDO2 is the same as TPS65219
|
||||
*
|
||||
*/
|
||||
TPS65214_LDO_1 = 3,
|
||||
TPS65214_LDO_2 = 4,
|
||||
};
|
||||
|
||||
enum tps65215_regulator_id {
|
||||
/* DCDC's same as TPS65219 */
|
||||
/* LDO1 is the same as TPS65219 */
|
||||
TPS65215_LDO_2 = 4,
|
||||
};
|
||||
|
||||
enum tps65219_regulator_id {
|
||||
/* DCDC's */
|
||||
TPS65219_BUCK_1,
|
||||
@ -300,11 +383,40 @@ enum tps65219_regulator_id {
|
||||
};
|
||||
|
||||
/* Number of step-down converters available */
|
||||
#define TPS65219_NUM_DCDC 3
|
||||
#define TPS6521X_NUM_BUCKS 3
|
||||
/* Number of LDO voltage regulators available */
|
||||
#define TPS65219_NUM_LDO 4
|
||||
#define TPS65215_NUM_LDO 2
|
||||
#define TPS65214_NUM_LDO 2
|
||||
/* Number of total regulators available */
|
||||
#define TPS65219_NUM_REGULATOR (TPS65219_NUM_DCDC + TPS65219_NUM_LDO)
|
||||
#define TPS65219_NUM_REGULATOR (TPS6521X_NUM_BUCKS + TPS65219_NUM_LDO)
|
||||
#define TPS65215_NUM_REGULATOR (TPS6521X_NUM_BUCKS + TPS65215_NUM_LDO)
|
||||
#define TPS65214_NUM_REGULATOR (TPS6521X_NUM_BUCKS + TPS65214_NUM_LDO)
|
||||
|
||||
/* Define the TPS65214 IRQ numbers */
|
||||
enum tps65214_irqs {
|
||||
/* INT source registers */
|
||||
TPS65214_TO_RV_SD_SET_IRQ,
|
||||
TPS65214_RV_SET_IRQ,
|
||||
TPS65214_SYS_SET_IRQ,
|
||||
TPS65214_BUCK_1_2_SET_IRQ,
|
||||
TPS65214_BUCK_3_SET_IRQ,
|
||||
TPS65214_LDO_1_2_SET_IRQ,
|
||||
TPS65214_PB_SET_IRQ = 7,
|
||||
};
|
||||
|
||||
/* Define the TPS65215 IRQ numbers */
|
||||
enum tps65215_irqs {
|
||||
/* INT source registers */
|
||||
TPS65215_TO_RV_SD_SET_IRQ,
|
||||
TPS65215_RV_SET_IRQ,
|
||||
TPS65215_SYS_SET_IRQ,
|
||||
TPS65215_BUCK_1_2_SET_IRQ,
|
||||
TPS65215_BUCK_3_SET_IRQ,
|
||||
TPS65215_LDO_1_SET_IRQ,
|
||||
TPS65215_LDO_2_SET_IRQ,
|
||||
TPS65215_PB_SET_IRQ,
|
||||
};
|
||||
|
||||
/* Define the TPS65219 IRQ numbers */
|
||||
enum tps65219_irqs {
|
||||
@ -326,6 +438,7 @@ enum tps65219_irqs {
|
||||
*
|
||||
* @dev: MFD device
|
||||
* @regmap: Regmap for accessing the device registers
|
||||
* @chip_id: Chip ID
|
||||
* @irq_data: Regmap irq data used for the irq chip
|
||||
* @nb: notifier block for the restart handler
|
||||
*/
|
||||
@ -333,6 +446,7 @@ struct tps65219 {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
|
||||
unsigned int chip_id;
|
||||
struct regmap_irq_chip_data *irq_data;
|
||||
struct notifier_block nb;
|
||||
};
|
||||
|
195
include/linux/power/max77705_charger.h
Normal file
195
include/linux/power/max77705_charger.h
Normal file
@ -0,0 +1,195 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Maxim MAX77705 definitions.
|
||||
*
|
||||
* Copyright (C) 2015 Samsung Electronics, Inc.
|
||||
* Copyright (C) 2025 Dzmitry Sankouski <dsankouski@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __MAX77705_CHARGER_H
|
||||
#define __MAX77705_CHARGER_H __FILE__
|
||||
|
||||
/* MAX77705_CHG_REG_CHG_INT */
|
||||
#define MAX77705_BYP_I BIT(0)
|
||||
#define MAX77705_INP_LIMIT_I BIT(1)
|
||||
#define MAX77705_BATP_I BIT(2)
|
||||
#define MAX77705_BAT_I BIT(3)
|
||||
#define MAX77705_CHG_I BIT(4)
|
||||
#define MAX77705_WCIN_I BIT(5)
|
||||
#define MAX77705_CHGIN_I BIT(6)
|
||||
#define MAX77705_AICL_I BIT(7)
|
||||
|
||||
/* MAX77705_CHG_REG_CHG_INT_MASK */
|
||||
#define MAX77705_BYP_IM BIT(0)
|
||||
#define MAX77705_INP_LIMIT_IM BIT(1)
|
||||
#define MAX77705_BATP_IM BIT(2)
|
||||
#define MAX77705_BAT_IM BIT(3)
|
||||
#define MAX77705_CHG_IM BIT(4)
|
||||
#define MAX77705_WCIN_IM BIT(5)
|
||||
#define MAX77705_CHGIN_IM BIT(6)
|
||||
#define MAX77705_AICL_IM BIT(7)
|
||||
|
||||
/* MAX77705_CHG_REG_CHG_INT_OK */
|
||||
#define MAX77705_BYP_OK BIT(0)
|
||||
#define MAX77705_DISQBAT_OK BIT(1)
|
||||
#define MAX77705_BATP_OK BIT(2)
|
||||
#define MAX77705_BAT_OK BIT(3)
|
||||
#define MAX77705_CHG_OK BIT(4)
|
||||
#define MAX77705_WCIN_OK BIT(5)
|
||||
#define MAX77705_CHGIN_OK BIT(6)
|
||||
#define MAX77705_AICL_OK BIT(7)
|
||||
|
||||
/* MAX77705_CHG_REG_DETAILS_00 */
|
||||
#define MAX77705_BATP_DTLS BIT(0)
|
||||
#define MAX77705_WCIN_DTLS GENMASK(4, 3)
|
||||
#define MAX77705_WCIN_DTLS_SHIFT 3
|
||||
#define MAX77705_CHGIN_DTLS GENMASK(6, 5)
|
||||
#define MAX77705_CHGIN_DTLS_SHIFT 5
|
||||
|
||||
/* MAX77705_CHG_REG_DETAILS_01 */
|
||||
#define MAX77705_CHG_DTLS GENMASK(3, 0)
|
||||
#define MAX77705_CHG_DTLS_SHIFT 0
|
||||
#define MAX77705_BAT_DTLS GENMASK(6, 4)
|
||||
#define MAX77705_BAT_DTLS_SHIFT 4
|
||||
|
||||
/* MAX77705_CHG_REG_DETAILS_02 */
|
||||
#define MAX77705_BYP_DTLS GENMASK(3, 0)
|
||||
#define MAX77705_BYP_DTLS_SHIFT 0
|
||||
|
||||
/* MAX77705_CHG_REG_CNFG_00 */
|
||||
#define MAX77705_CHG_SHIFT 0
|
||||
#define MAX77705_UNO_SHIFT 1
|
||||
#define MAX77705_OTG_SHIFT 1
|
||||
#define MAX77705_BUCK_SHIFT 2
|
||||
#define MAX77705_BOOST_SHIFT 3
|
||||
#define MAX77705_WDTEN_SHIFT 4
|
||||
#define MAX77705_MODE_MASK GENMASK(3, 0)
|
||||
#define MAX77705_CHG_MASK BIT(MAX77705_CHG_SHIFT)
|
||||
#define MAX77705_UNO_MASK BIT(MAX77705_UNO_SHIFT)
|
||||
#define MAX77705_OTG_MASK BIT(MAX77705_OTG_SHIFT)
|
||||
#define MAX77705_BUCK_MASK BIT(MAX77705_BUCK_SHIFT)
|
||||
#define MAX77705_BOOST_MASK BIT(MAX77705_BOOST_SHIFT)
|
||||
#define MAX77705_WDTEN_MASK BIT(MAX77705_WDTEN_SHIFT)
|
||||
#define MAX77705_UNO_CTRL (MAX77705_UNO_MASK | MAX77705_BOOST_MASK)
|
||||
#define MAX77705_OTG_CTRL (MAX77705_OTG_MASK | MAX77705_BOOST_MASK)
|
||||
|
||||
/* MAX77705_CHG_REG_CNFG_01 */
|
||||
#define MAX77705_FCHGTIME_SHIFT 0
|
||||
#define MAX77705_FCHGTIME_MASK GENMASK(2, 0)
|
||||
#define MAX77705_CHG_RSTRT_SHIFT 4
|
||||
#define MAX77705_CHG_RSTRT_MASK GENMASK(5, 4)
|
||||
#define MAX77705_FCHGTIME_DISABLE 0
|
||||
#define MAX77705_CHG_RSTRT_DISABLE 0x3
|
||||
|
||||
#define MAX77705_PQEN_SHIFT 7
|
||||
#define MAX77705_PQEN_MASK BIT(7)
|
||||
#define MAX77705_CHG_PQEN_DISABLE 0
|
||||
#define MAX77705_CHG_PQEN_ENABLE 1
|
||||
|
||||
/* MAX77705_CHG_REG_CNFG_02 */
|
||||
#define MAX77705_OTG_ILIM_SHIFT 6
|
||||
#define MAX77705_OTG_ILIM_MASK GENMASK(7, 6)
|
||||
#define MAX77705_OTG_ILIM_500 0
|
||||
#define MAX77705_OTG_ILIM_900 1
|
||||
#define MAX77705_OTG_ILIM_1200 2
|
||||
#define MAX77705_OTG_ILIM_1500 3
|
||||
#define MAX77705_CHG_CC GENMASK(5, 0)
|
||||
|
||||
/* MAX77705_CHG_REG_CNFG_03 */
|
||||
#define MAX77705_TO_ITH_SHIFT 0
|
||||
#define MAX77705_TO_ITH_MASK GENMASK(2, 0)
|
||||
#define MAX77705_TO_TIME_SHIFT 3
|
||||
#define MAX77705_TO_TIME_MASK GENMASK(5, 3)
|
||||
#define MAX77705_SYS_TRACK_DIS_SHIFT 7
|
||||
#define MAX77705_SYS_TRACK_DIS_MASK BIT(7)
|
||||
#define MAX77705_TO_ITH_150MA 0
|
||||
#define MAX77705_TO_TIME_30M 3
|
||||
#define MAX77705_SYS_TRACK_ENABLE 0
|
||||
#define MAX77705_SYS_TRACK_DISABLE 1
|
||||
|
||||
/* MAX77705_CHG_REG_CNFG_04 */
|
||||
#define MAX77705_CHG_MINVSYS_SHIFT 6
|
||||
#define MAX77705_CHG_MINVSYS_MASK GENMASK(7, 6)
|
||||
#define MAX77705_CHG_PRM_SHIFT 0
|
||||
#define MAX77705_CHG_PRM_MASK GENMASK(5, 0)
|
||||
|
||||
#define MAX77705_CHG_CV_PRM_SHIFT 0
|
||||
#define MAX77705_CHG_CV_PRM_MASK GENMASK(5, 0)
|
||||
|
||||
/* MAX77705_CHG_REG_CNFG_05 */
|
||||
#define MAX77705_REG_B2SOVRC_SHIFT 0
|
||||
#define MAX77705_REG_B2SOVRC_MASK GENMASK(3, 0)
|
||||
#define MAX77705_B2SOVRC_DISABLE 0
|
||||
#define MAX77705_B2SOVRC_4_5A 6
|
||||
#define MAX77705_B2SOVRC_4_8A 8
|
||||
#define MAX77705_B2SOVRC_5_0A 9
|
||||
|
||||
/* MAX77705_CHG_CNFG_06 */
|
||||
#define MAX77705_WDTCLR_SHIFT 0
|
||||
#define MAX77705_WDTCLR_MASK GENMASK(1, 0)
|
||||
#define MAX77705_WDTCLR 1
|
||||
#define MAX77705_CHGPROT_MASK GENMASK(3, 2)
|
||||
#define MAX77705_CHGPROT_UNLOCKED GENMASK(3, 2)
|
||||
#define MAX77705_SLOWEST_LX_SLOPE GENMASK(6, 5)
|
||||
|
||||
/* MAX77705_CHG_REG_CNFG_07 */
|
||||
#define MAX77705_CHG_FMBST 4
|
||||
#define MAX77705_REG_FMBST_SHIFT 2
|
||||
#define MAX77705_REG_FMBST_MASK BIT(MAX77705_REG_FMBST_SHIFT)
|
||||
#define MAX77705_REG_FGSRC_SHIFT 1
|
||||
#define MAX77705_REG_FGSRC_MASK BIT(MAX77705_REG_FGSRC_SHIFT)
|
||||
|
||||
/* MAX77705_CHG_REG_CNFG_08 */
|
||||
#define MAX77705_REG_FSW_SHIFT 0
|
||||
#define MAX77705_REG_FSW_MASK GENMASK(1, 0)
|
||||
#define MAX77705_CHG_FSW_3MHz 0
|
||||
#define MAX77705_CHG_FSW_2MHz 1
|
||||
#define MAX77705_CHG_FSW_1_5MHz 2
|
||||
|
||||
/* MAX77705_CHG_REG_CNFG_09 */
|
||||
#define MAX77705_CHG_CHGIN_LIM_MASK GENMASK(6, 0)
|
||||
#define MAX77705_CHG_EN_MASK BIT(7)
|
||||
#define MAX77705_CHG_DISABLE 0
|
||||
#define MAX77705_CHARGER_CHG_CHARGING(_reg) \
|
||||
(((_reg) & MAX77705_CHG_EN_MASK) > 1)
|
||||
|
||||
|
||||
/* MAX77705_CHG_REG_CNFG_10 */
|
||||
#define MAX77705_CHG_WCIN_LIM GENMASK(5, 0)
|
||||
|
||||
/* MAX77705_CHG_REG_CNFG_11 */
|
||||
#define MAX77705_VBYPSET_SHIFT 0
|
||||
#define MAX77705_VBYPSET_MASK GENMASK(6, 0)
|
||||
|
||||
/* MAX77705_CHG_REG_CNFG_12 */
|
||||
#define MAX77705_CHGINSEL_SHIFT 5
|
||||
#define MAX77705_CHGINSEL_MASK BIT(MAX77705_CHGINSEL_SHIFT)
|
||||
#define MAX77705_WCINSEL_SHIFT 6
|
||||
#define MAX77705_WCINSEL_MASK BIT(MAX77705_WCINSEL_SHIFT)
|
||||
#define MAX77705_VCHGIN_REG_MASK GENMASK(4, 3)
|
||||
#define MAX77705_WCIN_REG_MASK GENMASK(2, 1)
|
||||
#define MAX77705_REG_DISKIP_SHIFT 0
|
||||
#define MAX77705_REG_DISKIP_MASK BIT(MAX77705_REG_DISKIP_SHIFT)
|
||||
/* REG=4.5V, UVLO=4.7V */
|
||||
#define MAX77705_VCHGIN_4_5 0
|
||||
/* REG=4.5V, UVLO=4.7V */
|
||||
#define MAX77705_WCIN_4_5 0
|
||||
#define MAX77705_DISABLE_SKIP 1
|
||||
#define MAX77705_AUTO_SKIP 0
|
||||
|
||||
/* uA */
|
||||
#define MAX77705_CURRENT_CHGIN_STEP 25000
|
||||
#define MAX77705_CURRENT_CHG_STEP 50000
|
||||
#define MAX77705_CURRENT_CHGIN_MIN 100000
|
||||
#define MAX77705_CURRENT_CHGIN_MAX 3200000
|
||||
|
||||
struct max77705_charger_data {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
struct power_supply_battery_info *bat_info;
|
||||
struct workqueue_struct *wqueue;
|
||||
struct work_struct chgin_work;
|
||||
struct power_supply *psy_chg;
|
||||
};
|
||||
|
||||
#endif /* __MAX77705_CHARGER_H */
|
Loading…
x
Reference in New Issue
Block a user