Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branches 'ib-firmware-mfd-6.16', 'ib-mfd-clocksource-pwm-6.16', 'ib-mfd-gpio-nvmem-6.16', 'ib-mfd-regulator-6.16' and 'ib-mfd-regulator-6.16-1' into ibs-for-mfd-merged

Lee Jones 18e6c1d2 e36d96a2

+4523 -512
+44
Documentation/devicetree/bindings/gpio/maxim,max77759-gpio.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/gpio/maxim,max77759-gpio.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Maxim Integrated MAX77759 GPIO 8 + 9 + maintainers: 10 + - André Draszik <andre.draszik@linaro.org> 11 + 12 + description: | 13 + This module is part of the MAX77759 PMIC. For additional information, see 14 + Documentation/devicetree/bindings/mfd/maxim,max77759.yaml. 15 + 16 + The MAX77759 is a PMIC integrating, amongst others, a GPIO controller 17 + including interrupt support for 2 GPIO lines. 18 + 19 + properties: 20 + compatible: 21 + const: maxim,max77759-gpio 22 + 23 + "#gpio-cells": 24 + const: 2 25 + 26 + gpio-controller: true 27 + 28 + gpio-line-names: 29 + minItems: 1 30 + maxItems: 2 31 + 32 + "#interrupt-cells": 33 + const: 2 34 + 35 + interrupt-controller: true 36 + 37 + required: 38 + - compatible 39 + - "#gpio-cells" 40 + - gpio-controller 41 + - "#interrupt-cells" 42 + - interrupt-controller 43 + 44 + additionalProperties: false
-39
Documentation/devicetree/bindings/mfd/brcm,bcm59056.txt
··· 1 - ------------------------------- 2 - BCM590xx Power Management Units 3 - ------------------------------- 4 - 5 - Required properties: 6 - - compatible: "brcm,bcm59056" 7 - - reg: I2C slave address 8 - - interrupts: interrupt for the PMU. Generic interrupt client node bindings 9 - are described in interrupt-controller/interrupts.txt 10 - 11 - ------------------ 12 - Voltage Regulators 13 - ------------------ 14 - 15 - Optional child nodes: 16 - - regulators: container node for regulators following the generic 17 - regulator binding in regulator/regulator.txt 18 - 19 - The valid regulator node names for BCM59056 are: 20 - rfldo, camldo1, camldo2, simldo1, simldo2, sdldo, sdxldo, 21 - mmcldo1, mmcldo2, audldo, micldo, usbldo, vibldo, 22 - csr, iosr1, iosr2, msr, sdsr1, sdsr2, vsr, 23 - gpldo1, gpldo2, gpldo3, gpldo4, gpldo5, gpldo6, 24 - vbus 25 - 26 - Example: 27 - pmu: bcm59056@8 { 28 - compatible = "brcm,bcm59056"; 29 - reg = <0x08>; 30 - interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>; 31 - regulators { 32 - rfldo_reg: rfldo { 33 - regulator-min-microvolt = <1200000>; 34 - regulator-max-microvolt = <3300000>; 35 - }; 36 - 37 - ... 38 - }; 39 - };
+76
Documentation/devicetree/bindings/mfd/brcm,bcm59056.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/mfd/brcm,bcm59056.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Broadcom BCM590xx Power Management Units 8 + 9 + maintainers: 10 + - Artur Weber <aweber.kernel@gmail.com> 11 + 12 + properties: 13 + compatible: 14 + enum: 15 + - brcm,bcm59054 16 + - brcm,bcm59056 17 + 18 + reg: 19 + maxItems: 1 20 + 21 + interrupts: 22 + maxItems: 1 23 + 24 + regulators: 25 + type: object 26 + 27 + required: 28 + - compatible 29 + - reg 30 + - interrupts 31 + 32 + additionalProperties: false 33 + 34 + allOf: 35 + - if: 36 + properties: 37 + compatible: 38 + contains: 39 + const: brcm,bcm59054 40 + then: 41 + properties: 42 + regulators: 43 + $ref: /schemas/regulator/brcm,bcm59054.yaml# 44 + 45 + - if: 46 + properties: 47 + compatible: 48 + contains: 49 + const: brcm,bcm59056 50 + then: 51 + properties: 52 + regulators: 53 + $ref: /schemas/regulator/brcm,bcm59056.yaml# 54 + 55 + examples: 56 + - | 57 + #include <dt-bindings/interrupt-controller/arm-gic.h> 58 + #include <dt-bindings/interrupt-controller/irq.h> 59 + 60 + i2c { 61 + #address-cells = <1>; 62 + #size-cells = <0>; 63 + 64 + pmic@8 { 65 + compatible = "brcm,bcm59056"; 66 + reg = <0x08>; 67 + interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>; 68 + 69 + regulators { 70 + rfldo { 71 + regulator-min-microvolt = <1200000>; 72 + regulator-max-microvolt = <3300000>; 73 + }; 74 + }; 75 + }; 76 + };
+99
Documentation/devicetree/bindings/mfd/maxim,max77759.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/mfd/maxim,max77759.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Maxim Integrated MAX77759 PMIC for USB Type-C applications 8 + 9 + maintainers: 10 + - André Draszik <andre.draszik@linaro.org> 11 + 12 + description: | 13 + This is a part of device tree bindings for the MAX77759 companion Power 14 + Management IC for USB Type-C applications. 15 + 16 + The MAX77759 includes Battery Charger, Fuel Gauge, temperature sensors, USB 17 + Type-C Port Controller (TCPC), NVMEM, and a GPIO expander. 18 + 19 + properties: 20 + compatible: 21 + const: maxim,max77759 22 + 23 + interrupts: 24 + maxItems: 1 25 + 26 + interrupt-controller: true 27 + 28 + "#interrupt-cells": 29 + const: 2 30 + 31 + reg: 32 + maxItems: 1 33 + 34 + gpio: 35 + $ref: /schemas/gpio/maxim,max77759-gpio.yaml 36 + 37 + nvmem-0: 38 + $ref: /schemas/nvmem/maxim,max77759-nvmem.yaml 39 + 40 + required: 41 + - compatible 42 + - interrupts 43 + - reg 44 + 45 + additionalProperties: false 46 + 47 + examples: 48 + - | 49 + #include <dt-bindings/interrupt-controller/irq.h> 50 + 51 + i2c { 52 + #address-cells = <1>; 53 + #size-cells = <0>; 54 + 55 + pmic@66 { 56 + compatible = "maxim,max77759"; 57 + reg = <0x66>; 58 + interrupts-extended = <&gpa8 3 IRQ_TYPE_LEVEL_LOW>; 59 + 60 + interrupt-controller; 61 + #interrupt-cells = <2>; 62 + 63 + gpio { 64 + compatible = "maxim,max77759-gpio"; 65 + 66 + gpio-controller; 67 + #gpio-cells = <2>; 68 + 69 + interrupt-controller; 70 + #interrupt-cells = <2>; 71 + }; 72 + 73 + nvmem-0 { 74 + compatible = "maxim,max77759-nvmem"; 75 + 76 + nvmem-layout { 77 + compatible = "fixed-layout"; 78 + #address-cells = <1>; 79 + #size-cells = <1>; 80 + 81 + reboot-mode@0 { 82 + reg = <0x0 0x4>; 83 + }; 84 + 85 + boot-reason@4 { 86 + reg = <0x4 0x4>; 87 + }; 88 + 89 + shutdown-user-flag@8 { 90 + reg = <0x8 0x1>; 91 + }; 92 + 93 + rsoc@10 { 94 + reg = <0xa 0x2>; 95 + }; 96 + }; 97 + }; 98 + }; 99 + };
+6 -4
Documentation/devicetree/bindings/mfd/rohm,bd96801-pmic.yaml
··· 4 4 $id: http://devicetree.org/schemas/mfd/rohm,bd96801-pmic.yaml# 5 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 6 6 7 - title: ROHM BD96801 Scalable Power Management Integrated Circuit 7 + title: ROHM BD96801/BD96805 Scalable Power Management Integrated Circuit 8 8 9 9 maintainers: 10 10 - Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> 11 11 12 12 description: 13 - BD96801 is an automotive grade single-chip power management IC. 14 - It integrates 4 buck converters and 3 LDOs with safety features like 13 + BD96801 and BD96805 are automotive grade, single-chip power management ICs. 14 + They both integrate 4 buck converters and 3 LDOs with safety features like 15 15 over-/under voltage and over current detection and a watchdog. 16 16 17 17 properties: 18 18 compatible: 19 - const: rohm,bd96801 19 + enum: 20 + - rohm,bd96801 21 + - rohm,bd96805 20 22 21 23 reg: 22 24 maxItems: 1
+101
Documentation/devicetree/bindings/mfd/rohm,bd96802-pmic.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/mfd/rohm,bd96802-pmic.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: ROHM BD96802 / BD96806 Scalable Power Management Integrated Circuit 8 + 9 + maintainers: 10 + - Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> 11 + 12 + description: | 13 + BD96802Qxx-C and BD96806 are automotive grade configurable Power Management 14 + Integrated Circuits supporting Functional Safety features for application 15 + processors, SoCs and FPGAs 16 + 17 + properties: 18 + compatible: 19 + enum: 20 + - rohm,bd96802 21 + - rohm,bd96806 22 + 23 + reg: 24 + maxItems: 1 25 + 26 + interrupts: 27 + description: 28 + The PMIC provides intb and errb IRQ lines. The errb IRQ line is used 29 + for fatal IRQs which will cause the PMIC to shut down power outputs. 30 + In many systems this will shut down the SoC contolling the PMIC and 31 + connecting/handling the errb can be omitted. However, there are cases 32 + where the SoC is not powered by the PMIC or has a short time backup 33 + energy to handle shutdown of critical hardware. In that case it may be 34 + useful to connect the errb and handle errb events. 35 + minItems: 1 36 + maxItems: 2 37 + 38 + interrupt-names: 39 + minItems: 1 40 + items: 41 + - enum: [intb, errb] 42 + - const: errb 43 + 44 + regulators: 45 + $ref: ../regulator/rohm,bd96802-regulator.yaml 46 + description: 47 + List of child nodes that specify the regulators. 48 + 49 + required: 50 + - compatible 51 + - reg 52 + - interrupts 53 + - interrupt-names 54 + - regulators 55 + 56 + additionalProperties: false 57 + 58 + examples: 59 + - | 60 + #include <dt-bindings/interrupt-controller/irq.h> 61 + #include <dt-bindings/leds/common.h> 62 + i2c { 63 + #address-cells = <1>; 64 + #size-cells = <0>; 65 + pmic: pmic@62 { 66 + reg = <0x62>; 67 + compatible = "rohm,bd96802"; 68 + interrupt-parent = <&gpio1>; 69 + interrupts = <29 IRQ_TYPE_LEVEL_LOW>, <6 IRQ_TYPE_LEVEL_LOW>; 70 + interrupt-names = "intb", "errb"; 71 + 72 + regulators { 73 + buck1 { 74 + regulator-name = "buck1"; 75 + regulator-ramp-delay = <1250>; 76 + /* 0.5V min INITIAL - 150 mV tune */ 77 + regulator-min-microvolt = <350000>; 78 + /* 3.3V + 150mV tune */ 79 + regulator-max-microvolt = <3450000>; 80 + 81 + /* These can be set only when PMIC is in STBY */ 82 + rohm,initial-voltage-microvolt = <500000>; 83 + regulator-ov-error-microvolt = <230000>; 84 + regulator-uv-error-microvolt = <230000>; 85 + regulator-temp-protection-kelvin = <1>; 86 + regulator-temp-warn-kelvin = <0>; 87 + }; 88 + buck2 { 89 + regulator-name = "buck2"; 90 + regulator-min-microvolt = <350000>; 91 + regulator-max-microvolt = <3450000>; 92 + 93 + rohm,initial-voltage-microvolt = <3000000>; 94 + regulator-ov-error-microvolt = <18000>; 95 + regulator-uv-error-microvolt = <18000>; 96 + regulator-temp-protection-kelvin = <1>; 97 + regulator-temp-warn-kelvin = <1>; 98 + }; 99 + }; 100 + }; 101 + };
+34 -6
Documentation/devicetree/bindings/mfd/st,stm32-lptimer.yaml
··· 21 21 22 22 properties: 23 23 compatible: 24 - const: st,stm32-lptimer 24 + oneOf: 25 + - items: 26 + - const: st,stm32mp25-lptimer 27 + - const: st,stm32-lptimer 28 + - items: 29 + - const: st,stm32-lptimer 25 30 26 31 reg: 27 32 maxItems: 1 ··· 53 48 minItems: 1 54 49 maxItems: 2 55 50 51 + power-domains: 52 + maxItems: 1 53 + 56 54 pwm: 57 55 type: object 58 56 additionalProperties: false 59 57 60 58 properties: 61 59 compatible: 62 - const: st,stm32-pwm-lp 60 + oneOf: 61 + - items: 62 + - const: st,stm32mp25-pwm-lp 63 + - const: st,stm32-pwm-lp 64 + - items: 65 + - const: st,stm32-pwm-lp 63 66 64 67 "#pwm-cells": 65 68 const: 3 ··· 82 69 83 70 properties: 84 71 compatible: 85 - const: st,stm32-lptimer-counter 72 + oneOf: 73 + - items: 74 + - const: st,stm32mp25-lptimer-counter 75 + - const: st,stm32-lptimer-counter 76 + - items: 77 + - const: st,stm32-lptimer-counter 86 78 87 79 required: 88 80 - compatible ··· 98 80 99 81 properties: 100 82 compatible: 101 - const: st,stm32-lptimer-timer 83 + oneOf: 84 + - items: 85 + - const: st,stm32mp25-lptimer-timer 86 + - const: st,stm32-lptimer-timer 87 + - items: 88 + - const: st,stm32-lptimer-timer 102 89 103 90 required: 104 91 - compatible ··· 115 92 116 93 properties: 117 94 compatible: 118 - const: st,stm32-lptimer-trigger 95 + oneOf: 96 + - items: 97 + - const: st,stm32mp25-lptimer-trigger 98 + - const: st,stm32-lptimer-trigger 99 + - items: 100 + - const: st,stm32-lptimer-trigger 119 101 120 102 reg: 121 103 description: Identify trigger hardware block. 122 104 items: 123 105 minimum: 0 124 - maximum: 2 106 + maximum: 4 125 107 126 108 required: 127 109 - compatible
+32
Documentation/devicetree/bindings/nvmem/maxim,max77759-nvmem.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/nvmem/maxim,max77759-nvmem.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Maxim Integrated MAX77759 Non Volatile Memory 8 + 9 + maintainers: 10 + - André Draszik <andre.draszik@linaro.org> 11 + 12 + description: | 13 + This module is part of the MAX77759 PMIC. For additional information, see 14 + Documentation/devicetree/bindings/mfd/maxim,max77759.yaml. 15 + 16 + The MAX77759 is a PMIC integrating, amongst others, Non Volatile Memory 17 + (NVMEM) with 30 bytes of storage which can be used by software to store 18 + information or communicate with a boot loader. 19 + 20 + properties: 21 + compatible: 22 + const: maxim,max77759-nvmem 23 + 24 + wp-gpios: false 25 + 26 + required: 27 + - compatible 28 + 29 + allOf: 30 + - $ref: nvmem.yaml# 31 + 32 + unevaluatedProperties: false
+56
Documentation/devicetree/bindings/regulator/brcm,bcm59054.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/regulator/brcm,bcm59054.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Broadcom BCM59054 Power Management Unit regulators 8 + 9 + description: | 10 + This is a part of device tree bindings for the BCM59054 power 11 + management unit. 12 + 13 + See Documentation/devicetree/bindings/mfd/brcm,bcm59056.yaml for 14 + additional information and example. 15 + 16 + maintainers: 17 + - Artur Weber <aweber.kernel@gmail.com> 18 + 19 + patternProperties: 20 + "^(cam|sim|mmc)ldo[1-2]$": 21 + type: object 22 + $ref: /schemas/regulator/regulator.yaml# 23 + unevaluatedProperties: false 24 + 25 + "^(rf|sd|sdx|aud|mic|usb|vib|tcx)ldo$": 26 + type: object 27 + $ref: /schemas/regulator/regulator.yaml# 28 + unevaluatedProperties: false 29 + 30 + "^(c|mm|v)sr$": 31 + type: object 32 + $ref: /schemas/regulator/regulator.yaml# 33 + unevaluatedProperties: false 34 + 35 + "^(io|sd)sr[1-2]$": 36 + type: object 37 + $ref: /schemas/regulator/regulator.yaml# 38 + unevaluatedProperties: false 39 + 40 + "^gpldo[1-3]$": 41 + type: object 42 + $ref: /schemas/regulator/regulator.yaml# 43 + unevaluatedProperties: false 44 + 45 + "^lvldo[1-2]$": 46 + type: object 47 + $ref: /schemas/regulator/regulator.yaml# 48 + unevaluatedProperties: false 49 + 50 + properties: 51 + vbus: 52 + type: object 53 + $ref: /schemas/regulator/regulator.yaml# 54 + unevaluatedProperties: false 55 + 56 + additionalProperties: false
+51
Documentation/devicetree/bindings/regulator/brcm,bcm59056.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/regulator/brcm,bcm59056.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Broadcom BCM59056 Power Management Unit regulators 8 + 9 + description: | 10 + This is a part of device tree bindings for the BCM59056 power 11 + management unit. 12 + 13 + See Documentation/devicetree/bindings/mfd/brcm,bcm59056.yaml for 14 + additional information and example. 15 + 16 + maintainers: 17 + - Artur Weber <aweber.kernel@gmail.com> 18 + 19 + patternProperties: 20 + "^(cam|sim|mmc)ldo[1-2]$": 21 + type: object 22 + $ref: /schemas/regulator/regulator.yaml# 23 + unevaluatedProperties: false 24 + 25 + "^(rf|sd|sdx|aud|mic|usb|vib)ldo$": 26 + type: object 27 + $ref: /schemas/regulator/regulator.yaml# 28 + unevaluatedProperties: false 29 + 30 + "^(c|m|v)sr$": 31 + type: object 32 + $ref: /schemas/regulator/regulator.yaml# 33 + unevaluatedProperties: false 34 + 35 + "^(io|sd)sr[1-2]$": 36 + type: object 37 + $ref: /schemas/regulator/regulator.yaml# 38 + unevaluatedProperties: false 39 + 40 + "^gpldo[1-6]$": 41 + type: object 42 + $ref: /schemas/regulator/regulator.yaml# 43 + unevaluatedProperties: false 44 + 45 + properties: 46 + vbus: 47 + type: object 48 + $ref: /schemas/regulator/regulator.yaml# 49 + unevaluatedProperties: false 50 + 51 + additionalProperties: false
+44
Documentation/devicetree/bindings/regulator/rohm,bd96802-regulator.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/regulator/rohm,bd96802-regulator.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: ROHM BD96802 Power Management Integrated Circuit regulators 8 + 9 + maintainers: 10 + - Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> 11 + 12 + description: 13 + This module is part of the ROHM BD96802 MFD device. For more details 14 + see Documentation/devicetree/bindings/mfd/rohm,bd96802-pmic.yaml. 15 + 16 + The regulator controller is represented as a sub-node of the PMIC node 17 + on the device tree. 18 + 19 + Regulator nodes should be named to buck1 and buck2. 20 + 21 + patternProperties: 22 + "^buck[1-2]$": 23 + type: object 24 + description: 25 + Properties for single BUCK regulator. 26 + $ref: regulator.yaml# 27 + 28 + properties: 29 + rohm,initial-voltage-microvolt: 30 + description: 31 + Initial voltage for regulator. Voltage can be tuned +/-150 mV from 32 + this value. NOTE, This can be modified via I2C only when PMIC is in 33 + STBY state. 34 + minimum: 500000 35 + maximum: 3300000 36 + 37 + rohm,keep-on-stby: 38 + description: 39 + Keep the regulator powered when PMIC transitions to STBY state. 40 + type: boolean 41 + 42 + unevaluatedProperties: false 43 + 44 + additionalProperties: false
+11
MAINTAINERS
··· 14575 14575 F: drivers/mfd/max77714.c 14576 14576 F: include/linux/mfd/max77714.h 14577 14577 14578 + MAXIM MAX77759 PMIC MFD DRIVER 14579 + M: André Draszik <andre.draszik@linaro.org> 14580 + L: linux-kernel@vger.kernel.org 14581 + S: Maintained 14582 + F: Documentation/devicetree/bindings/*/maxim,max77759*.yaml 14583 + F: drivers/gpio/gpio-max77759.c 14584 + F: drivers/mfd/max77759.c 14585 + F: drivers/nvmem/max77759-nvmem.c 14586 + F: include/linux/mfd/max77759.h 14587 + 14578 14588 MAXIM MAX77802 PMIC REGULATOR DEVICE DRIVER 14579 14589 M: Javier Martinez Canillas <javier@dowhile0.org> 14580 14590 L: linux-kernel@vger.kernel.org ··· 21010 21000 F: include/linux/mfd/rohm-bd718x7.h 21011 21001 F: include/linux/mfd/rohm-bd957x.h 21012 21002 F: include/linux/mfd/rohm-bd96801.h 21003 + F: include/linux/mfd/rohm-bd96802.h 21013 21004 F: include/linux/mfd/rohm-generic.h 21014 21005 F: include/linux/mfd/rohm-shared.h 21015 21006
+57 -4
drivers/clocksource/timer-stm32-lp.c
··· 5 5 * Pascal Paillet <p.paillet@st.com> for STMicroelectronics. 6 6 */ 7 7 8 + #include <linux/bitfield.h> 8 9 #include <linux/clk.h> 9 10 #include <linux/clockchips.h> 10 11 #include <linux/interrupt.h> ··· 28 27 u32 psc; 29 28 struct device *dev; 30 29 struct clk *clk; 30 + u32 version; 31 31 }; 32 32 33 33 static struct stm32_lp_private* ··· 49 47 return 0; 50 48 } 51 49 52 - static int stm32_clkevent_lp_set_timer(unsigned long evt, 53 - struct clock_event_device *clkevt, 54 - int is_periodic) 50 + static int stm32mp25_clkevent_lp_set_evt(struct stm32_lp_private *priv, unsigned long evt) 55 51 { 56 - struct stm32_lp_private *priv = to_priv(clkevt); 52 + int ret; 53 + u32 val; 57 54 55 + regmap_read(priv->reg, STM32_LPTIM_CR, &val); 56 + if (!FIELD_GET(STM32_LPTIM_ENABLE, val)) { 57 + /* Enable LPTIMER to be able to write into IER and ARR registers */ 58 + regmap_write(priv->reg, STM32_LPTIM_CR, STM32_LPTIM_ENABLE); 59 + /* 60 + * After setting the ENABLE bit, a delay of two counter clock cycles is needed 61 + * before the LPTIM is actually enabled. For 32KHz rate, this makes approximately 62 + * 62.5 micro-seconds, round it up. 63 + */ 64 + udelay(63); 65 + } 66 + /* set next event counter */ 67 + regmap_write(priv->reg, STM32_LPTIM_ARR, evt); 68 + /* enable ARR interrupt */ 69 + regmap_write(priv->reg, STM32_LPTIM_IER, STM32_LPTIM_ARRMIE); 70 + 71 + /* Poll DIEROK and ARROK to ensure register access has completed */ 72 + ret = regmap_read_poll_timeout_atomic(priv->reg, STM32_LPTIM_ISR, val, 73 + (val & STM32_LPTIM_DIEROK_ARROK) == 74 + STM32_LPTIM_DIEROK_ARROK, 75 + 10, 500); 76 + if (ret) { 77 + dev_err(priv->dev, "access to LPTIM timed out\n"); 78 + /* Disable LPTIMER */ 79 + regmap_write(priv->reg, STM32_LPTIM_CR, 0); 80 + return ret; 81 + } 82 + /* Clear DIEROK and ARROK flags */ 83 + regmap_write(priv->reg, STM32_LPTIM_ICR, STM32_LPTIM_DIEROKCF_ARROKCF); 84 + 85 + return 0; 86 + } 87 + 88 + static void stm32_clkevent_lp_set_evt(struct stm32_lp_private *priv, unsigned long evt) 89 + { 58 90 /* disable LPTIMER to be able to write into IER register*/ 59 91 regmap_write(priv->reg, STM32_LPTIM_CR, 0); 60 92 /* enable ARR interrupt */ ··· 97 61 regmap_write(priv->reg, STM32_LPTIM_CR, STM32_LPTIM_ENABLE); 98 62 /* set next event counter */ 99 63 regmap_write(priv->reg, STM32_LPTIM_ARR, evt); 64 + } 65 + 66 + static int stm32_clkevent_lp_set_timer(unsigned long evt, 67 + struct clock_event_device *clkevt, 68 + int is_periodic) 69 + { 70 + struct stm32_lp_private *priv = to_priv(clkevt); 71 + int ret; 72 + 73 + if (priv->version == STM32_LPTIM_VERR_23) { 74 + ret = stm32mp25_clkevent_lp_set_evt(priv, evt); 75 + if (ret) 76 + return ret; 77 + } else { 78 + stm32_clkevent_lp_set_evt(priv, evt); 79 + } 100 80 101 81 /* start counter */ 102 82 if (is_periodic) ··· 228 176 return -ENOMEM; 229 177 230 178 priv->reg = ddata->regmap; 179 + priv->version = ddata->version; 231 180 priv->clk = ddata->clk; 232 181 ret = clk_prepare_enable(priv->clk); 233 182 if (ret)
+13
drivers/gpio/Kconfig
··· 1463 1463 GPIO driver for MAX77650/77651 PMIC from Maxim Semiconductor. 1464 1464 These chips have a single pin that can be configured as GPIO. 1465 1465 1466 + config GPIO_MAX77759 1467 + tristate "Maxim Integrated MAX77759 GPIO support" 1468 + depends on MFD_MAX77759 1469 + default MFD_MAX77759 1470 + select GPIOLIB_IRQCHIP 1471 + help 1472 + GPIO driver for MAX77759 PMIC from Maxim Integrated. 1473 + There are two GPIOs available on these chips in total, both of 1474 + which can also generate interrupts. 1475 + 1476 + This driver can also be built as a module. If so, the module will be 1477 + called gpio-max77759. 1478 + 1466 1479 config GPIO_PALMAS 1467 1480 bool "TI PALMAS series PMICs GPIO" 1468 1481 depends on MFD_PALMAS
+1
drivers/gpio/Makefile
··· 105 105 obj-$(CONFIG_GPIO_MAX732X) += gpio-max732x.o 106 106 obj-$(CONFIG_GPIO_MAX77620) += gpio-max77620.o 107 107 obj-$(CONFIG_GPIO_MAX77650) += gpio-max77650.o 108 + obj-$(CONFIG_GPIO_MAX77759) += gpio-max77759.o 108 109 obj-$(CONFIG_GPIO_MB86S7X) += gpio-mb86s7x.o 109 110 obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o 110 111 obj-$(CONFIG_GPIO_MENZ127) += gpio-menz127.o
+530
drivers/gpio/gpio-max77759.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + // 3 + // Copyright 2020 Google Inc 4 + // Copyright 2025 Linaro Ltd. 5 + // 6 + // GPIO driver for Maxim MAX77759 7 + 8 + #include <linux/dev_printk.h> 9 + #include <linux/device.h> 10 + #include <linux/device/driver.h> 11 + #include <linux/gpio/driver.h> 12 + #include <linux/interrupt.h> 13 + #include <linux/irq.h> 14 + #include <linux/irqreturn.h> 15 + #include <linux/lockdep.h> 16 + #include <linux/mfd/max77759.h> 17 + #include <linux/mod_devicetable.h> 18 + #include <linux/module.h> 19 + #include <linux/overflow.h> 20 + #include <linux/platform_device.h> 21 + #include <linux/regmap.h> 22 + #include <linux/seq_file.h> 23 + 24 + #define MAX77759_N_GPIOS ARRAY_SIZE(max77759_gpio_line_names) 25 + static const char * const max77759_gpio_line_names[] = { "GPIO5", "GPIO6" }; 26 + 27 + struct max77759_gpio_chip { 28 + struct regmap *map; 29 + struct max77759 *max77759; 30 + struct gpio_chip gc; 31 + struct mutex maxq_lock; /* protect MaxQ r/m/w operations */ 32 + 33 + struct mutex irq_lock; /* protect irq bus */ 34 + int irq_mask; 35 + int irq_mask_changed; 36 + int irq_trig; 37 + int irq_trig_changed; 38 + }; 39 + 40 + #define MAX77759_GPIOx_TRIGGER(offs, val) (((val) & 1) << (offs)) 41 + #define MAX77759_GPIOx_TRIGGER_MASK(offs) MAX77759_GPIOx_TRIGGER(offs, ~0) 42 + enum max77759_trigger_gpio_type { 43 + MAX77759_GPIO_TRIGGER_RISING = 0, 44 + MAX77759_GPIO_TRIGGER_FALLING = 1 45 + }; 46 + 47 + #define MAX77759_GPIOx_DIR(offs, dir) (((dir) & 1) << (2 + (3 * (offs)))) 48 + #define MAX77759_GPIOx_DIR_MASK(offs) MAX77759_GPIOx_DIR(offs, ~0) 49 + enum max77759_control_gpio_dir { 50 + MAX77759_GPIO_DIR_IN = 0, 51 + MAX77759_GPIO_DIR_OUT = 1 52 + }; 53 + 54 + #define MAX77759_GPIOx_OUTVAL(offs, val) (((val) & 1) << (3 + (3 * (offs)))) 55 + #define MAX77759_GPIOx_OUTVAL_MASK(offs) MAX77759_GPIOx_OUTVAL(offs, ~0) 56 + 57 + #define MAX77759_GPIOx_INVAL_MASK(offs) (BIT(4) << (3 * (offs))) 58 + 59 + static int max77759_gpio_maxq_gpio_trigger_read(struct max77759_gpio_chip *chip) 60 + { 61 + DEFINE_FLEX(struct max77759_maxq_command, cmd, cmd, length, 1); 62 + DEFINE_FLEX(struct max77759_maxq_response, rsp, rsp, length, 2); 63 + int ret; 64 + 65 + cmd->cmd[0] = MAX77759_MAXQ_OPCODE_GPIO_TRIGGER_READ; 66 + 67 + ret = max77759_maxq_command(chip->max77759, cmd, rsp); 68 + if (ret < 0) 69 + return ret; 70 + 71 + return rsp->rsp[1]; 72 + } 73 + 74 + static int max77759_gpio_maxq_gpio_trigger_write(struct max77759_gpio_chip *chip, 75 + u8 trigger) 76 + { 77 + DEFINE_FLEX(struct max77759_maxq_command, cmd, cmd, length, 2); 78 + 79 + cmd->cmd[0] = MAX77759_MAXQ_OPCODE_GPIO_TRIGGER_WRITE; 80 + cmd->cmd[1] = trigger; 81 + 82 + return max77759_maxq_command(chip->max77759, cmd, NULL); 83 + } 84 + 85 + static int max77759_gpio_maxq_gpio_control_read(struct max77759_gpio_chip *chip) 86 + { 87 + DEFINE_FLEX(struct max77759_maxq_command, cmd, cmd, length, 1); 88 + DEFINE_FLEX(struct max77759_maxq_response, rsp, rsp, length, 2); 89 + int ret; 90 + 91 + cmd->cmd[0] = MAX77759_MAXQ_OPCODE_GPIO_CONTROL_READ; 92 + 93 + ret = max77759_maxq_command(chip->max77759, cmd, rsp); 94 + if (ret < 0) 95 + return ret; 96 + 97 + return rsp->rsp[1]; 98 + } 99 + 100 + static int max77759_gpio_maxq_gpio_control_write(struct max77759_gpio_chip *chip, 101 + u8 ctrl) 102 + { 103 + DEFINE_FLEX(struct max77759_maxq_command, cmd, cmd, length, 2); 104 + 105 + cmd->cmd[0] = MAX77759_MAXQ_OPCODE_GPIO_CONTROL_WRITE; 106 + cmd->cmd[1] = ctrl; 107 + 108 + return max77759_maxq_command(chip->max77759, cmd, NULL); 109 + } 110 + 111 + static int 112 + max77759_gpio_direction_from_control(int ctrl, unsigned int offset) 113 + { 114 + enum max77759_control_gpio_dir dir; 115 + 116 + dir = !!(ctrl & MAX77759_GPIOx_DIR_MASK(offset)); 117 + return ((dir == MAX77759_GPIO_DIR_OUT) 118 + ? GPIO_LINE_DIRECTION_OUT 119 + : GPIO_LINE_DIRECTION_IN); 120 + } 121 + 122 + static int max77759_gpio_get_direction(struct gpio_chip *gc, 123 + unsigned int offset) 124 + { 125 + struct max77759_gpio_chip *chip = gpiochip_get_data(gc); 126 + int ctrl; 127 + 128 + ctrl = max77759_gpio_maxq_gpio_control_read(chip); 129 + if (ctrl < 0) 130 + return ctrl; 131 + 132 + return max77759_gpio_direction_from_control(ctrl, offset); 133 + } 134 + 135 + static int max77759_gpio_direction_helper(struct gpio_chip *gc, 136 + unsigned int offset, 137 + enum max77759_control_gpio_dir dir, 138 + int value) 139 + { 140 + struct max77759_gpio_chip *chip = gpiochip_get_data(gc); 141 + int ctrl, new_ctrl; 142 + 143 + guard(mutex)(&chip->maxq_lock); 144 + 145 + ctrl = max77759_gpio_maxq_gpio_control_read(chip); 146 + if (ctrl < 0) 147 + return ctrl; 148 + 149 + new_ctrl = ctrl & ~MAX77759_GPIOx_DIR_MASK(offset); 150 + new_ctrl |= MAX77759_GPIOx_DIR(offset, dir); 151 + 152 + if (dir == MAX77759_GPIO_DIR_OUT) { 153 + new_ctrl &= ~MAX77759_GPIOx_OUTVAL_MASK(offset); 154 + new_ctrl |= MAX77759_GPIOx_OUTVAL(offset, value); 155 + } 156 + 157 + if (new_ctrl == ctrl) 158 + return 0; 159 + 160 + return max77759_gpio_maxq_gpio_control_write(chip, new_ctrl); 161 + } 162 + 163 + static int max77759_gpio_direction_input(struct gpio_chip *gc, 164 + unsigned int offset) 165 + { 166 + return max77759_gpio_direction_helper(gc, offset, 167 + MAX77759_GPIO_DIR_IN, -1); 168 + } 169 + 170 + static int max77759_gpio_direction_output(struct gpio_chip *gc, 171 + unsigned int offset, int value) 172 + { 173 + return max77759_gpio_direction_helper(gc, offset, 174 + MAX77759_GPIO_DIR_OUT, value); 175 + } 176 + 177 + static int max77759_gpio_get_value(struct gpio_chip *gc, unsigned int offset) 178 + { 179 + struct max77759_gpio_chip *chip = gpiochip_get_data(gc); 180 + int ctrl, mask; 181 + 182 + ctrl = max77759_gpio_maxq_gpio_control_read(chip); 183 + if (ctrl < 0) 184 + return ctrl; 185 + 186 + /* 187 + * The input status bit doesn't reflect the pin state when the GPIO is 188 + * configured as an output. Check the direction, and inspect the input 189 + * or output bit accordingly. 190 + */ 191 + mask = ((max77759_gpio_direction_from_control(ctrl, offset) 192 + == GPIO_LINE_DIRECTION_IN) 193 + ? MAX77759_GPIOx_INVAL_MASK(offset) 194 + : MAX77759_GPIOx_OUTVAL_MASK(offset)); 195 + 196 + return !!(ctrl & mask); 197 + } 198 + 199 + static int max77759_gpio_set_value(struct gpio_chip *gc, 200 + unsigned int offset, int value) 201 + { 202 + struct max77759_gpio_chip *chip = gpiochip_get_data(gc); 203 + int ctrl, new_ctrl; 204 + 205 + guard(mutex)(&chip->maxq_lock); 206 + 207 + ctrl = max77759_gpio_maxq_gpio_control_read(chip); 208 + if (ctrl < 0) 209 + return ctrl; 210 + 211 + new_ctrl = ctrl & ~MAX77759_GPIOx_OUTVAL_MASK(offset); 212 + new_ctrl |= MAX77759_GPIOx_OUTVAL(offset, value); 213 + 214 + if (new_ctrl == ctrl) 215 + return 0; 216 + 217 + return max77759_gpio_maxq_gpio_control_write(chip, new_ctrl); 218 + } 219 + 220 + static void max77759_gpio_irq_mask(struct irq_data *d) 221 + { 222 + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 223 + struct max77759_gpio_chip *chip = gpiochip_get_data(gc); 224 + irq_hw_number_t hwirq = irqd_to_hwirq(d); 225 + 226 + chip->irq_mask &= ~MAX77759_MAXQ_REG_UIC_INT1_GPIOxI_MASK(hwirq); 227 + chip->irq_mask |= MAX77759_MAXQ_REG_UIC_INT1_GPIOxI(hwirq, 1); 228 + chip->irq_mask_changed |= MAX77759_MAXQ_REG_UIC_INT1_GPIOxI(hwirq, 1); 229 + 230 + gpiochip_disable_irq(gc, hwirq); 231 + } 232 + 233 + static void max77759_gpio_irq_unmask(struct irq_data *d) 234 + { 235 + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 236 + struct max77759_gpio_chip *chip = gpiochip_get_data(gc); 237 + irq_hw_number_t hwirq = irqd_to_hwirq(d); 238 + 239 + gpiochip_enable_irq(gc, hwirq); 240 + 241 + chip->irq_mask &= ~MAX77759_MAXQ_REG_UIC_INT1_GPIOxI_MASK(hwirq); 242 + chip->irq_mask |= MAX77759_MAXQ_REG_UIC_INT1_GPIOxI(hwirq, 0); 243 + chip->irq_mask_changed |= MAX77759_MAXQ_REG_UIC_INT1_GPIOxI(hwirq, 1); 244 + } 245 + 246 + static int max77759_gpio_set_irq_type(struct irq_data *d, unsigned int type) 247 + { 248 + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 249 + struct max77759_gpio_chip *chip = gpiochip_get_data(gc); 250 + irq_hw_number_t hwirq = irqd_to_hwirq(d); 251 + 252 + chip->irq_trig &= ~MAX77759_GPIOx_TRIGGER_MASK(hwirq); 253 + switch (type) { 254 + case IRQ_TYPE_EDGE_RISING: 255 + chip->irq_trig |= MAX77759_GPIOx_TRIGGER(hwirq, 256 + MAX77759_GPIO_TRIGGER_RISING); 257 + break; 258 + 259 + case IRQ_TYPE_EDGE_FALLING: 260 + chip->irq_trig |= MAX77759_GPIOx_TRIGGER(hwirq, 261 + MAX77759_GPIO_TRIGGER_FALLING); 262 + break; 263 + 264 + default: 265 + return -EINVAL; 266 + } 267 + 268 + chip->irq_trig_changed |= MAX77759_GPIOx_TRIGGER(hwirq, 1); 269 + 270 + return 0; 271 + } 272 + 273 + static void max77759_gpio_bus_lock(struct irq_data *d) 274 + { 275 + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 276 + struct max77759_gpio_chip *chip = gpiochip_get_data(gc); 277 + 278 + mutex_lock(&chip->irq_lock); 279 + } 280 + 281 + static int max77759_gpio_bus_sync_unlock_helper(struct gpio_chip *gc, 282 + struct max77759_gpio_chip *chip) 283 + __must_hold(&chip->maxq_lock) 284 + { 285 + int ctrl, trigger, new_trigger, new_ctrl; 286 + unsigned long irq_trig_changed; 287 + int offset; 288 + int ret; 289 + 290 + lockdep_assert_held(&chip->maxq_lock); 291 + 292 + ctrl = max77759_gpio_maxq_gpio_control_read(chip); 293 + trigger = max77759_gpio_maxq_gpio_trigger_read(chip); 294 + if (ctrl < 0 || trigger < 0) { 295 + dev_err(gc->parent, "failed to read current state: %d / %d\n", 296 + ctrl, trigger); 297 + return (ctrl < 0) ? ctrl : trigger; 298 + } 299 + 300 + new_trigger = trigger & ~chip->irq_trig_changed; 301 + new_trigger |= (chip->irq_trig & chip->irq_trig_changed); 302 + 303 + /* change GPIO direction if required */ 304 + new_ctrl = ctrl; 305 + irq_trig_changed = chip->irq_trig_changed; 306 + for_each_set_bit(offset, &irq_trig_changed, MAX77759_N_GPIOS) { 307 + new_ctrl &= ~MAX77759_GPIOx_DIR_MASK(offset); 308 + new_ctrl |= MAX77759_GPIOx_DIR(offset, MAX77759_GPIO_DIR_IN); 309 + } 310 + 311 + if (new_trigger != trigger) { 312 + ret = max77759_gpio_maxq_gpio_trigger_write(chip, new_trigger); 313 + if (ret) { 314 + dev_err(gc->parent, 315 + "failed to write new trigger: %d\n", ret); 316 + return ret; 317 + } 318 + } 319 + 320 + if (new_ctrl != ctrl) { 321 + ret = max77759_gpio_maxq_gpio_control_write(chip, new_ctrl); 322 + if (ret) { 323 + dev_err(gc->parent, 324 + "failed to write new control: %d\n", ret); 325 + return ret; 326 + } 327 + } 328 + 329 + chip->irq_trig_changed = 0; 330 + 331 + return 0; 332 + } 333 + 334 + static void max77759_gpio_bus_sync_unlock(struct irq_data *d) 335 + { 336 + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 337 + struct max77759_gpio_chip *chip = gpiochip_get_data(gc); 338 + int ret; 339 + 340 + scoped_guard(mutex, &chip->maxq_lock) { 341 + ret = max77759_gpio_bus_sync_unlock_helper(gc, chip); 342 + if (ret) 343 + goto out_unlock; 344 + } 345 + 346 + ret = regmap_update_bits(chip->map, 347 + MAX77759_MAXQ_REG_UIC_INT1_M, 348 + chip->irq_mask_changed, chip->irq_mask); 349 + if (ret) { 350 + dev_err(gc->parent, 351 + "failed to update UIC_INT1 irq mask: %d\n", ret); 352 + goto out_unlock; 353 + } 354 + 355 + chip->irq_mask_changed = 0; 356 + 357 + out_unlock: 358 + mutex_unlock(&chip->irq_lock); 359 + } 360 + 361 + static void max77759_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p) 362 + { 363 + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 364 + 365 + seq_puts(p, dev_name(gc->parent)); 366 + } 367 + 368 + static const struct irq_chip max77759_gpio_irq_chip = { 369 + .irq_mask = max77759_gpio_irq_mask, 370 + .irq_unmask = max77759_gpio_irq_unmask, 371 + .irq_set_type = max77759_gpio_set_irq_type, 372 + .irq_bus_lock = max77759_gpio_bus_lock, 373 + .irq_bus_sync_unlock = max77759_gpio_bus_sync_unlock, 374 + .irq_print_chip = max77759_gpio_irq_print_chip, 375 + .flags = IRQCHIP_IMMUTABLE, 376 + GPIOCHIP_IRQ_RESOURCE_HELPERS, 377 + }; 378 + 379 + static irqreturn_t max77759_gpio_irqhandler(int irq, void *data) 380 + { 381 + struct max77759_gpio_chip *chip = data; 382 + struct gpio_chip *gc = &chip->gc; 383 + bool handled = false; 384 + 385 + /* iterate until no interrupt is pending */ 386 + while (true) { 387 + unsigned int uic_int1; 388 + int ret; 389 + unsigned long pending; 390 + int offset; 391 + 392 + ret = regmap_read(chip->map, MAX77759_MAXQ_REG_UIC_INT1, 393 + &uic_int1); 394 + if (ret < 0) { 395 + dev_err_ratelimited(gc->parent, 396 + "failed to read IRQ status: %d\n", 397 + ret); 398 + /* 399 + * If !handled, we have looped not even once, which 400 + * means we should return IRQ_NONE in that case (and 401 + * of course IRQ_HANDLED otherwise). 402 + */ 403 + return IRQ_RETVAL(handled); 404 + } 405 + 406 + pending = uic_int1; 407 + pending &= (MAX77759_MAXQ_REG_UIC_INT1_GPIO6I 408 + | MAX77759_MAXQ_REG_UIC_INT1_GPIO5I); 409 + if (!pending) 410 + break; 411 + 412 + for_each_set_bit(offset, &pending, MAX77759_N_GPIOS) { 413 + /* 414 + * ACK interrupt by writing 1 to bit 'offset', all 415 + * others need to be written as 0. This needs to be 416 + * done unconditionally hence regmap_set_bits() is 417 + * inappropriate here. 418 + */ 419 + regmap_write(chip->map, MAX77759_MAXQ_REG_UIC_INT1, 420 + BIT(offset)); 421 + 422 + handle_nested_irq(irq_find_mapping(gc->irq.domain, 423 + offset)); 424 + 425 + handled = true; 426 + } 427 + } 428 + 429 + return IRQ_RETVAL(handled); 430 + } 431 + 432 + static int max77759_gpio_probe(struct platform_device *pdev) 433 + { 434 + struct max77759_gpio_chip *chip; 435 + int irq; 436 + struct gpio_irq_chip *girq; 437 + int ret; 438 + unsigned long irq_flags; 439 + struct irq_data *irqd; 440 + 441 + chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); 442 + if (!chip) 443 + return -ENOMEM; 444 + 445 + chip->map = dev_get_regmap(pdev->dev.parent, "maxq"); 446 + if (!chip->map) 447 + return dev_err_probe(&pdev->dev, -ENODEV, "Missing regmap\n"); 448 + 449 + irq = platform_get_irq_byname(pdev, "GPI"); 450 + if (irq < 0) 451 + return dev_err_probe(&pdev->dev, irq, "Failed to get IRQ\n"); 452 + 453 + chip->max77759 = dev_get_drvdata(pdev->dev.parent); 454 + ret = devm_mutex_init(&pdev->dev, &chip->maxq_lock); 455 + if (ret) 456 + return ret; 457 + ret = devm_mutex_init(&pdev->dev, &chip->irq_lock); 458 + if (ret) 459 + return ret; 460 + 461 + chip->gc.base = -1; 462 + chip->gc.label = dev_name(&pdev->dev); 463 + chip->gc.parent = &pdev->dev; 464 + chip->gc.can_sleep = true; 465 + 466 + chip->gc.names = max77759_gpio_line_names; 467 + chip->gc.ngpio = MAX77759_N_GPIOS; 468 + chip->gc.get_direction = max77759_gpio_get_direction; 469 + chip->gc.direction_input = max77759_gpio_direction_input; 470 + chip->gc.direction_output = max77759_gpio_direction_output; 471 + chip->gc.get = max77759_gpio_get_value; 472 + chip->gc.set_rv = max77759_gpio_set_value; 473 + 474 + girq = &chip->gc.irq; 475 + gpio_irq_chip_set_chip(girq, &max77759_gpio_irq_chip); 476 + /* This will let us handle the parent IRQ in the driver */ 477 + girq->parent_handler = NULL; 478 + girq->num_parents = 0; 479 + girq->parents = NULL; 480 + girq->default_type = IRQ_TYPE_NONE; 481 + girq->handler = handle_simple_irq; 482 + girq->threaded = true; 483 + 484 + ret = devm_gpiochip_add_data(&pdev->dev, &chip->gc, chip); 485 + if (ret < 0) 486 + return dev_err_probe(&pdev->dev, ret, 487 + "Failed to add GPIO chip\n"); 488 + 489 + irq_flags = IRQF_ONESHOT | IRQF_SHARED; 490 + irqd = irq_get_irq_data(irq); 491 + if (irqd) 492 + irq_flags |= irqd_get_trigger_type(irqd); 493 + 494 + ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, 495 + max77759_gpio_irqhandler, irq_flags, 496 + dev_name(&pdev->dev), chip); 497 + if (ret < 0) 498 + return dev_err_probe(&pdev->dev, ret, 499 + "Failed to request IRQ\n"); 500 + 501 + return ret; 502 + } 503 + 504 + static const struct of_device_id max77759_gpio_of_id[] = { 505 + { .compatible = "maxim,max77759-gpio", }, 506 + { } 507 + }; 508 + MODULE_DEVICE_TABLE(of, max77759_gpio_of_id); 509 + 510 + static const struct platform_device_id max77759_gpio_platform_id[] = { 511 + { "max77759-gpio", }, 512 + { } 513 + }; 514 + MODULE_DEVICE_TABLE(platform, max77759_gpio_platform_id); 515 + 516 + static struct platform_driver max77759_gpio_driver = { 517 + .driver = { 518 + .name = "max77759-gpio", 519 + .probe_type = PROBE_PREFER_ASYNCHRONOUS, 520 + .of_match_table = max77759_gpio_of_id, 521 + }, 522 + .probe = max77759_gpio_probe, 523 + .id_table = max77759_gpio_platform_id, 524 + }; 525 + 526 + module_platform_driver(max77759_gpio_driver); 527 + 528 + MODULE_AUTHOR("André Draszik <andre.draszik@linaro.org>"); 529 + MODULE_DESCRIPTION("GPIO driver for Maxim MAX77759"); 530 + MODULE_LICENSE("GPL");
+20
drivers/mfd/Kconfig
··· 943 943 drivers must be enabled in order to use each functionality of the 944 944 device. 945 945 946 + config MFD_MAX77759 947 + tristate "Maxim Integrated MAX77759 PMIC" 948 + depends on I2C 949 + depends on OF 950 + select IRQ_DOMAIN 951 + select MFD_CORE 952 + select REGMAP_I2C 953 + select REGMAP_IRQ 954 + help 955 + Say yes here to add support for Maxim Integrated MAX77759. 956 + This is a companion Power Management IC for USB Type-C applications 957 + with Battery Charger, Fuel Gauge, temperature sensors, USB Type-C 958 + Port Controller (TCPC), NVMEM, and additional GPIO interfaces. 959 + This driver provides common support for accessing the device; 960 + additional drivers must be enabled in order to use the functionality 961 + of the device. 962 + 963 + To compile this driver as a module, choose M here: the module will be 964 + called max77759. 965 + 946 966 config MFD_MAX77843 947 967 bool "Maxim Semiconductor MAX77843 PMIC Support" 948 968 depends on I2C=y
+1
drivers/mfd/Makefile
··· 169 169 obj-$(CONFIG_MFD_MAX77693) += max77693.o 170 170 obj-$(CONFIG_MFD_MAX77705) += max77705.o 171 171 obj-$(CONFIG_MFD_MAX77714) += max77714.o 172 + obj-$(CONFIG_MFD_MAX77759) += max77759.o 172 173 obj-$(CONFIG_MFD_MAX77843) += max77843.o 173 174 obj-$(CONFIG_MFD_MAX8907) += max8907.o 174 175 max8925-objs := max8925-core.o max8925-i2c.o
+65 -1
drivers/mfd/bcm590xx.c
··· 17 17 #include <linux/regmap.h> 18 18 #include <linux/slab.h> 19 19 20 + /* Under primary I2C address: */ 21 + #define BCM590XX_REG_PMUID 0x1e 22 + 23 + #define BCM590XX_REG_PMUREV 0x1f 24 + #define BCM590XX_PMUREV_DIG_MASK 0xF 25 + #define BCM590XX_PMUREV_DIG_SHIFT 0 26 + #define BCM590XX_PMUREV_ANA_MASK 0xF0 27 + #define BCM590XX_PMUREV_ANA_SHIFT 4 28 + 20 29 static const struct mfd_cell bcm590xx_devs[] = { 21 30 { 22 31 .name = "bcm590xx-vregs", ··· 46 37 .cache_type = REGCACHE_MAPLE, 47 38 }; 48 39 40 + /* Map PMU ID value to model name string */ 41 + static const char * const bcm590xx_names[] = { 42 + [BCM590XX_PMUID_BCM59054] = "BCM59054", 43 + [BCM590XX_PMUID_BCM59056] = "BCM59056", 44 + }; 45 + 46 + static int bcm590xx_parse_version(struct bcm590xx *bcm590xx) 47 + { 48 + unsigned int id, rev; 49 + int ret; 50 + 51 + /* Get PMU ID and verify that it matches compatible */ 52 + ret = regmap_read(bcm590xx->regmap_pri, BCM590XX_REG_PMUID, &id); 53 + if (ret) { 54 + dev_err(bcm590xx->dev, "failed to read PMU ID: %d\n", ret); 55 + return ret; 56 + } 57 + 58 + if (id != bcm590xx->pmu_id) { 59 + dev_err(bcm590xx->dev, "Incorrect ID for %s: expected %x, got %x.\n", 60 + bcm590xx_names[bcm590xx->pmu_id], bcm590xx->pmu_id, id); 61 + return -ENODEV; 62 + } 63 + 64 + /* Get PMU revision and store it in the info struct */ 65 + ret = regmap_read(bcm590xx->regmap_pri, BCM590XX_REG_PMUREV, &rev); 66 + if (ret) { 67 + dev_err(bcm590xx->dev, "failed to read PMU revision: %d\n", ret); 68 + return ret; 69 + } 70 + 71 + bcm590xx->rev_digital = (rev & BCM590XX_PMUREV_DIG_MASK) >> BCM590XX_PMUREV_DIG_SHIFT; 72 + 73 + bcm590xx->rev_analog = (rev & BCM590XX_PMUREV_ANA_MASK) >> BCM590XX_PMUREV_ANA_SHIFT; 74 + 75 + dev_dbg(bcm590xx->dev, "PMU ID 0x%x (%s), revision: digital %d, analog %d", 76 + id, bcm590xx_names[id], bcm590xx->rev_digital, bcm590xx->rev_analog); 77 + 78 + return 0; 79 + } 80 + 49 81 static int bcm590xx_i2c_probe(struct i2c_client *i2c_pri) 50 82 { 51 83 struct bcm590xx *bcm590xx; ··· 99 49 i2c_set_clientdata(i2c_pri, bcm590xx); 100 50 bcm590xx->dev = &i2c_pri->dev; 101 51 bcm590xx->i2c_pri = i2c_pri; 52 + 53 + bcm590xx->pmu_id = (uintptr_t) of_device_get_match_data(bcm590xx->dev); 102 54 103 55 bcm590xx->regmap_pri = devm_regmap_init_i2c(i2c_pri, 104 56 &bcm590xx_regmap_config_pri); ··· 128 76 goto err; 129 77 } 130 78 79 + ret = bcm590xx_parse_version(bcm590xx); 80 + if (ret) 81 + goto err; 82 + 131 83 ret = devm_mfd_add_devices(&i2c_pri->dev, -1, bcm590xx_devs, 132 84 ARRAY_SIZE(bcm590xx_devs), NULL, 0, NULL); 133 85 if (ret < 0) { ··· 147 91 } 148 92 149 93 static const struct of_device_id bcm590xx_of_match[] = { 150 - { .compatible = "brcm,bcm59056" }, 94 + { 95 + .compatible = "brcm,bcm59054", 96 + .data = (void *)BCM590XX_PMUID_BCM59054, 97 + }, 98 + { 99 + .compatible = "brcm,bcm59056", 100 + .data = (void *)BCM590XX_PMUID_BCM59056, 101 + }, 151 102 { } 152 103 }; 153 104 MODULE_DEVICE_TABLE(of, bcm590xx_of_match); 154 105 155 106 static const struct i2c_device_id bcm590xx_i2c_id[] = { 107 + { "bcm59054" }, 156 108 { "bcm59056" }, 157 109 { } 158 110 };
+690
drivers/mfd/max77759.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2020 Google Inc 4 + * Copyright 2025 Linaro Ltd. 5 + * 6 + * Core driver for Maxim MAX77759 companion PMIC for USB Type-C 7 + */ 8 + 9 + #include <linux/array_size.h> 10 + #include <linux/bitfield.h> 11 + #include <linux/bits.h> 12 + #include <linux/cleanup.h> 13 + #include <linux/completion.h> 14 + #include <linux/dev_printk.h> 15 + #include <linux/device.h> 16 + #include <linux/err.h> 17 + #include <linux/i2c.h> 18 + #include <linux/init.h> 19 + #include <linux/interrupt.h> 20 + #include <linux/irq.h> 21 + #include <linux/jiffies.h> 22 + #include <linux/mfd/core.h> 23 + #include <linux/mfd/max77759.h> 24 + #include <linux/mod_devicetable.h> 25 + #include <linux/module.h> 26 + #include <linux/mutex.h> 27 + #include <linux/of.h> 28 + #include <linux/overflow.h> 29 + #include <linux/regmap.h> 30 + 31 + /* Chip ID as per MAX77759_PMIC_REG_PMIC_ID */ 32 + enum { 33 + MAX77759_CHIP_ID = 59, 34 + }; 35 + 36 + enum max77759_i2c_subdev_id { 37 + /* 38 + * These are arbitrary and simply used to match struct 39 + * max77759_i2c_subdev entries to the regmap pointers in struct 40 + * max77759 during probe(). 41 + */ 42 + MAX77759_I2C_SUBDEV_ID_MAXQ, 43 + MAX77759_I2C_SUBDEV_ID_CHARGER, 44 + }; 45 + 46 + struct max77759_i2c_subdev { 47 + enum max77759_i2c_subdev_id id; 48 + const struct regmap_config *cfg; 49 + u16 i2c_address; 50 + }; 51 + 52 + static const struct regmap_range max77759_top_registers[] = { 53 + regmap_reg_range(0x00, 0x02), /* PMIC_ID / PMIC_REVISION / OTP_REVISION */ 54 + regmap_reg_range(0x22, 0x24), /* INTSRC / INTSRCMASK / TOPSYS_INT */ 55 + regmap_reg_range(0x26, 0x26), /* TOPSYS_INT_MASK */ 56 + regmap_reg_range(0x40, 0x40), /* I2C_CNFG */ 57 + regmap_reg_range(0x50, 0x51), /* SWRESET / CONTROL_FG */ 58 + }; 59 + 60 + static const struct regmap_range max77759_top_ro_registers[] = { 61 + regmap_reg_range(0x00, 0x02), 62 + regmap_reg_range(0x22, 0x22), 63 + }; 64 + 65 + static const struct regmap_range max77759_top_volatile_registers[] = { 66 + regmap_reg_range(0x22, 0x22), 67 + regmap_reg_range(0x24, 0x24), 68 + }; 69 + 70 + static const struct regmap_access_table max77759_top_wr_table = { 71 + .yes_ranges = max77759_top_registers, 72 + .n_yes_ranges = ARRAY_SIZE(max77759_top_registers), 73 + .no_ranges = max77759_top_ro_registers, 74 + .n_no_ranges = ARRAY_SIZE(max77759_top_ro_registers), 75 + }; 76 + 77 + static const struct regmap_access_table max77759_top_rd_table = { 78 + .yes_ranges = max77759_top_registers, 79 + .n_yes_ranges = ARRAY_SIZE(max77759_top_registers), 80 + }; 81 + 82 + static const struct regmap_access_table max77759_top_volatile_table = { 83 + .yes_ranges = max77759_top_volatile_registers, 84 + .n_yes_ranges = ARRAY_SIZE(max77759_top_volatile_registers), 85 + }; 86 + 87 + static const struct regmap_config max77759_regmap_config_top = { 88 + .name = "top", 89 + .reg_bits = 8, 90 + .val_bits = 8, 91 + .max_register = MAX77759_PMIC_REG_CONTROL_FG, 92 + .wr_table = &max77759_top_wr_table, 93 + .rd_table = &max77759_top_rd_table, 94 + .volatile_table = &max77759_top_volatile_table, 95 + .num_reg_defaults_raw = MAX77759_PMIC_REG_CONTROL_FG + 1, 96 + .cache_type = REGCACHE_FLAT, 97 + }; 98 + 99 + static const struct regmap_range max77759_maxq_registers[] = { 100 + regmap_reg_range(0x60, 0x73), /* Device ID, Rev, INTx, STATUSx, MASKx */ 101 + regmap_reg_range(0x81, 0xa1), /* AP_DATAOUTx */ 102 + regmap_reg_range(0xb1, 0xd1), /* AP_DATAINx */ 103 + regmap_reg_range(0xe0, 0xe0), /* UIC_SWRST */ 104 + }; 105 + 106 + static const struct regmap_range max77759_maxq_ro_registers[] = { 107 + regmap_reg_range(0x60, 0x63), /* Device ID, Rev */ 108 + regmap_reg_range(0x68, 0x6f), /* STATUSx */ 109 + regmap_reg_range(0xb1, 0xd1), 110 + }; 111 + 112 + static const struct regmap_range max77759_maxq_volatile_registers[] = { 113 + regmap_reg_range(0x64, 0x6f), /* INTx, STATUSx */ 114 + regmap_reg_range(0xb1, 0xd1), 115 + regmap_reg_range(0xe0, 0xe0), 116 + }; 117 + 118 + static const struct regmap_access_table max77759_maxq_wr_table = { 119 + .yes_ranges = max77759_maxq_registers, 120 + .n_yes_ranges = ARRAY_SIZE(max77759_maxq_registers), 121 + .no_ranges = max77759_maxq_ro_registers, 122 + .n_no_ranges = ARRAY_SIZE(max77759_maxq_ro_registers), 123 + }; 124 + 125 + static const struct regmap_access_table max77759_maxq_rd_table = { 126 + .yes_ranges = max77759_maxq_registers, 127 + .n_yes_ranges = ARRAY_SIZE(max77759_maxq_registers), 128 + }; 129 + 130 + static const struct regmap_access_table max77759_maxq_volatile_table = { 131 + .yes_ranges = max77759_maxq_volatile_registers, 132 + .n_yes_ranges = ARRAY_SIZE(max77759_maxq_volatile_registers), 133 + }; 134 + 135 + static const struct regmap_config max77759_regmap_config_maxq = { 136 + .name = "maxq", 137 + .reg_bits = 8, 138 + .val_bits = 8, 139 + .max_register = MAX77759_MAXQ_REG_UIC_SWRST, 140 + .wr_table = &max77759_maxq_wr_table, 141 + .rd_table = &max77759_maxq_rd_table, 142 + .volatile_table = &max77759_maxq_volatile_table, 143 + .num_reg_defaults_raw = MAX77759_MAXQ_REG_UIC_SWRST + 1, 144 + .cache_type = REGCACHE_FLAT, 145 + }; 146 + 147 + static const struct regmap_range max77759_charger_registers[] = { 148 + regmap_reg_range(0xb0, 0xcc), 149 + }; 150 + 151 + static const struct regmap_range max77759_charger_ro_registers[] = { 152 + regmap_reg_range(0xb4, 0xb8), /* INT_OK, DETAILS_0x */ 153 + }; 154 + 155 + static const struct regmap_range max77759_charger_volatile_registers[] = { 156 + regmap_reg_range(0xb0, 0xb1), /* INTx */ 157 + regmap_reg_range(0xb4, 0xb8), 158 + }; 159 + 160 + static const struct regmap_access_table max77759_charger_wr_table = { 161 + .yes_ranges = max77759_charger_registers, 162 + .n_yes_ranges = ARRAY_SIZE(max77759_charger_registers), 163 + .no_ranges = max77759_charger_ro_registers, 164 + .n_no_ranges = ARRAY_SIZE(max77759_charger_ro_registers), 165 + }; 166 + 167 + static const struct regmap_access_table max77759_charger_rd_table = { 168 + .yes_ranges = max77759_charger_registers, 169 + .n_yes_ranges = ARRAY_SIZE(max77759_charger_registers), 170 + }; 171 + 172 + static const struct regmap_access_table max77759_charger_volatile_table = { 173 + .yes_ranges = max77759_charger_volatile_registers, 174 + .n_yes_ranges = ARRAY_SIZE(max77759_charger_volatile_registers), 175 + }; 176 + 177 + static const struct regmap_config max77759_regmap_config_charger = { 178 + .name = "charger", 179 + .reg_bits = 8, 180 + .val_bits = 8, 181 + .max_register = MAX77759_CHGR_REG_CHG_CNFG_19, 182 + .wr_table = &max77759_charger_wr_table, 183 + .rd_table = &max77759_charger_rd_table, 184 + .volatile_table = &max77759_charger_volatile_table, 185 + .num_reg_defaults_raw = MAX77759_CHGR_REG_CHG_CNFG_19 + 1, 186 + .cache_type = REGCACHE_FLAT, 187 + }; 188 + 189 + /* 190 + * Interrupts - with the following interrupt hierarchy: 191 + * pmic IRQs (INTSRC) 192 + * - MAXQ_INT: MaxQ IRQs 193 + * - UIC_INT1 194 + * - APCmdResI 195 + * - SysMsgI 196 + * - GPIOxI 197 + * - TOPSYS_INT: topsys 198 + * - TOPSYS_INT 199 + * - TSHDN_INT 200 + * - SYSOVLO_INT 201 + * - SYSUVLO_INT 202 + * - FSHIP_NOT_RD 203 + * - CHGR_INT: charger 204 + * - CHG_INT 205 + * - CHG_INT2 206 + */ 207 + enum { 208 + MAX77759_INT_MAXQ, 209 + MAX77759_INT_TOPSYS, 210 + MAX77759_INT_CHGR, 211 + }; 212 + 213 + enum { 214 + MAX77759_TOPSYS_INT_TSHDN, 215 + MAX77759_TOPSYS_INT_SYSOVLO, 216 + MAX77759_TOPSYS_INT_SYSUVLO, 217 + MAX77759_TOPSYS_INT_FSHIP_NOT_RD, 218 + }; 219 + 220 + enum { 221 + MAX77759_MAXQ_INT_APCMDRESI, 222 + MAX77759_MAXQ_INT_SYSMSGI, 223 + MAX77759_MAXQ_INT_GPIO, 224 + MAX77759_MAXQ_INT_UIC1, 225 + MAX77759_MAXQ_INT_UIC2, 226 + MAX77759_MAXQ_INT_UIC3, 227 + MAX77759_MAXQ_INT_UIC4, 228 + }; 229 + 230 + enum { 231 + MAX77759_CHARGER_INT_1, 232 + MAX77759_CHARGER_INT_2, 233 + }; 234 + 235 + static const struct regmap_irq max77759_pmic_irqs[] = { 236 + REGMAP_IRQ_REG(MAX77759_INT_MAXQ, 0, MAX77759_PMIC_REG_INTSRC_MAXQ), 237 + REGMAP_IRQ_REG(MAX77759_INT_TOPSYS, 0, MAX77759_PMIC_REG_INTSRC_TOPSYS), 238 + REGMAP_IRQ_REG(MAX77759_INT_CHGR, 0, MAX77759_PMIC_REG_INTSRC_CHGR), 239 + }; 240 + 241 + static const struct regmap_irq max77759_maxq_irqs[] = { 242 + REGMAP_IRQ_REG(MAX77759_MAXQ_INT_APCMDRESI, 0, MAX77759_MAXQ_REG_UIC_INT1_APCMDRESI), 243 + REGMAP_IRQ_REG(MAX77759_MAXQ_INT_SYSMSGI, 0, MAX77759_MAXQ_REG_UIC_INT1_SYSMSGI), 244 + REGMAP_IRQ_REG(MAX77759_MAXQ_INT_GPIO, 0, GENMASK(1, 0)), 245 + REGMAP_IRQ_REG(MAX77759_MAXQ_INT_UIC1, 0, GENMASK(5, 2)), 246 + REGMAP_IRQ_REG(MAX77759_MAXQ_INT_UIC2, 1, GENMASK(7, 0)), 247 + REGMAP_IRQ_REG(MAX77759_MAXQ_INT_UIC3, 2, GENMASK(7, 0)), 248 + REGMAP_IRQ_REG(MAX77759_MAXQ_INT_UIC4, 3, GENMASK(7, 0)), 249 + }; 250 + 251 + static const struct regmap_irq max77759_topsys_irqs[] = { 252 + REGMAP_IRQ_REG(MAX77759_TOPSYS_INT_TSHDN, 0, MAX77759_PMIC_REG_TOPSYS_INT_TSHDN), 253 + REGMAP_IRQ_REG(MAX77759_TOPSYS_INT_SYSOVLO, 0, MAX77759_PMIC_REG_TOPSYS_INT_SYSOVLO), 254 + REGMAP_IRQ_REG(MAX77759_TOPSYS_INT_SYSUVLO, 0, MAX77759_PMIC_REG_TOPSYS_INT_SYSUVLO), 255 + REGMAP_IRQ_REG(MAX77759_TOPSYS_INT_FSHIP_NOT_RD, 0, MAX77759_PMIC_REG_TOPSYS_INT_FSHIP), 256 + }; 257 + 258 + static const struct regmap_irq max77759_chgr_irqs[] = { 259 + REGMAP_IRQ_REG(MAX77759_CHARGER_INT_1, 0, GENMASK(7, 0)), 260 + REGMAP_IRQ_REG(MAX77759_CHARGER_INT_2, 1, GENMASK(7, 0)), 261 + }; 262 + 263 + static const struct regmap_irq_chip max77759_pmic_irq_chip = { 264 + .name = "max77759-pmic", 265 + /* INTSRC is read-only and doesn't require clearing */ 266 + .status_base = MAX77759_PMIC_REG_INTSRC, 267 + .mask_base = MAX77759_PMIC_REG_INTSRCMASK, 268 + .num_regs = 1, 269 + .irqs = max77759_pmic_irqs, 270 + .num_irqs = ARRAY_SIZE(max77759_pmic_irqs), 271 + }; 272 + 273 + /* 274 + * We can let regmap-irq auto-ack the topsys interrupt bits as required, but 275 + * for all others the individual drivers need to know which interrupt bit 276 + * exactly is set inside their interrupt handlers, and therefore we can not set 277 + * .ack_base for those. 278 + */ 279 + static const struct regmap_irq_chip max77759_maxq_irq_chip = { 280 + .name = "max77759-maxq", 281 + .domain_suffix = "MAXQ", 282 + .status_base = MAX77759_MAXQ_REG_UIC_INT1, 283 + .mask_base = MAX77759_MAXQ_REG_UIC_INT1_M, 284 + .num_regs = 4, 285 + .irqs = max77759_maxq_irqs, 286 + .num_irqs = ARRAY_SIZE(max77759_maxq_irqs), 287 + }; 288 + 289 + static const struct regmap_irq_chip max77759_topsys_irq_chip = { 290 + .name = "max77759-topsys", 291 + .domain_suffix = "TOPSYS", 292 + .status_base = MAX77759_PMIC_REG_TOPSYS_INT, 293 + .mask_base = MAX77759_PMIC_REG_TOPSYS_INT_MASK, 294 + .ack_base = MAX77759_PMIC_REG_TOPSYS_INT, 295 + .num_regs = 1, 296 + .irqs = max77759_topsys_irqs, 297 + .num_irqs = ARRAY_SIZE(max77759_topsys_irqs), 298 + }; 299 + 300 + static const struct regmap_irq_chip max77759_chrg_irq_chip = { 301 + .name = "max77759-chgr", 302 + .domain_suffix = "CHGR", 303 + .status_base = MAX77759_CHGR_REG_CHG_INT, 304 + .mask_base = MAX77759_CHGR_REG_CHG_INT_MASK, 305 + .num_regs = 2, 306 + .irqs = max77759_chgr_irqs, 307 + .num_irqs = ARRAY_SIZE(max77759_chgr_irqs), 308 + }; 309 + 310 + static const struct max77759_i2c_subdev max77759_i2c_subdevs[] = { 311 + { 312 + .id = MAX77759_I2C_SUBDEV_ID_MAXQ, 313 + .cfg = &max77759_regmap_config_maxq, 314 + /* I2C address is same as for sub-block 'top' */ 315 + }, 316 + { 317 + .id = MAX77759_I2C_SUBDEV_ID_CHARGER, 318 + .cfg = &max77759_regmap_config_charger, 319 + .i2c_address = 0x69, 320 + }, 321 + }; 322 + 323 + static const struct resource max77759_gpio_resources[] = { 324 + DEFINE_RES_IRQ_NAMED(MAX77759_MAXQ_INT_GPIO, "GPI"), 325 + }; 326 + 327 + static const struct resource max77759_charger_resources[] = { 328 + DEFINE_RES_IRQ_NAMED(MAX77759_CHARGER_INT_1, "INT1"), 329 + DEFINE_RES_IRQ_NAMED(MAX77759_CHARGER_INT_2, "INT2"), 330 + }; 331 + 332 + static const struct mfd_cell max77759_cells[] = { 333 + MFD_CELL_OF("max77759-nvmem", NULL, NULL, 0, 0, 334 + "maxim,max77759-nvmem"), 335 + }; 336 + 337 + static const struct mfd_cell max77759_maxq_cells[] = { 338 + MFD_CELL_OF("max77759-gpio", max77759_gpio_resources, NULL, 0, 0, 339 + "maxim,max77759-gpio"), 340 + }; 341 + 342 + static const struct mfd_cell max77759_charger_cells[] = { 343 + MFD_CELL_RES("max77759-charger", max77759_charger_resources), 344 + }; 345 + 346 + int max77759_maxq_command(struct max77759 *max77759, 347 + const struct max77759_maxq_command *cmd, 348 + struct max77759_maxq_response *rsp) 349 + { 350 + DEFINE_FLEX(struct max77759_maxq_response, _rsp, rsp, length, 1); 351 + struct device *dev = regmap_get_device(max77759->regmap_maxq); 352 + static const unsigned int timeout_ms = 200; 353 + int ret; 354 + 355 + if (cmd->length > MAX77759_MAXQ_OPCODE_MAXLENGTH) 356 + return -EINVAL; 357 + 358 + /* 359 + * As a convenience for API users when issuing simple commands, rsp is 360 + * allowed to be NULL. In that case we need a temporary here to write 361 + * the response to, as we need to verify that the command was indeed 362 + * completed correctly. 363 + */ 364 + if (!rsp) 365 + rsp = _rsp; 366 + 367 + if (!rsp->length || rsp->length > MAX77759_MAXQ_OPCODE_MAXLENGTH) 368 + return -EINVAL; 369 + 370 + guard(mutex)(&max77759->maxq_lock); 371 + 372 + reinit_completion(&max77759->cmd_done); 373 + 374 + /* 375 + * MaxQ latches the message when the DATAOUT32 register is written. If 376 + * cmd->length is shorter we still need to write 0 to it. 377 + */ 378 + ret = regmap_bulk_write(max77759->regmap_maxq, 379 + MAX77759_MAXQ_REG_AP_DATAOUT0, cmd->cmd, 380 + cmd->length); 381 + if (!ret && cmd->length < MAX77759_MAXQ_OPCODE_MAXLENGTH) 382 + ret = regmap_write(max77759->regmap_maxq, 383 + MAX77759_MAXQ_REG_AP_DATAOUT32, 0); 384 + if (ret) { 385 + dev_err(dev, "writing command failed: %d\n", ret); 386 + return ret; 387 + } 388 + 389 + /* Wait for response from MaxQ */ 390 + if (!wait_for_completion_timeout(&max77759->cmd_done, 391 + msecs_to_jiffies(timeout_ms))) { 392 + dev_err(dev, "timed out waiting for response\n"); 393 + return -ETIMEDOUT; 394 + } 395 + 396 + ret = regmap_bulk_read(max77759->regmap_maxq, 397 + MAX77759_MAXQ_REG_AP_DATAIN0, 398 + rsp->rsp, rsp->length); 399 + if (ret) { 400 + dev_err(dev, "reading response failed: %d\n", ret); 401 + return ret; 402 + } 403 + 404 + /* 405 + * As per the protocol, the first byte of the reply will match the 406 + * request. 407 + */ 408 + if (cmd->cmd[0] != rsp->rsp[0]) { 409 + dev_err(dev, "unexpected opcode response for %#.2x: %*ph\n", 410 + cmd->cmd[0], (int)rsp->length, rsp->rsp); 411 + return -EIO; 412 + } 413 + 414 + return 0; 415 + } 416 + EXPORT_SYMBOL_GPL(max77759_maxq_command); 417 + 418 + static irqreturn_t apcmdres_irq_handler(int irq, void *irq_data) 419 + { 420 + struct max77759 *max77759 = irq_data; 421 + 422 + regmap_write(max77759->regmap_maxq, MAX77759_MAXQ_REG_UIC_INT1, 423 + MAX77759_MAXQ_REG_UIC_INT1_APCMDRESI); 424 + 425 + complete(&max77759->cmd_done); 426 + 427 + return IRQ_HANDLED; 428 + } 429 + 430 + static int max77759_create_i2c_subdev(struct i2c_client *client, 431 + struct max77759 *max77759, 432 + const struct max77759_i2c_subdev *sd) 433 + { 434 + struct i2c_client *sub; 435 + struct regmap *regmap; 436 + int ret; 437 + 438 + /* 439 + * If 'sd' has an I2C address, 'sub' will be assigned a new 'dummy' 440 + * device, otherwise use it as-is. 441 + */ 442 + sub = client; 443 + if (sd->i2c_address) { 444 + sub = devm_i2c_new_dummy_device(&client->dev, 445 + client->adapter, 446 + sd->i2c_address); 447 + 448 + if (IS_ERR(sub)) 449 + return dev_err_probe(&client->dev, PTR_ERR(sub), 450 + "failed to claim I2C device %s\n", 451 + sd->cfg->name); 452 + } 453 + 454 + regmap = devm_regmap_init_i2c(sub, sd->cfg); 455 + if (IS_ERR(regmap)) 456 + return dev_err_probe(&sub->dev, PTR_ERR(regmap), 457 + "regmap init for '%s' failed\n", 458 + sd->cfg->name); 459 + 460 + ret = regmap_attach_dev(&client->dev, regmap, sd->cfg); 461 + if (ret) 462 + return dev_err_probe(&client->dev, ret, 463 + "regmap attach of '%s' failed\n", 464 + sd->cfg->name); 465 + 466 + if (sd->id == MAX77759_I2C_SUBDEV_ID_MAXQ) 467 + max77759->regmap_maxq = regmap; 468 + else if (sd->id == MAX77759_I2C_SUBDEV_ID_CHARGER) 469 + max77759->regmap_charger = regmap; 470 + 471 + return 0; 472 + } 473 + 474 + static int max77759_add_chained_irq_chip(struct device *dev, 475 + struct regmap *regmap, 476 + int pirq, 477 + struct regmap_irq_chip_data *parent, 478 + const struct regmap_irq_chip *chip, 479 + struct regmap_irq_chip_data **data) 480 + { 481 + int irq, ret; 482 + 483 + irq = regmap_irq_get_virq(parent, pirq); 484 + if (irq < 0) 485 + return dev_err_probe(dev, irq, 486 + "failed to get parent vIRQ(%d) for chip %s\n", 487 + pirq, chip->name); 488 + 489 + ret = devm_regmap_add_irq_chip(dev, regmap, irq, 490 + IRQF_ONESHOT | IRQF_SHARED, 0, chip, 491 + data); 492 + if (ret) 493 + return dev_err_probe(dev, ret, "failed to add %s IRQ chip\n", 494 + chip->name); 495 + 496 + return 0; 497 + } 498 + 499 + static int max77759_add_chained_maxq(struct i2c_client *client, 500 + struct max77759 *max77759, 501 + struct regmap_irq_chip_data *parent) 502 + { 503 + struct regmap_irq_chip_data *irq_chip_data; 504 + int apcmdres_irq; 505 + int ret; 506 + 507 + ret = max77759_add_chained_irq_chip(&client->dev, 508 + max77759->regmap_maxq, 509 + MAX77759_INT_MAXQ, 510 + parent, 511 + &max77759_maxq_irq_chip, 512 + &irq_chip_data); 513 + if (ret) 514 + return ret; 515 + 516 + init_completion(&max77759->cmd_done); 517 + apcmdres_irq = regmap_irq_get_virq(irq_chip_data, 518 + MAX77759_MAXQ_INT_APCMDRESI); 519 + 520 + ret = devm_request_threaded_irq(&client->dev, apcmdres_irq, 521 + NULL, apcmdres_irq_handler, 522 + IRQF_ONESHOT | IRQF_SHARED, 523 + dev_name(&client->dev), max77759); 524 + if (ret) 525 + return dev_err_probe(&client->dev, ret, 526 + "MAX77759_MAXQ_INT_APCMDRESI failed\n"); 527 + 528 + ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_AUTO, 529 + max77759_maxq_cells, 530 + ARRAY_SIZE(max77759_maxq_cells), 531 + NULL, 0, 532 + regmap_irq_get_domain(irq_chip_data)); 533 + if (ret) 534 + return dev_err_probe(&client->dev, ret, 535 + "failed to add child devices (MaxQ)\n"); 536 + 537 + return 0; 538 + } 539 + 540 + static int max77759_add_chained_topsys(struct i2c_client *client, 541 + struct max77759 *max77759, 542 + struct regmap_irq_chip_data *parent) 543 + { 544 + struct regmap_irq_chip_data *irq_chip_data; 545 + int ret; 546 + 547 + ret = max77759_add_chained_irq_chip(&client->dev, 548 + max77759->regmap_top, 549 + MAX77759_INT_TOPSYS, 550 + parent, 551 + &max77759_topsys_irq_chip, 552 + &irq_chip_data); 553 + if (ret) 554 + return ret; 555 + 556 + return 0; 557 + } 558 + 559 + static int max77759_add_chained_charger(struct i2c_client *client, 560 + struct max77759 *max77759, 561 + struct regmap_irq_chip_data *parent) 562 + { 563 + struct regmap_irq_chip_data *irq_chip_data; 564 + int ret; 565 + 566 + ret = max77759_add_chained_irq_chip(&client->dev, 567 + max77759->regmap_charger, 568 + MAX77759_INT_CHGR, 569 + parent, 570 + &max77759_chrg_irq_chip, 571 + &irq_chip_data); 572 + if (ret) 573 + return ret; 574 + 575 + ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_AUTO, 576 + max77759_charger_cells, 577 + ARRAY_SIZE(max77759_charger_cells), 578 + NULL, 0, 579 + regmap_irq_get_domain(irq_chip_data)); 580 + if (ret) 581 + return dev_err_probe(&client->dev, ret, 582 + "failed to add child devices (charger)\n"); 583 + 584 + return 0; 585 + } 586 + 587 + static int max77759_probe(struct i2c_client *client) 588 + { 589 + struct regmap_irq_chip_data *irq_chip_data_pmic; 590 + struct irq_data *irq_data; 591 + struct max77759 *max77759; 592 + unsigned long irq_flags; 593 + unsigned int pmic_id; 594 + int ret; 595 + 596 + max77759 = devm_kzalloc(&client->dev, sizeof(*max77759), GFP_KERNEL); 597 + if (!max77759) 598 + return -ENOMEM; 599 + 600 + i2c_set_clientdata(client, max77759); 601 + 602 + max77759->regmap_top = devm_regmap_init_i2c(client, 603 + &max77759_regmap_config_top); 604 + if (IS_ERR(max77759->regmap_top)) 605 + return dev_err_probe(&client->dev, PTR_ERR(max77759->regmap_top), 606 + "regmap init for '%s' failed\n", 607 + max77759_regmap_config_top.name); 608 + 609 + ret = regmap_read(max77759->regmap_top, 610 + MAX77759_PMIC_REG_PMIC_ID, &pmic_id); 611 + if (ret) 612 + return dev_err_probe(&client->dev, ret, 613 + "unable to read device ID\n"); 614 + 615 + if (pmic_id != MAX77759_CHIP_ID) 616 + return dev_err_probe(&client->dev, -ENODEV, 617 + "unsupported device ID %#.2x (%d)\n", 618 + pmic_id, pmic_id); 619 + 620 + ret = devm_mutex_init(&client->dev, &max77759->maxq_lock); 621 + if (ret) 622 + return ret; 623 + 624 + for (int i = 0; i < ARRAY_SIZE(max77759_i2c_subdevs); i++) { 625 + ret = max77759_create_i2c_subdev(client, max77759, 626 + &max77759_i2c_subdevs[i]); 627 + if (ret) 628 + return ret; 629 + } 630 + 631 + irq_data = irq_get_irq_data(client->irq); 632 + if (!irq_data) 633 + return dev_err_probe(&client->dev, -EINVAL, 634 + "invalid IRQ: %d\n", client->irq); 635 + 636 + irq_flags = IRQF_ONESHOT | IRQF_SHARED; 637 + irq_flags |= irqd_get_trigger_type(irq_data); 638 + 639 + ret = devm_regmap_add_irq_chip(&client->dev, max77759->regmap_top, 640 + client->irq, irq_flags, 0, 641 + &max77759_pmic_irq_chip, 642 + &irq_chip_data_pmic); 643 + if (ret) 644 + return dev_err_probe(&client->dev, ret, 645 + "failed to add IRQ chip '%s'\n", 646 + max77759_pmic_irq_chip.name); 647 + 648 + ret = max77759_add_chained_maxq(client, max77759, irq_chip_data_pmic); 649 + if (ret) 650 + return ret; 651 + 652 + ret = max77759_add_chained_topsys(client, max77759, irq_chip_data_pmic); 653 + if (ret) 654 + return ret; 655 + 656 + ret = max77759_add_chained_charger(client, max77759, irq_chip_data_pmic); 657 + if (ret) 658 + return ret; 659 + 660 + return devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_AUTO, 661 + max77759_cells, ARRAY_SIZE(max77759_cells), 662 + NULL, 0, 663 + regmap_irq_get_domain(irq_chip_data_pmic)); 664 + } 665 + 666 + static const struct i2c_device_id max77759_i2c_id[] = { 667 + { "max77759" }, 668 + { } 669 + }; 670 + MODULE_DEVICE_TABLE(i2c, max77759_i2c_id); 671 + 672 + static const struct of_device_id max77759_of_id[] = { 673 + { .compatible = "maxim,max77759", }, 674 + { } 675 + }; 676 + MODULE_DEVICE_TABLE(of, max77759_of_id); 677 + 678 + static struct i2c_driver max77759_i2c_driver = { 679 + .driver = { 680 + .name = "max77759", 681 + .of_match_table = max77759_of_id, 682 + }, 683 + .probe = max77759_probe, 684 + .id_table = max77759_i2c_id, 685 + }; 686 + module_i2c_driver(max77759_i2c_driver); 687 + 688 + MODULE_AUTHOR("André Draszik <andre.draszik@linaro.org>"); 689 + MODULE_DESCRIPTION("Maxim MAX77759 core driver"); 690 + MODULE_LICENSE("GPL");
+423 -110
drivers/mfd/rohm-bd96801.c
··· 38 38 #include <linux/types.h> 39 39 40 40 #include <linux/mfd/rohm-bd96801.h> 41 + #include <linux/mfd/rohm-bd96802.h> 41 42 #include <linux/mfd/rohm-generic.h> 42 43 43 - static const struct resource regulator_errb_irqs[] = { 44 - DEFINE_RES_IRQ_NAMED(BD96801_OTP_ERR_STAT, "bd96801-otp-err"), 45 - DEFINE_RES_IRQ_NAMED(BD96801_DBIST_ERR_STAT, "bd96801-dbist-err"), 46 - DEFINE_RES_IRQ_NAMED(BD96801_EEP_ERR_STAT, "bd96801-eep-err"), 47 - DEFINE_RES_IRQ_NAMED(BD96801_ABIST_ERR_STAT, "bd96801-abist-err"), 48 - DEFINE_RES_IRQ_NAMED(BD96801_PRSTB_ERR_STAT, "bd96801-prstb-err"), 49 - DEFINE_RES_IRQ_NAMED(BD96801_DRMOS1_ERR_STAT, "bd96801-drmoserr1"), 50 - DEFINE_RES_IRQ_NAMED(BD96801_DRMOS2_ERR_STAT, "bd96801-drmoserr2"), 51 - DEFINE_RES_IRQ_NAMED(BD96801_SLAVE_ERR_STAT, "bd96801-slave-err"), 52 - DEFINE_RES_IRQ_NAMED(BD96801_VREF_ERR_STAT, "bd96801-vref-err"), 53 - DEFINE_RES_IRQ_NAMED(BD96801_TSD_ERR_STAT, "bd96801-tsd"), 54 - DEFINE_RES_IRQ_NAMED(BD96801_UVLO_ERR_STAT, "bd96801-uvlo-err"), 55 - DEFINE_RES_IRQ_NAMED(BD96801_OVLO_ERR_STAT, "bd96801-ovlo-err"), 56 - DEFINE_RES_IRQ_NAMED(BD96801_OSC_ERR_STAT, "bd96801-osc-err"), 57 - DEFINE_RES_IRQ_NAMED(BD96801_PON_ERR_STAT, "bd96801-pon-err"), 58 - DEFINE_RES_IRQ_NAMED(BD96801_POFF_ERR_STAT, "bd96801-poff-err"), 59 - DEFINE_RES_IRQ_NAMED(BD96801_CMD_SHDN_ERR_STAT, "bd96801-cmd-shdn-err"), 44 + struct bd968xx { 45 + const struct resource *errb_irqs; 46 + const struct resource *intb_irqs; 47 + int num_errb_irqs; 48 + int num_intb_irqs; 49 + const struct regmap_irq_chip *errb_irq_chip; 50 + const struct regmap_irq_chip *intb_irq_chip; 51 + const struct regmap_config *regmap_config; 52 + struct mfd_cell *cells; 53 + int num_cells; 54 + int unlock_reg; 55 + int unlock_val; 56 + }; 57 + 58 + static const struct resource bd96801_reg_errb_irqs[] = { 59 + DEFINE_RES_IRQ_NAMED(BD96801_OTP_ERR_STAT, "otp-err"), 60 + DEFINE_RES_IRQ_NAMED(BD96801_DBIST_ERR_STAT, "dbist-err"), 61 + DEFINE_RES_IRQ_NAMED(BD96801_EEP_ERR_STAT, "eep-err"), 62 + DEFINE_RES_IRQ_NAMED(BD96801_ABIST_ERR_STAT, "abist-err"), 63 + DEFINE_RES_IRQ_NAMED(BD96801_PRSTB_ERR_STAT, "prstb-err"), 64 + DEFINE_RES_IRQ_NAMED(BD96801_DRMOS1_ERR_STAT, "drmoserr1"), 65 + DEFINE_RES_IRQ_NAMED(BD96801_DRMOS2_ERR_STAT, "drmoserr2"), 66 + DEFINE_RES_IRQ_NAMED(BD96801_SLAVE_ERR_STAT, "slave-err"), 67 + DEFINE_RES_IRQ_NAMED(BD96801_VREF_ERR_STAT, "vref-err"), 68 + DEFINE_RES_IRQ_NAMED(BD96801_TSD_ERR_STAT, "tsd"), 69 + DEFINE_RES_IRQ_NAMED(BD96801_UVLO_ERR_STAT, "uvlo-err"), 70 + DEFINE_RES_IRQ_NAMED(BD96801_OVLO_ERR_STAT, "ovlo-err"), 71 + DEFINE_RES_IRQ_NAMED(BD96801_OSC_ERR_STAT, "osc-err"), 72 + DEFINE_RES_IRQ_NAMED(BD96801_PON_ERR_STAT, "pon-err"), 73 + DEFINE_RES_IRQ_NAMED(BD96801_POFF_ERR_STAT, "poff-err"), 74 + DEFINE_RES_IRQ_NAMED(BD96801_CMD_SHDN_ERR_STAT, "cmd-shdn-err"), 60 75 61 76 DEFINE_RES_IRQ_NAMED(BD96801_INT_PRSTB_WDT_ERR, "bd96801-prstb-wdt-err"), 62 77 DEFINE_RES_IRQ_NAMED(BD96801_INT_CHIP_IF_ERR, "bd96801-chip-if-err"), 63 - DEFINE_RES_IRQ_NAMED(BD96801_INT_SHDN_ERR_STAT, "bd96801-int-shdn-err"), 64 78 65 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_PVIN_ERR_STAT, "bd96801-buck1-pvin-err"), 66 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OVP_ERR_STAT, "bd96801-buck1-ovp-err"), 67 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_UVP_ERR_STAT, "bd96801-buck1-uvp-err"), 68 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_SHDN_ERR_STAT, "bd96801-buck1-shdn-err"), 79 + DEFINE_RES_IRQ_NAMED(BD96801_INT_SHDN_ERR_STAT, "int-shdn-err"), 69 80 70 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_PVIN_ERR_STAT, "bd96801-buck2-pvin-err"), 71 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OVP_ERR_STAT, "bd96801-buck2-ovp-err"), 72 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_UVP_ERR_STAT, "bd96801-buck2-uvp-err"), 73 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_SHDN_ERR_STAT, "bd96801-buck2-shdn-err"), 81 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_PVIN_ERR_STAT, "buck1-pvin-err"), 82 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OVP_ERR_STAT, "buck1-ovp-err"), 83 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_UVP_ERR_STAT, "buck1-uvp-err"), 84 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_SHDN_ERR_STAT, "buck1-shdn-err"), 74 85 75 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_PVIN_ERR_STAT, "bd96801-buck3-pvin-err"), 76 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OVP_ERR_STAT, "bd96801-buck3-ovp-err"), 77 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_UVP_ERR_STAT, "bd96801-buck3-uvp-err"), 78 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_SHDN_ERR_STAT, "bd96801-buck3-shdn-err"), 86 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_PVIN_ERR_STAT, "buck2-pvin-err"), 87 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OVP_ERR_STAT, "buck2-ovp-err"), 88 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_UVP_ERR_STAT, "buck2-uvp-err"), 89 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_SHDN_ERR_STAT, "buck2-shdn-err"), 79 90 80 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_PVIN_ERR_STAT, "bd96801-buck4-pvin-err"), 81 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OVP_ERR_STAT, "bd96801-buck4-ovp-err"), 82 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_UVP_ERR_STAT, "bd96801-buck4-uvp-err"), 83 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_SHDN_ERR_STAT, "bd96801-buck4-shdn-err"), 91 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_PVIN_ERR_STAT, "buck3-pvin-err"), 92 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OVP_ERR_STAT, "buck3-ovp-err"), 93 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_UVP_ERR_STAT, "buck3-uvp-err"), 94 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_SHDN_ERR_STAT, "buck3-shdn-err"), 84 95 85 - DEFINE_RES_IRQ_NAMED(BD96801_LDO5_PVIN_ERR_STAT, "bd96801-ldo5-pvin-err"), 86 - DEFINE_RES_IRQ_NAMED(BD96801_LDO5_OVP_ERR_STAT, "bd96801-ldo5-ovp-err"), 87 - DEFINE_RES_IRQ_NAMED(BD96801_LDO5_UVP_ERR_STAT, "bd96801-ldo5-uvp-err"), 88 - DEFINE_RES_IRQ_NAMED(BD96801_LDO5_SHDN_ERR_STAT, "bd96801-ldo5-shdn-err"), 96 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_PVIN_ERR_STAT, "buck4-pvin-err"), 97 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OVP_ERR_STAT, "buck4-ovp-err"), 98 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_UVP_ERR_STAT, "buck4-uvp-err"), 99 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_SHDN_ERR_STAT, "buck4-shdn-err"), 89 100 90 - DEFINE_RES_IRQ_NAMED(BD96801_LDO6_PVIN_ERR_STAT, "bd96801-ldo6-pvin-err"), 91 - DEFINE_RES_IRQ_NAMED(BD96801_LDO6_OVP_ERR_STAT, "bd96801-ldo6-ovp-err"), 92 - DEFINE_RES_IRQ_NAMED(BD96801_LDO6_UVP_ERR_STAT, "bd96801-ldo6-uvp-err"), 93 - DEFINE_RES_IRQ_NAMED(BD96801_LDO6_SHDN_ERR_STAT, "bd96801-ldo6-shdn-err"), 101 + DEFINE_RES_IRQ_NAMED(BD96801_LDO5_PVIN_ERR_STAT, "ldo5-pvin-err"), 102 + DEFINE_RES_IRQ_NAMED(BD96801_LDO5_OVP_ERR_STAT, "ldo5-ovp-err"), 103 + DEFINE_RES_IRQ_NAMED(BD96801_LDO5_UVP_ERR_STAT, "ldo5-uvp-err"), 104 + DEFINE_RES_IRQ_NAMED(BD96801_LDO5_SHDN_ERR_STAT, "ldo5-shdn-err"), 94 105 95 - DEFINE_RES_IRQ_NAMED(BD96801_LDO7_PVIN_ERR_STAT, "bd96801-ldo7-pvin-err"), 96 - DEFINE_RES_IRQ_NAMED(BD96801_LDO7_OVP_ERR_STAT, "bd96801-ldo7-ovp-err"), 97 - DEFINE_RES_IRQ_NAMED(BD96801_LDO7_UVP_ERR_STAT, "bd96801-ldo7-uvp-err"), 98 - DEFINE_RES_IRQ_NAMED(BD96801_LDO7_SHDN_ERR_STAT, "bd96801-ldo7-shdn-err"), 106 + DEFINE_RES_IRQ_NAMED(BD96801_LDO6_PVIN_ERR_STAT, "ldo6-pvin-err"), 107 + DEFINE_RES_IRQ_NAMED(BD96801_LDO6_OVP_ERR_STAT, "ldo6-ovp-err"), 108 + DEFINE_RES_IRQ_NAMED(BD96801_LDO6_UVP_ERR_STAT, "ldo6-uvp-err"), 109 + DEFINE_RES_IRQ_NAMED(BD96801_LDO6_SHDN_ERR_STAT, "ldo6-shdn-err"), 110 + 111 + DEFINE_RES_IRQ_NAMED(BD96801_LDO7_PVIN_ERR_STAT, "ldo7-pvin-err"), 112 + DEFINE_RES_IRQ_NAMED(BD96801_LDO7_OVP_ERR_STAT, "ldo7-ovp-err"), 113 + DEFINE_RES_IRQ_NAMED(BD96801_LDO7_UVP_ERR_STAT, "ldo7-uvp-err"), 114 + DEFINE_RES_IRQ_NAMED(BD96801_LDO7_SHDN_ERR_STAT, "ldo7-shdn-err"), 99 115 }; 100 116 101 - static const struct resource regulator_intb_irqs[] = { 102 - DEFINE_RES_IRQ_NAMED(BD96801_TW_STAT, "bd96801-core-thermal"), 117 + static const struct resource bd96802_reg_errb_irqs[] = { 118 + DEFINE_RES_IRQ_NAMED(BD96802_OTP_ERR_STAT, "otp-err"), 119 + DEFINE_RES_IRQ_NAMED(BD96802_DBIST_ERR_STAT, "dbist-err"), 120 + DEFINE_RES_IRQ_NAMED(BD96802_EEP_ERR_STAT, "eep-err"), 121 + DEFINE_RES_IRQ_NAMED(BD96802_ABIST_ERR_STAT, "abist-err"), 122 + DEFINE_RES_IRQ_NAMED(BD96802_PRSTB_ERR_STAT, "prstb-err"), 123 + DEFINE_RES_IRQ_NAMED(BD96802_DRMOS1_ERR_STAT, "drmoserr1"), 124 + DEFINE_RES_IRQ_NAMED(BD96802_DRMOS1_ERR_STAT, "drmoserr2"), 125 + DEFINE_RES_IRQ_NAMED(BD96802_SLAVE_ERR_STAT, "slave-err"), 126 + DEFINE_RES_IRQ_NAMED(BD96802_VREF_ERR_STAT, "vref-err"), 127 + DEFINE_RES_IRQ_NAMED(BD96802_TSD_ERR_STAT, "tsd"), 128 + DEFINE_RES_IRQ_NAMED(BD96802_UVLO_ERR_STAT, "uvlo-err"), 129 + DEFINE_RES_IRQ_NAMED(BD96802_OVLO_ERR_STAT, "ovlo-err"), 130 + DEFINE_RES_IRQ_NAMED(BD96802_OSC_ERR_STAT, "osc-err"), 131 + DEFINE_RES_IRQ_NAMED(BD96802_PON_ERR_STAT, "pon-err"), 132 + DEFINE_RES_IRQ_NAMED(BD96802_POFF_ERR_STAT, "poff-err"), 133 + DEFINE_RES_IRQ_NAMED(BD96802_CMD_SHDN_ERR_STAT, "cmd-shdn-err"), 134 + DEFINE_RES_IRQ_NAMED(BD96802_INT_SHDN_ERR_STAT, "int-shdn-err"), 103 135 104 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OCPH_STAT, "bd96801-buck1-overcurr-h"), 105 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OCPL_STAT, "bd96801-buck1-overcurr-l"), 106 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OCPN_STAT, "bd96801-buck1-overcurr-n"), 107 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OVD_STAT, "bd96801-buck1-overvolt"), 108 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_UVD_STAT, "bd96801-buck1-undervolt"), 109 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_TW_CH_STAT, "bd96801-buck1-thermal"), 136 + DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_PVIN_ERR_STAT, "buck1-pvin-err"), 137 + DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_OVP_ERR_STAT, "buck1-ovp-err"), 138 + DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_UVP_ERR_STAT, "buck1-uvp-err"), 139 + DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_SHDN_ERR_STAT, "buck1-shdn-err"), 110 140 111 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OCPH_STAT, "bd96801-buck2-overcurr-h"), 112 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OCPL_STAT, "bd96801-buck2-overcurr-l"), 113 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OCPN_STAT, "bd96801-buck2-overcurr-n"), 114 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OVD_STAT, "bd96801-buck2-overvolt"), 115 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_UVD_STAT, "bd96801-buck2-undervolt"), 116 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_TW_CH_STAT, "bd96801-buck2-thermal"), 141 + DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_PVIN_ERR_STAT, "buck2-pvin-err"), 142 + DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_OVP_ERR_STAT, "buck2-ovp-err"), 143 + DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_UVP_ERR_STAT, "buck2-uvp-err"), 144 + DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_SHDN_ERR_STAT, "buck2-shdn-err"), 145 + }; 117 146 118 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OCPH_STAT, "bd96801-buck3-overcurr-h"), 119 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OCPL_STAT, "bd96801-buck3-overcurr-l"), 120 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OCPN_STAT, "bd96801-buck3-overcurr-n"), 121 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OVD_STAT, "bd96801-buck3-overvolt"), 122 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_UVD_STAT, "bd96801-buck3-undervolt"), 123 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_TW_CH_STAT, "bd96801-buck3-thermal"), 147 + static const struct resource bd96801_reg_intb_irqs[] = { 148 + DEFINE_RES_IRQ_NAMED(BD96801_TW_STAT, "core-thermal"), 124 149 125 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OCPH_STAT, "bd96801-buck4-overcurr-h"), 126 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OCPL_STAT, "bd96801-buck4-overcurr-l"), 127 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OCPN_STAT, "bd96801-buck4-overcurr-n"), 128 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OVD_STAT, "bd96801-buck4-overvolt"), 129 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_UVD_STAT, "bd96801-buck4-undervolt"), 130 - DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_TW_CH_STAT, "bd96801-buck4-thermal"), 150 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OCPH_STAT, "buck1-overcurr-h"), 151 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OCPL_STAT, "buck1-overcurr-l"), 152 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OCPN_STAT, "buck1-overcurr-n"), 153 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_OVD_STAT, "buck1-overvolt"), 154 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_UVD_STAT, "buck1-undervolt"), 155 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK1_TW_CH_STAT, "buck1-thermal"), 131 156 132 - DEFINE_RES_IRQ_NAMED(BD96801_LDO5_OCPH_STAT, "bd96801-ldo5-overcurr"), 133 - DEFINE_RES_IRQ_NAMED(BD96801_LDO5_OVD_STAT, "bd96801-ldo5-overvolt"), 134 - DEFINE_RES_IRQ_NAMED(BD96801_LDO5_UVD_STAT, "bd96801-ldo5-undervolt"), 157 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OCPH_STAT, "buck2-overcurr-h"), 158 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OCPL_STAT, "buck2-overcurr-l"), 159 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OCPN_STAT, "buck2-overcurr-n"), 160 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_OVD_STAT, "buck2-overvolt"), 161 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_UVD_STAT, "buck2-undervolt"), 162 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK2_TW_CH_STAT, "buck2-thermal"), 135 163 136 - DEFINE_RES_IRQ_NAMED(BD96801_LDO6_OCPH_STAT, "bd96801-ldo6-overcurr"), 137 - DEFINE_RES_IRQ_NAMED(BD96801_LDO6_OVD_STAT, "bd96801-ldo6-overvolt"), 138 - DEFINE_RES_IRQ_NAMED(BD96801_LDO6_UVD_STAT, "bd96801-ldo6-undervolt"), 164 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OCPH_STAT, "buck3-overcurr-h"), 165 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OCPL_STAT, "buck3-overcurr-l"), 166 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OCPN_STAT, "buck3-overcurr-n"), 167 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_OVD_STAT, "buck3-overvolt"), 168 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_UVD_STAT, "buck3-undervolt"), 169 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK3_TW_CH_STAT, "buck3-thermal"), 139 170 140 - DEFINE_RES_IRQ_NAMED(BD96801_LDO7_OCPH_STAT, "bd96801-ldo7-overcurr"), 141 - DEFINE_RES_IRQ_NAMED(BD96801_LDO7_OVD_STAT, "bd96801-ldo7-overvolt"), 142 - DEFINE_RES_IRQ_NAMED(BD96801_LDO7_UVD_STAT, "bd96801-ldo7-undervolt"), 171 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OCPH_STAT, "buck4-overcurr-h"), 172 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OCPL_STAT, "buck4-overcurr-l"), 173 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OCPN_STAT, "buck4-overcurr-n"), 174 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_OVD_STAT, "buck4-overvolt"), 175 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_UVD_STAT, "buck4-undervolt"), 176 + DEFINE_RES_IRQ_NAMED(BD96801_BUCK4_TW_CH_STAT, "buck4-thermal"), 177 + 178 + DEFINE_RES_IRQ_NAMED(BD96801_LDO5_OCPH_STAT, "ldo5-overcurr"), 179 + DEFINE_RES_IRQ_NAMED(BD96801_LDO5_OVD_STAT, "ldo5-overvolt"), 180 + DEFINE_RES_IRQ_NAMED(BD96801_LDO5_UVD_STAT, "ldo5-undervolt"), 181 + 182 + DEFINE_RES_IRQ_NAMED(BD96801_LDO6_OCPH_STAT, "ldo6-overcurr"), 183 + DEFINE_RES_IRQ_NAMED(BD96801_LDO6_OVD_STAT, "ldo6-overvolt"), 184 + DEFINE_RES_IRQ_NAMED(BD96801_LDO6_UVD_STAT, "ldo6-undervolt"), 185 + 186 + DEFINE_RES_IRQ_NAMED(BD96801_LDO7_OCPH_STAT, "ldo7-overcurr"), 187 + DEFINE_RES_IRQ_NAMED(BD96801_LDO7_OVD_STAT, "ldo7-overvolt"), 188 + DEFINE_RES_IRQ_NAMED(BD96801_LDO7_UVD_STAT, "ldo7-undervolt"), 189 + }; 190 + 191 + static const struct resource bd96802_reg_intb_irqs[] = { 192 + DEFINE_RES_IRQ_NAMED(BD96802_TW_STAT, "core-thermal"), 193 + 194 + DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_OCPH_STAT, "buck1-overcurr-h"), 195 + DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_OCPL_STAT, "buck1-overcurr-l"), 196 + DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_OCPN_STAT, "buck1-overcurr-n"), 197 + DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_OVD_STAT, "buck1-overvolt"), 198 + DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_UVD_STAT, "buck1-undervolt"), 199 + DEFINE_RES_IRQ_NAMED(BD96802_BUCK1_TW_CH_STAT, "buck1-thermal"), 200 + 201 + DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_OCPH_STAT, "buck2-overcurr-h"), 202 + DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_OCPL_STAT, "buck2-overcurr-l"), 203 + DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_OCPN_STAT, "buck2-overcurr-n"), 204 + DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_OVD_STAT, "buck2-overvolt"), 205 + DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_UVD_STAT, "buck2-undervolt"), 206 + DEFINE_RES_IRQ_NAMED(BD96802_BUCK2_TW_CH_STAT, "buck2-thermal"), 143 207 }; 144 208 145 209 enum { ··· 214 150 static struct mfd_cell bd96801_cells[] = { 215 151 [WDG_CELL] = { .name = "bd96801-wdt", }, 216 152 [REGULATOR_CELL] = { .name = "bd96801-regulator", }, 153 + }; 154 + 155 + static struct mfd_cell bd96802_cells[] = { 156 + [WDG_CELL] = { .name = "bd96801-wdt", }, 157 + [REGULATOR_CELL] = { .name = "bd96802-regulator", }, 158 + }; 159 + static struct mfd_cell bd96805_cells[] = { 160 + [WDG_CELL] = { .name = "bd96801-wdt", }, 161 + [REGULATOR_CELL] = { .name = "bd96805-regulator", }, 162 + }; 163 + 164 + static struct mfd_cell bd96806_cells[] = { 165 + [WDG_CELL] = { .name = "bd96806-wdt", }, 166 + [REGULATOR_CELL] = { .name = "bd96806-regulator", }, 217 167 }; 218 168 219 169 static const struct regmap_range bd96801_volatile_ranges[] = { ··· 247 169 regmap_reg_range(BD96801_LDO5_VOL_LVL_REG, BD96801_LDO7_VOL_LVL_REG), 248 170 }; 249 171 250 - static const struct regmap_access_table volatile_regs = { 172 + static const struct regmap_range bd96802_volatile_ranges[] = { 173 + /* Status regs */ 174 + regmap_reg_range(BD96801_REG_WD_FEED, BD96801_REG_WD_FAILCOUNT), 175 + regmap_reg_range(BD96801_REG_WD_ASK, BD96801_REG_WD_ASK), 176 + regmap_reg_range(BD96801_REG_WD_STATUS, BD96801_REG_WD_STATUS), 177 + regmap_reg_range(BD96801_REG_PMIC_STATE, BD96801_REG_INT_BUCK2_ERRB), 178 + regmap_reg_range(BD96801_REG_INT_SYS_INTB, BD96801_REG_INT_BUCK2_INTB), 179 + /* Registers which do not update value unless PMIC is in STBY */ 180 + regmap_reg_range(BD96801_REG_SSCG_CTRL, BD96801_REG_SHD_INTB), 181 + regmap_reg_range(BD96801_REG_BUCK_OVP, BD96801_REG_BOOT_OVERTIME), 182 + }; 183 + 184 + static const struct regmap_access_table bd96801_volatile_regs = { 251 185 .yes_ranges = bd96801_volatile_ranges, 252 186 .n_yes_ranges = ARRAY_SIZE(bd96801_volatile_ranges), 187 + }; 188 + 189 + static const struct regmap_access_table bd96802_volatile_regs = { 190 + .yes_ranges = bd96802_volatile_ranges, 191 + .n_yes_ranges = ARRAY_SIZE(bd96802_volatile_ranges), 253 192 }; 254 193 255 194 /* ··· 283 188 static unsigned int bit6_offsets[] = {8}; /* LDO 6 stat */ 284 189 static unsigned int bit7_offsets[] = {9}; /* LDO 7 stat */ 285 190 286 - static const struct regmap_irq_sub_irq_map errb_sub_irq_offsets[] = { 191 + static const struct regmap_irq_sub_irq_map bd96801_errb_sub_irq_offsets[] = { 287 192 REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets), 288 193 REGMAP_IRQ_MAIN_REG_OFFSET(bit1_offsets), 289 194 REGMAP_IRQ_MAIN_REG_OFFSET(bit2_offsets), ··· 292 197 REGMAP_IRQ_MAIN_REG_OFFSET(bit5_offsets), 293 198 REGMAP_IRQ_MAIN_REG_OFFSET(bit6_offsets), 294 199 REGMAP_IRQ_MAIN_REG_OFFSET(bit7_offsets), 200 + }; 201 + 202 + static const struct regmap_irq_sub_irq_map bd96802_errb_sub_irq_offsets[] = { 203 + REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets), 204 + REGMAP_IRQ_MAIN_REG_OFFSET(bit1_offsets), 205 + REGMAP_IRQ_MAIN_REG_OFFSET(bit2_offsets), 295 206 }; 296 207 297 208 static const struct regmap_irq bd96801_errb_irqs[] = { ··· 360 259 REGMAP_IRQ_REG(BD96801_LDO7_SHDN_ERR_STAT, 9, BD96801_OUT_SHDN_ERR_MASK), 361 260 }; 362 261 262 + static const struct regmap_irq bd96802_errb_irqs[] = { 263 + /* Reg 0x52 Fatal ERRB1 */ 264 + REGMAP_IRQ_REG(BD96802_OTP_ERR_STAT, 0, BD96801_OTP_ERR_MASK), 265 + REGMAP_IRQ_REG(BD96802_DBIST_ERR_STAT, 0, BD96801_DBIST_ERR_MASK), 266 + REGMAP_IRQ_REG(BD96802_EEP_ERR_STAT, 0, BD96801_EEP_ERR_MASK), 267 + REGMAP_IRQ_REG(BD96802_ABIST_ERR_STAT, 0, BD96801_ABIST_ERR_MASK), 268 + REGMAP_IRQ_REG(BD96802_PRSTB_ERR_STAT, 0, BD96801_PRSTB_ERR_MASK), 269 + REGMAP_IRQ_REG(BD96802_DRMOS1_ERR_STAT, 0, BD96801_DRMOS1_ERR_MASK), 270 + REGMAP_IRQ_REG(BD96802_DRMOS2_ERR_STAT, 0, BD96801_DRMOS2_ERR_MASK), 271 + REGMAP_IRQ_REG(BD96802_SLAVE_ERR_STAT, 0, BD96801_SLAVE_ERR_MASK), 272 + /* 0x53 Fatal ERRB2 */ 273 + REGMAP_IRQ_REG(BD96802_VREF_ERR_STAT, 1, BD96801_VREF_ERR_MASK), 274 + REGMAP_IRQ_REG(BD96802_TSD_ERR_STAT, 1, BD96801_TSD_ERR_MASK), 275 + REGMAP_IRQ_REG(BD96802_UVLO_ERR_STAT, 1, BD96801_UVLO_ERR_MASK), 276 + REGMAP_IRQ_REG(BD96802_OVLO_ERR_STAT, 1, BD96801_OVLO_ERR_MASK), 277 + REGMAP_IRQ_REG(BD96802_OSC_ERR_STAT, 1, BD96801_OSC_ERR_MASK), 278 + REGMAP_IRQ_REG(BD96802_PON_ERR_STAT, 1, BD96801_PON_ERR_MASK), 279 + REGMAP_IRQ_REG(BD96802_POFF_ERR_STAT, 1, BD96801_POFF_ERR_MASK), 280 + REGMAP_IRQ_REG(BD96802_CMD_SHDN_ERR_STAT, 1, BD96801_CMD_SHDN_ERR_MASK), 281 + /* 0x54 Fatal INTB shadowed to ERRB */ 282 + REGMAP_IRQ_REG(BD96802_INT_SHDN_ERR_STAT, 2, BD96801_INT_SHDN_ERR_MASK), 283 + /* Reg 0x55 BUCK1 ERR IRQs */ 284 + REGMAP_IRQ_REG(BD96802_BUCK1_PVIN_ERR_STAT, 3, BD96801_OUT_PVIN_ERR_MASK), 285 + REGMAP_IRQ_REG(BD96802_BUCK1_OVP_ERR_STAT, 3, BD96801_OUT_OVP_ERR_MASK), 286 + REGMAP_IRQ_REG(BD96802_BUCK1_UVP_ERR_STAT, 3, BD96801_OUT_UVP_ERR_MASK), 287 + REGMAP_IRQ_REG(BD96802_BUCK1_SHDN_ERR_STAT, 3, BD96801_OUT_SHDN_ERR_MASK), 288 + /* Reg 0x56 BUCK2 ERR IRQs */ 289 + REGMAP_IRQ_REG(BD96802_BUCK2_PVIN_ERR_STAT, 4, BD96801_OUT_PVIN_ERR_MASK), 290 + REGMAP_IRQ_REG(BD96802_BUCK2_OVP_ERR_STAT, 4, BD96801_OUT_OVP_ERR_MASK), 291 + REGMAP_IRQ_REG(BD96802_BUCK2_UVP_ERR_STAT, 4, BD96801_OUT_UVP_ERR_MASK), 292 + REGMAP_IRQ_REG(BD96802_BUCK2_SHDN_ERR_STAT, 4, BD96801_OUT_SHDN_ERR_MASK), 293 + }; 294 + 363 295 static const struct regmap_irq bd96801_intb_irqs[] = { 364 296 /* STATUS SYSTEM INTB */ 365 297 REGMAP_IRQ_REG(BD96801_TW_STAT, 0, BD96801_TW_STAT_MASK), ··· 441 307 REGMAP_IRQ_REG(BD96801_LDO7_UVD_STAT, 7, BD96801_LDO_UVD_STAT_MASK), 442 308 }; 443 309 310 + static const struct regmap_irq bd96802_intb_irqs[] = { 311 + /* STATUS SYSTEM INTB */ 312 + REGMAP_IRQ_REG(BD96802_TW_STAT, 0, BD96801_TW_STAT_MASK), 313 + REGMAP_IRQ_REG(BD96802_WDT_ERR_STAT, 0, BD96801_WDT_ERR_STAT_MASK), 314 + REGMAP_IRQ_REG(BD96802_I2C_ERR_STAT, 0, BD96801_I2C_ERR_STAT_MASK), 315 + REGMAP_IRQ_REG(BD96802_CHIP_IF_ERR_STAT, 0, BD96801_CHIP_IF_ERR_STAT_MASK), 316 + /* STATUS BUCK1 INTB */ 317 + REGMAP_IRQ_REG(BD96802_BUCK1_OCPH_STAT, 1, BD96801_BUCK_OCPH_STAT_MASK), 318 + REGMAP_IRQ_REG(BD96802_BUCK1_OCPL_STAT, 1, BD96801_BUCK_OCPL_STAT_MASK), 319 + REGMAP_IRQ_REG(BD96802_BUCK1_OCPN_STAT, 1, BD96801_BUCK_OCPN_STAT_MASK), 320 + REGMAP_IRQ_REG(BD96802_BUCK1_OVD_STAT, 1, BD96801_BUCK_OVD_STAT_MASK), 321 + REGMAP_IRQ_REG(BD96802_BUCK1_UVD_STAT, 1, BD96801_BUCK_UVD_STAT_MASK), 322 + REGMAP_IRQ_REG(BD96802_BUCK1_TW_CH_STAT, 1, BD96801_BUCK_TW_CH_STAT_MASK), 323 + /* BUCK 2 INTB */ 324 + REGMAP_IRQ_REG(BD96802_BUCK2_OCPH_STAT, 2, BD96801_BUCK_OCPH_STAT_MASK), 325 + REGMAP_IRQ_REG(BD96802_BUCK2_OCPL_STAT, 2, BD96801_BUCK_OCPL_STAT_MASK), 326 + REGMAP_IRQ_REG(BD96802_BUCK2_OCPN_STAT, 2, BD96801_BUCK_OCPN_STAT_MASK), 327 + REGMAP_IRQ_REG(BD96802_BUCK2_OVD_STAT, 2, BD96801_BUCK_OVD_STAT_MASK), 328 + REGMAP_IRQ_REG(BD96802_BUCK2_UVD_STAT, 2, BD96801_BUCK_UVD_STAT_MASK), 329 + REGMAP_IRQ_REG(BD96802_BUCK2_TW_CH_STAT, 2, BD96801_BUCK_TW_CH_STAT_MASK), 330 + }; 331 + 332 + /* 333 + * The IRQ stuff is a bit hairy. The BD96801 / BD96802 provide two physical 334 + * IRQ lines called INTB and ERRB. They share the same main status register. 335 + * 336 + * For ERRB, mapping from main status to sub-status is such that the 337 + * 'global' faults are mapped to first 3 sub-status registers - and indicated 338 + * by the first bit[0] in main status reg. 339 + * 340 + * Rest of the status registers are for indicating stuff for individual 341 + * regulators, 1 sub register / regulator and 1 main status register bit / 342 + * regulator, starting from bit[1]. 343 + * 344 + * Eg, regulator specific stuff has 1 to 1 mapping from main-status to sub 345 + * registers but 'global' ERRB IRQs require mapping from main status bit[0] to 346 + * 3 status registers. 347 + * 348 + * Furthermore, the BD96801 has 7 regulators where the BD96802 has only 2. 349 + * 350 + * INTB has only 1 sub status register for 'global' events and then own sub 351 + * status register for each of the regulators. So, for INTB we have direct 352 + * 1 to 1 mapping - BD96801 just having 5 register and 5 main status bits 353 + * more than the BD96802. 354 + * 355 + * Sharing the main status bits could be a problem if we had both INTB and 356 + * ERRB IRQs asserted but for different sub-status offsets. This might lead 357 + * IRQ controller code to go read a sub status register which indicates no 358 + * active IRQs. I assume this occurring repeteadly might lead the IRQ to be 359 + * disabled by core as a result of repeteadly returned IRQ_NONEs. 360 + * 361 + * I don't consider this as a fatal problem for now because: 362 + * a) Having ERRB asserted leads to PMIC fault state which will kill 363 + * the SoC powered by the PMIC. (So, relevant only for potential 364 + * case of not powering the processor with this PMIC). 365 + * b) Having ERRB set without having respective INTB is unlikely 366 + * (haven't actually verified this). 367 + * 368 + * So, let's proceed with main status enabled for both INTB and ERRB. We can 369 + * later disable main-status usage on systems where this ever proves to be 370 + * a problem. 371 + */ 372 + 444 373 static const struct regmap_irq_chip bd96801_irq_chip_errb = { 445 374 .name = "bd96801-irq-errb", 446 375 .domain_suffix = "errb", ··· 517 320 .init_ack_masked = true, 518 321 .num_regs = 10, 519 322 .irq_reg_stride = 1, 520 - .sub_reg_offsets = &errb_sub_irq_offsets[0], 323 + .sub_reg_offsets = &bd96801_errb_sub_irq_offsets[0], 324 + }; 325 + 326 + static const struct regmap_irq_chip bd96802_irq_chip_errb = { 327 + .name = "bd96802-irq-errb", 328 + .domain_suffix = "errb", 329 + .main_status = BD96801_REG_INT_MAIN, 330 + .num_main_regs = 1, 331 + .irqs = &bd96802_errb_irqs[0], 332 + .num_irqs = ARRAY_SIZE(bd96802_errb_irqs), 333 + .status_base = BD96801_REG_INT_SYS_ERRB1, 334 + .mask_base = BD96801_REG_MASK_SYS_ERRB, 335 + .ack_base = BD96801_REG_INT_SYS_ERRB1, 336 + .init_ack_masked = true, 337 + .num_regs = 5, 338 + .irq_reg_stride = 1, 339 + .sub_reg_offsets = &bd96802_errb_sub_irq_offsets[0], 521 340 }; 522 341 523 342 static const struct regmap_irq_chip bd96801_irq_chip_intb = { ··· 551 338 .irq_reg_stride = 1, 552 339 }; 553 340 341 + static const struct regmap_irq_chip bd96802_irq_chip_intb = { 342 + .name = "bd96802-irq-intb", 343 + .domain_suffix = "intb", 344 + .main_status = BD96801_REG_INT_MAIN, 345 + .num_main_regs = 1, 346 + .irqs = &bd96802_intb_irqs[0], 347 + .num_irqs = ARRAY_SIZE(bd96802_intb_irqs), 348 + .status_base = BD96801_REG_INT_SYS_INTB, 349 + .mask_base = BD96801_REG_MASK_SYS_INTB, 350 + .ack_base = BD96801_REG_INT_SYS_INTB, 351 + .init_ack_masked = true, 352 + .num_regs = 3, 353 + .irq_reg_stride = 1, 354 + }; 355 + 554 356 static const struct regmap_config bd96801_regmap_config = { 555 357 .reg_bits = 8, 556 358 .val_bits = 8, 557 - .volatile_table = &volatile_regs, 359 + .volatile_table = &bd96801_volatile_regs, 558 360 .cache_type = REGCACHE_MAPLE, 361 + }; 362 + 363 + static const struct regmap_config bd96802_regmap_config = { 364 + .reg_bits = 8, 365 + .val_bits = 8, 366 + .volatile_table = &bd96802_volatile_regs, 367 + .cache_type = REGCACHE_MAPLE, 368 + }; 369 + 370 + static const struct bd968xx bd96801_data = { 371 + .errb_irqs = bd96801_reg_errb_irqs, 372 + .intb_irqs = bd96801_reg_intb_irqs, 373 + .num_errb_irqs = ARRAY_SIZE(bd96801_reg_errb_irqs), 374 + .num_intb_irqs = ARRAY_SIZE(bd96801_reg_intb_irqs), 375 + .errb_irq_chip = &bd96801_irq_chip_errb, 376 + .intb_irq_chip = &bd96801_irq_chip_intb, 377 + .regmap_config = &bd96801_regmap_config, 378 + .cells = bd96801_cells, 379 + .num_cells = ARRAY_SIZE(bd96801_cells), 380 + .unlock_reg = BD96801_LOCK_REG, 381 + .unlock_val = BD96801_UNLOCK, 382 + }; 383 + 384 + static const struct bd968xx bd96802_data = { 385 + .errb_irqs = bd96802_reg_errb_irqs, 386 + .intb_irqs = bd96802_reg_intb_irqs, 387 + .num_errb_irqs = ARRAY_SIZE(bd96802_reg_errb_irqs), 388 + .num_intb_irqs = ARRAY_SIZE(bd96802_reg_intb_irqs), 389 + .errb_irq_chip = &bd96802_irq_chip_errb, 390 + .intb_irq_chip = &bd96802_irq_chip_intb, 391 + .regmap_config = &bd96802_regmap_config, 392 + .cells = bd96802_cells, 393 + .num_cells = ARRAY_SIZE(bd96802_cells), 394 + .unlock_reg = BD96801_LOCK_REG, 395 + .unlock_val = BD96801_UNLOCK, 396 + }; 397 + 398 + static const struct bd968xx bd96805_data = { 399 + .errb_irqs = bd96801_reg_errb_irqs, 400 + .intb_irqs = bd96801_reg_intb_irqs, 401 + .num_errb_irqs = ARRAY_SIZE(bd96801_reg_errb_irqs), 402 + .num_intb_irqs = ARRAY_SIZE(bd96801_reg_intb_irqs), 403 + .errb_irq_chip = &bd96801_irq_chip_errb, 404 + .intb_irq_chip = &bd96801_irq_chip_intb, 405 + .regmap_config = &bd96801_regmap_config, 406 + .cells = bd96805_cells, 407 + .num_cells = ARRAY_SIZE(bd96805_cells), 408 + .unlock_reg = BD96801_LOCK_REG, 409 + .unlock_val = BD96801_UNLOCK, 410 + }; 411 + 412 + static struct bd968xx bd96806_data = { 413 + .errb_irqs = bd96802_reg_errb_irqs, 414 + .intb_irqs = bd96802_reg_intb_irqs, 415 + .num_errb_irqs = ARRAY_SIZE(bd96802_reg_errb_irqs), 416 + .num_intb_irqs = ARRAY_SIZE(bd96802_reg_intb_irqs), 417 + .errb_irq_chip = &bd96802_irq_chip_errb, 418 + .intb_irq_chip = &bd96802_irq_chip_intb, 419 + .regmap_config = &bd96802_regmap_config, 420 + .cells = bd96806_cells, 421 + .num_cells = ARRAY_SIZE(bd96806_cells), 422 + .unlock_reg = BD96801_LOCK_REG, 423 + .unlock_val = BD96801_UNLOCK, 559 424 }; 560 425 561 426 static int bd96801_i2c_probe(struct i2c_client *i2c) 562 427 { 563 428 struct regmap_irq_chip_data *intb_irq_data, *errb_irq_data; 564 429 struct irq_domain *intb_domain, *errb_domain; 430 + const struct bd968xx *ddata; 565 431 const struct fwnode_handle *fwnode; 566 432 struct resource *regulator_res; 567 433 struct resource wdg_irq; 568 434 struct regmap *regmap; 569 - int intb_irq, errb_irq, num_intb, num_errb = 0; 435 + int intb_irq, errb_irq, num_errb = 0; 570 436 int num_regu_irqs, wdg_irq_no; 437 + unsigned int chip_type; 571 438 int i, ret; 439 + 440 + chip_type = (unsigned int)(uintptr_t)device_get_match_data(&i2c->dev); 441 + switch (chip_type) { 442 + case ROHM_CHIP_TYPE_BD96801: 443 + ddata = &bd96801_data; 444 + break; 445 + case ROHM_CHIP_TYPE_BD96802: 446 + ddata = &bd96802_data; 447 + break; 448 + case ROHM_CHIP_TYPE_BD96805: 449 + ddata = &bd96805_data; 450 + break; 451 + case ROHM_CHIP_TYPE_BD96806: 452 + ddata = &bd96806_data; 453 + break; 454 + default: 455 + dev_err(&i2c->dev, "Unknown IC\n"); 456 + return -EINVAL; 457 + } 572 458 573 459 fwnode = dev_fwnode(&i2c->dev); 574 460 if (!fwnode) ··· 677 365 if (intb_irq < 0) 678 366 return dev_err_probe(&i2c->dev, intb_irq, "INTB IRQ not configured\n"); 679 367 680 - num_intb = ARRAY_SIZE(regulator_intb_irqs); 681 - 682 368 /* ERRB may be omitted if processor is powered by the PMIC */ 683 369 errb_irq = fwnode_irq_get_byname(fwnode, "errb"); 684 - if (errb_irq < 0) 685 - errb_irq = 0; 370 + if (errb_irq == -EPROBE_DEFER) 371 + return errb_irq; 686 372 687 - if (errb_irq) 688 - num_errb = ARRAY_SIZE(regulator_errb_irqs); 373 + if (errb_irq > 0) 374 + num_errb = ddata->num_errb_irqs; 689 375 690 - num_regu_irqs = num_intb + num_errb; 376 + num_regu_irqs = ddata->num_intb_irqs + num_errb; 691 377 692 378 regulator_res = devm_kcalloc(&i2c->dev, num_regu_irqs, 693 379 sizeof(*regulator_res), GFP_KERNEL); 694 380 if (!regulator_res) 695 381 return -ENOMEM; 696 382 697 - regmap = devm_regmap_init_i2c(i2c, &bd96801_regmap_config); 383 + regmap = devm_regmap_init_i2c(i2c, ddata->regmap_config); 698 384 if (IS_ERR(regmap)) 699 385 return dev_err_probe(&i2c->dev, PTR_ERR(regmap), 700 386 "Regmap initialization failed\n"); 701 387 702 - ret = regmap_write(regmap, BD96801_LOCK_REG, BD96801_UNLOCK); 388 + ret = regmap_write(regmap, ddata->unlock_reg, ddata->unlock_val); 703 389 if (ret) 704 390 return dev_err_probe(&i2c->dev, ret, "Failed to unlock PMIC\n"); 705 391 706 392 ret = devm_regmap_add_irq_chip(&i2c->dev, regmap, intb_irq, 707 - IRQF_ONESHOT, 0, &bd96801_irq_chip_intb, 393 + IRQF_ONESHOT, 0, ddata->intb_irq_chip, 708 394 &intb_irq_data); 709 395 if (ret) 710 396 return dev_err_probe(&i2c->dev, ret, "Failed to add INTB IRQ chip\n"); ··· 714 404 * has two domains so we do IRQ mapping here and provide the 715 405 * already mapped IRQ numbers to sub-devices. 716 406 */ 717 - for (i = 0; i < num_intb; i++) { 407 + for (i = 0; i < ddata->num_intb_irqs; i++) { 718 408 struct resource *res = &regulator_res[i]; 719 409 720 - *res = regulator_intb_irqs[i]; 410 + *res = ddata->intb_irqs[i]; 721 411 res->start = res->end = irq_create_mapping(intb_domain, 722 412 res->start); 723 413 } 724 414 725 415 wdg_irq_no = irq_create_mapping(intb_domain, BD96801_WDT_ERR_STAT); 726 416 wdg_irq = DEFINE_RES_IRQ_NAMED(wdg_irq_no, "bd96801-wdg"); 727 - bd96801_cells[WDG_CELL].resources = &wdg_irq; 728 - bd96801_cells[WDG_CELL].num_resources = 1; 417 + 418 + ddata->cells[WDG_CELL].resources = &wdg_irq; 419 + ddata->cells[WDG_CELL].num_resources = 1; 729 420 730 421 if (!num_errb) 731 422 goto skip_errb; 732 423 733 424 ret = devm_regmap_add_irq_chip(&i2c->dev, regmap, errb_irq, IRQF_ONESHOT, 734 - 0, &bd96801_irq_chip_errb, &errb_irq_data); 425 + 0, ddata->errb_irq_chip, &errb_irq_data); 735 426 if (ret) 736 427 return dev_err_probe(&i2c->dev, ret, 737 428 "Failed to add ERRB IRQ chip\n"); ··· 740 429 errb_domain = regmap_irq_get_domain(errb_irq_data); 741 430 742 431 for (i = 0; i < num_errb; i++) { 743 - struct resource *res = &regulator_res[num_intb + i]; 432 + struct resource *res = &regulator_res[ddata->num_intb_irqs + i]; 744 433 745 - *res = regulator_errb_irqs[i]; 434 + *res = ddata->errb_irqs[i]; 746 435 res->start = res->end = irq_create_mapping(errb_domain, res->start); 747 436 } 748 437 749 438 skip_errb: 750 - bd96801_cells[REGULATOR_CELL].resources = regulator_res; 751 - bd96801_cells[REGULATOR_CELL].num_resources = num_regu_irqs; 752 - 753 - ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO, bd96801_cells, 754 - ARRAY_SIZE(bd96801_cells), NULL, 0, NULL); 439 + ddata->cells[REGULATOR_CELL].resources = regulator_res; 440 + ddata->cells[REGULATOR_CELL].num_resources = num_regu_irqs; 441 + ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO, ddata->cells, 442 + ddata->num_cells, NULL, 0, NULL); 755 443 if (ret) 756 444 dev_err_probe(&i2c->dev, ret, "Failed to create subdevices\n"); 757 445 ··· 758 448 } 759 449 760 450 static const struct of_device_id bd96801_of_match[] = { 761 - { .compatible = "rohm,bd96801", }, 451 + { .compatible = "rohm,bd96801", .data = (void *)ROHM_CHIP_TYPE_BD96801 }, 452 + { .compatible = "rohm,bd96802", .data = (void *)ROHM_CHIP_TYPE_BD96802 }, 453 + { .compatible = "rohm,bd96805", .data = (void *)ROHM_CHIP_TYPE_BD96805 }, 454 + { .compatible = "rohm,bd96806", .data = (void *)ROHM_CHIP_TYPE_BD96806 }, 762 455 { } 763 456 }; 764 457 MODULE_DEVICE_TABLE(of, bd96801_of_match); ··· 789 476 module_exit(bd96801_i2c_exit); 790 477 791 478 MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); 792 - MODULE_DESCRIPTION("ROHM BD96801 Power Management IC driver"); 479 + MODULE_DESCRIPTION("ROHM BD9680X Power Management IC driver"); 793 480 MODULE_LICENSE("GPL");
+32 -1
drivers/mfd/stm32-lptimer.c
··· 6 6 * Inspired by Benjamin Gaignard's stm32-timers driver 7 7 */ 8 8 9 + #include <linux/bitfield.h> 9 10 #include <linux/mfd/stm32-lptimer.h> 10 11 #include <linux/module.h> 11 12 #include <linux/of_platform.h> ··· 50 49 return 0; 51 50 } 52 51 52 + static int stm32_lptimer_detect_hwcfgr(struct stm32_lptimer *ddata) 53 + { 54 + u32 val; 55 + int ret; 56 + 57 + ret = regmap_read(ddata->regmap, STM32_LPTIM_VERR, &ddata->version); 58 + if (ret) 59 + return ret; 60 + 61 + /* Try to guess parameters from HWCFGR: e.g. encoder mode (STM32MP15) */ 62 + ret = regmap_read(ddata->regmap, STM32_LPTIM_HWCFGR1, &val); 63 + if (ret) 64 + return ret; 65 + 66 + /* Fallback to legacy init if HWCFGR isn't present */ 67 + if (!val) 68 + return stm32_lptimer_detect_encoder(ddata); 69 + 70 + ddata->has_encoder = FIELD_GET(STM32_LPTIM_HWCFGR1_ENCODER, val); 71 + 72 + ret = regmap_read(ddata->regmap, STM32_LPTIM_HWCFGR2, &val); 73 + if (ret) 74 + return ret; 75 + 76 + /* Number of capture/compare channels */ 77 + ddata->num_cc_chans = FIELD_GET(STM32_LPTIM_HWCFGR2_CHAN_NUM, val); 78 + 79 + return 0; 80 + } 81 + 53 82 static int stm32_lptimer_probe(struct platform_device *pdev) 54 83 { 55 84 struct device *dev = &pdev->dev; ··· 104 73 if (IS_ERR(ddata->clk)) 105 74 return PTR_ERR(ddata->clk); 106 75 107 - ret = stm32_lptimer_detect_encoder(ddata); 76 + ret = stm32_lptimer_detect_hwcfgr(ddata); 108 77 if (ret) 109 78 return ret; 110 79
+12
drivers/nvmem/Kconfig
··· 154 154 To compile this driver as a module, choose M here: the module 155 155 will be called nvmem_lpc18xx_otp. 156 156 157 + config NVMEM_MAX77759 158 + tristate "Maxim Integrated MAX77759 NVMEM Support" 159 + depends on MFD_MAX77759 160 + default MFD_MAX77759 161 + help 162 + Say Y here to include support for the user-accessible storage found 163 + in Maxim Integrated MAX77759 PMICs. This IC provides space for 30 164 + bytes of storage. 165 + 166 + This driver can also be built as a module. If so, the module 167 + will be called nvmem-max77759. 168 + 157 169 config NVMEM_MESON_EFUSE 158 170 tristate "Amlogic Meson GX eFuse Support" 159 171 depends on (ARCH_MESON || COMPILE_TEST) && MESON_SM
+2
drivers/nvmem/Makefile
··· 34 34 nvmem_lpc18xx_eeprom-y := lpc18xx_eeprom.o 35 35 obj-$(CONFIG_NVMEM_LPC18XX_OTP) += nvmem_lpc18xx_otp.o 36 36 nvmem_lpc18xx_otp-y := lpc18xx_otp.o 37 + obj-$(CONFIG_NVMEM_MAX77759) += nvmem-max77759.o 38 + nvmem-max77759-y := max77759-nvmem.o 37 39 obj-$(CONFIG_NVMEM_MESON_EFUSE) += nvmem_meson_efuse.o 38 40 nvmem_meson_efuse-y := meson-efuse.o 39 41 obj-$(CONFIG_NVMEM_MESON_MX_EFUSE) += nvmem_meson_mx_efuse.o
+145
drivers/nvmem/max77759-nvmem.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + // 3 + // Copyright 2020 Google Inc 4 + // Copyright 2025 Linaro Ltd. 5 + // 6 + // NVMEM driver for Maxim MAX77759 7 + 8 + #include <linux/dev_printk.h> 9 + #include <linux/device.h> 10 + #include <linux/device/driver.h> 11 + #include <linux/err.h> 12 + #include <linux/mfd/max77759.h> 13 + #include <linux/mod_devicetable.h> 14 + #include <linux/module.h> 15 + #include <linux/nvmem-provider.h> 16 + #include <linux/overflow.h> 17 + #include <linux/platform_device.h> 18 + #include <linux/string.h> 19 + 20 + #define MAX77759_NVMEM_OPCODE_HEADER_LEN 3 21 + /* 22 + * NVMEM commands have a three byte header (which becomes part of the command), 23 + * so we need to subtract that. 24 + */ 25 + #define MAX77759_NVMEM_SIZE (MAX77759_MAXQ_OPCODE_MAXLENGTH \ 26 + - MAX77759_NVMEM_OPCODE_HEADER_LEN) 27 + 28 + struct max77759_nvmem { 29 + struct device *dev; 30 + struct max77759 *max77759; 31 + }; 32 + 33 + static int max77759_nvmem_reg_read(void *priv, unsigned int offset, 34 + void *val, size_t bytes) 35 + { 36 + struct max77759_nvmem *nvmem = priv; 37 + DEFINE_FLEX(struct max77759_maxq_command, cmd, cmd, length, 38 + MAX77759_NVMEM_OPCODE_HEADER_LEN); 39 + DEFINE_FLEX(struct max77759_maxq_response, rsp, rsp, length, 40 + MAX77759_MAXQ_OPCODE_MAXLENGTH); 41 + int ret; 42 + 43 + cmd->cmd[0] = MAX77759_MAXQ_OPCODE_USER_SPACE_READ; 44 + cmd->cmd[1] = offset; 45 + cmd->cmd[2] = bytes; 46 + rsp->length = bytes + MAX77759_NVMEM_OPCODE_HEADER_LEN; 47 + 48 + ret = max77759_maxq_command(nvmem->max77759, cmd, rsp); 49 + if (ret < 0) 50 + return ret; 51 + 52 + if (memcmp(cmd->cmd, rsp->rsp, MAX77759_NVMEM_OPCODE_HEADER_LEN)) { 53 + dev_warn(nvmem->dev, "protocol error (read)\n"); 54 + return -EIO; 55 + } 56 + 57 + memcpy(val, &rsp->rsp[MAX77759_NVMEM_OPCODE_HEADER_LEN], bytes); 58 + 59 + return 0; 60 + } 61 + 62 + static int max77759_nvmem_reg_write(void *priv, unsigned int offset, 63 + void *val, size_t bytes) 64 + { 65 + struct max77759_nvmem *nvmem = priv; 66 + DEFINE_FLEX(struct max77759_maxq_command, cmd, cmd, length, 67 + MAX77759_MAXQ_OPCODE_MAXLENGTH); 68 + DEFINE_FLEX(struct max77759_maxq_response, rsp, rsp, length, 69 + MAX77759_MAXQ_OPCODE_MAXLENGTH); 70 + int ret; 71 + 72 + cmd->cmd[0] = MAX77759_MAXQ_OPCODE_USER_SPACE_WRITE; 73 + cmd->cmd[1] = offset; 74 + cmd->cmd[2] = bytes; 75 + memcpy(&cmd->cmd[MAX77759_NVMEM_OPCODE_HEADER_LEN], val, bytes); 76 + cmd->length = bytes + MAX77759_NVMEM_OPCODE_HEADER_LEN; 77 + rsp->length = cmd->length; 78 + 79 + ret = max77759_maxq_command(nvmem->max77759, cmd, rsp); 80 + if (ret < 0) 81 + return ret; 82 + 83 + if (memcmp(cmd->cmd, rsp->rsp, cmd->length)) { 84 + dev_warn(nvmem->dev, "protocol error (write)\n"); 85 + return -EIO; 86 + } 87 + 88 + return 0; 89 + } 90 + 91 + static int max77759_nvmem_probe(struct platform_device *pdev) 92 + { 93 + struct nvmem_config config = { 94 + .dev = &pdev->dev, 95 + .name = dev_name(&pdev->dev), 96 + .id = NVMEM_DEVID_NONE, 97 + .type = NVMEM_TYPE_EEPROM, 98 + .ignore_wp = true, 99 + .size = MAX77759_NVMEM_SIZE, 100 + .word_size = sizeof(u8), 101 + .stride = sizeof(u8), 102 + .reg_read = max77759_nvmem_reg_read, 103 + .reg_write = max77759_nvmem_reg_write, 104 + }; 105 + struct max77759_nvmem *nvmem; 106 + 107 + nvmem = devm_kzalloc(&pdev->dev, sizeof(*nvmem), GFP_KERNEL); 108 + if (!nvmem) 109 + return -ENOMEM; 110 + 111 + nvmem->dev = &pdev->dev; 112 + nvmem->max77759 = dev_get_drvdata(pdev->dev.parent); 113 + 114 + config.priv = nvmem; 115 + 116 + return PTR_ERR_OR_ZERO(devm_nvmem_register(config.dev, &config)); 117 + } 118 + 119 + static const struct of_device_id max77759_nvmem_of_id[] = { 120 + { .compatible = "maxim,max77759-nvmem", }, 121 + { } 122 + }; 123 + MODULE_DEVICE_TABLE(of, max77759_nvmem_of_id); 124 + 125 + static const struct platform_device_id max77759_nvmem_platform_id[] = { 126 + { "max77759-nvmem", }, 127 + { } 128 + }; 129 + MODULE_DEVICE_TABLE(platform, max77759_nvmem_platform_id); 130 + 131 + static struct platform_driver max77759_nvmem_driver = { 132 + .driver = { 133 + .name = "max77759-nvmem", 134 + .probe_type = PROBE_PREFER_ASYNCHRONOUS, 135 + .of_match_table = max77759_nvmem_of_id, 136 + }, 137 + .probe = max77759_nvmem_probe, 138 + .id_table = max77759_nvmem_platform_id, 139 + }; 140 + 141 + module_platform_driver(max77759_nvmem_driver); 142 + 143 + MODULE_AUTHOR("André Draszik <andre.draszik@linaro.org>"); 144 + MODULE_DESCRIPTION("NVMEM driver for Maxim MAX77759"); 145 + MODULE_LICENSE("GPL");
+192 -25
drivers/pwm/pwm-stm32-lp.c
··· 20 20 struct stm32_pwm_lp { 21 21 struct clk *clk; 22 22 struct regmap *regmap; 23 + unsigned int num_cc_chans; 23 24 }; 24 25 25 26 static inline struct stm32_pwm_lp *to_stm32_pwm_lp(struct pwm_chip *chip) ··· 31 30 /* STM32 Low-Power Timer is preceded by a configurable power-of-2 prescaler */ 32 31 #define STM32_LPTIM_MAX_PRESCALER 128 33 32 33 + static int stm32_pwm_lp_update_allowed(struct stm32_pwm_lp *priv, int channel) 34 + { 35 + int ret; 36 + u32 ccmr1; 37 + unsigned long ccmr; 38 + 39 + /* Only one PWM on this LPTIMER: enable, prescaler and reload value can be changed */ 40 + if (!priv->num_cc_chans) 41 + return true; 42 + 43 + ret = regmap_read(priv->regmap, STM32_LPTIM_CCMR1, &ccmr1); 44 + if (ret) 45 + return ret; 46 + ccmr = ccmr1 & (STM32_LPTIM_CC1E | STM32_LPTIM_CC2E); 47 + 48 + /* More than one channel enabled: enable, prescaler or ARR value can't be changed */ 49 + if (bitmap_weight(&ccmr, sizeof(u32) * BITS_PER_BYTE) > 1) 50 + return false; 51 + 52 + /* 53 + * Only one channel is enabled (or none): check status on the other channel, to 54 + * report if enable, prescaler or ARR value can be changed. 55 + */ 56 + if (channel) 57 + return !(ccmr1 & STM32_LPTIM_CC1E); 58 + else 59 + return !(ccmr1 & STM32_LPTIM_CC2E); 60 + } 61 + 62 + static int stm32_pwm_lp_compare_channel_apply(struct stm32_pwm_lp *priv, int channel, 63 + bool enable, enum pwm_polarity polarity) 64 + { 65 + u32 ccmr1, val, mask; 66 + bool reenable; 67 + int ret; 68 + 69 + /* No dedicated CC channel: nothing to do */ 70 + if (!priv->num_cc_chans) 71 + return 0; 72 + 73 + ret = regmap_read(priv->regmap, STM32_LPTIM_CCMR1, &ccmr1); 74 + if (ret) 75 + return ret; 76 + 77 + if (channel) { 78 + /* Must disable CC channel (CCxE) to modify polarity (CCxP), then re-enable */ 79 + reenable = (enable && FIELD_GET(STM32_LPTIM_CC2E, ccmr1)) && 80 + (polarity != FIELD_GET(STM32_LPTIM_CC2P, ccmr1)); 81 + 82 + mask = STM32_LPTIM_CC2SEL | STM32_LPTIM_CC2E | STM32_LPTIM_CC2P; 83 + val = FIELD_PREP(STM32_LPTIM_CC2P, polarity); 84 + val |= FIELD_PREP(STM32_LPTIM_CC2E, enable); 85 + } else { 86 + reenable = (enable && FIELD_GET(STM32_LPTIM_CC1E, ccmr1)) && 87 + (polarity != FIELD_GET(STM32_LPTIM_CC1P, ccmr1)); 88 + 89 + mask = STM32_LPTIM_CC1SEL | STM32_LPTIM_CC1E | STM32_LPTIM_CC1P; 90 + val = FIELD_PREP(STM32_LPTIM_CC1P, polarity); 91 + val |= FIELD_PREP(STM32_LPTIM_CC1E, enable); 92 + } 93 + 94 + if (reenable) { 95 + u32 cfgr, presc; 96 + unsigned long rate; 97 + unsigned int delay_us; 98 + 99 + ret = regmap_update_bits(priv->regmap, STM32_LPTIM_CCMR1, 100 + channel ? STM32_LPTIM_CC2E : STM32_LPTIM_CC1E, 0); 101 + if (ret) 102 + return ret; 103 + /* 104 + * After a write to the LPTIM_CCMRx register, a new write operation can only be 105 + * performed after a delay of at least (PRESC × 3) clock cycles 106 + */ 107 + ret = regmap_read(priv->regmap, STM32_LPTIM_CFGR, &cfgr); 108 + if (ret) 109 + return ret; 110 + presc = FIELD_GET(STM32_LPTIM_PRESC, cfgr); 111 + rate = clk_get_rate(priv->clk) >> presc; 112 + if (!rate) 113 + return -EINVAL; 114 + delay_us = 3 * DIV_ROUND_UP(USEC_PER_SEC, rate); 115 + usleep_range(delay_us, delay_us * 2); 116 + } 117 + 118 + return regmap_update_bits(priv->regmap, STM32_LPTIM_CCMR1, mask, val); 119 + } 120 + 34 121 static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm, 35 122 const struct pwm_state *state) 36 123 { 37 124 struct stm32_pwm_lp *priv = to_stm32_pwm_lp(chip); 38 125 unsigned long long prd, div, dty; 39 126 struct pwm_state cstate; 40 - u32 val, mask, cfgr, presc = 0; 127 + u32 arr, val, mask, cfgr, presc = 0; 41 128 bool reenable; 42 129 int ret; 43 130 ··· 134 45 135 46 if (!state->enabled) { 136 47 if (cstate.enabled) { 137 - /* Disable LP timer */ 138 - ret = regmap_write(priv->regmap, STM32_LPTIM_CR, 0); 48 + /* Disable CC channel if any */ 49 + ret = stm32_pwm_lp_compare_channel_apply(priv, pwm->hwpwm, false, 50 + state->polarity); 139 51 if (ret) 140 52 return ret; 53 + ret = regmap_write(priv->regmap, pwm->hwpwm ? 54 + STM32_LPTIM_CCR2 : STM32_LPTIM_CMP, 0); 55 + if (ret) 56 + return ret; 57 + 58 + /* Check if the timer can be disabled */ 59 + ret = stm32_pwm_lp_update_allowed(priv, pwm->hwpwm); 60 + if (ret < 0) 61 + return ret; 62 + 63 + if (ret) { 64 + /* Disable LP timer */ 65 + ret = regmap_write(priv->regmap, STM32_LPTIM_CR, 0); 66 + if (ret) 67 + return ret; 68 + } 69 + 141 70 /* disable clock to PWM counter */ 142 71 clk_disable(priv->clk); 143 72 } ··· 186 79 dty = prd * state->duty_cycle; 187 80 do_div(dty, state->period); 188 81 82 + ret = regmap_read(priv->regmap, STM32_LPTIM_CFGR, &cfgr); 83 + if (ret) 84 + return ret; 85 + 86 + /* 87 + * When there are several channels, they share the same prescaler and reload value. 88 + * Check if this can be changed, or the values are the same for all channels. 89 + */ 90 + if (!stm32_pwm_lp_update_allowed(priv, pwm->hwpwm)) { 91 + ret = regmap_read(priv->regmap, STM32_LPTIM_ARR, &arr); 92 + if (ret) 93 + return ret; 94 + 95 + if ((FIELD_GET(STM32_LPTIM_PRESC, cfgr) != presc) || (arr != prd - 1)) 96 + return -EBUSY; 97 + } 98 + 189 99 if (!cstate.enabled) { 190 100 /* enable clock to drive PWM counter */ 191 101 ret = clk_enable(priv->clk); ··· 210 86 return ret; 211 87 } 212 88 213 - ret = regmap_read(priv->regmap, STM32_LPTIM_CFGR, &cfgr); 214 - if (ret) 215 - goto err; 216 - 217 89 if ((FIELD_GET(STM32_LPTIM_PRESC, cfgr) != presc) || 218 - (FIELD_GET(STM32_LPTIM_WAVPOL, cfgr) != state->polarity)) { 90 + ((FIELD_GET(STM32_LPTIM_WAVPOL, cfgr) != state->polarity) && !priv->num_cc_chans)) { 219 91 val = FIELD_PREP(STM32_LPTIM_PRESC, presc); 220 - val |= FIELD_PREP(STM32_LPTIM_WAVPOL, state->polarity); 221 - mask = STM32_LPTIM_PRESC | STM32_LPTIM_WAVPOL; 92 + mask = STM32_LPTIM_PRESC; 93 + 94 + if (!priv->num_cc_chans) { 95 + /* 96 + * WAVPOL bit is only available when no capature compare channel is used, 97 + * e.g. on LPTIMER instances that have only one output channel. CCMR1 is 98 + * used otherwise. 99 + */ 100 + val |= FIELD_PREP(STM32_LPTIM_WAVPOL, state->polarity); 101 + mask |= STM32_LPTIM_WAVPOL; 102 + } 222 103 223 104 /* Must disable LP timer to modify CFGR */ 224 105 reenable = true; ··· 249 120 if (ret) 250 121 goto err; 251 122 252 - ret = regmap_write(priv->regmap, STM32_LPTIM_CMP, prd - (1 + dty)); 123 + /* Write CMP/CCRx register and ensure it's been properly written */ 124 + ret = regmap_write(priv->regmap, pwm->hwpwm ? STM32_LPTIM_CCR2 : STM32_LPTIM_CMP, 125 + prd - (1 + dty)); 253 126 if (ret) 254 127 goto err; 255 128 256 - /* ensure CMP & ARR registers are properly written */ 257 - ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val, 129 + /* ensure ARR and CMP/CCRx registers are properly written */ 130 + ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val, pwm->hwpwm ? 131 + (val & STM32_LPTIM_CMP2_ARROK) == STM32_LPTIM_CMP2_ARROK : 258 132 (val & STM32_LPTIM_CMPOK_ARROK) == STM32_LPTIM_CMPOK_ARROK, 259 133 100, 1000); 260 134 if (ret) { 261 135 dev_err(pwmchip_parent(chip), "ARR/CMP registers write issue\n"); 262 136 goto err; 263 137 } 264 - ret = regmap_write(priv->regmap, STM32_LPTIM_ICR, 265 - STM32_LPTIM_CMPOKCF_ARROKCF); 138 + ret = regmap_write(priv->regmap, STM32_LPTIM_ICR, pwm->hwpwm ? 139 + STM32_LPTIM_CMP2OKCF_ARROKCF : STM32_LPTIM_CMPOKCF_ARROKCF); 140 + if (ret) 141 + goto err; 142 + 143 + ret = stm32_pwm_lp_compare_channel_apply(priv, pwm->hwpwm, true, state->polarity); 266 144 if (ret) 267 145 goto err; 268 146 ··· 297 161 { 298 162 struct stm32_pwm_lp *priv = to_stm32_pwm_lp(chip); 299 163 unsigned long rate = clk_get_rate(priv->clk); 300 - u32 val, presc, prd; 164 + u32 val, presc, prd, ccmr1; 165 + bool enabled; 301 166 u64 tmp; 302 167 303 168 regmap_read(priv->regmap, STM32_LPTIM_CR, &val); 304 - state->enabled = !!FIELD_GET(STM32_LPTIM_ENABLE, val); 169 + enabled = !!FIELD_GET(STM32_LPTIM_ENABLE, val); 170 + if (priv->num_cc_chans) { 171 + /* There's a CC chan, need to also check if it's enabled */ 172 + regmap_read(priv->regmap, STM32_LPTIM_CCMR1, &ccmr1); 173 + if (pwm->hwpwm) 174 + enabled &= !!FIELD_GET(STM32_LPTIM_CC2E, ccmr1); 175 + else 176 + enabled &= !!FIELD_GET(STM32_LPTIM_CC1E, ccmr1); 177 + } 178 + state->enabled = enabled; 179 + 305 180 /* Keep PWM counter clock refcount in sync with PWM initial state */ 306 181 if (state->enabled) { 307 182 int ret = clk_enable(priv->clk); ··· 323 176 324 177 regmap_read(priv->regmap, STM32_LPTIM_CFGR, &val); 325 178 presc = FIELD_GET(STM32_LPTIM_PRESC, val); 326 - state->polarity = FIELD_GET(STM32_LPTIM_WAVPOL, val); 179 + if (priv->num_cc_chans) { 180 + if (pwm->hwpwm) 181 + state->polarity = FIELD_GET(STM32_LPTIM_CC2P, ccmr1); 182 + else 183 + state->polarity = FIELD_GET(STM32_LPTIM_CC1P, ccmr1); 184 + } else { 185 + state->polarity = FIELD_GET(STM32_LPTIM_WAVPOL, val); 186 + } 327 187 328 188 regmap_read(priv->regmap, STM32_LPTIM_ARR, &prd); 329 189 tmp = prd + 1; 330 190 tmp = (tmp << presc) * NSEC_PER_SEC; 331 191 state->period = DIV_ROUND_CLOSEST_ULL(tmp, rate); 332 192 333 - regmap_read(priv->regmap, STM32_LPTIM_CMP, &val); 193 + regmap_read(priv->regmap, pwm->hwpwm ? STM32_LPTIM_CCR2 : STM32_LPTIM_CMP, &val); 334 194 tmp = prd - val; 335 195 tmp = (tmp << presc) * NSEC_PER_SEC; 336 196 state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, rate); ··· 355 201 struct stm32_lptimer *ddata = dev_get_drvdata(pdev->dev.parent); 356 202 struct stm32_pwm_lp *priv; 357 203 struct pwm_chip *chip; 204 + unsigned int npwm; 358 205 int ret; 359 206 360 - chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*priv)); 207 + if (!ddata->num_cc_chans) { 208 + /* No dedicated CC channel, so there's only one PWM channel */ 209 + npwm = 1; 210 + } else { 211 + /* There are dedicated CC channels, each with one PWM output */ 212 + npwm = ddata->num_cc_chans; 213 + } 214 + 215 + chip = devm_pwmchip_alloc(&pdev->dev, npwm, sizeof(*priv)); 361 216 if (IS_ERR(chip)) 362 217 return PTR_ERR(chip); 363 218 priv = to_stm32_pwm_lp(chip); 364 219 365 220 priv->regmap = ddata->regmap; 366 221 priv->clk = ddata->clk; 222 + priv->num_cc_chans = ddata->num_cc_chans; 367 223 chip->ops = &stm32_pwm_lp_ops; 368 224 369 225 ret = devm_pwmchip_add(&pdev->dev, chip); ··· 389 225 { 390 226 struct pwm_chip *chip = dev_get_drvdata(dev); 391 227 struct pwm_state state; 228 + unsigned int i; 392 229 393 - pwm_get_state(&chip->pwms[0], &state); 394 - if (state.enabled) { 395 - dev_err(dev, "The consumer didn't stop us (%s)\n", 396 - chip->pwms[0].label); 397 - return -EBUSY; 230 + for (i = 0; i < chip->npwm; i++) { 231 + pwm_get_state(&chip->pwms[i], &state); 232 + if (state.enabled) { 233 + dev_err(dev, "The consumer didn't stop us (%s)\n", 234 + chip->pwms[i].label); 235 + return -EBUSY; 236 + } 398 237 } 399 238 400 239 return pinctrl_pm_select_sleep_state(dev);
+1078 -267
drivers/regulator/bcm590xx-regulator.c
··· 18 18 #include <linux/regulator/of_regulator.h> 19 19 #include <linux/slab.h> 20 20 21 - /* I2C slave 0 registers */ 22 - #define BCM590XX_RFLDOPMCTRL1 0x60 23 - #define BCM590XX_IOSR1PMCTRL1 0x7a 24 - #define BCM590XX_IOSR2PMCTRL1 0x7c 25 - #define BCM590XX_CSRPMCTRL1 0x7e 26 - #define BCM590XX_SDSR1PMCTRL1 0x82 27 - #define BCM590XX_SDSR2PMCTRL1 0x86 28 - #define BCM590XX_MSRPMCTRL1 0x8a 29 - #define BCM590XX_VSRPMCTRL1 0x8e 30 - #define BCM590XX_RFLDOCTRL 0x96 31 - #define BCM590XX_CSRVOUT1 0xc0 32 - 33 - /* I2C slave 1 registers */ 34 - #define BCM590XX_GPLDO5PMCTRL1 0x16 35 - #define BCM590XX_GPLDO6PMCTRL1 0x18 36 - #define BCM590XX_GPLDO1CTRL 0x1a 37 - #define BCM590XX_GPLDO2CTRL 0x1b 38 - #define BCM590XX_GPLDO3CTRL 0x1c 39 - #define BCM590XX_GPLDO4CTRL 0x1d 40 - #define BCM590XX_GPLDO5CTRL 0x1e 41 - #define BCM590XX_GPLDO6CTRL 0x1f 42 - #define BCM590XX_OTG_CTRL 0x40 43 - #define BCM590XX_GPLDO1PMCTRL1 0x57 44 - #define BCM590XX_GPLDO2PMCTRL1 0x59 45 - #define BCM590XX_GPLDO3PMCTRL1 0x5b 46 - #define BCM590XX_GPLDO4PMCTRL1 0x5d 47 - 48 21 #define BCM590XX_REG_ENABLE BIT(7) 49 22 #define BCM590XX_VBUS_ENABLE BIT(2) 50 23 #define BCM590XX_LDO_VSEL_MASK GENMASK(5, 3) 51 24 #define BCM590XX_SR_VSEL_MASK GENMASK(5, 0) 52 25 53 - /* 54 - * RFLDO to VSR regulators are 55 - * accessed via I2C slave 0 56 - */ 57 - 58 - /* LDO regulator IDs */ 59 - #define BCM590XX_REG_RFLDO 0 60 - #define BCM590XX_REG_CAMLDO1 1 61 - #define BCM590XX_REG_CAMLDO2 2 62 - #define BCM590XX_REG_SIMLDO1 3 63 - #define BCM590XX_REG_SIMLDO2 4 64 - #define BCM590XX_REG_SDLDO 5 65 - #define BCM590XX_REG_SDXLDO 6 66 - #define BCM590XX_REG_MMCLDO1 7 67 - #define BCM590XX_REG_MMCLDO2 8 68 - #define BCM590XX_REG_AUDLDO 9 69 - #define BCM590XX_REG_MICLDO 10 70 - #define BCM590XX_REG_USBLDO 11 71 - #define BCM590XX_REG_VIBLDO 12 72 - 73 - /* DCDC regulator IDs */ 74 - #define BCM590XX_REG_CSR 13 75 - #define BCM590XX_REG_IOSR1 14 76 - #define BCM590XX_REG_IOSR2 15 77 - #define BCM590XX_REG_MSR 16 78 - #define BCM590XX_REG_SDSR1 17 79 - #define BCM590XX_REG_SDSR2 18 80 - #define BCM590XX_REG_VSR 19 81 - 82 - /* 83 - * GPLDO1 to VBUS regulators are 84 - * accessed via I2C slave 1 85 - */ 86 - 87 - #define BCM590XX_REG_GPLDO1 20 88 - #define BCM590XX_REG_GPLDO2 21 89 - #define BCM590XX_REG_GPLDO3 22 90 - #define BCM590XX_REG_GPLDO4 23 91 - #define BCM590XX_REG_GPLDO5 24 92 - #define BCM590XX_REG_GPLDO6 25 93 - #define BCM590XX_REG_VBUS 26 94 - 95 - #define BCM590XX_NUM_REGS 27 96 - 97 - #define BCM590XX_REG_IS_LDO(n) (n < BCM590XX_REG_CSR) 98 - #define BCM590XX_REG_IS_GPLDO(n) \ 99 - ((n > BCM590XX_REG_VSR) && (n < BCM590XX_REG_VBUS)) 100 - #define BCM590XX_REG_IS_VBUS(n) (n == BCM590XX_REG_VBUS) 101 - 102 - /* LDO group A: supported voltages in microvolts */ 103 - static const unsigned int ldo_a_table[] = { 104 - 1200000, 1800000, 2500000, 2700000, 2800000, 105 - 2900000, 3000000, 3300000, 26 + enum bcm590xx_reg_type { 27 + BCM590XX_REG_TYPE_LDO, 28 + BCM590XX_REG_TYPE_GPLDO, 29 + BCM590XX_REG_TYPE_SR, 30 + BCM590XX_REG_TYPE_VBUS 106 31 }; 107 32 108 - /* LDO group C: supported voltages in microvolts */ 109 - static const unsigned int ldo_c_table[] = { 110 - 3100000, 1800000, 2500000, 2700000, 2800000, 111 - 2900000, 3000000, 3300000, 112 - }; 113 - 114 - static const unsigned int ldo_vbus[] = { 115 - 5000000, 116 - }; 117 - 118 - /* DCDC group CSR: supported voltages in microvolts */ 119 - static const struct linear_range dcdc_csr_ranges[] = { 120 - REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000), 121 - REGULATOR_LINEAR_RANGE(1360000, 51, 55, 20000), 122 - REGULATOR_LINEAR_RANGE(900000, 56, 63, 0), 123 - }; 124 - 125 - /* DCDC group IOSR1: supported voltages in microvolts */ 126 - static const struct linear_range dcdc_iosr1_ranges[] = { 127 - REGULATOR_LINEAR_RANGE(860000, 2, 51, 10000), 128 - REGULATOR_LINEAR_RANGE(1500000, 52, 52, 0), 129 - REGULATOR_LINEAR_RANGE(1800000, 53, 53, 0), 130 - REGULATOR_LINEAR_RANGE(900000, 54, 63, 0), 131 - }; 132 - 133 - /* DCDC group SDSR1: supported voltages in microvolts */ 134 - static const struct linear_range dcdc_sdsr1_ranges[] = { 135 - REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000), 136 - REGULATOR_LINEAR_RANGE(1340000, 51, 51, 0), 137 - REGULATOR_LINEAR_RANGE(900000, 52, 63, 0), 138 - }; 139 - 140 - struct bcm590xx_info { 141 - const char *name; 142 - const char *vin_name; 143 - u8 n_voltages; 144 - const unsigned int *volt_table; 145 - u8 n_linear_ranges; 146 - const struct linear_range *linear_ranges; 147 - }; 148 - 149 - #define BCM590XX_REG_TABLE(_name, _table) \ 150 - { \ 151 - .name = #_name, \ 152 - .n_voltages = ARRAY_SIZE(_table), \ 153 - .volt_table = _table, \ 154 - } 155 - 156 - #define BCM590XX_REG_RANGES(_name, _ranges) \ 157 - { \ 158 - .name = #_name, \ 159 - .n_voltages = 64, \ 160 - .n_linear_ranges = ARRAY_SIZE(_ranges), \ 161 - .linear_ranges = _ranges, \ 162 - } 163 - 164 - static struct bcm590xx_info bcm590xx_regs[] = { 165 - BCM590XX_REG_TABLE(rfldo, ldo_a_table), 166 - BCM590XX_REG_TABLE(camldo1, ldo_c_table), 167 - BCM590XX_REG_TABLE(camldo2, ldo_c_table), 168 - BCM590XX_REG_TABLE(simldo1, ldo_a_table), 169 - BCM590XX_REG_TABLE(simldo2, ldo_a_table), 170 - BCM590XX_REG_TABLE(sdldo, ldo_c_table), 171 - BCM590XX_REG_TABLE(sdxldo, ldo_a_table), 172 - BCM590XX_REG_TABLE(mmcldo1, ldo_a_table), 173 - BCM590XX_REG_TABLE(mmcldo2, ldo_a_table), 174 - BCM590XX_REG_TABLE(audldo, ldo_a_table), 175 - BCM590XX_REG_TABLE(micldo, ldo_a_table), 176 - BCM590XX_REG_TABLE(usbldo, ldo_a_table), 177 - BCM590XX_REG_TABLE(vibldo, ldo_c_table), 178 - BCM590XX_REG_RANGES(csr, dcdc_csr_ranges), 179 - BCM590XX_REG_RANGES(iosr1, dcdc_iosr1_ranges), 180 - BCM590XX_REG_RANGES(iosr2, dcdc_iosr1_ranges), 181 - BCM590XX_REG_RANGES(msr, dcdc_iosr1_ranges), 182 - BCM590XX_REG_RANGES(sdsr1, dcdc_sdsr1_ranges), 183 - BCM590XX_REG_RANGES(sdsr2, dcdc_iosr1_ranges), 184 - BCM590XX_REG_RANGES(vsr, dcdc_iosr1_ranges), 185 - BCM590XX_REG_TABLE(gpldo1, ldo_a_table), 186 - BCM590XX_REG_TABLE(gpldo2, ldo_a_table), 187 - BCM590XX_REG_TABLE(gpldo3, ldo_a_table), 188 - BCM590XX_REG_TABLE(gpldo4, ldo_a_table), 189 - BCM590XX_REG_TABLE(gpldo5, ldo_a_table), 190 - BCM590XX_REG_TABLE(gpldo6, ldo_a_table), 191 - BCM590XX_REG_TABLE(vbus, ldo_vbus), 33 + struct bcm590xx_reg_data { 34 + enum bcm590xx_reg_type type; 35 + enum bcm590xx_regmap_type regmap; 36 + const struct regulator_desc desc; 192 37 }; 193 38 194 39 struct bcm590xx_reg { 195 - struct regulator_desc *desc; 196 40 struct bcm590xx *mfd; 41 + unsigned int n_regulators; 42 + const struct bcm590xx_reg_data *regs; 197 43 }; 198 - 199 - static int bcm590xx_get_vsel_register(int id) 200 - { 201 - if (BCM590XX_REG_IS_LDO(id)) 202 - return BCM590XX_RFLDOCTRL + id; 203 - else if (BCM590XX_REG_IS_GPLDO(id)) 204 - return BCM590XX_GPLDO1CTRL + id; 205 - else 206 - return BCM590XX_CSRVOUT1 + (id - BCM590XX_REG_CSR) * 3; 207 - } 208 - 209 - static int bcm590xx_get_enable_register(int id) 210 - { 211 - int reg = 0; 212 - 213 - if (BCM590XX_REG_IS_LDO(id)) 214 - reg = BCM590XX_RFLDOPMCTRL1 + id * 2; 215 - else if (BCM590XX_REG_IS_GPLDO(id)) 216 - reg = BCM590XX_GPLDO1PMCTRL1 + id * 2; 217 - else 218 - switch (id) { 219 - case BCM590XX_REG_CSR: 220 - reg = BCM590XX_CSRPMCTRL1; 221 - break; 222 - case BCM590XX_REG_IOSR1: 223 - reg = BCM590XX_IOSR1PMCTRL1; 224 - break; 225 - case BCM590XX_REG_IOSR2: 226 - reg = BCM590XX_IOSR2PMCTRL1; 227 - break; 228 - case BCM590XX_REG_MSR: 229 - reg = BCM590XX_MSRPMCTRL1; 230 - break; 231 - case BCM590XX_REG_SDSR1: 232 - reg = BCM590XX_SDSR1PMCTRL1; 233 - break; 234 - case BCM590XX_REG_SDSR2: 235 - reg = BCM590XX_SDSR2PMCTRL1; 236 - break; 237 - case BCM590XX_REG_VSR: 238 - reg = BCM590XX_VSRPMCTRL1; 239 - break; 240 - case BCM590XX_REG_VBUS: 241 - reg = BCM590XX_OTG_CTRL; 242 - break; 243 - } 244 - 245 - 246 - return reg; 247 - } 248 44 249 45 static const struct regulator_ops bcm590xx_ops_ldo = { 250 46 .is_enabled = regulator_is_enabled_regmap, ··· 50 254 .set_voltage_sel = regulator_set_voltage_sel_regmap, 51 255 .list_voltage = regulator_list_voltage_table, 52 256 .map_voltage = regulator_map_voltage_iterate, 257 + }; 258 + 259 + /* 260 + * LDO ops without voltage selection, used for MICLDO on BCM59054. 261 + * (These are currently the same as VBUS ops, but will be different 262 + * in the future once full PMMODE support is implemented.) 263 + */ 264 + static const struct regulator_ops bcm590xx_ops_ldo_novolt = { 265 + .is_enabled = regulator_is_enabled_regmap, 266 + .enable = regulator_enable_regmap, 267 + .disable = regulator_disable_regmap, 53 268 }; 54 269 55 270 static const struct regulator_ops bcm590xx_ops_dcdc = { ··· 79 272 .disable = regulator_disable_regmap, 80 273 }; 81 274 275 + #define BCM590XX_REG_DESC(_model, _name, _name_lower) \ 276 + .id = _model##_REG_##_name, \ 277 + .name = #_name_lower, \ 278 + .of_match = of_match_ptr(#_name_lower), \ 279 + .regulators_node = of_match_ptr("regulators"), \ 280 + .type = REGULATOR_VOLTAGE, \ 281 + .owner = THIS_MODULE \ 282 + 283 + #define BCM590XX_LDO_DESC(_model, _model_lower, _name, _name_lower, _table) \ 284 + BCM590XX_REG_DESC(_model, _name, _name_lower), \ 285 + .ops = &bcm590xx_ops_ldo, \ 286 + .n_voltages = ARRAY_SIZE(_model_lower##_##_table), \ 287 + .volt_table = _model_lower##_##_table, \ 288 + .vsel_reg = _model##_##_name##CTRL, \ 289 + .vsel_mask = BCM590XX_LDO_VSEL_MASK, \ 290 + .enable_reg = _model##_##_name##PMCTRL1, \ 291 + .enable_mask = BCM590XX_REG_ENABLE, \ 292 + .enable_is_inverted = true 293 + 294 + #define BCM590XX_SR_DESC(_model, _model_lower, _name, _name_lower, _ranges) \ 295 + BCM590XX_REG_DESC(_model, _name, _name_lower), \ 296 + .ops = &bcm590xx_ops_dcdc, \ 297 + .n_voltages = 64, \ 298 + .linear_ranges = _model_lower##_##_ranges, \ 299 + .n_linear_ranges = ARRAY_SIZE(_model_lower##_##_ranges), \ 300 + .vsel_reg = _model##_##_name##VOUT1, \ 301 + .vsel_mask = BCM590XX_SR_VSEL_MASK, \ 302 + .enable_reg = _model##_##_name##PMCTRL1, \ 303 + .enable_mask = BCM590XX_REG_ENABLE, \ 304 + .enable_is_inverted = true 305 + 306 + #define BCM59056_REG_DESC(_name, _name_lower) \ 307 + BCM590XX_REG_DESC(BCM59056, _name, _name_lower) 308 + #define BCM59056_LDO_DESC(_name, _name_lower, _table) \ 309 + BCM590XX_LDO_DESC(BCM59056, bcm59056, _name, _name_lower, _table) 310 + #define BCM59056_SR_DESC(_name, _name_lower, _ranges) \ 311 + BCM590XX_SR_DESC(BCM59056, bcm59056, _name, _name_lower, _ranges) 312 + 313 + #define BCM59054_REG_DESC(_name, _name_lower) \ 314 + BCM590XX_REG_DESC(BCM59054, _name, _name_lower) 315 + #define BCM59054_LDO_DESC(_name, _name_lower, _table) \ 316 + BCM590XX_LDO_DESC(BCM59054, bcm59054, _name, _name_lower, _table) 317 + #define BCM59054_SR_DESC(_name, _name_lower, _ranges) \ 318 + BCM590XX_SR_DESC(BCM59054, bcm59054, _name, _name_lower, _ranges) 319 + 320 + /* BCM59056 data */ 321 + 322 + /* I2C slave 0 registers */ 323 + #define BCM59056_RFLDOPMCTRL1 0x60 324 + #define BCM59056_CAMLDO1PMCTRL1 0x62 325 + #define BCM59056_CAMLDO2PMCTRL1 0x64 326 + #define BCM59056_SIMLDO1PMCTRL1 0x66 327 + #define BCM59056_SIMLDO2PMCTRL1 0x68 328 + #define BCM59056_SDLDOPMCTRL1 0x6a 329 + #define BCM59056_SDXLDOPMCTRL1 0x6c 330 + #define BCM59056_MMCLDO1PMCTRL1 0x6e 331 + #define BCM59056_MMCLDO2PMCTRL1 0x70 332 + #define BCM59056_AUDLDOPMCTRL1 0x72 333 + #define BCM59056_MICLDOPMCTRL1 0x74 334 + #define BCM59056_USBLDOPMCTRL1 0x76 335 + #define BCM59056_VIBLDOPMCTRL1 0x78 336 + #define BCM59056_IOSR1PMCTRL1 0x7a 337 + #define BCM59056_IOSR2PMCTRL1 0x7c 338 + #define BCM59056_CSRPMCTRL1 0x7e 339 + #define BCM59056_SDSR1PMCTRL1 0x82 340 + #define BCM59056_SDSR2PMCTRL1 0x86 341 + #define BCM59056_MSRPMCTRL1 0x8a 342 + #define BCM59056_VSRPMCTRL1 0x8e 343 + #define BCM59056_RFLDOCTRL 0x96 344 + #define BCM59056_CAMLDO1CTRL 0x97 345 + #define BCM59056_CAMLDO2CTRL 0x98 346 + #define BCM59056_SIMLDO1CTRL 0x99 347 + #define BCM59056_SIMLDO2CTRL 0x9a 348 + #define BCM59056_SDLDOCTRL 0x9b 349 + #define BCM59056_SDXLDOCTRL 0x9c 350 + #define BCM59056_MMCLDO1CTRL 0x9d 351 + #define BCM59056_MMCLDO2CTRL 0x9e 352 + #define BCM59056_AUDLDOCTRL 0x9f 353 + #define BCM59056_MICLDOCTRL 0xa0 354 + #define BCM59056_USBLDOCTRL 0xa1 355 + #define BCM59056_VIBLDOCTRL 0xa2 356 + #define BCM59056_CSRVOUT1 0xc0 357 + #define BCM59056_IOSR1VOUT1 0xc3 358 + #define BCM59056_IOSR2VOUT1 0xc6 359 + #define BCM59056_MSRVOUT1 0xc9 360 + #define BCM59056_SDSR1VOUT1 0xcc 361 + #define BCM59056_SDSR2VOUT1 0xcf 362 + #define BCM59056_VSRVOUT1 0xd2 363 + 364 + /* I2C slave 1 registers */ 365 + #define BCM59056_GPLDO5PMCTRL1 0x16 366 + #define BCM59056_GPLDO6PMCTRL1 0x18 367 + #define BCM59056_GPLDO1CTRL 0x1a 368 + #define BCM59056_GPLDO2CTRL 0x1b 369 + #define BCM59056_GPLDO3CTRL 0x1c 370 + #define BCM59056_GPLDO4CTRL 0x1d 371 + #define BCM59056_GPLDO5CTRL 0x1e 372 + #define BCM59056_GPLDO6CTRL 0x1f 373 + #define BCM59056_OTG_CTRL 0x40 374 + #define BCM59056_GPLDO1PMCTRL1 0x57 375 + #define BCM59056_GPLDO2PMCTRL1 0x59 376 + #define BCM59056_GPLDO3PMCTRL1 0x5b 377 + #define BCM59056_GPLDO4PMCTRL1 0x5d 378 + 379 + /* 380 + * RFLDO to VSR regulators are 381 + * accessed via I2C slave 0 382 + */ 383 + 384 + /* LDO regulator IDs */ 385 + #define BCM59056_REG_RFLDO 0 386 + #define BCM59056_REG_CAMLDO1 1 387 + #define BCM59056_REG_CAMLDO2 2 388 + #define BCM59056_REG_SIMLDO1 3 389 + #define BCM59056_REG_SIMLDO2 4 390 + #define BCM59056_REG_SDLDO 5 391 + #define BCM59056_REG_SDXLDO 6 392 + #define BCM59056_REG_MMCLDO1 7 393 + #define BCM59056_REG_MMCLDO2 8 394 + #define BCM59056_REG_AUDLDO 9 395 + #define BCM59056_REG_MICLDO 10 396 + #define BCM59056_REG_USBLDO 11 397 + #define BCM59056_REG_VIBLDO 12 398 + 399 + /* DCDC regulator IDs */ 400 + #define BCM59056_REG_CSR 13 401 + #define BCM59056_REG_IOSR1 14 402 + #define BCM59056_REG_IOSR2 15 403 + #define BCM59056_REG_MSR 16 404 + #define BCM59056_REG_SDSR1 17 405 + #define BCM59056_REG_SDSR2 18 406 + #define BCM59056_REG_VSR 19 407 + 408 + /* 409 + * GPLDO1 to VBUS regulators are 410 + * accessed via I2C slave 1 411 + */ 412 + 413 + #define BCM59056_REG_GPLDO1 20 414 + #define BCM59056_REG_GPLDO2 21 415 + #define BCM59056_REG_GPLDO3 22 416 + #define BCM59056_REG_GPLDO4 23 417 + #define BCM59056_REG_GPLDO5 24 418 + #define BCM59056_REG_GPLDO6 25 419 + #define BCM59056_REG_VBUS 26 420 + 421 + #define BCM59056_NUM_REGS 27 422 + 423 + /* LDO group A: supported voltages in microvolts */ 424 + static const unsigned int bcm59056_ldo_a_table[] = { 425 + 1200000, 1800000, 2500000, 2700000, 2800000, 426 + 2900000, 3000000, 3300000, 427 + }; 428 + 429 + /* LDO group C: supported voltages in microvolts */ 430 + static const unsigned int bcm59056_ldo_c_table[] = { 431 + 3100000, 1800000, 2500000, 2700000, 2800000, 432 + 2900000, 3000000, 3300000, 433 + }; 434 + 435 + /* DCDC group CSR: supported voltages in microvolts */ 436 + static const struct linear_range bcm59056_dcdc_csr_ranges[] = { 437 + REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000), 438 + REGULATOR_LINEAR_RANGE(1360000, 51, 55, 20000), 439 + REGULATOR_LINEAR_RANGE(900000, 56, 63, 0), 440 + }; 441 + 442 + /* DCDC group IOSR1: supported voltages in microvolts */ 443 + static const struct linear_range bcm59056_dcdc_iosr1_ranges[] = { 444 + REGULATOR_LINEAR_RANGE(860000, 2, 51, 10000), 445 + REGULATOR_LINEAR_RANGE(1500000, 52, 52, 0), 446 + REGULATOR_LINEAR_RANGE(1800000, 53, 53, 0), 447 + REGULATOR_LINEAR_RANGE(900000, 54, 63, 0), 448 + }; 449 + 450 + /* DCDC group SDSR1: supported voltages in microvolts */ 451 + static const struct linear_range bcm59056_dcdc_sdsr1_ranges[] = { 452 + REGULATOR_LINEAR_RANGE(860000, 2, 50, 10000), 453 + REGULATOR_LINEAR_RANGE(1340000, 51, 51, 0), 454 + REGULATOR_LINEAR_RANGE(900000, 52, 63, 0), 455 + }; 456 + 457 + static const struct bcm590xx_reg_data bcm59056_regs[BCM59056_NUM_REGS] = { 458 + { 459 + .type = BCM590XX_REG_TYPE_LDO, 460 + .regmap = BCM590XX_REGMAP_PRI, 461 + .desc = { 462 + BCM59056_LDO_DESC(RFLDO, rfldo, ldo_a_table), 463 + }, 464 + }, 465 + 466 + { 467 + .type = BCM590XX_REG_TYPE_LDO, 468 + .regmap = BCM590XX_REGMAP_PRI, 469 + .desc = { 470 + BCM59056_LDO_DESC(CAMLDO1, camldo1, ldo_c_table), 471 + }, 472 + }, 473 + 474 + { 475 + .type = BCM590XX_REG_TYPE_LDO, 476 + .regmap = BCM590XX_REGMAP_PRI, 477 + .desc = { 478 + BCM59056_LDO_DESC(CAMLDO2, camldo2, ldo_c_table), 479 + }, 480 + }, 481 + 482 + { 483 + .type = BCM590XX_REG_TYPE_LDO, 484 + .regmap = BCM590XX_REGMAP_PRI, 485 + .desc = { 486 + BCM59056_LDO_DESC(SIMLDO1, simldo1, ldo_a_table), 487 + }, 488 + }, 489 + 490 + { 491 + .type = BCM590XX_REG_TYPE_LDO, 492 + .regmap = BCM590XX_REGMAP_PRI, 493 + .desc = { 494 + BCM59056_LDO_DESC(SIMLDO2, simldo2, ldo_a_table), 495 + }, 496 + }, 497 + 498 + { 499 + .type = BCM590XX_REG_TYPE_LDO, 500 + .regmap = BCM590XX_REGMAP_PRI, 501 + .desc = { 502 + BCM59056_LDO_DESC(SDLDO, sdldo, ldo_c_table), 503 + }, 504 + }, 505 + 506 + { 507 + .type = BCM590XX_REG_TYPE_LDO, 508 + .regmap = BCM590XX_REGMAP_PRI, 509 + .desc = { 510 + BCM59056_LDO_DESC(SDXLDO, sdxldo, ldo_a_table), 511 + }, 512 + }, 513 + 514 + { 515 + .type = BCM590XX_REG_TYPE_LDO, 516 + .regmap = BCM590XX_REGMAP_PRI, 517 + .desc = { 518 + BCM59056_LDO_DESC(MMCLDO1, mmcldo1, ldo_a_table), 519 + }, 520 + }, 521 + 522 + { 523 + .type = BCM590XX_REG_TYPE_LDO, 524 + .regmap = BCM590XX_REGMAP_PRI, 525 + .desc = { 526 + BCM59056_LDO_DESC(MMCLDO2, mmcldo2, ldo_a_table), 527 + }, 528 + }, 529 + 530 + { 531 + .type = BCM590XX_REG_TYPE_LDO, 532 + .regmap = BCM590XX_REGMAP_PRI, 533 + .desc = { 534 + BCM59056_LDO_DESC(AUDLDO, audldo, ldo_a_table), 535 + }, 536 + }, 537 + 538 + { 539 + .type = BCM590XX_REG_TYPE_LDO, 540 + .regmap = BCM590XX_REGMAP_PRI, 541 + .desc = { 542 + BCM59056_LDO_DESC(MICLDO, micldo, ldo_a_table), 543 + }, 544 + }, 545 + 546 + { 547 + .type = BCM590XX_REG_TYPE_LDO, 548 + .regmap = BCM590XX_REGMAP_PRI, 549 + .desc = { 550 + BCM59056_LDO_DESC(USBLDO, usbldo, ldo_a_table), 551 + }, 552 + }, 553 + 554 + { 555 + .type = BCM590XX_REG_TYPE_LDO, 556 + .regmap = BCM590XX_REGMAP_PRI, 557 + .desc = { 558 + BCM59056_LDO_DESC(VIBLDO, vibldo, ldo_c_table), 559 + }, 560 + }, 561 + 562 + { 563 + .type = BCM590XX_REG_TYPE_SR, 564 + .regmap = BCM590XX_REGMAP_PRI, 565 + .desc = { 566 + BCM59056_SR_DESC(CSR, csr, dcdc_csr_ranges), 567 + }, 568 + }, 569 + 570 + { 571 + .type = BCM590XX_REG_TYPE_SR, 572 + .regmap = BCM590XX_REGMAP_PRI, 573 + .desc = { 574 + BCM59056_SR_DESC(IOSR1, iosr1, dcdc_iosr1_ranges), 575 + }, 576 + }, 577 + 578 + { 579 + .type = BCM590XX_REG_TYPE_SR, 580 + .regmap = BCM590XX_REGMAP_PRI, 581 + .desc = { 582 + BCM59056_SR_DESC(IOSR2, iosr2, dcdc_iosr1_ranges), 583 + }, 584 + }, 585 + 586 + { 587 + .type = BCM590XX_REG_TYPE_SR, 588 + .regmap = BCM590XX_REGMAP_PRI, 589 + .desc = { 590 + BCM59056_SR_DESC(MSR, msr, dcdc_iosr1_ranges), 591 + }, 592 + }, 593 + 594 + { 595 + .type = BCM590XX_REG_TYPE_SR, 596 + .regmap = BCM590XX_REGMAP_PRI, 597 + .desc = { 598 + BCM59056_SR_DESC(SDSR1, sdsr1, dcdc_sdsr1_ranges), 599 + }, 600 + }, 601 + 602 + { 603 + .type = BCM590XX_REG_TYPE_SR, 604 + .regmap = BCM590XX_REGMAP_PRI, 605 + .desc = { 606 + BCM59056_SR_DESC(SDSR2, sdsr2, dcdc_iosr1_ranges), 607 + }, 608 + }, 609 + 610 + { 611 + .type = BCM590XX_REG_TYPE_SR, 612 + .regmap = BCM590XX_REGMAP_PRI, 613 + .desc = { 614 + BCM59056_SR_DESC(VSR, vsr, dcdc_iosr1_ranges), 615 + }, 616 + }, 617 + 618 + { 619 + .type = BCM590XX_REG_TYPE_GPLDO, 620 + .regmap = BCM590XX_REGMAP_SEC, 621 + .desc = { 622 + BCM59056_LDO_DESC(GPLDO1, gpldo1, ldo_a_table), 623 + }, 624 + }, 625 + 626 + { 627 + .type = BCM590XX_REG_TYPE_GPLDO, 628 + .regmap = BCM590XX_REGMAP_SEC, 629 + .desc = { 630 + BCM59056_LDO_DESC(GPLDO2, gpldo2, ldo_a_table), 631 + }, 632 + }, 633 + 634 + { 635 + .type = BCM590XX_REG_TYPE_GPLDO, 636 + .regmap = BCM590XX_REGMAP_SEC, 637 + .desc = { 638 + BCM59056_LDO_DESC(GPLDO3, gpldo3, ldo_a_table), 639 + }, 640 + }, 641 + 642 + { 643 + .type = BCM590XX_REG_TYPE_GPLDO, 644 + .regmap = BCM590XX_REGMAP_SEC, 645 + .desc = { 646 + BCM59056_LDO_DESC(GPLDO4, gpldo4, ldo_a_table), 647 + }, 648 + }, 649 + 650 + { 651 + .type = BCM590XX_REG_TYPE_GPLDO, 652 + .regmap = BCM590XX_REGMAP_SEC, 653 + .desc = { 654 + BCM59056_LDO_DESC(GPLDO5, gpldo5, ldo_a_table), 655 + }, 656 + }, 657 + 658 + { 659 + .type = BCM590XX_REG_TYPE_GPLDO, 660 + .regmap = BCM590XX_REGMAP_SEC, 661 + .desc = { 662 + BCM59056_LDO_DESC(GPLDO6, gpldo6, ldo_a_table), 663 + }, 664 + }, 665 + 666 + { 667 + .type = BCM590XX_REG_TYPE_VBUS, 668 + .regmap = BCM590XX_REGMAP_SEC, 669 + .desc = { 670 + BCM59056_REG_DESC(VBUS, vbus), 671 + .ops = &bcm590xx_ops_vbus, 672 + .n_voltages = 1, 673 + .fixed_uV = 5000000, 674 + .enable_reg = BCM59056_OTG_CTRL, 675 + .enable_mask = BCM590XX_VBUS_ENABLE, 676 + }, 677 + }, 678 + }; 679 + 680 + /* BCM59054 data */ 681 + 682 + /* I2C slave 0 registers */ 683 + #define BCM59054_RFLDOPMCTRL1 0x60 684 + #define BCM59054_CAMLDO1PMCTRL1 0x62 685 + #define BCM59054_CAMLDO2PMCTRL1 0x64 686 + #define BCM59054_SIMLDO1PMCTRL1 0x66 687 + #define BCM59054_SIMLDO2PMCTRL1 0x68 688 + #define BCM59054_SDLDOPMCTRL1 0x6a 689 + #define BCM59054_SDXLDOPMCTRL1 0x6c 690 + #define BCM59054_MMCLDO1PMCTRL1 0x6e 691 + #define BCM59054_MMCLDO2PMCTRL1 0x70 692 + #define BCM59054_AUDLDOPMCTRL1 0x72 693 + #define BCM59054_MICLDOPMCTRL1 0x74 694 + #define BCM59054_USBLDOPMCTRL1 0x76 695 + #define BCM59054_VIBLDOPMCTRL1 0x78 696 + #define BCM59054_IOSR1PMCTRL1 0x7a 697 + #define BCM59054_IOSR2PMCTRL1 0x7c 698 + #define BCM59054_CSRPMCTRL1 0x7e 699 + #define BCM59054_SDSR1PMCTRL1 0x82 700 + #define BCM59054_SDSR2PMCTRL1 0x86 701 + #define BCM59054_MMSRPMCTRL1 0x8a 702 + #define BCM59054_VSRPMCTRL1 0x8e 703 + #define BCM59054_RFLDOCTRL 0x96 704 + #define BCM59054_CAMLDO1CTRL 0x97 705 + #define BCM59054_CAMLDO2CTRL 0x98 706 + #define BCM59054_SIMLDO1CTRL 0x99 707 + #define BCM59054_SIMLDO2CTRL 0x9a 708 + #define BCM59054_SDLDOCTRL 0x9b 709 + #define BCM59054_SDXLDOCTRL 0x9c 710 + #define BCM59054_MMCLDO1CTRL 0x9d 711 + #define BCM59054_MMCLDO2CTRL 0x9e 712 + #define BCM59054_AUDLDOCTRL 0x9f 713 + #define BCM59054_MICLDOCTRL 0xa0 714 + #define BCM59054_USBLDOCTRL 0xa1 715 + #define BCM59054_VIBLDOCTRL 0xa2 716 + #define BCM59054_CSRVOUT1 0xc0 717 + #define BCM59054_IOSR1VOUT1 0xc3 718 + #define BCM59054_IOSR2VOUT1 0xc6 719 + #define BCM59054_MMSRVOUT1 0xc9 720 + #define BCM59054_SDSR1VOUT1 0xcc 721 + #define BCM59054_SDSR2VOUT1 0xcf 722 + #define BCM59054_VSRVOUT1 0xd2 723 + 724 + /* I2C slave 1 registers */ 725 + #define BCM59054_LVLDO1PMCTRL1 0x16 726 + #define BCM59054_LVLDO2PMCTRL1 0x18 727 + #define BCM59054_GPLDO1CTRL 0x1a 728 + #define BCM59054_GPLDO2CTRL 0x1b 729 + #define BCM59054_GPLDO3CTRL 0x1c 730 + #define BCM59054_TCXLDOCTRL 0x1d 731 + #define BCM59054_LVLDO1CTRL 0x1e 732 + #define BCM59054_LVLDO2CTRL 0x1f 733 + #define BCM59054_OTG_CTRL 0x40 734 + #define BCM59054_GPLDO1PMCTRL1 0x57 735 + #define BCM59054_GPLDO2PMCTRL1 0x59 736 + #define BCM59054_GPLDO3PMCTRL1 0x5b 737 + #define BCM59054_TCXLDOPMCTRL1 0x5d 738 + 739 + /* 740 + * RFLDO to VSR regulators are 741 + * accessed via I2C slave 0 742 + */ 743 + 744 + /* LDO regulator IDs */ 745 + #define BCM59054_REG_RFLDO 0 746 + #define BCM59054_REG_CAMLDO1 1 747 + #define BCM59054_REG_CAMLDO2 2 748 + #define BCM59054_REG_SIMLDO1 3 749 + #define BCM59054_REG_SIMLDO2 4 750 + #define BCM59054_REG_SDLDO 5 751 + #define BCM59054_REG_SDXLDO 6 752 + #define BCM59054_REG_MMCLDO1 7 753 + #define BCM59054_REG_MMCLDO2 8 754 + #define BCM59054_REG_AUDLDO 9 755 + #define BCM59054_REG_MICLDO 10 756 + #define BCM59054_REG_USBLDO 11 757 + #define BCM59054_REG_VIBLDO 12 758 + 759 + /* DCDC regulator IDs */ 760 + #define BCM59054_REG_CSR 13 761 + #define BCM59054_REG_IOSR1 14 762 + #define BCM59054_REG_IOSR2 15 763 + #define BCM59054_REG_MMSR 16 764 + #define BCM59054_REG_SDSR1 17 765 + #define BCM59054_REG_SDSR2 18 766 + #define BCM59054_REG_VSR 19 767 + 768 + /* 769 + * GPLDO1 to VBUS regulators are 770 + * accessed via I2C slave 1 771 + */ 772 + 773 + #define BCM59054_REG_GPLDO1 20 774 + #define BCM59054_REG_GPLDO2 21 775 + #define BCM59054_REG_GPLDO3 22 776 + #define BCM59054_REG_TCXLDO 23 777 + #define BCM59054_REG_LVLDO1 24 778 + #define BCM59054_REG_LVLDO2 25 779 + #define BCM59054_REG_VBUS 26 780 + 781 + #define BCM59054_NUM_REGS 27 782 + 783 + /* LDO group 1: supported voltages in microvolts */ 784 + static const unsigned int bcm59054_ldo_1_table[] = { 785 + 1200000, 1800000, 2500000, 2700000, 2800000, 786 + 2900000, 3000000, 3300000, 787 + }; 788 + 789 + /* LDO group 2: supported voltages in microvolts */ 790 + static const unsigned int bcm59054_ldo_2_table[] = { 791 + 3100000, 1800000, 2500000, 2700000, 2800000, 792 + 2900000, 3000000, 3300000, 793 + }; 794 + 795 + /* LDO group 3: supported voltages in microvolts */ 796 + static const unsigned int bcm59054_ldo_3_table[] = { 797 + 1000000, 1107000, 1143000, 1214000, 1250000, 798 + 1464000, 1500000, 1786000, 799 + }; 800 + 801 + /* DCDC group SR: supported voltages in microvolts */ 802 + static const struct linear_range bcm59054_dcdc_sr_ranges[] = { 803 + REGULATOR_LINEAR_RANGE(0, 0, 1, 0), 804 + REGULATOR_LINEAR_RANGE(860000, 2, 60, 10000), 805 + REGULATOR_LINEAR_RANGE(1500000, 61, 61, 0), 806 + REGULATOR_LINEAR_RANGE(1800000, 62, 62, 0), 807 + REGULATOR_LINEAR_RANGE(900000, 63, 63, 0), 808 + }; 809 + 810 + /* DCDC group VSR (BCM59054A1): supported voltages in microvolts */ 811 + static const struct linear_range bcm59054_dcdc_vsr_a1_ranges[] = { 812 + REGULATOR_LINEAR_RANGE(0, 0, 1, 0), 813 + REGULATOR_LINEAR_RANGE(860000, 2, 59, 10000), 814 + REGULATOR_LINEAR_RANGE(1700000, 60, 60, 0), 815 + REGULATOR_LINEAR_RANGE(1500000, 61, 61, 0), 816 + REGULATOR_LINEAR_RANGE(1800000, 62, 62, 0), 817 + REGULATOR_LINEAR_RANGE(1600000, 63, 63, 0), 818 + }; 819 + 820 + /* DCDC group CSR: supported voltages in microvolts */ 821 + static const struct linear_range bcm59054_dcdc_csr_ranges[] = { 822 + REGULATOR_LINEAR_RANGE(700000, 0, 1, 100000), 823 + REGULATOR_LINEAR_RANGE(860000, 2, 60, 10000), 824 + REGULATOR_LINEAR_RANGE(900000, 61, 63, 0), 825 + }; 826 + 827 + static const struct bcm590xx_reg_data bcm59054_regs[BCM59054_NUM_REGS] = { 828 + { 829 + .type = BCM590XX_REG_TYPE_LDO, 830 + .regmap = BCM590XX_REGMAP_PRI, 831 + .desc = { 832 + BCM59054_LDO_DESC(RFLDO, rfldo, ldo_1_table), 833 + }, 834 + }, 835 + 836 + { 837 + .type = BCM590XX_REG_TYPE_LDO, 838 + .regmap = BCM590XX_REGMAP_PRI, 839 + .desc = { 840 + BCM59054_LDO_DESC(CAMLDO1, camldo1, ldo_2_table), 841 + }, 842 + }, 843 + 844 + { 845 + .type = BCM590XX_REG_TYPE_LDO, 846 + .regmap = BCM590XX_REGMAP_PRI, 847 + .desc = { 848 + BCM59054_LDO_DESC(CAMLDO2, camldo2, ldo_2_table), 849 + }, 850 + }, 851 + 852 + { 853 + .type = BCM590XX_REG_TYPE_LDO, 854 + .regmap = BCM590XX_REGMAP_PRI, 855 + .desc = { 856 + BCM59054_LDO_DESC(SIMLDO1, simldo1, ldo_1_table), 857 + }, 858 + }, 859 + 860 + { 861 + .type = BCM590XX_REG_TYPE_LDO, 862 + .regmap = BCM590XX_REGMAP_PRI, 863 + .desc = { 864 + BCM59054_LDO_DESC(SIMLDO2, simldo2, ldo_1_table), 865 + }, 866 + }, 867 + 868 + { 869 + .type = BCM590XX_REG_TYPE_LDO, 870 + .regmap = BCM590XX_REGMAP_PRI, 871 + .desc = { 872 + BCM59054_LDO_DESC(SDLDO, sdldo, ldo_2_table), 873 + }, 874 + }, 875 + 876 + { 877 + .type = BCM590XX_REG_TYPE_LDO, 878 + .regmap = BCM590XX_REGMAP_PRI, 879 + .desc = { 880 + BCM59054_LDO_DESC(SDXLDO, sdxldo, ldo_1_table), 881 + }, 882 + }, 883 + 884 + { 885 + .type = BCM590XX_REG_TYPE_LDO, 886 + .regmap = BCM590XX_REGMAP_PRI, 887 + .desc = { 888 + BCM59054_LDO_DESC(MMCLDO1, mmcldo1, ldo_1_table), 889 + }, 890 + }, 891 + 892 + { 893 + .type = BCM590XX_REG_TYPE_LDO, 894 + .regmap = BCM590XX_REGMAP_PRI, 895 + .desc = { 896 + BCM59054_LDO_DESC(MMCLDO2, mmcldo2, ldo_1_table), 897 + }, 898 + }, 899 + 900 + { 901 + .type = BCM590XX_REG_TYPE_LDO, 902 + .regmap = BCM590XX_REGMAP_PRI, 903 + .desc = { 904 + BCM59054_LDO_DESC(AUDLDO, audldo, ldo_1_table), 905 + }, 906 + }, 907 + 908 + { 909 + .type = BCM590XX_REG_TYPE_LDO, 910 + .regmap = BCM590XX_REGMAP_PRI, 911 + .desc = { 912 + BCM59054_REG_DESC(MICLDO, micldo), 913 + .ops = &bcm590xx_ops_ldo_novolt, 914 + /* MICLDO is locked at 1.8V */ 915 + .n_voltages = 1, 916 + .fixed_uV = 1800000, 917 + .enable_reg = BCM59054_MICLDOPMCTRL1, 918 + .enable_mask = BCM590XX_REG_ENABLE, 919 + .enable_is_inverted = true, 920 + }, 921 + }, 922 + 923 + { 924 + .type = BCM590XX_REG_TYPE_LDO, 925 + .regmap = BCM590XX_REGMAP_PRI, 926 + .desc = { 927 + BCM59054_LDO_DESC(USBLDO, usbldo, ldo_1_table), 928 + }, 929 + }, 930 + 931 + { 932 + .type = BCM590XX_REG_TYPE_LDO, 933 + .regmap = BCM590XX_REGMAP_PRI, 934 + .desc = { 935 + BCM59054_LDO_DESC(VIBLDO, vibldo, ldo_2_table), 936 + }, 937 + }, 938 + 939 + { 940 + .type = BCM590XX_REG_TYPE_SR, 941 + .regmap = BCM590XX_REGMAP_PRI, 942 + .desc = { 943 + BCM59054_SR_DESC(CSR, csr, dcdc_csr_ranges), 944 + }, 945 + }, 946 + 947 + { 948 + .type = BCM590XX_REG_TYPE_SR, 949 + .regmap = BCM590XX_REGMAP_PRI, 950 + .desc = { 951 + BCM59054_SR_DESC(IOSR1, iosr1, dcdc_sr_ranges), 952 + }, 953 + }, 954 + 955 + { 956 + .type = BCM590XX_REG_TYPE_SR, 957 + .regmap = BCM590XX_REGMAP_PRI, 958 + .desc = { 959 + BCM59054_SR_DESC(IOSR2, iosr2, dcdc_sr_ranges), 960 + }, 961 + }, 962 + 963 + { 964 + .type = BCM590XX_REG_TYPE_SR, 965 + .regmap = BCM590XX_REGMAP_PRI, 966 + .desc = { 967 + BCM59054_SR_DESC(MMSR, mmsr, dcdc_sr_ranges), 968 + }, 969 + }, 970 + 971 + { 972 + .type = BCM590XX_REG_TYPE_SR, 973 + .regmap = BCM590XX_REGMAP_PRI, 974 + .desc = { 975 + BCM59054_SR_DESC(SDSR1, sdsr1, dcdc_sr_ranges), 976 + }, 977 + }, 978 + 979 + { 980 + .type = BCM590XX_REG_TYPE_SR, 981 + .regmap = BCM590XX_REGMAP_PRI, 982 + .desc = { 983 + BCM59054_SR_DESC(SDSR2, sdsr2, dcdc_sr_ranges), 984 + }, 985 + }, 986 + 987 + { 988 + .type = BCM590XX_REG_TYPE_SR, 989 + .regmap = BCM590XX_REGMAP_PRI, 990 + .desc = { 991 + BCM59054_SR_DESC(VSR, vsr, dcdc_sr_ranges), 992 + }, 993 + }, 994 + 995 + { 996 + .type = BCM590XX_REG_TYPE_GPLDO, 997 + .regmap = BCM590XX_REGMAP_SEC, 998 + .desc = { 999 + BCM59054_LDO_DESC(GPLDO1, gpldo1, ldo_1_table), 1000 + }, 1001 + }, 1002 + 1003 + { 1004 + .type = BCM590XX_REG_TYPE_GPLDO, 1005 + .regmap = BCM590XX_REGMAP_SEC, 1006 + .desc = { 1007 + BCM59054_LDO_DESC(GPLDO2, gpldo2, ldo_1_table), 1008 + }, 1009 + }, 1010 + 1011 + { 1012 + .type = BCM590XX_REG_TYPE_GPLDO, 1013 + .regmap = BCM590XX_REGMAP_SEC, 1014 + .desc = { 1015 + BCM59054_LDO_DESC(GPLDO3, gpldo3, ldo_1_table), 1016 + }, 1017 + }, 1018 + 1019 + { 1020 + .type = BCM590XX_REG_TYPE_GPLDO, 1021 + .regmap = BCM590XX_REGMAP_SEC, 1022 + .desc = { 1023 + BCM59054_LDO_DESC(TCXLDO, tcxldo, ldo_1_table), 1024 + }, 1025 + }, 1026 + 1027 + { 1028 + .type = BCM590XX_REG_TYPE_GPLDO, 1029 + .regmap = BCM590XX_REGMAP_SEC, 1030 + .desc = { 1031 + BCM59054_LDO_DESC(LVLDO1, lvldo1, ldo_3_table), 1032 + }, 1033 + }, 1034 + 1035 + { 1036 + .type = BCM590XX_REG_TYPE_GPLDO, 1037 + .regmap = BCM590XX_REGMAP_SEC, 1038 + .desc = { 1039 + BCM59054_LDO_DESC(LVLDO2, lvldo2, ldo_3_table), 1040 + }, 1041 + }, 1042 + 1043 + { 1044 + .type = BCM590XX_REG_TYPE_VBUS, 1045 + .regmap = BCM590XX_REGMAP_SEC, 1046 + .desc = { 1047 + BCM59054_REG_DESC(VBUS, vbus), 1048 + .ops = &bcm590xx_ops_vbus, 1049 + .n_voltages = 1, 1050 + .fixed_uV = 5000000, 1051 + .enable_reg = BCM59054_OTG_CTRL, 1052 + .enable_mask = BCM590XX_VBUS_ENABLE, 1053 + }, 1054 + }, 1055 + }; 1056 + 1057 + /* 1058 + * BCM59054A1 regulators; same as previous revision, but with different 1059 + * VSR voltage table. 1060 + */ 1061 + static const struct bcm590xx_reg_data bcm59054_a1_regs[BCM59054_NUM_REGS] = { 1062 + { 1063 + .type = BCM590XX_REG_TYPE_LDO, 1064 + .regmap = BCM590XX_REGMAP_PRI, 1065 + .desc = { 1066 + BCM59054_LDO_DESC(RFLDO, rfldo, ldo_1_table), 1067 + }, 1068 + }, 1069 + 1070 + { 1071 + .type = BCM590XX_REG_TYPE_LDO, 1072 + .regmap = BCM590XX_REGMAP_PRI, 1073 + .desc = { 1074 + BCM59054_LDO_DESC(CAMLDO1, camldo1, ldo_2_table), 1075 + }, 1076 + }, 1077 + 1078 + { 1079 + .type = BCM590XX_REG_TYPE_LDO, 1080 + .regmap = BCM590XX_REGMAP_PRI, 1081 + .desc = { 1082 + BCM59054_LDO_DESC(CAMLDO2, camldo2, ldo_2_table), 1083 + }, 1084 + }, 1085 + 1086 + { 1087 + .type = BCM590XX_REG_TYPE_LDO, 1088 + .regmap = BCM590XX_REGMAP_PRI, 1089 + .desc = { 1090 + BCM59054_LDO_DESC(SIMLDO1, simldo1, ldo_1_table), 1091 + }, 1092 + }, 1093 + 1094 + { 1095 + .type = BCM590XX_REG_TYPE_LDO, 1096 + .regmap = BCM590XX_REGMAP_PRI, 1097 + .desc = { 1098 + BCM59054_LDO_DESC(SIMLDO2, simldo2, ldo_1_table), 1099 + }, 1100 + }, 1101 + 1102 + { 1103 + .type = BCM590XX_REG_TYPE_LDO, 1104 + .regmap = BCM590XX_REGMAP_PRI, 1105 + .desc = { 1106 + BCM59054_LDO_DESC(SDLDO, sdldo, ldo_2_table), 1107 + }, 1108 + }, 1109 + 1110 + { 1111 + .type = BCM590XX_REG_TYPE_LDO, 1112 + .regmap = BCM590XX_REGMAP_PRI, 1113 + .desc = { 1114 + BCM59054_LDO_DESC(SDXLDO, sdxldo, ldo_1_table), 1115 + }, 1116 + }, 1117 + 1118 + { 1119 + .type = BCM590XX_REG_TYPE_LDO, 1120 + .regmap = BCM590XX_REGMAP_PRI, 1121 + .desc = { 1122 + BCM59054_LDO_DESC(MMCLDO1, mmcldo1, ldo_1_table), 1123 + }, 1124 + }, 1125 + 1126 + { 1127 + .type = BCM590XX_REG_TYPE_LDO, 1128 + .regmap = BCM590XX_REGMAP_PRI, 1129 + .desc = { 1130 + BCM59054_LDO_DESC(MMCLDO2, mmcldo2, ldo_1_table), 1131 + }, 1132 + }, 1133 + 1134 + { 1135 + .type = BCM590XX_REG_TYPE_LDO, 1136 + .regmap = BCM590XX_REGMAP_PRI, 1137 + .desc = { 1138 + BCM59054_LDO_DESC(AUDLDO, audldo, ldo_1_table), 1139 + }, 1140 + }, 1141 + 1142 + { 1143 + .type = BCM590XX_REG_TYPE_LDO, 1144 + .regmap = BCM590XX_REGMAP_PRI, 1145 + .desc = { 1146 + BCM59054_REG_DESC(MICLDO, micldo), 1147 + .ops = &bcm590xx_ops_ldo_novolt, 1148 + /* MICLDO is locked at 1.8V */ 1149 + .n_voltages = 1, 1150 + .fixed_uV = 1800000, 1151 + .enable_reg = BCM59054_MICLDOPMCTRL1, 1152 + .enable_mask = BCM590XX_REG_ENABLE, 1153 + .enable_is_inverted = true, 1154 + }, 1155 + }, 1156 + 1157 + { 1158 + .type = BCM590XX_REG_TYPE_LDO, 1159 + .regmap = BCM590XX_REGMAP_PRI, 1160 + .desc = { 1161 + BCM59054_LDO_DESC(USBLDO, usbldo, ldo_1_table), 1162 + }, 1163 + }, 1164 + 1165 + { 1166 + .type = BCM590XX_REG_TYPE_LDO, 1167 + .regmap = BCM590XX_REGMAP_PRI, 1168 + .desc = { 1169 + BCM59054_LDO_DESC(VIBLDO, vibldo, ldo_2_table), 1170 + }, 1171 + }, 1172 + 1173 + { 1174 + .type = BCM590XX_REG_TYPE_SR, 1175 + .regmap = BCM590XX_REGMAP_PRI, 1176 + .desc = { 1177 + BCM59054_SR_DESC(CSR, csr, dcdc_csr_ranges), 1178 + }, 1179 + }, 1180 + 1181 + { 1182 + .type = BCM590XX_REG_TYPE_SR, 1183 + .regmap = BCM590XX_REGMAP_PRI, 1184 + .desc = { 1185 + BCM59054_SR_DESC(IOSR1, iosr1, dcdc_sr_ranges), 1186 + }, 1187 + }, 1188 + 1189 + { 1190 + .type = BCM590XX_REG_TYPE_SR, 1191 + .regmap = BCM590XX_REGMAP_PRI, 1192 + .desc = { 1193 + BCM59054_SR_DESC(IOSR2, iosr2, dcdc_sr_ranges), 1194 + }, 1195 + }, 1196 + 1197 + { 1198 + .type = BCM590XX_REG_TYPE_SR, 1199 + .regmap = BCM590XX_REGMAP_PRI, 1200 + .desc = { 1201 + BCM59054_SR_DESC(MMSR, mmsr, dcdc_sr_ranges), 1202 + }, 1203 + }, 1204 + 1205 + { 1206 + .type = BCM590XX_REG_TYPE_SR, 1207 + .regmap = BCM590XX_REGMAP_PRI, 1208 + .desc = { 1209 + BCM59054_SR_DESC(SDSR1, sdsr1, dcdc_sr_ranges), 1210 + }, 1211 + }, 1212 + 1213 + { 1214 + .type = BCM590XX_REG_TYPE_SR, 1215 + .regmap = BCM590XX_REGMAP_PRI, 1216 + .desc = { 1217 + BCM59054_SR_DESC(SDSR2, sdsr2, dcdc_sr_ranges), 1218 + }, 1219 + }, 1220 + 1221 + { 1222 + .type = BCM590XX_REG_TYPE_SR, 1223 + .regmap = BCM590XX_REGMAP_PRI, 1224 + .desc = { 1225 + BCM59054_SR_DESC(VSR, vsr, dcdc_vsr_a1_ranges), 1226 + }, 1227 + }, 1228 + 1229 + { 1230 + .type = BCM590XX_REG_TYPE_GPLDO, 1231 + .regmap = BCM590XX_REGMAP_SEC, 1232 + .desc = { 1233 + BCM59054_LDO_DESC(GPLDO1, gpldo1, ldo_1_table), 1234 + }, 1235 + }, 1236 + 1237 + { 1238 + .type = BCM590XX_REG_TYPE_GPLDO, 1239 + .regmap = BCM590XX_REGMAP_SEC, 1240 + .desc = { 1241 + BCM59054_LDO_DESC(GPLDO2, gpldo2, ldo_1_table), 1242 + }, 1243 + }, 1244 + 1245 + { 1246 + .type = BCM590XX_REG_TYPE_GPLDO, 1247 + .regmap = BCM590XX_REGMAP_SEC, 1248 + .desc = { 1249 + BCM59054_LDO_DESC(GPLDO3, gpldo3, ldo_1_table), 1250 + }, 1251 + }, 1252 + 1253 + { 1254 + .type = BCM590XX_REG_TYPE_GPLDO, 1255 + .regmap = BCM590XX_REGMAP_SEC, 1256 + .desc = { 1257 + BCM59054_LDO_DESC(TCXLDO, tcxldo, ldo_1_table), 1258 + }, 1259 + }, 1260 + 1261 + { 1262 + .type = BCM590XX_REG_TYPE_GPLDO, 1263 + .regmap = BCM590XX_REGMAP_SEC, 1264 + .desc = { 1265 + BCM59054_LDO_DESC(LVLDO1, lvldo1, ldo_3_table), 1266 + }, 1267 + }, 1268 + 1269 + { 1270 + .type = BCM590XX_REG_TYPE_GPLDO, 1271 + .regmap = BCM590XX_REGMAP_SEC, 1272 + .desc = { 1273 + BCM59054_LDO_DESC(LVLDO2, lvldo2, ldo_3_table), 1274 + }, 1275 + }, 1276 + 1277 + { 1278 + .type = BCM590XX_REG_TYPE_VBUS, 1279 + .regmap = BCM590XX_REGMAP_SEC, 1280 + .desc = { 1281 + BCM59054_REG_DESC(VBUS, vbus), 1282 + .ops = &bcm590xx_ops_vbus, 1283 + .n_voltages = 1, 1284 + .fixed_uV = 5000000, 1285 + .enable_reg = BCM59054_OTG_CTRL, 1286 + .enable_mask = BCM590XX_VBUS_ENABLE, 1287 + }, 1288 + }, 1289 + }; 1290 + 82 1291 static int bcm590xx_probe(struct platform_device *pdev) 83 1292 { 84 1293 struct bcm590xx *bcm590xx = dev_get_drvdata(pdev->dev.parent); 85 1294 struct bcm590xx_reg *pmu; 1295 + const struct bcm590xx_reg_data *info; 86 1296 struct regulator_config config = { }; 87 - struct bcm590xx_info *info; 88 1297 struct regulator_dev *rdev; 89 - int i; 1298 + unsigned int i; 90 1299 91 1300 pmu = devm_kzalloc(&pdev->dev, sizeof(*pmu), GFP_KERNEL); 92 1301 if (!pmu) ··· 1110 287 1111 288 pmu->mfd = bcm590xx; 1112 289 290 + switch (pmu->mfd->pmu_id) { 291 + case BCM590XX_PMUID_BCM59054: 292 + pmu->n_regulators = BCM59054_NUM_REGS; 293 + if (pmu->mfd->rev_analog == BCM59054_REV_ANALOG_A1) 294 + pmu->regs = bcm59054_a1_regs; 295 + else 296 + pmu->regs = bcm59054_regs; 297 + break; 298 + case BCM590XX_PMUID_BCM59056: 299 + pmu->n_regulators = BCM59056_NUM_REGS; 300 + pmu->regs = bcm59056_regs; 301 + break; 302 + default: 303 + dev_err(bcm590xx->dev, 304 + "unknown device type, could not initialize\n"); 305 + return -EINVAL; 306 + } 307 + 1113 308 platform_set_drvdata(pdev, pmu); 1114 309 1115 - pmu->desc = devm_kcalloc(&pdev->dev, 1116 - BCM590XX_NUM_REGS, 1117 - sizeof(struct regulator_desc), 1118 - GFP_KERNEL); 1119 - if (!pmu->desc) 1120 - return -ENOMEM; 1121 - 1122 - info = bcm590xx_regs; 1123 - 1124 - for (i = 0; i < BCM590XX_NUM_REGS; i++, info++) { 1125 - /* Register the regulators */ 1126 - pmu->desc[i].name = info->name; 1127 - pmu->desc[i].of_match = of_match_ptr(info->name); 1128 - pmu->desc[i].regulators_node = of_match_ptr("regulators"); 1129 - pmu->desc[i].supply_name = info->vin_name; 1130 - pmu->desc[i].id = i; 1131 - pmu->desc[i].volt_table = info->volt_table; 1132 - pmu->desc[i].n_voltages = info->n_voltages; 1133 - pmu->desc[i].linear_ranges = info->linear_ranges; 1134 - pmu->desc[i].n_linear_ranges = info->n_linear_ranges; 1135 - 1136 - if ((BCM590XX_REG_IS_LDO(i)) || (BCM590XX_REG_IS_GPLDO(i))) { 1137 - pmu->desc[i].ops = &bcm590xx_ops_ldo; 1138 - pmu->desc[i].vsel_mask = BCM590XX_LDO_VSEL_MASK; 1139 - } else if (BCM590XX_REG_IS_VBUS(i)) 1140 - pmu->desc[i].ops = &bcm590xx_ops_vbus; 1141 - else { 1142 - pmu->desc[i].ops = &bcm590xx_ops_dcdc; 1143 - pmu->desc[i].vsel_mask = BCM590XX_SR_VSEL_MASK; 1144 - } 1145 - 1146 - if (BCM590XX_REG_IS_VBUS(i)) 1147 - pmu->desc[i].enable_mask = BCM590XX_VBUS_ENABLE; 1148 - else { 1149 - pmu->desc[i].vsel_reg = bcm590xx_get_vsel_register(i); 1150 - pmu->desc[i].enable_is_inverted = true; 1151 - pmu->desc[i].enable_mask = BCM590XX_REG_ENABLE; 1152 - } 1153 - pmu->desc[i].enable_reg = bcm590xx_get_enable_register(i); 1154 - pmu->desc[i].type = REGULATOR_VOLTAGE; 1155 - pmu->desc[i].owner = THIS_MODULE; 310 + /* Register the regulators */ 311 + for (i = 0; i < pmu->n_regulators; i++) { 312 + info = &pmu->regs[i]; 1156 313 1157 314 config.dev = bcm590xx->dev; 1158 315 config.driver_data = pmu; 1159 - if (BCM590XX_REG_IS_GPLDO(i) || BCM590XX_REG_IS_VBUS(i)) 1160 - config.regmap = bcm590xx->regmap_sec; 1161 - else 1162 - config.regmap = bcm590xx->regmap_pri; 1163 316 1164 - rdev = devm_regulator_register(&pdev->dev, &pmu->desc[i], 1165 - &config); 1166 - if (IS_ERR(rdev)) { 317 + switch (info->regmap) { 318 + case BCM590XX_REGMAP_PRI: 319 + config.regmap = bcm590xx->regmap_pri; 320 + break; 321 + case BCM590XX_REGMAP_SEC: 322 + config.regmap = bcm590xx->regmap_sec; 323 + break; 324 + default: 1167 325 dev_err(bcm590xx->dev, 1168 - "failed to register %s regulator\n", 326 + "invalid regmap for %s regulator; this is a driver bug\n", 1169 327 pdev->name); 1170 - return PTR_ERR(rdev); 328 + return -EINVAL; 1171 329 } 330 + 331 + rdev = devm_regulator_register(&pdev->dev, &info->desc, 332 + &config); 333 + if (IS_ERR(rdev)) 334 + return dev_err_probe(bcm590xx->dev, PTR_ERR(rdev), 335 + "failed to register %s regulator\n", 336 + pdev->name); 1172 337 } 1173 338 1174 339 return 0;
+403 -52
drivers/regulator/bd96801-regulator.c
··· 83 83 #define BD96801_LDO6_VSEL_REG 0x26 84 84 #define BD96801_LDO7_VSEL_REG 0x27 85 85 #define BD96801_BUCK_VSEL_MASK 0x1F 86 + #define BD96805_BUCK_VSEL_MASK 0x3f 86 87 #define BD96801_LDO_VSEL_MASK 0xff 87 88 88 89 #define BD96801_MASK_RAMP_DELAY 0xc0 ··· 91 90 #define BD96801_BUCK_INT_VOUT_MASK 0xff 92 91 93 92 #define BD96801_BUCK_VOLTS 256 93 + #define BD96805_BUCK_VOLTS 64 94 94 #define BD96801_LDO_VOLTS 256 95 95 96 96 #define BD96801_OVP_MASK 0x03 ··· 162 160 REGULATOR_LINEAR_RANGE(3300000 - 150000, 0xed, 0xff, 0), 163 161 }; 164 162 163 + /* BD96802 uses same voltage ranges for bucks as BD96801 */ 164 + #define bd96802_tune_volts bd96801_tune_volts 165 + #define bd96802_buck_init_volts bd96801_buck_init_volts 166 + 167 + /* 168 + * On BD96805 we have similar "negative tuning range" as on BD96801, except 169 + * that the max tuning is -310 ... +310 mV (instead of the 150mV). We use same 170 + * approach as with the BD96801 ranges. 171 + */ 172 + static const struct linear_range bd96805_tune_volts[] = { 173 + REGULATOR_LINEAR_RANGE(310000, 0x00, 0x1F, 10000), 174 + REGULATOR_LINEAR_RANGE(0, 0x20, 0x3F, 10000), 175 + }; 176 + 177 + static const struct linear_range bd96805_buck_init_volts[] = { 178 + REGULATOR_LINEAR_RANGE(500000 - 310000, 0x00, 0xc8, 5000), 179 + REGULATOR_LINEAR_RANGE(1550000 - 310000, 0xc9, 0xec, 50000), 180 + REGULATOR_LINEAR_RANGE(3300000 - 310000, 0xed, 0xff, 0), 181 + }; 182 + 183 + /* BD96806 uses same voltage ranges for bucks as BD96805 */ 184 + #define bd96806_tune_volts bd96805_tune_volts 185 + #define bd96806_buck_init_volts bd96805_buck_init_volts 186 + 165 187 static const struct linear_range bd96801_ldo_int_volts[] = { 166 188 REGULATOR_LINEAR_RANGE(300000, 0x00, 0x78, 25000), 167 189 REGULATOR_LINEAR_RANGE(3300000, 0x79, 0xff, 0), ··· 224 198 225 199 static const struct bd96801_irqinfo buck1_irqinfo[] = { 226 200 BD96801_IRQINFO(BD96801_PROT_OCP, "buck1-over-curr-h", 500, 227 - "bd96801-buck1-overcurr-h"), 201 + "buck1-overcurr-h"), 228 202 BD96801_IRQINFO(BD96801_PROT_OCP, "buck1-over-curr-l", 500, 229 - "bd96801-buck1-overcurr-l"), 203 + "buck1-overcurr-l"), 230 204 BD96801_IRQINFO(BD96801_PROT_OCP, "buck1-over-curr-n", 500, 231 - "bd96801-buck1-overcurr-n"), 205 + "buck1-overcurr-n"), 232 206 BD96801_IRQINFO(BD96801_PROT_OVP, "buck1-over-voltage", 500, 233 - "bd96801-buck1-overvolt"), 207 + "buck1-overvolt"), 234 208 BD96801_IRQINFO(BD96801_PROT_UVP, "buck1-under-voltage", 500, 235 - "bd96801-buck1-undervolt"), 209 + "buck1-undervolt"), 236 210 BD96801_IRQINFO(BD96801_PROT_TEMP, "buck1-over-temp", 500, 237 - "bd96801-buck1-thermal") 211 + "buck1-thermal") 238 212 }; 239 213 240 214 static const struct bd96801_irqinfo buck2_irqinfo[] = { 241 215 BD96801_IRQINFO(BD96801_PROT_OCP, "buck2-over-curr-h", 500, 242 - "bd96801-buck2-overcurr-h"), 216 + "buck2-overcurr-h"), 243 217 BD96801_IRQINFO(BD96801_PROT_OCP, "buck2-over-curr-l", 500, 244 - "bd96801-buck2-overcurr-l"), 218 + "buck2-overcurr-l"), 245 219 BD96801_IRQINFO(BD96801_PROT_OCP, "buck2-over-curr-n", 500, 246 - "bd96801-buck2-overcurr-n"), 220 + "buck2-overcurr-n"), 247 221 BD96801_IRQINFO(BD96801_PROT_OVP, "buck2-over-voltage", 500, 248 - "bd96801-buck2-overvolt"), 222 + "buck2-overvolt"), 249 223 BD96801_IRQINFO(BD96801_PROT_UVP, "buck2-under-voltage", 500, 250 - "bd96801-buck2-undervolt"), 224 + "buck2-undervolt"), 251 225 BD96801_IRQINFO(BD96801_PROT_TEMP, "buck2-over-temp", 500, 252 - "bd96801-buck2-thermal") 226 + "buck2-thermal") 253 227 }; 254 228 255 229 static const struct bd96801_irqinfo buck3_irqinfo[] = { 256 230 BD96801_IRQINFO(BD96801_PROT_OCP, "buck3-over-curr-h", 500, 257 - "bd96801-buck3-overcurr-h"), 231 + "buck3-overcurr-h"), 258 232 BD96801_IRQINFO(BD96801_PROT_OCP, "buck3-over-curr-l", 500, 259 - "bd96801-buck3-overcurr-l"), 233 + "buck3-overcurr-l"), 260 234 BD96801_IRQINFO(BD96801_PROT_OCP, "buck3-over-curr-n", 500, 261 - "bd96801-buck3-overcurr-n"), 235 + "buck3-overcurr-n"), 262 236 BD96801_IRQINFO(BD96801_PROT_OVP, "buck3-over-voltage", 500, 263 - "bd96801-buck3-overvolt"), 237 + "buck3-overvolt"), 264 238 BD96801_IRQINFO(BD96801_PROT_UVP, "buck3-under-voltage", 500, 265 - "bd96801-buck3-undervolt"), 239 + "buck3-undervolt"), 266 240 BD96801_IRQINFO(BD96801_PROT_TEMP, "buck3-over-temp", 500, 267 - "bd96801-buck3-thermal") 241 + "buck3-thermal") 268 242 }; 269 243 270 244 static const struct bd96801_irqinfo buck4_irqinfo[] = { 271 245 BD96801_IRQINFO(BD96801_PROT_OCP, "buck4-over-curr-h", 500, 272 - "bd96801-buck4-overcurr-h"), 246 + "buck4-overcurr-h"), 273 247 BD96801_IRQINFO(BD96801_PROT_OCP, "buck4-over-curr-l", 500, 274 - "bd96801-buck4-overcurr-l"), 248 + "buck4-overcurr-l"), 275 249 BD96801_IRQINFO(BD96801_PROT_OCP, "buck4-over-curr-n", 500, 276 - "bd96801-buck4-overcurr-n"), 250 + "buck4-overcurr-n"), 277 251 BD96801_IRQINFO(BD96801_PROT_OVP, "buck4-over-voltage", 500, 278 - "bd96801-buck4-overvolt"), 252 + "buck4-overvolt"), 279 253 BD96801_IRQINFO(BD96801_PROT_UVP, "buck4-under-voltage", 500, 280 - "bd96801-buck4-undervolt"), 254 + "buck4-undervolt"), 281 255 BD96801_IRQINFO(BD96801_PROT_TEMP, "buck4-over-temp", 500, 282 - "bd96801-buck4-thermal") 256 + "buck4-thermal") 283 257 }; 284 258 285 259 static const struct bd96801_irqinfo ldo5_irqinfo[] = { 286 260 BD96801_IRQINFO(BD96801_PROT_OCP, "ldo5-overcurr", 500, 287 - "bd96801-ldo5-overcurr"), 261 + "ldo5-overcurr"), 288 262 BD96801_IRQINFO(BD96801_PROT_OVP, "ldo5-over-voltage", 500, 289 - "bd96801-ldo5-overvolt"), 263 + "ldo5-overvolt"), 290 264 BD96801_IRQINFO(BD96801_PROT_UVP, "ldo5-under-voltage", 500, 291 - "bd96801-ldo5-undervolt"), 265 + "ldo5-undervolt"), 292 266 }; 293 267 294 268 static const struct bd96801_irqinfo ldo6_irqinfo[] = { 295 269 BD96801_IRQINFO(BD96801_PROT_OCP, "ldo6-overcurr", 500, 296 - "bd96801-ldo6-overcurr"), 270 + "ldo6-overcurr"), 297 271 BD96801_IRQINFO(BD96801_PROT_OVP, "ldo6-over-voltage", 500, 298 - "bd96801-ldo6-overvolt"), 272 + "ldo6-overvolt"), 299 273 BD96801_IRQINFO(BD96801_PROT_UVP, "ldo6-under-voltage", 500, 300 - "bd96801-ldo6-undervolt"), 274 + "ldo6-undervolt"), 301 275 }; 302 276 303 277 static const struct bd96801_irqinfo ldo7_irqinfo[] = { 304 278 BD96801_IRQINFO(BD96801_PROT_OCP, "ldo7-overcurr", 500, 305 - "bd96801-ldo7-overcurr"), 279 + "ldo7-overcurr"), 306 280 BD96801_IRQINFO(BD96801_PROT_OVP, "ldo7-over-voltage", 500, 307 - "bd96801-ldo7-overvolt"), 281 + "ldo7-overvolt"), 308 282 BD96801_IRQINFO(BD96801_PROT_UVP, "ldo7-under-voltage", 500, 309 - "bd96801-ldo7-undervolt"), 283 + "ldo7-undervolt"), 310 284 }; 311 285 312 286 struct bd96801_irq_desc { ··· 328 302 struct bd96801_regulator_data regulator_data[BD96801_NUM_REGULATORS]; 329 303 struct regmap *regmap; 330 304 int fatal_ind; 305 + int num_regulators; 331 306 }; 332 307 333 308 static int ldo_map_notif(int irq, struct regulator_irq_data *rid, ··· 530 503 * case later. What we can easly do for preparing is to not use static global 531 504 * data for regulators though. 532 505 */ 506 + static const struct bd96801_pmic_data bd96802_data = { 507 + .regulator_data = { 508 + { 509 + .desc = { 510 + .name = "buck1", 511 + .of_match = of_match_ptr("buck1"), 512 + .regulators_node = of_match_ptr("regulators"), 513 + .id = BD96801_BUCK1, 514 + .ops = &bd96801_buck_ops, 515 + .type = REGULATOR_VOLTAGE, 516 + .linear_ranges = bd96802_tune_volts, 517 + .n_linear_ranges = ARRAY_SIZE(bd96802_tune_volts), 518 + .n_voltages = BD96801_BUCK_VOLTS, 519 + .enable_reg = BD96801_REG_ENABLE, 520 + .enable_mask = BD96801_BUCK1_EN_MASK, 521 + .enable_is_inverted = true, 522 + .vsel_reg = BD96801_BUCK1_VSEL_REG, 523 + .vsel_mask = BD96801_BUCK_VSEL_MASK, 524 + .ramp_reg = BD96801_BUCK1_VSEL_REG, 525 + .ramp_mask = BD96801_MASK_RAMP_DELAY, 526 + .ramp_delay_table = &buck_ramp_table[0], 527 + .n_ramp_values = ARRAY_SIZE(buck_ramp_table), 528 + .owner = THIS_MODULE, 529 + }, 530 + .init_ranges = bd96802_buck_init_volts, 531 + .num_ranges = ARRAY_SIZE(bd96802_buck_init_volts), 532 + .irq_desc = { 533 + .irqinfo = (struct bd96801_irqinfo *)&buck1_irqinfo[0], 534 + .num_irqs = ARRAY_SIZE(buck1_irqinfo), 535 + }, 536 + }, 537 + { 538 + .desc = { 539 + .name = "buck2", 540 + .of_match = of_match_ptr("buck2"), 541 + .regulators_node = of_match_ptr("regulators"), 542 + .id = BD96801_BUCK2, 543 + .ops = &bd96801_buck_ops, 544 + .type = REGULATOR_VOLTAGE, 545 + .linear_ranges = bd96802_tune_volts, 546 + .n_linear_ranges = ARRAY_SIZE(bd96802_tune_volts), 547 + .n_voltages = BD96801_BUCK_VOLTS, 548 + .enable_reg = BD96801_REG_ENABLE, 549 + .enable_mask = BD96801_BUCK2_EN_MASK, 550 + .enable_is_inverted = true, 551 + .vsel_reg = BD96801_BUCK2_VSEL_REG, 552 + .vsel_mask = BD96801_BUCK_VSEL_MASK, 553 + .ramp_reg = BD96801_BUCK2_VSEL_REG, 554 + .ramp_mask = BD96801_MASK_RAMP_DELAY, 555 + .ramp_delay_table = &buck_ramp_table[0], 556 + .n_ramp_values = ARRAY_SIZE(buck_ramp_table), 557 + .owner = THIS_MODULE, 558 + }, 559 + .irq_desc = { 560 + .irqinfo = (struct bd96801_irqinfo *)&buck2_irqinfo[0], 561 + .num_irqs = ARRAY_SIZE(buck2_irqinfo), 562 + }, 563 + .init_ranges = bd96802_buck_init_volts, 564 + .num_ranges = ARRAY_SIZE(bd96802_buck_init_volts), 565 + }, 566 + }, 567 + .num_regulators = 2, 568 + }; 569 + 533 570 static const struct bd96801_pmic_data bd96801_data = { 534 571 .regulator_data = { 535 572 { ··· 779 688 .ldo_vol_lvl = BD96801_LDO7_VOL_LVL_REG, 780 689 }, 781 690 }, 691 + .num_regulators = 7, 782 692 }; 783 693 784 - static int initialize_pmic_data(struct device *dev, 694 + static const struct bd96801_pmic_data bd96805_data = { 695 + .regulator_data = { 696 + { 697 + .desc = { 698 + .name = "buck1", 699 + .of_match = of_match_ptr("buck1"), 700 + .regulators_node = of_match_ptr("regulators"), 701 + .id = BD96801_BUCK1, 702 + .ops = &bd96801_buck_ops, 703 + .type = REGULATOR_VOLTAGE, 704 + .linear_ranges = bd96805_tune_volts, 705 + .n_linear_ranges = ARRAY_SIZE(bd96805_tune_volts), 706 + .n_voltages = BD96805_BUCK_VOLTS, 707 + .enable_reg = BD96801_REG_ENABLE, 708 + .enable_mask = BD96801_BUCK1_EN_MASK, 709 + .enable_is_inverted = true, 710 + .vsel_reg = BD96801_BUCK1_VSEL_REG, 711 + .vsel_mask = BD96805_BUCK_VSEL_MASK, 712 + .ramp_reg = BD96801_BUCK1_VSEL_REG, 713 + .ramp_mask = BD96801_MASK_RAMP_DELAY, 714 + .ramp_delay_table = &buck_ramp_table[0], 715 + .n_ramp_values = ARRAY_SIZE(buck_ramp_table), 716 + .owner = THIS_MODULE, 717 + }, 718 + .init_ranges = bd96805_buck_init_volts, 719 + .num_ranges = ARRAY_SIZE(bd96805_buck_init_volts), 720 + .irq_desc = { 721 + .irqinfo = (struct bd96801_irqinfo *)&buck1_irqinfo[0], 722 + .num_irqs = ARRAY_SIZE(buck1_irqinfo), 723 + }, 724 + }, { 725 + .desc = { 726 + .name = "buck2", 727 + .of_match = of_match_ptr("buck2"), 728 + .regulators_node = of_match_ptr("regulators"), 729 + .id = BD96801_BUCK2, 730 + .ops = &bd96801_buck_ops, 731 + .type = REGULATOR_VOLTAGE, 732 + .linear_ranges = bd96805_tune_volts, 733 + .n_linear_ranges = ARRAY_SIZE(bd96805_tune_volts), 734 + .n_voltages = BD96805_BUCK_VOLTS, 735 + .enable_reg = BD96801_REG_ENABLE, 736 + .enable_mask = BD96801_BUCK2_EN_MASK, 737 + .enable_is_inverted = true, 738 + .vsel_reg = BD96801_BUCK2_VSEL_REG, 739 + .vsel_mask = BD96805_BUCK_VSEL_MASK, 740 + .ramp_reg = BD96801_BUCK2_VSEL_REG, 741 + .ramp_mask = BD96801_MASK_RAMP_DELAY, 742 + .ramp_delay_table = &buck_ramp_table[0], 743 + .n_ramp_values = ARRAY_SIZE(buck_ramp_table), 744 + .owner = THIS_MODULE, 745 + }, 746 + .irq_desc = { 747 + .irqinfo = (struct bd96801_irqinfo *)&buck2_irqinfo[0], 748 + .num_irqs = ARRAY_SIZE(buck2_irqinfo), 749 + }, 750 + .init_ranges = bd96805_buck_init_volts, 751 + .num_ranges = ARRAY_SIZE(bd96805_buck_init_volts), 752 + }, { 753 + .desc = { 754 + .name = "buck3", 755 + .of_match = of_match_ptr("buck3"), 756 + .regulators_node = of_match_ptr("regulators"), 757 + .id = BD96801_BUCK3, 758 + .ops = &bd96801_buck_ops, 759 + .type = REGULATOR_VOLTAGE, 760 + .linear_ranges = bd96805_tune_volts, 761 + .n_linear_ranges = ARRAY_SIZE(bd96805_tune_volts), 762 + .n_voltages = BD96805_BUCK_VOLTS, 763 + .enable_reg = BD96801_REG_ENABLE, 764 + .enable_mask = BD96801_BUCK3_EN_MASK, 765 + .enable_is_inverted = true, 766 + .vsel_reg = BD96801_BUCK3_VSEL_REG, 767 + .vsel_mask = BD96805_BUCK_VSEL_MASK, 768 + .ramp_reg = BD96801_BUCK3_VSEL_REG, 769 + .ramp_mask = BD96801_MASK_RAMP_DELAY, 770 + .ramp_delay_table = &buck_ramp_table[0], 771 + .n_ramp_values = ARRAY_SIZE(buck_ramp_table), 772 + .owner = THIS_MODULE, 773 + }, 774 + .irq_desc = { 775 + .irqinfo = (struct bd96801_irqinfo *)&buck3_irqinfo[0], 776 + .num_irqs = ARRAY_SIZE(buck3_irqinfo), 777 + }, 778 + .init_ranges = bd96805_buck_init_volts, 779 + .num_ranges = ARRAY_SIZE(bd96805_buck_init_volts), 780 + }, { 781 + .desc = { 782 + .name = "buck4", 783 + .of_match = of_match_ptr("buck4"), 784 + .regulators_node = of_match_ptr("regulators"), 785 + .id = BD96801_BUCK4, 786 + .ops = &bd96801_buck_ops, 787 + .type = REGULATOR_VOLTAGE, 788 + .linear_ranges = bd96805_tune_volts, 789 + .n_linear_ranges = ARRAY_SIZE(bd96805_tune_volts), 790 + .n_voltages = BD96805_BUCK_VOLTS, 791 + .enable_reg = BD96801_REG_ENABLE, 792 + .enable_mask = BD96801_BUCK4_EN_MASK, 793 + .enable_is_inverted = true, 794 + .vsel_reg = BD96801_BUCK4_VSEL_REG, 795 + .vsel_mask = BD96805_BUCK_VSEL_MASK, 796 + .ramp_reg = BD96801_BUCK4_VSEL_REG, 797 + .ramp_mask = BD96801_MASK_RAMP_DELAY, 798 + .ramp_delay_table = &buck_ramp_table[0], 799 + .n_ramp_values = ARRAY_SIZE(buck_ramp_table), 800 + .owner = THIS_MODULE, 801 + }, 802 + .irq_desc = { 803 + .irqinfo = (struct bd96801_irqinfo *)&buck4_irqinfo[0], 804 + .num_irqs = ARRAY_SIZE(buck4_irqinfo), 805 + }, 806 + .init_ranges = bd96805_buck_init_volts, 807 + .num_ranges = ARRAY_SIZE(bd96805_buck_init_volts), 808 + }, { 809 + .desc = { 810 + .name = "ldo5", 811 + .of_match = of_match_ptr("ldo5"), 812 + .regulators_node = of_match_ptr("regulators"), 813 + .id = BD96801_LDO5, 814 + .ops = &bd96801_ldo_ops, 815 + .type = REGULATOR_VOLTAGE, 816 + .linear_ranges = bd96801_ldo_int_volts, 817 + .n_linear_ranges = ARRAY_SIZE(bd96801_ldo_int_volts), 818 + .n_voltages = BD96801_LDO_VOLTS, 819 + .enable_reg = BD96801_REG_ENABLE, 820 + .enable_mask = BD96801_LDO5_EN_MASK, 821 + .enable_is_inverted = true, 822 + .vsel_reg = BD96801_LDO5_VSEL_REG, 823 + .vsel_mask = BD96801_LDO_VSEL_MASK, 824 + .owner = THIS_MODULE, 825 + }, 826 + .irq_desc = { 827 + .irqinfo = (struct bd96801_irqinfo *)&ldo5_irqinfo[0], 828 + .num_irqs = ARRAY_SIZE(ldo5_irqinfo), 829 + }, 830 + .ldo_vol_lvl = BD96801_LDO5_VOL_LVL_REG, 831 + }, { 832 + .desc = { 833 + .name = "ldo6", 834 + .of_match = of_match_ptr("ldo6"), 835 + .regulators_node = of_match_ptr("regulators"), 836 + .id = BD96801_LDO6, 837 + .ops = &bd96801_ldo_ops, 838 + .type = REGULATOR_VOLTAGE, 839 + .linear_ranges = bd96801_ldo_int_volts, 840 + .n_linear_ranges = ARRAY_SIZE(bd96801_ldo_int_volts), 841 + .n_voltages = BD96801_LDO_VOLTS, 842 + .enable_reg = BD96801_REG_ENABLE, 843 + .enable_mask = BD96801_LDO6_EN_MASK, 844 + .enable_is_inverted = true, 845 + .vsel_reg = BD96801_LDO6_VSEL_REG, 846 + .vsel_mask = BD96801_LDO_VSEL_MASK, 847 + .owner = THIS_MODULE, 848 + }, 849 + .irq_desc = { 850 + .irqinfo = (struct bd96801_irqinfo *)&ldo6_irqinfo[0], 851 + .num_irqs = ARRAY_SIZE(ldo6_irqinfo), 852 + }, 853 + .ldo_vol_lvl = BD96801_LDO6_VOL_LVL_REG, 854 + }, { 855 + .desc = { 856 + .name = "ldo7", 857 + .of_match = of_match_ptr("ldo7"), 858 + .regulators_node = of_match_ptr("regulators"), 859 + .id = BD96801_LDO7, 860 + .ops = &bd96801_ldo_ops, 861 + .type = REGULATOR_VOLTAGE, 862 + .linear_ranges = bd96801_ldo_int_volts, 863 + .n_linear_ranges = ARRAY_SIZE(bd96801_ldo_int_volts), 864 + .n_voltages = BD96801_LDO_VOLTS, 865 + .enable_reg = BD96801_REG_ENABLE, 866 + .enable_mask = BD96801_LDO7_EN_MASK, 867 + .enable_is_inverted = true, 868 + .vsel_reg = BD96801_LDO7_VSEL_REG, 869 + .vsel_mask = BD96801_LDO_VSEL_MASK, 870 + .owner = THIS_MODULE, 871 + }, 872 + .irq_desc = { 873 + .irqinfo = (struct bd96801_irqinfo *)&ldo7_irqinfo[0], 874 + .num_irqs = ARRAY_SIZE(ldo7_irqinfo), 875 + }, 876 + .ldo_vol_lvl = BD96801_LDO7_VOL_LVL_REG, 877 + }, 878 + }, 879 + .num_regulators = 7, 880 + }; 881 + 882 + static const struct bd96801_pmic_data bd96806_data = { 883 + .regulator_data = { 884 + { 885 + .desc = { 886 + .name = "buck1", 887 + .of_match = of_match_ptr("buck1"), 888 + .regulators_node = of_match_ptr("regulators"), 889 + .id = BD96801_BUCK1, 890 + .ops = &bd96801_buck_ops, 891 + .type = REGULATOR_VOLTAGE, 892 + .linear_ranges = bd96806_tune_volts, 893 + .n_linear_ranges = ARRAY_SIZE(bd96806_tune_volts), 894 + .n_voltages = BD96805_BUCK_VOLTS, 895 + .enable_reg = BD96801_REG_ENABLE, 896 + .enable_mask = BD96801_BUCK1_EN_MASK, 897 + .enable_is_inverted = true, 898 + .vsel_reg = BD96801_BUCK1_VSEL_REG, 899 + .vsel_mask = BD96805_BUCK_VSEL_MASK, 900 + .ramp_reg = BD96801_BUCK1_VSEL_REG, 901 + .ramp_mask = BD96801_MASK_RAMP_DELAY, 902 + .ramp_delay_table = &buck_ramp_table[0], 903 + .n_ramp_values = ARRAY_SIZE(buck_ramp_table), 904 + .owner = THIS_MODULE, 905 + }, 906 + .init_ranges = bd96806_buck_init_volts, 907 + .num_ranges = ARRAY_SIZE(bd96806_buck_init_volts), 908 + .irq_desc = { 909 + .irqinfo = (struct bd96801_irqinfo *)&buck1_irqinfo[0], 910 + .num_irqs = ARRAY_SIZE(buck1_irqinfo), 911 + }, 912 + }, 913 + { 914 + .desc = { 915 + .name = "buck2", 916 + .of_match = of_match_ptr("buck2"), 917 + .regulators_node = of_match_ptr("regulators"), 918 + .id = BD96801_BUCK2, 919 + .ops = &bd96801_buck_ops, 920 + .type = REGULATOR_VOLTAGE, 921 + .linear_ranges = bd96806_tune_volts, 922 + .n_linear_ranges = ARRAY_SIZE(bd96806_tune_volts), 923 + .n_voltages = BD96805_BUCK_VOLTS, 924 + .enable_reg = BD96801_REG_ENABLE, 925 + .enable_mask = BD96801_BUCK2_EN_MASK, 926 + .enable_is_inverted = true, 927 + .vsel_reg = BD96801_BUCK2_VSEL_REG, 928 + .vsel_mask = BD96805_BUCK_VSEL_MASK, 929 + .ramp_reg = BD96801_BUCK2_VSEL_REG, 930 + .ramp_mask = BD96801_MASK_RAMP_DELAY, 931 + .ramp_delay_table = &buck_ramp_table[0], 932 + .n_ramp_values = ARRAY_SIZE(buck_ramp_table), 933 + .owner = THIS_MODULE, 934 + }, 935 + .irq_desc = { 936 + .irqinfo = (struct bd96801_irqinfo *)&buck2_irqinfo[0], 937 + .num_irqs = ARRAY_SIZE(buck2_irqinfo), 938 + }, 939 + .init_ranges = bd96806_buck_init_volts, 940 + .num_ranges = ARRAY_SIZE(bd96806_buck_init_volts), 941 + }, 942 + }, 943 + .num_regulators = 2, 944 + }; 945 + 946 + static int initialize_pmic_data(struct platform_device *pdev, 785 947 struct bd96801_pmic_data *pdata) 786 948 { 949 + struct device *dev = &pdev->dev; 787 950 int r, i; 788 951 789 952 /* ··· 1045 700 * wish to modify IRQ information independently for each driver 1046 701 * instance. 1047 702 */ 1048 - for (r = 0; r < BD96801_NUM_REGULATORS; r++) { 703 + for (r = 0; r < pdata->num_regulators; r++) { 1049 704 const struct bd96801_irqinfo *template; 1050 705 struct bd96801_irqinfo *new; 1051 706 int num_infos; ··· 1086 741 int i; 1087 742 void *retp; 1088 743 static const char * const single_out_errb_irqs[] = { 1089 - "bd96801-%s-pvin-err", "bd96801-%s-ovp-err", 1090 - "bd96801-%s-uvp-err", "bd96801-%s-shdn-err", 744 + "%s-pvin-err", "%s-ovp-err", "%s-uvp-err", "%s-shdn-err", 1091 745 }; 1092 746 1093 747 for (i = 0; i < ARRAY_SIZE(single_out_errb_irqs); i++) { ··· 1123 779 int i, num_irqs; 1124 780 void *retp; 1125 781 static const char * const global_errb_irqs[] = { 1126 - "bd96801-otp-err", "bd96801-dbist-err", "bd96801-eep-err", 1127 - "bd96801-abist-err", "bd96801-prstb-err", "bd96801-drmoserr1", 1128 - "bd96801-drmoserr2", "bd96801-slave-err", "bd96801-vref-err", 1129 - "bd96801-tsd", "bd96801-uvlo-err", "bd96801-ovlo-err", 1130 - "bd96801-osc-err", "bd96801-pon-err", "bd96801-poff-err", 1131 - "bd96801-cmd-shdn-err", "bd96801-int-shdn-err" 782 + "otp-err", "dbist-err", "eep-err", "abist-err", "prstb-err", 783 + "drmoserr1", "drmoserr2", "slave-err", "vref-err", "tsd", 784 + "uvlo-err", "ovlo-err", "osc-err", "pon-err", "poff-err", 785 + "cmd-shdn-err", "int-shdn-err" 1132 786 }; 1133 787 1134 788 num_irqs = ARRAY_SIZE(global_errb_irqs); ··· 1211 869 { 1212 870 struct regulator_dev *ldo_errs_rdev_arr[BD96801_NUM_LDOS]; 1213 871 struct regulator_dev *all_rdevs[BD96801_NUM_REGULATORS]; 872 + struct bd96801_pmic_data *pdata_template; 1214 873 struct bd96801_regulator_data *rdesc; 1215 874 struct regulator_config config = {}; 1216 875 int ldo_errs_arr[BD96801_NUM_LDOS]; ··· 1224 881 1225 882 parent = pdev->dev.parent; 1226 883 1227 - pdata = devm_kmemdup(&pdev->dev, &bd96801_data, sizeof(bd96801_data), 884 + pdata_template = (struct bd96801_pmic_data *)platform_get_device_id(pdev)->driver_data; 885 + if (!pdata_template) 886 + return -ENODEV; 887 + 888 + pdata = devm_kmemdup(&pdev->dev, pdata_template, sizeof(bd96801_data), 1228 889 GFP_KERNEL); 1229 890 if (!pdata) 1230 891 return -ENOMEM; 1231 892 1232 - if (initialize_pmic_data(&pdev->dev, pdata)) 893 + if (initialize_pmic_data(pdev, pdata)) 1233 894 return -ENOMEM; 1234 895 1235 896 pdata->regmap = dev_get_regmap(parent, NULL); ··· 1256 909 use_errb = true; 1257 910 1258 911 ret = bd96801_walk_regulator_dt(&pdev->dev, pdata->regmap, rdesc, 1259 - BD96801_NUM_REGULATORS); 912 + pdata->num_regulators); 1260 913 if (ret) 1261 914 return ret; 1262 915 1263 - for (i = 0; i < ARRAY_SIZE(pdata->regulator_data); i++) { 916 + for (i = 0; i < pdata->num_regulators; i++) { 1264 917 struct regulator_dev *rdev; 1265 918 struct bd96801_irq_desc *idesc = &rdesc[i].irq_desc; 1266 919 int j; ··· 1273 926 rdesc[i].desc.name); 1274 927 return PTR_ERR(rdev); 1275 928 } 929 + 1276 930 all_rdevs[i] = rdev; 1277 931 /* 1278 932 * LDOs don't have own temperature monitoring. If temperature ··· 1304 956 if (temp_notif_ldos) { 1305 957 int irq; 1306 958 struct regulator_irq_desc tw_desc = { 1307 - .name = "bd96801-core-thermal", 959 + .name = "core-thermal", 1308 960 .irq_off_ms = 500, 1309 961 .map_event = ldo_map_notif, 1310 962 }; 1311 963 1312 - irq = platform_get_irq_byname(pdev, "bd96801-core-thermal"); 964 + irq = platform_get_irq_byname(pdev, "core-thermal"); 1313 965 if (irq < 0) 1314 966 return irq; 1315 967 ··· 1323 975 1324 976 if (use_errb) 1325 977 return bd96801_global_errb_irqs(pdev, all_rdevs, 1326 - ARRAY_SIZE(all_rdevs)); 978 + pdata->num_regulators); 1327 979 1328 980 return 0; 1329 981 } 1330 982 1331 983 static const struct platform_device_id bd96801_pmic_id[] = { 1332 - { "bd96801-regulator", }, 1333 - { } 984 + { "bd96801-regulator", (kernel_ulong_t)&bd96801_data }, 985 + { "bd96802-regulator", (kernel_ulong_t)&bd96802_data }, 986 + { "bd96805-regulator", (kernel_ulong_t)&bd96805_data }, 987 + { "bd96806-regulator", (kernel_ulong_t)&bd96806_data }, 988 + { }, 1334 989 }; 1335 990 MODULE_DEVICE_TABLE(platform, bd96801_pmic_id); 1336 991
+27
include/linux/mfd/bcm590xx.h
··· 13 13 #include <linux/i2c.h> 14 14 #include <linux/regmap.h> 15 15 16 + /* PMU ID register values; also used as device type */ 17 + #define BCM590XX_PMUID_BCM59054 0x54 18 + #define BCM590XX_PMUID_BCM59056 0x56 19 + 20 + /* Known chip revision IDs */ 21 + #define BCM59054_REV_DIGITAL_A1 1 22 + #define BCM59054_REV_ANALOG_A1 2 23 + 24 + #define BCM59056_REV_DIGITAL_A0 1 25 + #define BCM59056_REV_ANALOG_A0 1 26 + 27 + #define BCM59056_REV_DIGITAL_B0 2 28 + #define BCM59056_REV_ANALOG_B0 2 29 + 30 + /* regmap types */ 31 + enum bcm590xx_regmap_type { 32 + BCM590XX_REGMAP_PRI, 33 + BCM590XX_REGMAP_SEC, 34 + }; 35 + 16 36 /* max register address */ 17 37 #define BCM590XX_MAX_REGISTER_PRI 0xe7 18 38 #define BCM590XX_MAX_REGISTER_SEC 0xf0 ··· 44 24 struct regmap *regmap_pri; 45 25 struct regmap *regmap_sec; 46 26 unsigned int id; 27 + 28 + /* PMU ID value; also used as device type */ 29 + u8 pmu_id; 30 + 31 + /* Chip revision, read from PMUREV reg */ 32 + u8 rev_digital; 33 + u8 rev_analog; 47 34 }; 48 35 49 36 #endif /* __LINUX_MFD_BCM590XX_H */
+165
include/linux/mfd/max77759.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright 2020 Google Inc. 4 + * Copyright 2025 Linaro Ltd. 5 + * 6 + * Maxim MAX77759 core driver 7 + */ 8 + 9 + #ifndef __LINUX_MFD_MAX77759_H 10 + #define __LINUX_MFD_MAX77759_H 11 + 12 + #include <linux/completion.h> 13 + #include <linux/mutex.h> 14 + #include <linux/regmap.h> 15 + 16 + #define MAX77759_PMIC_REG_PMIC_ID 0x00 17 + #define MAX77759_PMIC_REG_PMIC_REVISION 0x01 18 + #define MAX77759_PMIC_REG_OTP_REVISION 0x02 19 + #define MAX77759_PMIC_REG_INTSRC 0x22 20 + #define MAX77759_PMIC_REG_INTSRCMASK 0x23 21 + #define MAX77759_PMIC_REG_INTSRC_MAXQ BIT(3) 22 + #define MAX77759_PMIC_REG_INTSRC_TOPSYS BIT(1) 23 + #define MAX77759_PMIC_REG_INTSRC_CHGR BIT(0) 24 + #define MAX77759_PMIC_REG_TOPSYS_INT 0x24 25 + #define MAX77759_PMIC_REG_TOPSYS_INT_MASK 0x26 26 + #define MAX77759_PMIC_REG_TOPSYS_INT_TSHDN BIT(6) 27 + #define MAX77759_PMIC_REG_TOPSYS_INT_SYSOVLO BIT(5) 28 + #define MAX77759_PMIC_REG_TOPSYS_INT_SYSUVLO BIT(4) 29 + #define MAX77759_PMIC_REG_TOPSYS_INT_FSHIP BIT(0) 30 + #define MAX77759_PMIC_REG_I2C_CNFG 0x40 31 + #define MAX77759_PMIC_REG_SWRESET 0x50 32 + #define MAX77759_PMIC_REG_CONTROL_FG 0x51 33 + 34 + #define MAX77759_MAXQ_REG_UIC_INT1 0x64 35 + #define MAX77759_MAXQ_REG_UIC_INT1_APCMDRESI BIT(7) 36 + #define MAX77759_MAXQ_REG_UIC_INT1_SYSMSGI BIT(6) 37 + #define MAX77759_MAXQ_REG_UIC_INT1_GPIO6I BIT(1) 38 + #define MAX77759_MAXQ_REG_UIC_INT1_GPIO5I BIT(0) 39 + #define MAX77759_MAXQ_REG_UIC_INT1_GPIOxI(offs, en) (((en) & 1) << (offs)) 40 + #define MAX77759_MAXQ_REG_UIC_INT1_GPIOxI_MASK(offs) \ 41 + MAX77759_MAXQ_REG_UIC_INT1_GPIOxI(offs, ~0) 42 + #define MAX77759_MAXQ_REG_UIC_INT2 0x65 43 + #define MAX77759_MAXQ_REG_UIC_INT3 0x66 44 + #define MAX77759_MAXQ_REG_UIC_INT4 0x67 45 + #define MAX77759_MAXQ_REG_UIC_UIC_STATUS1 0x68 46 + #define MAX77759_MAXQ_REG_UIC_UIC_STATUS2 0x69 47 + #define MAX77759_MAXQ_REG_UIC_UIC_STATUS3 0x6a 48 + #define MAX77759_MAXQ_REG_UIC_UIC_STATUS4 0x6b 49 + #define MAX77759_MAXQ_REG_UIC_UIC_STATUS5 0x6c 50 + #define MAX77759_MAXQ_REG_UIC_UIC_STATUS6 0x6d 51 + #define MAX77759_MAXQ_REG_UIC_UIC_STATUS7 0x6f 52 + #define MAX77759_MAXQ_REG_UIC_UIC_STATUS8 0x6f 53 + #define MAX77759_MAXQ_REG_UIC_INT1_M 0x70 54 + #define MAX77759_MAXQ_REG_UIC_INT2_M 0x71 55 + #define MAX77759_MAXQ_REG_UIC_INT3_M 0x72 56 + #define MAX77759_MAXQ_REG_UIC_INT4_M 0x73 57 + #define MAX77759_MAXQ_REG_AP_DATAOUT0 0x81 58 + #define MAX77759_MAXQ_REG_AP_DATAOUT32 0xa1 59 + #define MAX77759_MAXQ_REG_AP_DATAIN0 0xb1 60 + #define MAX77759_MAXQ_REG_UIC_SWRST 0xe0 61 + 62 + #define MAX77759_CHGR_REG_CHG_INT 0xb0 63 + #define MAX77759_CHGR_REG_CHG_INT2 0xb1 64 + #define MAX77759_CHGR_REG_CHG_INT_MASK 0xb2 65 + #define MAX77759_CHGR_REG_CHG_INT2_MASK 0xb3 66 + #define MAX77759_CHGR_REG_CHG_INT_OK 0xb4 67 + #define MAX77759_CHGR_REG_CHG_DETAILS_00 0xb5 68 + #define MAX77759_CHGR_REG_CHG_DETAILS_01 0xb6 69 + #define MAX77759_CHGR_REG_CHG_DETAILS_02 0xb7 70 + #define MAX77759_CHGR_REG_CHG_DETAILS_03 0xb8 71 + #define MAX77759_CHGR_REG_CHG_CNFG_00 0xb9 72 + #define MAX77759_CHGR_REG_CHG_CNFG_01 0xba 73 + #define MAX77759_CHGR_REG_CHG_CNFG_02 0xbb 74 + #define MAX77759_CHGR_REG_CHG_CNFG_03 0xbc 75 + #define MAX77759_CHGR_REG_CHG_CNFG_04 0xbd 76 + #define MAX77759_CHGR_REG_CHG_CNFG_05 0xbe 77 + #define MAX77759_CHGR_REG_CHG_CNFG_06 0xbf 78 + #define MAX77759_CHGR_REG_CHG_CNFG_07 0xc0 79 + #define MAX77759_CHGR_REG_CHG_CNFG_08 0xc1 80 + #define MAX77759_CHGR_REG_CHG_CNFG_09 0xc2 81 + #define MAX77759_CHGR_REG_CHG_CNFG_10 0xc3 82 + #define MAX77759_CHGR_REG_CHG_CNFG_11 0xc4 83 + #define MAX77759_CHGR_REG_CHG_CNFG_12 0xc5 84 + #define MAX77759_CHGR_REG_CHG_CNFG_13 0xc6 85 + #define MAX77759_CHGR_REG_CHG_CNFG_14 0xc7 86 + #define MAX77759_CHGR_REG_CHG_CNFG_15 0xc8 87 + #define MAX77759_CHGR_REG_CHG_CNFG_16 0xc9 88 + #define MAX77759_CHGR_REG_CHG_CNFG_17 0xca 89 + #define MAX77759_CHGR_REG_CHG_CNFG_18 0xcb 90 + #define MAX77759_CHGR_REG_CHG_CNFG_19 0xcc 91 + 92 + /* MaxQ opcodes for max77759_maxq_command() */ 93 + #define MAX77759_MAXQ_OPCODE_MAXLENGTH (MAX77759_MAXQ_REG_AP_DATAOUT32 - \ 94 + MAX77759_MAXQ_REG_AP_DATAOUT0 + \ 95 + 1) 96 + 97 + #define MAX77759_MAXQ_OPCODE_GPIO_TRIGGER_READ 0x21 98 + #define MAX77759_MAXQ_OPCODE_GPIO_TRIGGER_WRITE 0x22 99 + #define MAX77759_MAXQ_OPCODE_GPIO_CONTROL_READ 0x23 100 + #define MAX77759_MAXQ_OPCODE_GPIO_CONTROL_WRITE 0x24 101 + #define MAX77759_MAXQ_OPCODE_USER_SPACE_READ 0x81 102 + #define MAX77759_MAXQ_OPCODE_USER_SPACE_WRITE 0x82 103 + 104 + /** 105 + * struct max77759 - core max77759 internal data structure 106 + * 107 + * @regmap_top: Regmap for accessing TOP registers 108 + * @maxq_lock: Lock for serializing access to MaxQ 109 + * @regmap_maxq: Regmap for accessing MaxQ registers 110 + * @cmd_done: Used to signal completion of a MaxQ command 111 + * @regmap_charger: Regmap for accessing charger registers 112 + * 113 + * The MAX77759 comprises several sub-blocks, namely TOP, MaxQ, Charger, 114 + * Fuel Gauge, and TCPCI. 115 + */ 116 + struct max77759 { 117 + struct regmap *regmap_top; 118 + 119 + /* This protects MaxQ commands - only one can be active */ 120 + struct mutex maxq_lock; 121 + struct regmap *regmap_maxq; 122 + struct completion cmd_done; 123 + 124 + struct regmap *regmap_charger; 125 + }; 126 + 127 + /** 128 + * struct max77759_maxq_command - structure containing the MaxQ command to 129 + * send 130 + * 131 + * @length: The number of bytes to send. 132 + * @cmd: The data to send. 133 + */ 134 + struct max77759_maxq_command { 135 + u8 length; 136 + u8 cmd[] __counted_by(length); 137 + }; 138 + 139 + /** 140 + * struct max77759_maxq_response - structure containing the MaxQ response 141 + * 142 + * @length: The number of bytes to receive. 143 + * @rsp: The data received. Must have at least @length bytes space. 144 + */ 145 + struct max77759_maxq_response { 146 + u8 length; 147 + u8 rsp[] __counted_by(length); 148 + }; 149 + 150 + /** 151 + * max77759_maxq_command() - issue a MaxQ command and wait for the response 152 + * and associated data 153 + * 154 + * @max77759: The core max77759 device handle. 155 + * @cmd: The command to be sent. 156 + * @rsp: Any response data associated with the command will be copied here; 157 + * can be %NULL if the command has no response (other than ACK). 158 + * 159 + * Return: 0 on success, a negative error number otherwise. 160 + */ 161 + int max77759_maxq_command(struct max77759 *max77759, 162 + const struct max77759_maxq_command *cmd, 163 + struct max77759_maxq_response *rsp); 164 + 165 + #endif /* __LINUX_MFD_MAX77759_H */
+2
include/linux/mfd/rohm-bd96801.h
··· 40 40 * INTB status registers are at range 0x5c ... 0x63 41 41 */ 42 42 #define BD96801_REG_INT_SYS_ERRB1 0x52 43 + #define BD96801_REG_INT_BUCK2_ERRB 0x56 43 44 #define BD96801_REG_INT_SYS_INTB 0x5c 45 + #define BD96801_REG_INT_BUCK2_INTB 0x5e 44 46 #define BD96801_REG_INT_LDO7_INTB 0x63 45 47 46 48 /* MASK registers */
+74
include/linux/mfd/rohm-bd96802.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 + /* 3 + * Copyright (C) 2025 ROHM Semiconductors 4 + * 5 + * The digital interface of trhe BD96802 PMIC is a reduced version of the 6 + * BD96801. Hence the BD96801 definitions are used for registers and masks 7 + * while this header only holds the IRQ definitions - mainly to avoid gaps in 8 + * IRQ numbers caused by the lack of some BUCKs / LDOs and their respective 9 + * IRQs. 10 + */ 11 + 12 + #ifndef __LINUX_MFD_BD96802_H__ 13 + #define __LINUX_MFD_BD96802_H__ 14 + 15 + /* ERRB IRQs */ 16 + enum { 17 + /* Reg 0x52, 0x53, 0x54 - ERRB system IRQs */ 18 + BD96802_OTP_ERR_STAT, 19 + BD96802_DBIST_ERR_STAT, 20 + BD96802_EEP_ERR_STAT, 21 + BD96802_ABIST_ERR_STAT, 22 + BD96802_PRSTB_ERR_STAT, 23 + BD96802_DRMOS1_ERR_STAT, 24 + BD96802_DRMOS2_ERR_STAT, 25 + BD96802_SLAVE_ERR_STAT, 26 + BD96802_VREF_ERR_STAT, 27 + BD96802_TSD_ERR_STAT, 28 + BD96802_UVLO_ERR_STAT, 29 + BD96802_OVLO_ERR_STAT, 30 + BD96802_OSC_ERR_STAT, 31 + BD96802_PON_ERR_STAT, 32 + BD96802_POFF_ERR_STAT, 33 + BD96802_CMD_SHDN_ERR_STAT, 34 + BD96802_INT_SHDN_ERR_STAT, 35 + 36 + /* Reg 0x55 BUCK1 ERR IRQs */ 37 + BD96802_BUCK1_PVIN_ERR_STAT, 38 + BD96802_BUCK1_OVP_ERR_STAT, 39 + BD96802_BUCK1_UVP_ERR_STAT, 40 + BD96802_BUCK1_SHDN_ERR_STAT, 41 + 42 + /* Reg 0x56 BUCK2 ERR IRQs */ 43 + BD96802_BUCK2_PVIN_ERR_STAT, 44 + BD96802_BUCK2_OVP_ERR_STAT, 45 + BD96802_BUCK2_UVP_ERR_STAT, 46 + BD96802_BUCK2_SHDN_ERR_STAT, 47 + }; 48 + 49 + /* INTB IRQs */ 50 + enum { 51 + /* Reg 0x5c (System INTB) */ 52 + BD96802_TW_STAT, 53 + BD96802_WDT_ERR_STAT, 54 + BD96802_I2C_ERR_STAT, 55 + BD96802_CHIP_IF_ERR_STAT, 56 + 57 + /* Reg 0x5d (BUCK1 INTB) */ 58 + BD96802_BUCK1_OCPH_STAT, 59 + BD96802_BUCK1_OCPL_STAT, 60 + BD96802_BUCK1_OCPN_STAT, 61 + BD96802_BUCK1_OVD_STAT, 62 + BD96802_BUCK1_UVD_STAT, 63 + BD96802_BUCK1_TW_CH_STAT, 64 + 65 + /* Reg 0x5e (BUCK2 INTB) */ 66 + BD96802_BUCK2_OCPH_STAT, 67 + BD96802_BUCK2_OCPL_STAT, 68 + BD96802_BUCK2_OCPN_STAT, 69 + BD96802_BUCK2_OVD_STAT, 70 + BD96802_BUCK2_UVD_STAT, 71 + BD96802_BUCK2_TW_CH_STAT, 72 + }; 73 + 74 + #endif
+3
include/linux/mfd/rohm-generic.h
··· 17 17 ROHM_CHIP_TYPE_BD71837, 18 18 ROHM_CHIP_TYPE_BD71847, 19 19 ROHM_CHIP_TYPE_BD96801, 20 + ROHM_CHIP_TYPE_BD96802, 21 + ROHM_CHIP_TYPE_BD96805, 22 + ROHM_CHIP_TYPE_BD96806, 20 23 ROHM_CHIP_TYPE_AMOUNT 21 24 }; 22 25
+34 -3
include/linux/mfd/stm32-lptimer.h
··· 17 17 #define STM32_LPTIM_IER 0x08 /* Interrupt Enable Reg */ 18 18 #define STM32_LPTIM_CFGR 0x0C /* Configuration Reg */ 19 19 #define STM32_LPTIM_CR 0x10 /* Control Reg */ 20 - #define STM32_LPTIM_CMP 0x14 /* Compare Reg */ 20 + #define STM32_LPTIM_CMP 0x14 /* Compare Reg (MP25 CCR1) */ 21 21 #define STM32_LPTIM_ARR 0x18 /* Autoreload Reg */ 22 22 #define STM32_LPTIM_CNT 0x1C /* Counter Reg */ 23 + #define STM32_LPTIM_CCMR1 0x2C /* Capture/Compare Mode MP25 */ 24 + #define STM32_LPTIM_CCR2 0x34 /* Compare Reg2 MP25 */ 25 + 26 + #define STM32_LPTIM_HWCFGR2 0x3EC /* Hardware configuration register 2 - MP25 */ 27 + #define STM32_LPTIM_HWCFGR1 0x3F0 /* Hardware configuration register 1 - MP15 */ 28 + #define STM32_LPTIM_VERR 0x3F4 /* Version identification register - MP15 */ 23 29 24 30 /* STM32_LPTIM_ISR - bit fields */ 31 + #define STM32_LPTIM_DIEROK_ARROK (BIT(24) | BIT(4)) /* MP25 */ 32 + #define STM32_LPTIM_CMP2_ARROK (BIT(19) | BIT(4)) 25 33 #define STM32_LPTIM_CMPOK_ARROK GENMASK(4, 3) 26 34 #define STM32_LPTIM_ARROK BIT(4) 27 35 #define STM32_LPTIM_CMPOK BIT(3) 28 36 29 37 /* STM32_LPTIM_ICR - bit fields */ 30 - #define STM32_LPTIM_ARRMCF BIT(1) 38 + #define STM32_LPTIM_DIEROKCF_ARROKCF (BIT(24) | BIT(4)) /* MP25 */ 39 + #define STM32_LPTIM_CMP2OKCF_ARROKCF (BIT(19) | BIT(4)) 31 40 #define STM32_LPTIM_CMPOKCF_ARROKCF GENMASK(4, 3) 41 + #define STM32_LPTIM_ARRMCF BIT(1) 32 42 33 - /* STM32_LPTIM_IER - bit flieds */ 43 + /* STM32_LPTIM_IER - bit fields */ 34 44 #define STM32_LPTIM_ARRMIE BIT(1) 35 45 36 46 /* STM32_LPTIM_CR - bit fields */ ··· 63 53 /* STM32_LPTIM_ARR */ 64 54 #define STM32_LPTIM_MAX_ARR 0xFFFF 65 55 56 + /* STM32_LPTIM_CCMR1 */ 57 + #define STM32_LPTIM_CC2P GENMASK(19, 18) 58 + #define STM32_LPTIM_CC2E BIT(17) 59 + #define STM32_LPTIM_CC2SEL BIT(16) 60 + #define STM32_LPTIM_CC1P GENMASK(3, 2) 61 + #define STM32_LPTIM_CC1E BIT(1) 62 + #define STM32_LPTIM_CC1SEL BIT(0) 63 + 64 + /* STM32_LPTIM_HWCFGR1 */ 65 + #define STM32_LPTIM_HWCFGR1_ENCODER BIT(16) 66 + 67 + /* STM32_LPTIM_HWCFGR2 */ 68 + #define STM32_LPTIM_HWCFGR2_CHAN_NUM GENMASK(3, 0) 69 + 70 + /* STM32_LPTIM_VERR */ 71 + #define STM32_LPTIM_VERR_23 0x23 /* STM32MP25 */ 72 + 66 73 /** 67 74 * struct stm32_lptimer - STM32 Low-Power Timer data assigned by parent device 68 75 * @clk: clock reference for this instance 69 76 * @regmap: register map reference for this instance 70 77 * @has_encoder: indicates this Low-Power Timer supports encoder mode 78 + * @num_cc_chans: indicates the number of capture/compare channels 79 + * @version: indicates the major and minor revision of the controller 71 80 */ 72 81 struct stm32_lptimer { 73 82 struct clk *clk; 74 83 struct regmap *regmap; 75 84 bool has_encoder; 85 + unsigned int num_cc_chans; 86 + u32 version; 76 87 }; 77 88 78 89 #endif