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

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

Pull MFD updates from Lee Jones:
"Core Framework:
- Add support for Software Nodes to MFD Core
- Remove support for Device Properties from MFD Core
- Use standard APIs in MFD Core

New Drivers:
- Add support for ROHM BD9576MUF and BD9573MUF PMICs
- Add support for Netronix Embedded Controller, PWM and RTC
- Add support for Actions Semi ATC260x PMICs and OnKey

New Device Support:
- Add support for DG1 PCIe Graphics Card to Intel PMT
- Add support for ROHM BD71815 PMIC to ROHM BD71828
- Add support for Tolino Shine 2 HD to Netronix Embedded Controller
- Add support for AX10 BMC Secure Updates to Intel M10 BMC

Removed Device Support:
- Remove Arizona Extcon support from MFD
- Remove ST-E AB8500 Power Supply code from MFD
- Remove AB3100 altogether

New Functionality:
- Add support for SMBus and I2C modes to Dialog DA9063
- Switch to using Software Nodes in Intel (various)

New/converted Device Tree bindings:
- rohm bd71815-pmic, rohm bd9576-pmic, netronix ntxec, actions
atc260x, ricoh rn5t618, qcom pm8xxx

- Fix-ups:
- Fix error handling/path; intel_pmt
- Simplify code; rohm-bd718x7, ab8500-core, intel-m10-bmc
- Trivial clean-ups (reordering, spelling); rohm-generic, rn5t618,
max8997
- Use correct data-type; db8500-prcmu
- Remove superfluous code; lp87565, intel_quark_i2c_gpi, lpc_sch, twl
- Use generic APIs/defines; lm3533-core, intel_quark_i2c_gpio
- Regmap related fix-ups; intel-m10-bmc, sec-core
- Reorder resource freeing during remove; intel_quark_i2c_gpio
- Make table indexing more robust; intel_quark_i2c_gpio
- Fix reference imbalances; arizona-irq
- Staticify and (un)constify things; arizona-spi, stmpe, ene-kb3930,
intel-lpss-acpi, intel-lpss-pci, atc260x-i2c, intel_quark_i2c_gpio

Bug Fixes:
- Fix incorrect (register) values; intel-m10-bmc
- Kconfig related fixes; ABX500_CORE
- Do not clear the Auto Reload Register; stm32-timers"

* tag 'mfd-next-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (84 commits)
mfd: intel-m10-bmc: Add support for MAX10 BMC Secure Updates
Revert "mfd: max8997: Add of_compatible to Extcon and Charger mfd_cell"
mfd: twl: Remove unused inline function twl4030charger_usb_en()
dt-bindings: mfd: Convert pm8xxx bindings to yaml
dt-bindings: mfd: Add compatible for pmk8350 rtc
i2c: designware: Get rid of legacy platform data
mfd: intel_quark_i2c_gpio: Convert I²C to use software nodes
mfd: lpc_sch: Partially revert "Add support for Intel Quark X1000"
mfd: arizona: Fix rumtime PM imbalance on error
mfd: max8997: Replace 8998 with 8997
mfd: core: Use acpi_find_child_device() for child devices lookup
mfd: intel_quark_i2c_gpio: Don't play dirty trick with const
mfd: intel_quark_i2c_gpio: Enable MSI interrupt
mfd: intel_quark_i2c_gpio: Reuse BAR definitions for MFD cell indexing
mfd: ntxec: Support for EC in Tolino Shine 2 HD
mfd: stm32-timers: Avoid clearing auto reload register
mfd: intel_quark_i2c_gpio: Replace I²C speeds with descriptive definitions
mfd: intel_quark_i2c_gpio: Remove unused struct device member
mfd: intel_quark_i2c_gpio: Unregister resources in reversed order
mfd: Kconfig: ABX500_CORE should depend on ARCH_U8500
...

+5926 -2057
+3
CREDITS
··· 1933 1933 E: kgene@kernel.org 1934 1934 D: Samsung S3C, S5P and Exynos ARM architectures 1935 1935 1936 + N: Milo Kim 1937 + D: TI LP855x, LP8727 and LP8788 drivers 1938 + 1936 1939 N: Sangbeom Kim 1937 1940 E: sbkim73@samsung.com 1938 1941 D: Samsung SoC Audio (ASoC) drivers
+7
Documentation/devicetree/bindings/input/input.yaml
··· 33 33 power off automatically. Device with key pressed shutdown feature can 34 34 specify this property. 35 35 36 + reset-time-sec: 37 + description: 38 + Duration in seconds which the key should be kept pressed for device to 39 + reset automatically. Device with key pressed reset feature can specify 40 + this property. 41 + $ref: /schemas/types.yaml#/definitions/uint32 42 + 36 43 additionalProperties: true
+183
Documentation/devicetree/bindings/mfd/actions,atc260x.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/actions,atc260x.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Actions Semi ATC260x Power Management IC bindings 8 + 9 + maintainers: 10 + - Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> 11 + - Cristian Ciocaltea <cristian.ciocaltea@gmail.com> 12 + 13 + description: | 14 + ATC260x series PMICs integrates Audio Codec, Power Management, RTC, IR 15 + and GPIO controller blocks. Currently only the PM related functionalities 16 + (i.e. regulators and system power-off/reboot) for the ATC2603C and ATC2609A 17 + chip variants are supported. 18 + ATC2603C includes 3 programmable DC-DC converters, 9 programmable LDO 19 + regulators and 1 fixed LDO regulator. 20 + ATC2609A includes 5 programmable DC-DC converters and 10 programmable LDO 21 + regulators. 22 + 23 + allOf: 24 + - $ref: ../input/input.yaml 25 + 26 + properties: 27 + compatible: 28 + enum: 29 + - actions,atc2603c 30 + - actions,atc2609a 31 + 32 + reg: 33 + maxItems: 1 34 + 35 + interrupts: 36 + maxItems: 1 37 + 38 + reset-time-sec: 39 + description: | 40 + Duration in seconds which the key should be kept pressed for device 41 + to reset automatically. The hardware default is 8. Use 0 to disable 42 + this functionality. 43 + enum: [0, 6, 8, 10, 12] 44 + 45 + regulators: 46 + type: object 47 + description: | 48 + List of child nodes specifying the regulators, depending on chip variant: 49 + * ATC2603C: dcdc[1-3], ldo[1-3,5-8,11,12], switchldo1 50 + * ATC2609A: dcdc[0-4], ldo[0-9] 51 + 52 + properties: 53 + compatible: 54 + enum: 55 + - actions,atc2603c-regulator 56 + - actions,atc2609a-regulator 57 + 58 + switchldo1: 59 + type: object 60 + $ref: ../regulator/regulator.yaml 61 + 62 + properties: 63 + regulator-name: true 64 + regulator-boot-on: true 65 + regulator-always-on: true 66 + regulator-min-microvolt: true 67 + regulator-max-microvolt: true 68 + regulator-allow-bypass: true 69 + regulator-active-discharge: true 70 + 71 + additionalProperties: false 72 + 73 + patternProperties: 74 + "^(dcdc[0-4]|ldo[0-9]|ldo1[1-2]|switchldo1)-supply$": 75 + description: ATC260x voltage regulators supplies 76 + 77 + "^(dcdc[0-4]|ldo[0-9]|ldo1[1-2])$": 78 + type: object 79 + $ref: ../regulator/regulator.yaml 80 + 81 + properties: 82 + regulator-name: true 83 + regulator-boot-on: true 84 + regulator-always-on: true 85 + regulator-min-microvolt: true 86 + regulator-max-microvolt: true 87 + regulator-allow-bypass: true 88 + 89 + additionalProperties: false 90 + 91 + allOf: 92 + - if: 93 + properties: 94 + compatible: 95 + contains: 96 + const: actions,atc2603c-regulator 97 + then: 98 + patternProperties: 99 + "^(dcdc[0,4]|ldo[0,4,9])(-supply)?$": false 100 + 101 + "^(ldo|dcdc)": 102 + properties: 103 + regulator-allow-bypass: false 104 + - if: 105 + properties: 106 + compatible: 107 + contains: 108 + const: actions,atc2609a-regulator 109 + then: 110 + patternProperties: 111 + "^(ldo1[1-2]|switchldo1)(-supply)?$": false 112 + 113 + "^(dcdc|ldo[3-9])": 114 + properties: 115 + regulator-allow-bypass: false 116 + 117 + required: 118 + - compatible 119 + 120 + additionalProperties: false 121 + 122 + additionalProperties: false 123 + 124 + required: 125 + - compatible 126 + - reg 127 + - interrupts 128 + 129 + examples: 130 + - | 131 + #include <dt-bindings/interrupt-controller/arm-gic.h> 132 + i2c0 { 133 + #address-cells = <1>; 134 + #size-cells = <0>; 135 + 136 + pmic@65 { 137 + compatible = "actions,atc2603c"; 138 + reg = <0x65>; 139 + interrupt-parent = <&sirq>; 140 + interrupts = <2 IRQ_TYPE_LEVEL_HIGH>; 141 + 142 + reset-time-sec = <6>; 143 + 144 + regulators { 145 + compatible = "actions,atc2603c-regulator"; 146 + 147 + dcdc1-supply = <&reg_5v0>; 148 + dcdc3-supply = <&reg_5v0>; 149 + ldo5-supply = <&reg_5v0>; 150 + switchldo1-supply = <&vcc>; 151 + 152 + vdd_cpu: dcdc1 { 153 + regulator-name = "VDD_CPU"; 154 + regulator-min-microvolt = <700000>; 155 + regulator-max-microvolt = <1400000>; 156 + regulator-always-on; 157 + }; 158 + 159 + vcc: dcdc3 { 160 + regulator-name = "VCC"; 161 + regulator-min-microvolt = <2600000>; 162 + regulator-max-microvolt = <3300000>; 163 + regulator-always-on; 164 + }; 165 + 166 + vcc_3v1: ldo5 { 167 + regulator-name = "VCC_3V1"; 168 + regulator-min-microvolt = <2600000>; 169 + regulator-max-microvolt = <3300000>; 170 + }; 171 + 172 + sd_vcc: switchldo1 { 173 + regulator-name = "SD_VCC"; 174 + regulator-min-microvolt = <3000000>; 175 + regulator-max-microvolt = <3300000>; 176 + regulator-always-on; 177 + regulator-boot-on; 178 + }; 179 + }; 180 + }; 181 + }; 182 + 183 + ...
+76
Documentation/devicetree/bindings/mfd/netronix,ntxec.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/netronix,ntxec.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Netronix Embedded Controller 8 + 9 + maintainers: 10 + - Jonathan Neuschäfer <j.neuschaefer@gmx.net> 11 + 12 + description: | 13 + This EC is found in e-book readers of multiple brands (e.g. Kobo, Tolino), and 14 + is typically implemented as a TI MSP430 microcontroller. 15 + 16 + properties: 17 + compatible: 18 + const: netronix,ntxec 19 + 20 + reg: 21 + items: 22 + - description: The I2C address of the EC 23 + 24 + system-power-controller: 25 + type: boolean 26 + description: See Documentation/devicetree/bindings/power/power-controller.txt 27 + 28 + interrupts: 29 + minItems: 1 30 + description: 31 + The EC can signal interrupts via a GPIO line 32 + 33 + "#pwm-cells": 34 + const: 2 35 + description: | 36 + Number of cells in a PWM specifier. 37 + 38 + The following PWM channels are supported: 39 + - 0: The PWM channel controlled by registers 0xa1-0xa7 40 + 41 + required: 42 + - compatible 43 + - reg 44 + 45 + additionalProperties: false 46 + 47 + examples: 48 + - | 49 + #include <dt-bindings/interrupt-controller/irq.h> 50 + i2c { 51 + #address-cells = <1>; 52 + #size-cells = <0>; 53 + 54 + ec: embedded-controller@43 { 55 + pinctrl-names = "default"; 56 + pinctrl-0 = <&pinctrl_ntxec>; 57 + 58 + compatible = "netronix,ntxec"; 59 + reg = <0x43>; 60 + system-power-controller; 61 + interrupt-parent = <&gpio4>; 62 + interrupts = <11 IRQ_TYPE_EDGE_FALLING>; 63 + #pwm-cells = <2>; 64 + }; 65 + }; 66 + 67 + backlight { 68 + compatible = "pwm-backlight"; 69 + pwms = <&ec 0 50000>; 70 + power-supply = <&backlight_regulator>; 71 + }; 72 + 73 + backlight_regulator: regulator-dummy { 74 + compatible = "regulator-fixed"; 75 + regulator-name = "backlight"; 76 + };
-99
Documentation/devicetree/bindings/mfd/qcom-pm8xxx.txt
··· 1 - Qualcomm PM8xxx PMIC multi-function devices 2 - 3 - The PM8xxx family of Power Management ICs are used to provide regulated 4 - voltages and other various functionality to Qualcomm SoCs. 5 - 6 - = PROPERTIES 7 - 8 - - compatible: 9 - Usage: required 10 - Value type: <string> 11 - Definition: must be one of: 12 - "qcom,pm8058" 13 - "qcom,pm8821" 14 - "qcom,pm8921" 15 - 16 - - #address-cells: 17 - Usage: required 18 - Value type: <u32> 19 - Definition: must be 1 20 - 21 - - #size-cells: 22 - Usage: required 23 - Value type: <u32> 24 - Definition: must be 0 25 - 26 - - interrupts: 27 - Usage: required 28 - Value type: <prop-encoded-array> 29 - Definition: specifies the interrupt that indicates a subdevice 30 - has generated an interrupt (summary interrupt). The 31 - format of the specifier is defined by the binding document 32 - describing the node's interrupt parent. 33 - 34 - - #interrupt-cells: 35 - Usage: required 36 - Value type : <u32> 37 - Definition: must be 2. Specifies the number of cells needed to encode 38 - an interrupt source. The 1st cell contains the interrupt 39 - number. The 2nd cell is the trigger type and level flags 40 - encoded as follows: 41 - 42 - 1 = low-to-high edge triggered 43 - 2 = high-to-low edge triggered 44 - 4 = active high level-sensitive 45 - 8 = active low level-sensitive 46 - 47 - - interrupt-controller: 48 - Usage: required 49 - Value type: <empty> 50 - Definition: identifies this node as an interrupt controller 51 - 52 - = SUBCOMPONENTS 53 - 54 - The PMIC contains multiple independent functions, each described in a subnode. 55 - The below bindings specify the set of valid subnodes. 56 - 57 - == Real-Time Clock 58 - 59 - - compatible: 60 - Usage: required 61 - Value type: <string> 62 - Definition: must be one of: 63 - "qcom,pm8058-rtc" 64 - "qcom,pm8921-rtc" 65 - "qcom,pm8941-rtc" 66 - "qcom,pm8018-rtc" 67 - 68 - - reg: 69 - Usage: required 70 - Value type: <prop-encoded-array> 71 - Definition: single entry specifying the base address of the RTC registers 72 - 73 - - interrupts: 74 - Usage: required 75 - Value type: <prop-encoded-array> 76 - Definition: single entry specifying the RTC's alarm interrupt 77 - 78 - - allow-set-time: 79 - Usage: optional 80 - Value type: <empty> 81 - Definition: indicates that the setting of RTC time is allowed by 82 - the host CPU 83 - 84 - = EXAMPLE 85 - 86 - pmicintc: pmic@0 { 87 - compatible = "qcom,pm8921"; 88 - interrupts = <104 8>; 89 - #interrupt-cells = <2>; 90 - interrupt-controller; 91 - #address-cells = <1>; 92 - #size-cells = <0>; 93 - 94 - rtc@11d { 95 - compatible = "qcom,pm8921-rtc"; 96 - reg = <0x11d>; 97 - interrupts = <0x27 0>; 98 - }; 99 - };
+54
Documentation/devicetree/bindings/mfd/qcom-pm8xxx.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/mfd/qcom-pm8xxx.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Qualcomm PM8xxx PMIC multi-function devices 8 + 9 + maintainers: 10 + - Satya Priya <skakit@codeaurora.org> 11 + 12 + description: | 13 + The PM8xxx family of Power Management ICs are used to provide regulated 14 + voltages and other various functionality to Qualcomm SoCs. 15 + 16 + properties: 17 + compatible: 18 + enum: 19 + - qcom,pm8058 20 + - qcom,pm8821 21 + - qcom,pm8921 22 + 23 + reg: 24 + maxItems: 1 25 + 26 + '#address-cells': 27 + const: 1 28 + 29 + '#size-cells': 30 + const: 0 31 + 32 + interrupts: 33 + maxItems: 1 34 + 35 + '#interrupt-cells': 36 + const: 2 37 + 38 + interrupt-controller: true 39 + 40 + patternProperties: 41 + "rtc@[0-9a-f]+$": 42 + type: object 43 + $ref: "../rtc/qcom-pm8xxx-rtc.yaml" 44 + 45 + required: 46 + - compatible 47 + - '#address-cells' 48 + - '#size-cells' 49 + - interrupts 50 + - '#interrupt-cells' 51 + - interrupt-controller 52 + 53 + additionalProperties: false 54 + ...
+111
Documentation/devicetree/bindings/mfd/ricoh,rn5t618.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/mfd/ricoh,rn5t618.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Ricoh RN5T567/RN5T618/RC5T619 PMIC 8 + 9 + maintainers: 10 + - Andreas Kemnade <andreas@kemnade.info> 11 + 12 + description: | 13 + Ricoh RN5T567/RN5T618/RC5T619 is a power management IC family which 14 + integrates 3 to 5 step-down DCDC converters, 7 to 10 low-dropout regulators, 15 + GPIOs, and a watchdog timer. It can be controlled through an I2C interface. 16 + The RN5T618/RC5T619 provides additionally a Li-ion battery charger, 17 + fuel gauge, and an ADC. 18 + The RC5T619 additionally includes USB charger detection and an RTC. 19 + 20 + allOf: 21 + - if: 22 + properties: 23 + compatible: 24 + contains: 25 + const: ricoh,rn5t567 26 + then: 27 + properties: 28 + regulators: 29 + patternProperties: 30 + "^(DCDC[1-4]|LDO[1-5]|LDORTC[12])$": 31 + $ref: ../regulator/regulator.yaml 32 + additionalProperties: false 33 + - if: 34 + properties: 35 + compatible: 36 + contains: 37 + const: ricoh,rn5t618 38 + then: 39 + properties: 40 + regulators: 41 + patternProperties: 42 + "^(DCDC[1-3]|LDO[1-5]|LDORTC[12])$": 43 + $ref: ../regulator/regulator.yaml 44 + additionalProperties: false 45 + - if: 46 + properties: 47 + compatible: 48 + contains: 49 + const: ricoh,rc5t619 50 + then: 51 + properties: 52 + regulators: 53 + patternProperties: 54 + "^(DCDC[1-5]|LDO[1-9]|LDO10|LDORTC[12])$": 55 + $ref: ../regulator/regulator.yaml 56 + additionalProperties: false 57 + 58 + properties: 59 + compatible: 60 + enum: 61 + - ricoh,rn5t567 62 + - ricoh,rn5t618 63 + - ricoh,rc5t619 64 + 65 + reg: 66 + maxItems: 1 67 + 68 + interrupts: 69 + maxItems: 1 70 + 71 + system-power-controller: 72 + type: boolean 73 + description: | 74 + See Documentation/devicetree/bindings/power/power-controller.txt 75 + 76 + regulators: 77 + type: object 78 + 79 + additionalProperties: false 80 + 81 + required: 82 + - compatible 83 + - reg 84 + 85 + examples: 86 + - | 87 + #include <dt-bindings/interrupt-controller/irq.h> 88 + i2c { 89 + #address-cells = <1>; 90 + #size-cells = <0>; 91 + 92 + pmic@32 { 93 + compatible = "ricoh,rn5t618"; 94 + reg = <0x32>; 95 + interrupt-parent = <&gpio5>; 96 + interrupts = <11 IRQ_TYPE_EDGE_FALLING>; 97 + system-power-controller; 98 + 99 + regulators { 100 + DCDC1 { 101 + regulator-min-microvolt = <1050000>; 102 + regulator-max-microvolt = <1050000>; 103 + }; 104 + 105 + DCDC2 { 106 + regulator-min-microvolt = <1175000>; 107 + regulator-max-microvolt = <1175000>; 108 + }; 109 + }; 110 + }; 111 + };
-52
Documentation/devicetree/bindings/mfd/rn5t618.txt
··· 1 - * Ricoh RN5T567/RN5T618 PMIC 2 - 3 - Ricoh RN5T567/RN5T618/RC5T619 is a power management IC family which 4 - integrates 3 to 5 step-down DCDC converters, 7 to 10 low-dropout regulators, 5 - GPIOs, and a watchdog timer. It can be controlled through an I2C interface. 6 - The RN5T618/RC5T619 provides additionally a Li-ion battery charger, 7 - fuel gauge, and an ADC. 8 - The RC5T619 additionnally includes USB charger detection and an RTC. 9 - 10 - Required properties: 11 - - compatible: must be one of 12 - "ricoh,rn5t567" 13 - "ricoh,rn5t618" 14 - "ricoh,rc5t619" 15 - - reg: the I2C slave address of the device 16 - 17 - Optional properties: 18 - - interrupts: interrupt mapping for IRQ 19 - See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt 20 - - system-power-controller: 21 - See Documentation/devicetree/bindings/power/power-controller.txt 22 - 23 - Sub-nodes: 24 - - regulators: the node is required if the regulator functionality is 25 - needed. The valid regulator names are: DCDC1, DCDC2, DCDC3, DCDC4 26 - (RN5T567/RC5T619), LDO1, LDO2, LDO3, LDO4, LDO5, LDO6, LDO7, LDO8, 27 - LDO9, LDO10, LDORTC1 and LDORTC2. 28 - LDO7-10 are specific to RC5T619. 29 - The common bindings for each individual regulator can be found in: 30 - Documentation/devicetree/bindings/regulator/regulator.txt 31 - 32 - Example: 33 - 34 - pmic@32 { 35 - compatible = "ricoh,rn5t618"; 36 - reg = <0x32>; 37 - interrupt-parent = <&gpio5>; 38 - interrupts = <11 IRQ_TYPE_EDGE_FALLING>; 39 - system-power-controller; 40 - 41 - regulators { 42 - DCDC1 { 43 - regulator-min-microvolt = <1050000>; 44 - regulator-max-microvolt = <1050000>; 45 - }; 46 - 47 - DCDC2 { 48 - regulator-min-microvolt = <1175000>; 49 - regulator-max-microvolt = <1175000>; 50 - }; 51 - }; 52 - };
+201
Documentation/devicetree/bindings/mfd/rohm,bd71815-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,bd71815-pmic.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: ROHM BD71815 Power Management Integrated Circuit bindings 8 + 9 + maintainers: 10 + - Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> 11 + 12 + description: | 13 + BD71815AGW is a single-chip power management ICs for battery-powered 14 + portable devices. It integrates 5 buck converters, 8 LDOs, a boost driver 15 + for LED and a 500 mA single-cell linear charger. Also included is a Coulomb 16 + counter, a real-time clock (RTC), and a 32.768 kHz clock gate and two GPOs. 17 + 18 + properties: 19 + compatible: 20 + const: rohm,bd71815 21 + 22 + reg: 23 + description: 24 + I2C slave address. 25 + maxItems: 1 26 + 27 + interrupts: 28 + maxItems: 1 29 + 30 + gpio-controller: true 31 + 32 + "#gpio-cells": 33 + const: 2 34 + description: | 35 + The first cell is the pin number and the second cell is used to specify 36 + flags. See ../gpio/gpio.txt for more information. 37 + 38 + clocks: 39 + maxItems: 1 40 + 41 + "#clock-cells": 42 + const: 0 43 + 44 + clock-output-names: 45 + const: bd71815-32k-out 46 + 47 + rohm,clkout-open-drain: 48 + description: clk32kout mode. Set to 1 for "open-drain" or 0 for "cmos". 49 + $ref: "/schemas/types.yaml#/definitions/uint32" 50 + minimum: 0 51 + maximum: 1 52 + 53 + rohm,charger-sense-resistor-ohms: 54 + minimum: 10000000 55 + maximum: 50000000 56 + description: | 57 + BD71827 and BD71828 have SAR ADC for measuring charging currents. 58 + External sense resistor (RSENSE in data sheet) should be used. If 59 + something other but 30MOhm resistor is used the resistance value 60 + should be given here in Ohms. 61 + default: 30000000 62 + 63 + regulators: 64 + $ref: ../regulator/rohm,bd71815-regulator.yaml 65 + description: 66 + List of child nodes that specify the regulators. 67 + 68 + gpio-reserved-ranges: 69 + description: | 70 + Usage of BD71828 GPIO pins can be changed via OTP. This property can be 71 + used to mark the pins which should not be configured for GPIO. Please see 72 + the ../gpio/gpio.txt for more information. 73 + 74 + rohm,enable-hidden-gpo: 75 + description: | 76 + The BD71815 has undocumented GPO at pin E5. Pin is marked as GND at the 77 + data-sheet as it's location in the middle of GND pins makes it hard to 78 + use on PCB. If your board has managed to use this pin you can enable the 79 + second GPO by defining this property. Dont enable this if you are unsure 80 + about how the E5 pin is connected on your board. 81 + type: boolean 82 + 83 + required: 84 + - compatible 85 + - reg 86 + - interrupts 87 + - clocks 88 + - "#clock-cells" 89 + - regulators 90 + - gpio-controller 91 + - "#gpio-cells" 92 + 93 + additionalProperties: false 94 + 95 + examples: 96 + - | 97 + #include <dt-bindings/interrupt-controller/irq.h> 98 + #include <dt-bindings/leds/common.h> 99 + i2c { 100 + #address-cells = <1>; 101 + #size-cells = <0>; 102 + pmic: pmic@4b { 103 + compatible = "rohm,bd71815"; 104 + reg = <0x4b>; 105 + 106 + interrupt-parent = <&gpio1>; 107 + interrupts = <29 IRQ_TYPE_LEVEL_LOW>; 108 + 109 + clocks = <&osc 0>; 110 + #clock-cells = <0>; 111 + clock-output-names = "bd71815-32k-out"; 112 + 113 + gpio-controller; 114 + #gpio-cells = <2>; 115 + 116 + rohm,charger-sense-resistor-ohms = <10000000>; 117 + 118 + regulators { 119 + buck1: buck1 { 120 + regulator-name = "buck1"; 121 + regulator-min-microvolt = <800000>; 122 + regulator-max-microvolt = <2000000>; 123 + regulator-always-on; 124 + regulator-ramp-delay = <1250>; 125 + rohm,dvs-run-voltage = <1150000>; 126 + rohm,dvs-suspend-voltage = <950000>; 127 + }; 128 + buck2: buck2 { 129 + regulator-name = "buck2"; 130 + regulator-min-microvolt = <800000>; 131 + regulator-max-microvolt = <2000000>; 132 + regulator-always-on; 133 + regulator-ramp-delay = <1250>; 134 + rohm,dvs-run-voltage = <1150000>; 135 + rohm,dvs-suspend-voltage = <950000>; 136 + }; 137 + buck3: buck3 { 138 + regulator-name = "buck3"; 139 + regulator-min-microvolt = <1200000>; 140 + regulator-max-microvolt = <2700000>; 141 + regulator-always-on; 142 + }; 143 + buck4: buck4 { 144 + regulator-name = "buck4"; 145 + regulator-min-microvolt = <1100000>; 146 + regulator-max-microvolt = <1850000>; 147 + regulator-always-on; 148 + }; 149 + buck5: buck5 { 150 + regulator-name = "buck5"; 151 + regulator-min-microvolt = <1800000>; 152 + regulator-max-microvolt = <3300000>; 153 + regulator-always-on; 154 + }; 155 + ldo1: ldo1 { 156 + regulator-name = "ldo1"; 157 + regulator-min-microvolt = <800000>; 158 + regulator-max-microvolt = <3300000>; 159 + regulator-always-on; 160 + }; 161 + ldo2: ldo2 { 162 + regulator-name = "ldo2"; 163 + regulator-min-microvolt = <800000>; 164 + regulator-max-microvolt = <3300000>; 165 + regulator-always-on; 166 + }; 167 + ldo3: ldo3 { 168 + regulator-name = "ldo3"; 169 + regulator-min-microvolt = <800000>; 170 + regulator-max-microvolt = <3300000>; 171 + regulator-always-on; 172 + }; 173 + ldo4: ldo4 { 174 + regulator-name = "ldo4"; 175 + regulator-min-microvolt = <800000>; 176 + regulator-max-microvolt = <3300000>; 177 + regulator-always-on; 178 + }; 179 + ldo5: ldo5 { 180 + regulator-name = "ldo5"; 181 + regulator-min-microvolt = <800000>; 182 + regulator-max-microvolt = <3300000>; 183 + regulator-always-on; 184 + }; 185 + ldo6: ldodvref { 186 + regulator-name = "ldodvref"; 187 + regulator-always-on; 188 + }; 189 + ldo7: ldolpsr { 190 + regulator-name = "ldolpsr"; 191 + regulator-always-on; 192 + }; 193 + 194 + boost: wled { 195 + regulator-name = "wled"; 196 + regulator-min-microamp = <10>; 197 + regulator-max-microamp = <25000>; 198 + }; 199 + }; 200 + }; 201 + };
+6
Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml
··· 44 44 clock-output-names: 45 45 const: bd71828-32k-out 46 46 47 + rohm,clkout-open-drain: 48 + description: clk32kout mode. Set to 1 for "open-drain" or 0 for "cmos". 49 + $ref: "/schemas/types.yaml#/definitions/uint32" 50 + minimum: 0 51 + maximum: 1 52 + 47 53 rohm,charger-sense-resistor-ohms: 48 54 minimum: 10000000 49 55 maximum: 50000000
+123
Documentation/devicetree/bindings/mfd/rohm,bd9576-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,bd9576-pmic.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: ROHM BD9576MUF and BD9573MUF Power Management Integrated Circuit bindings 8 + 9 + maintainers: 10 + - Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> 11 + 12 + description: | 13 + BD9576MUF and BD9573MUF are power management ICs primarily intended for 14 + powering the R-Car series processors. 15 + The IC provides 6 power outputs with configurable sequencing and safety 16 + monitoring. A watchdog logic with slow ping/windowed modes is also included. 17 + 18 + properties: 19 + compatible: 20 + enum: 21 + - rohm,bd9576 22 + - rohm,bd9573 23 + 24 + reg: 25 + description: 26 + I2C slave address. 27 + maxItems: 1 28 + 29 + interrupts: 30 + maxItems: 1 31 + 32 + rohm,vout1-en-low: 33 + description: 34 + BD9576 and BD9573 VOUT1 regulator enable state can be individually 35 + controlled by a GPIO. This is dictated by state of vout1-en pin during 36 + the PMIC startup. If vout1-en is LOW during PMIC startup then the VOUT1 37 + enable sate is controlled via this pin. Set this property if vout1-en 38 + is wired to be down at PMIC start-up. 39 + type: boolean 40 + 41 + rohm,vout1-en-gpios: 42 + description: 43 + GPIO specifier to specify the GPIO connected to vout1-en for vout1 ON/OFF 44 + state control. 45 + maxItems: 1 46 + 47 + rohm,ddr-sel-low: 48 + description: 49 + The BD9576 and BD9573 output voltage for DDR can be selected by setting 50 + the ddr-sel pin low or high. Set this property if ddr-sel is grounded. 51 + type: boolean 52 + 53 + rohm,watchdog-enable-gpios: 54 + description: The GPIO line used to enable the watchdog. 55 + maxItems: 1 56 + 57 + rohm,watchdog-ping-gpios: 58 + description: The GPIO line used to ping the watchdog. 59 + maxItems: 1 60 + 61 + rohm,hw-timeout-ms: 62 + maxItems: 2 63 + description: 64 + Watchog timeout in milliseconds. If single value is given it is 65 + the maximum timeout. Eg. if pinging watchdog is not done within this time 66 + limit the watchdog will be triggered. If two values are given watchdog 67 + is configured in "window mode". Then first value is limit for short-ping 68 + Eg. if watchdog is pinged sooner than that the watchdog will trigger. 69 + When two values is given the second value is the maximum timeout. 70 + # (HW) minimum for short timeout is 2ms, maximum 220 ms. 71 + # (HW) minimum for max timeout is 4ms, maximum 4416 ms. 72 + 73 + regulators: 74 + $ref: ../regulator/rohm,bd9576-regulator.yaml 75 + description: 76 + List of child nodes that specify the regulators. 77 + 78 + required: 79 + - compatible 80 + - reg 81 + - regulators 82 + 83 + additionalProperties: false 84 + 85 + examples: 86 + - | 87 + #include <dt-bindings/gpio/gpio.h> 88 + #include <dt-bindings/leds/common.h> 89 + i2c { 90 + #address-cells = <1>; 91 + #size-cells = <0>; 92 + pmic: pmic@30 { 93 + compatible = "rohm,bd9576"; 94 + reg = <0x30>; 95 + rohm,vout1-en-low; 96 + rohm,vout1-en-gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>; 97 + rohm,ddr-sel-low; 98 + rohm,watchdog-enable-gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>; 99 + rohm,watchdog-ping-gpios = <&gpio2 7 GPIO_ACTIVE_HIGH>; 100 + rohm,hw-timeout-ms = <150>, <2300>; 101 + 102 + regulators { 103 + boost1: regulator-vd50 { 104 + regulator-name = "VD50"; 105 + }; 106 + buck1: regulator-vd18 { 107 + regulator-name = "VD18"; 108 + }; 109 + buck2: regulator-vdddr { 110 + regulator-name = "VDDDR"; 111 + }; 112 + buck3: regulator-vd10 { 113 + regulator-name = "VD10"; 114 + }; 115 + ldo: regulator-voutl1 { 116 + regulator-name = "VOUTL1"; 117 + }; 118 + sw: regulator-vouts1 { 119 + regulator-name = "VOUTS1"; 120 + }; 121 + }; 122 + }; 123 + };
+4
Documentation/devicetree/bindings/mfd/ti,lp87524-q1.yaml
··· 17 17 description: I2C slave address 18 18 const: 0x60 19 19 20 + reset-gpios: 21 + description: GPIO connected to NRST pin (active low reset, pin 20) 22 + maxItems: 1 23 + 20 24 gpio-controller: true 21 25 22 26 '#gpio-cells':
+4
Documentation/devicetree/bindings/mfd/ti,lp87561-q1.yaml
··· 17 17 description: I2C slave address 18 18 const: 0x60 19 19 20 + reset-gpios: 21 + description: GPIO connected to NRST pin (active low reset, pin 20) 22 + maxItems: 1 23 + 20 24 gpio-controller: true 21 25 22 26 '#gpio-cells':
+4
Documentation/devicetree/bindings/mfd/ti,lp87565-q1.yaml
··· 19 19 description: I2C slave address 20 20 const: 0x60 21 21 22 + reset-gpios: 23 + description: GPIO connected to NRST pin (active low reset, pin 20) 24 + maxItems: 1 25 + 22 26 gpio-controller: true 23 27 24 28 '#gpio-cells':
+116
Documentation/devicetree/bindings/regulator/rohm,bd71815-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,bd71815-regulator.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: ROHM BD71815 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 BD718215 MFD device. For more details 14 + see Documentation/devicetree/bindings/mfd/rohm,bd71815-pmic.yaml. 15 + 16 + The regulator controller is represented as a sub-node of the PMIC node 17 + on the device tree. 18 + 19 + The valid names for BD71815 regulator nodes are 20 + buck1, buck2, buck3, buck4, buck5, 21 + ldo1, ldo2, ldo3, ldo4, ldo5, 22 + ldodvref, ldolpsr, wled 23 + 24 + properties: 25 + wled: 26 + type: object 27 + description: 28 + properties for wled regulator 29 + $ref: regulator.yaml# 30 + 31 + properties: 32 + regulator-name: 33 + const: wled 34 + 35 + patternProperties: 36 + "^((ldo|buck)[1-5]|ldolpsr|ldodvref)$": 37 + type: object 38 + description: 39 + Properties for single LDO/BUCK regulator. 40 + $ref: regulator.yaml# 41 + 42 + properties: 43 + regulator-name: 44 + pattern: "^((ldo|buck)[1-5]|ldolpsr|ldodvref)$" 45 + description: 46 + should be "ldo1", ..., "ldo5", "buck1", ..., "buck5" and "ldolpsr" 47 + for ldolpsr regulator, "ldodvref" for ldodvref reglator. 48 + 49 + rohm,vsel-gpios: 50 + description: 51 + GPIO used to control ldo4 state (when ldo4 is controlled by GPIO). 52 + 53 + rohm,dvs-run-voltage: 54 + description: 55 + PMIC "RUN" state voltage in uV when PMIC HW states are used. See 56 + comments below for bucks/LDOs which support this. 0 means 57 + regulator should be disabled at RUN state. 58 + $ref: "/schemas/types.yaml#/definitions/uint32" 59 + minimum: 0 60 + maximum: 3300000 61 + 62 + rohm,dvs-snvs-voltage: 63 + description: 64 + Whether to keep regulator enabled at "SNVS" state or not. 65 + 0 means regulator should be disabled at SNVS state, non zero voltage 66 + keeps regulator enabled. BD71815 does not change voltage level 67 + when PMIC transitions to SNVS.SNVS voltage depends on the previous 68 + state (from which the PMIC transitioned to SNVS). 69 + $ref: "/schemas/types.yaml#/definitions/uint32" 70 + minimum: 0 71 + maximum: 3300000 72 + 73 + rohm,dvs-suspend-voltage: 74 + description: 75 + PMIC "SUSPEND" state voltage in uV when PMIC HW states are used. See 76 + comments below for bucks/LDOs which support this. 0 means 77 + regulator should be disabled at SUSPEND state. 78 + $ref: "/schemas/types.yaml#/definitions/uint32" 79 + minimum: 0 80 + maximum: 3300000 81 + 82 + rohm,dvs-lpsr-voltage: 83 + description: 84 + PMIC "LPSR" state voltage in uV when PMIC HW states are used. See 85 + comments below for bucks/LDOs which support this. 0 means 86 + regulator should be disabled at LPSR state. 87 + $ref: "/schemas/types.yaml#/definitions/uint32" 88 + minimum: 0 89 + maximum: 3300000 90 + 91 + # Bucks 1 and 2 support giving separate voltages for operational states 92 + # (RUN /CLEAN according to data-sheet) and non operational states 93 + # (LPSR/SUSPEND). The voltage is automatically changed when HW 94 + # state changes. Omitting these properties from bucks 1 and 2 leave 95 + # buck voltages to not be toggled by HW state. Enable status may still 96 + # be toggled by state changes depending on HW default settings. 97 + # 98 + # Bucks 3-5 and ldos 1-5 support setting the RUN state voltage here. 99 + # Given RUN voltage is used at all states if regulator is enabled at 100 + # given state. 101 + # Values given for other states are regarded as enable/disable at 102 + # given state (see below). 103 + # 104 + # All regulators except WLED support specifying enable/disable status 105 + # for each of the HW states (RUN/SNVS/SUSPEND/LPSR). HW defaults can 106 + # be overridden by setting voltage to 0 (regulator disabled at given 107 + # state) or non-zero (regulator enabled at given state). Please note 108 + # that setting non zero voltages for bucks 1/2 will also enable voltage 109 + # changes according to state change. 110 + 111 + required: 112 + - regulator-name 113 + 114 + unevaluatedProperties: false 115 + 116 + additionalProperties: false
+2
Documentation/devicetree/bindings/vendor-prefixes.yaml
··· 772 772 description: Broadcom Corporation (formerly NetLogic Microsystems) 773 773 "^netron-dy,.*": 774 774 description: Netron DY 775 + "^netronix,.*": 776 + description: Netronix, Inc. 775 777 "^netxeon,.*": 776 778 description: Shenzhen Netxeon Technology CO., LTD 777 779 "^neweast,.*":
+49 -25
MAINTAINERS
··· 2894 2894 F: Documentation/admin-guide/aoe/ 2895 2895 F: drivers/block/aoe/ 2896 2896 2897 + ATC260X PMIC MFD DRIVER 2898 + M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> 2899 + M: Cristian Ciocaltea <cristian.ciocaltea@gmail.com> 2900 + L: linux-actions@lists.infradead.org 2901 + S: Maintained 2902 + F: Documentation/devicetree/bindings/mfd/actions,atc260x.yaml 2903 + F: drivers/input/misc/atc260x-onkey.c 2904 + F: drivers/mfd/atc260* 2905 + F: drivers/power/reset/atc260x-poweroff.c 2906 + F: drivers/regulator/atc260x-regulator.c 2907 + F: include/linux/mfd/atc260x/* 2908 + 2897 2909 ATHEROS 71XX/9XXX GPIO DRIVER 2898 2910 M: Alban Bedel <albeu@free.fr> 2899 2911 S: Maintained ··· 9233 9221 F: include/uapi/linux/mei.h 9234 9222 F: samples/mei/* 9235 9223 9224 + INTEL MAX 10 BMC MFD DRIVER 9225 + M: Xu Yilun <yilun.xu@intel.com> 9226 + R: Tom Rix <trix@redhat.com> 9227 + S: Maintained 9228 + F: Documentation/ABI/testing/sysfs-driver-intel-m10-bmc 9229 + F: Documentation/hwmon/intel-m10-bmc-hwmon.rst 9230 + F: drivers/hwmon/intel-m10-bmc-hwmon.c 9231 + F: drivers/mfd/intel-m10-bmc.c 9232 + F: include/linux/mfd/intel-m10-bmc.h 9233 + 9234 + INTEL MAX 10 BMC MFD DRIVER 9235 + M: Xu Yilun <yilun.xu@intel.com> 9236 + R: Tom Rix <trix@redhat.com> 9237 + S: Maintained 9238 + F: Documentation/ABI/testing/sysfs-driver-intel-m10-bmc 9239 + F: Documentation/hwmon/intel-m10-bmc-hwmon.rst 9240 + F: drivers/hwmon/intel-m10-bmc-hwmon.c 9241 + F: drivers/mfd/intel-m10-bmc.c 9242 + F: include/linux/mfd/intel-m10-bmc.h 9243 + 9236 9244 INTEL MENLOW THERMAL DRIVER 9237 9245 M: Sujith Thomas <sujith.thomas@intel.com> 9238 9246 L: platform-driver-x86@vger.kernel.org ··· 12575 12543 F: include/uapi/linux/netrom.h 12576 12544 F: net/netrom/ 12577 12545 12546 + NETRONIX EMBEDDED CONTROLLER 12547 + M: Jonathan Neuschäfer <j.neuschaefer@gmx.net> 12548 + S: Maintained 12549 + F: Documentation/devicetree/bindings/mfd/netronix,ntxec.yaml 12550 + F: drivers/mfd/ntxec.c 12551 + F: drivers/pwm/pwm-ntxec.c 12552 + F: drivers/rtc/rtc-ntxec.c 12553 + F: include/linux/mfd/ntxec.h 12554 + 12578 12555 NETRONOME ETHERNET DRIVERS 12579 12556 M: Simon Horman <simon.horman@netronome.com> 12580 12557 R: Jakub Kicinski <kuba@kernel.org> ··· 15675 15634 F: Documentation/devicetree/bindings/regulator/rohm,bd70528-regulator.txt 15676 15635 F: drivers/clk/clk-bd718x7.c 15677 15636 F: drivers/gpio/gpio-bd70528.c 15637 + F: drivers/gpio/gpio-bd71815.c 15678 15638 F: drivers/gpio/gpio-bd71828.c 15679 15639 F: drivers/mfd/rohm-bd70528.c 15680 15640 F: drivers/mfd/rohm-bd71828.c 15681 15641 F: drivers/mfd/rohm-bd718x7.c 15642 + F: drivers/mfd/rohm-bd9576.c 15682 15643 F: drivers/power/supply/bd70528-charger.c 15683 15644 F: drivers/regulator/bd70528-regulator.c 15645 + F: drivers/regulator/bd71815-regulator.c 15684 15646 F: drivers/regulator/bd71828-regulator.c 15685 15647 F: drivers/regulator/bd718x7-regulator.c 15648 + F: drivers/regulator/bd9576-regulator.c 15686 15649 F: drivers/regulator/rohm-regulator.c 15687 15650 F: drivers/rtc/rtc-bd70528.c 15688 15651 F: drivers/watchdog/bd70528_wdt.c 15652 + F: drivers/watchdog/bd9576_wdt.c 15689 15653 F: include/linux/mfd/rohm-bd70528.h 15654 + F: include/linux/mfd/rohm-bd71815.h 15690 15655 F: include/linux/mfd/rohm-bd71828.h 15691 15656 F: include/linux/mfd/rohm-bd718x7.h 15657 + F: include/linux/mfd/rohm-bd957x.h 15692 15658 F: include/linux/mfd/rohm-generic.h 15693 15659 F: include/linux/mfd/rohm-shared.h 15694 15660 ··· 18195 18147 F: sound/soc/codecs/isabelle* 18196 18148 F: sound/soc/codecs/lm49453* 18197 18149 18198 - TI LP855x BACKLIGHT DRIVER 18199 - M: Milo Kim <milo.kim@ti.com> 18200 - S: Maintained 18201 - F: Documentation/driver-api/backlight/lp855x-driver.rst 18202 - F: drivers/video/backlight/lp855x_bl.c 18203 - F: include/linux/platform_data/lp855x.h 18204 - 18205 - TI LP8727 CHARGER DRIVER 18206 - M: Milo Kim <milo.kim@ti.com> 18207 - S: Maintained 18208 - F: drivers/power/supply/lp8727_charger.c 18209 - F: include/linux/platform_data/lp8727.h 18210 - 18211 - TI LP8788 MFD DRIVER 18212 - M: Milo Kim <milo.kim@ti.com> 18213 - S: Maintained 18214 - F: drivers/iio/adc/lp8788_adc.c 18215 - F: drivers/leds/leds-lp8788.c 18216 - F: drivers/mfd/lp8788*.c 18217 - F: drivers/power/supply/lp8788-charger.c 18218 - F: drivers/regulator/lp8788-*.c 18219 - F: include/linux/mfd/lp8788*.h 18220 - 18221 18150 TI NETCP ETHERNET DRIVER 18222 18151 M: Wingman Kwok <w-kwok2@ti.com> 18223 18152 M: Murali Karicheri <m-karicheri2@ti.com> ··· 19612 19587 F: Documentation/hwmon/wm83??.rst 19613 19588 F: arch/arm/mach-s3c/mach-crag6410* 19614 19589 F: drivers/clk/clk-wm83*.c 19615 - F: drivers/extcon/extcon-arizona.c 19616 19590 F: drivers/gpio/gpio-*wm*.c 19617 19591 F: drivers/gpio/gpio-arizona.c 19618 19592 F: drivers/hwmon/wm83??-hwmon.c ··· 19635 19611 F: include/linux/regulator/arizona* 19636 19612 F: include/linux/wm97xx.h 19637 19613 F: include/sound/wm????.h 19638 - F: sound/soc/codecs/arizona.? 19614 + F: sound/soc/codecs/arizona* 19639 19615 F: sound/soc/codecs/cs47l24* 19640 19616 F: sound/soc/codecs/wm* 19641 19617
+8 -1
drivers/clk/clk-bd718x7.c
··· 13 13 #include <linux/regmap.h> 14 14 15 15 /* clk control registers */ 16 + /* BD71815 */ 17 + #define BD71815_REG_OUT32K 0x1d 16 18 /* BD70528 */ 17 19 #define BD70528_REG_OUT32K 0x2c 18 20 /* BD71828 */ ··· 120 118 c->reg = BD70528_REG_OUT32K; 121 119 c->mask = CLK_OUT_EN_MASK; 122 120 break; 121 + case ROHM_CHIP_TYPE_BD71815: 122 + c->reg = BD71815_REG_OUT32K; 123 + c->mask = CLK_OUT_EN_MASK; 124 + break; 123 125 default: 124 126 dev_err(&pdev->dev, "Unknown clk chip\n"); 125 127 return -EINVAL; ··· 152 146 { "bd71847-clk", ROHM_CHIP_TYPE_BD71847 }, 153 147 { "bd70528-clk", ROHM_CHIP_TYPE_BD70528 }, 154 148 { "bd71828-clk", ROHM_CHIP_TYPE_BD71828 }, 149 + { "bd71815-clk", ROHM_CHIP_TYPE_BD71815 }, 155 150 { }, 156 151 }; 157 152 MODULE_DEVICE_TABLE(platform, bd718x7_clk_id); ··· 168 161 module_platform_driver(bd71837_clk); 169 162 170 163 MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); 171 - MODULE_DESCRIPTION("BD71837/BD71847/BD70528 chip clk driver"); 164 + MODULE_DESCRIPTION("BD718(15/18/28/37/47/50) and BD70528 chip clk driver"); 172 165 MODULE_LICENSE("GPL"); 173 166 MODULE_ALIAS("platform:bd718xx-clk");
-8
drivers/extcon/Kconfig
··· 21 21 help 22 22 Say Y here to enable extcon device driver based on ADC values. 23 23 24 - config EXTCON_ARIZONA 25 - tristate "Wolfson Arizona EXTCON support" 26 - depends on MFD_ARIZONA && INPUT && SND_SOC 27 - help 28 - Say Y here to enable support for external accessory detection 29 - with Wolfson Arizona devices. These are audio CODECs with 30 - advanced audio accessory detection support. 31 - 32 24 config EXTCON_AXP288 33 25 tristate "X-Power AXP288 EXTCON support" 34 26 depends on MFD_AXP20X && USB_SUPPORT && X86 && ACPI
-1
drivers/extcon/Makefile
··· 6 6 obj-$(CONFIG_EXTCON) += extcon-core.o 7 7 extcon-core-objs += extcon.o devres.o 8 8 obj-$(CONFIG_EXTCON_ADC_JACK) += extcon-adc-jack.o 9 - obj-$(CONFIG_EXTCON_ARIZONA) += extcon-arizona.o 10 9 obj-$(CONFIG_EXTCON_AXP288) += extcon-axp288.o 11 10 obj-$(CONFIG_EXTCON_FSA9480) += extcon-fsa9480.o 12 11 obj-$(CONFIG_EXTCON_GPIO) += extcon-gpio.o
+33 -30
drivers/extcon/extcon-arizona.c sound/soc/codecs/arizona-jack.c
··· 290 290 unsigned int mode; 291 291 292 292 /* Microphone detection can't use idle mode */ 293 - pm_runtime_get(info->dev); 293 + pm_runtime_get_sync(info->dev); 294 294 295 295 if (info->detecting) { 296 296 ret = regulator_allow_bypass(info->micvdd, false); ··· 601 601 struct arizona *arizona = info->arizona; 602 602 int id_gpio = arizona->pdata.hpdet_id_gpio; 603 603 unsigned int report = EXTCON_JACK_HEADPHONE; 604 - int ret, reading; 604 + int ret, reading, state; 605 605 bool mic = false; 606 606 607 607 mutex_lock(&info->lock); ··· 614 614 } 615 615 616 616 /* If the cable was removed while measuring ignore the result */ 617 - ret = extcon_get_state(info->edev, EXTCON_MECHANICAL); 618 - if (ret < 0) { 619 - dev_err(arizona->dev, "Failed to check cable state: %d\n", 620 - ret); 617 + state = extcon_get_state(info->edev, EXTCON_MECHANICAL); 618 + if (state < 0) { 619 + dev_err(arizona->dev, "Failed to check cable state: %d\n", state); 621 620 goto out; 622 - } else if (!ret) { 621 + } else if (!state) { 623 622 dev_dbg(arizona->dev, "Ignoring HPDET for removed cable\n"); 624 623 goto done; 625 624 } ··· 666 667 gpio_set_value_cansleep(id_gpio, 0); 667 668 668 669 /* If we have a mic then reenable MICDET */ 669 - if (mic || info->mic) 670 + if (state && (mic || info->mic)) 670 671 arizona_start_mic(info); 671 672 672 673 if (info->hpdet_active) { ··· 674 675 info->hpdet_active = false; 675 676 } 676 677 677 - info->hpdet_done = true; 678 + /* Do not set hp_det done when the cable has been unplugged */ 679 + if (state) 680 + info->hpdet_done = true; 678 681 679 682 out: 680 683 mutex_unlock(&info->lock); ··· 695 694 dev_dbg(arizona->dev, "Starting HPDET\n"); 696 695 697 696 /* Make sure we keep the device enabled during the measurement */ 698 - pm_runtime_get(info->dev); 697 + pm_runtime_get_sync(info->dev); 699 698 700 699 info->hpdet_active = true; 701 700 ··· 1510 1509 */ 1511 1510 info->micd_pol_gpio = gpiod_get_optional(arizona->dev, 1512 1511 "wlf,micd-pol", 1513 - GPIOD_OUT_LOW); 1512 + mode); 1514 1513 if (IS_ERR(info->micd_pol_gpio)) { 1515 1514 ret = PTR_ERR(info->micd_pol_gpio); 1516 1515 dev_err(arizona->dev, ··· 1760 1759 bool change; 1761 1760 int ret; 1762 1761 1763 - ret = regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1, 1764 - ARIZONA_MICD_ENA, 0, 1765 - &change); 1766 - if (ret < 0) { 1767 - dev_err(&pdev->dev, "Failed to disable micd on remove: %d\n", 1768 - ret); 1769 - } else if (change) { 1770 - regulator_disable(info->micvdd); 1771 - pm_runtime_put(info->dev); 1772 - } 1773 - 1774 - gpiod_put(info->micd_pol_gpio); 1775 - 1776 - pm_runtime_disable(&pdev->dev); 1777 - 1778 - regmap_update_bits(arizona->regmap, 1779 - ARIZONA_MICD_CLAMP_CONTROL, 1780 - ARIZONA_MICD_CLAMP_MODE_MASK, 0); 1781 - 1782 1762 if (info->micd_clamp) { 1783 1763 jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE; 1784 1764 jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL; ··· 1775 1793 arizona_free_irq(arizona, jack_irq_rise, info); 1776 1794 arizona_free_irq(arizona, jack_irq_fall, info); 1777 1795 cancel_delayed_work_sync(&info->hpdet_work); 1796 + cancel_delayed_work_sync(&info->micd_detect_work); 1797 + cancel_delayed_work_sync(&info->micd_timeout_work); 1798 + 1799 + ret = regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1, 1800 + ARIZONA_MICD_ENA, 0, 1801 + &change); 1802 + if (ret < 0) { 1803 + dev_err(&pdev->dev, "Failed to disable micd on remove: %d\n", 1804 + ret); 1805 + } else if (change) { 1806 + regulator_disable(info->micvdd); 1807 + pm_runtime_put(info->dev); 1808 + } 1809 + 1810 + regmap_update_bits(arizona->regmap, 1811 + ARIZONA_MICD_CLAMP_CONTROL, 1812 + ARIZONA_MICD_CLAMP_MODE_MASK, 0); 1778 1813 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, 1779 1814 ARIZONA_JD1_ENA, 0); 1780 1815 arizona_clk32k_disable(arizona); 1816 + 1817 + gpiod_put(info->micd_pol_gpio); 1818 + 1819 + pm_runtime_disable(&pdev->dev); 1781 1820 1782 1821 return 0; 1783 1822 }
+10
drivers/gpio/Kconfig
··· 1105 1105 This driver can also be built as a module. If so, the module 1106 1106 will be called gpio-bd70528. 1107 1107 1108 + config GPIO_BD71815 1109 + tristate "ROHM BD71815 PMIC GPIO support" 1110 + depends on MFD_ROHM_BD71828 1111 + help 1112 + Support for GPO(s) on ROHM BD71815 PMIC. There are two GPOs 1113 + available on the ROHM PMIC. 1114 + 1115 + This driver can also be built as a module. If so, the module 1116 + will be called gpio-bd71815. 1117 + 1108 1118 config GPIO_BD71828 1109 1119 tristate "ROHM BD71828 GPIO support" 1110 1120 depends on MFD_ROHM_BD71828
+1
drivers/gpio/Makefile
··· 39 39 obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o 40 40 obj-$(CONFIG_GPIO_BCM_XGS_IPROC) += gpio-xgs-iproc.o 41 41 obj-$(CONFIG_GPIO_BD70528) += gpio-bd70528.o 42 + obj-$(CONFIG_GPIO_BD71815) += gpio-bd71815.o 42 43 obj-$(CONFIG_GPIO_BD71828) += gpio-bd71828.o 43 44 obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd9571mwv.o 44 45 obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o
+185
drivers/gpio/gpio-bd71815.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Support to GPOs on ROHM BD71815 4 + * Copyright 2021 ROHM Semiconductors. 5 + * Author: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> 6 + * 7 + * Copyright 2014 Embest Technology Co. Ltd. Inc. 8 + * Author: yanglsh@embest-tech.com 9 + */ 10 + 11 + #include <linux/gpio/driver.h> 12 + #include <linux/init.h> 13 + #include <linux/irq.h> 14 + #include <linux/module.h> 15 + #include <linux/of.h> 16 + #include <linux/platform_device.h> 17 + /* For the BD71815 register definitions */ 18 + #include <linux/mfd/rohm-bd71815.h> 19 + 20 + struct bd71815_gpio { 21 + /* chip.parent points the MFD which provides DT node and regmap */ 22 + struct gpio_chip chip; 23 + /* dev points to the platform device for devm and prints */ 24 + struct device *dev; 25 + struct regmap *regmap; 26 + }; 27 + 28 + static int bd71815gpo_get(struct gpio_chip *chip, unsigned int offset) 29 + { 30 + struct bd71815_gpio *bd71815 = gpiochip_get_data(chip); 31 + int ret, val; 32 + 33 + ret = regmap_read(bd71815->regmap, BD71815_REG_GPO, &val); 34 + if (ret) 35 + return ret; 36 + 37 + return (val >> offset) & 1; 38 + } 39 + 40 + static void bd71815gpo_set(struct gpio_chip *chip, unsigned int offset, 41 + int value) 42 + { 43 + struct bd71815_gpio *bd71815 = gpiochip_get_data(chip); 44 + int ret, bit; 45 + 46 + bit = BIT(offset); 47 + 48 + if (value) 49 + ret = regmap_set_bits(bd71815->regmap, BD71815_REG_GPO, bit); 50 + else 51 + ret = regmap_clear_bits(bd71815->regmap, BD71815_REG_GPO, bit); 52 + 53 + if (ret) 54 + dev_warn(bd71815->dev, "failed to toggle GPO\n"); 55 + } 56 + 57 + static int bd71815_gpio_set_config(struct gpio_chip *chip, unsigned int offset, 58 + unsigned long config) 59 + { 60 + struct bd71815_gpio *bdgpio = gpiochip_get_data(chip); 61 + 62 + switch (pinconf_to_config_param(config)) { 63 + case PIN_CONFIG_DRIVE_OPEN_DRAIN: 64 + return regmap_update_bits(bdgpio->regmap, 65 + BD71815_REG_GPO, 66 + BD71815_GPIO_DRIVE_MASK << offset, 67 + BD71815_GPIO_OPEN_DRAIN << offset); 68 + case PIN_CONFIG_DRIVE_PUSH_PULL: 69 + return regmap_update_bits(bdgpio->regmap, 70 + BD71815_REG_GPO, 71 + BD71815_GPIO_DRIVE_MASK << offset, 72 + BD71815_GPIO_CMOS << offset); 73 + default: 74 + break; 75 + } 76 + return -ENOTSUPP; 77 + } 78 + 79 + /* BD71815 GPIO is actually GPO */ 80 + static int bd71815gpo_direction_get(struct gpio_chip *gc, unsigned int offset) 81 + { 82 + return GPIO_LINE_DIRECTION_OUT; 83 + } 84 + 85 + /* Template for GPIO chip */ 86 + static const struct gpio_chip bd71815gpo_chip = { 87 + .label = "bd71815", 88 + .owner = THIS_MODULE, 89 + .get = bd71815gpo_get, 90 + .get_direction = bd71815gpo_direction_get, 91 + .set = bd71815gpo_set, 92 + .set_config = bd71815_gpio_set_config, 93 + .can_sleep = true, 94 + }; 95 + 96 + #define BD71815_TWO_GPIOS GENMASK(1, 0) 97 + #define BD71815_ONE_GPIO BIT(0) 98 + 99 + /* 100 + * Sigh. The BD71815 and BD71817 were originally designed to support two GPO 101 + * pins. At some point it was noticed the second GPO pin which is the E5 pin 102 + * located at the center of IC is hard to use on PCB (due to the location). It 103 + * was decided to not promote this second GPO and the pin is marked as GND in 104 + * the datasheet. The functionality is still there though! I guess driving a GPO 105 + * connected to the ground is a bad idea. Thus we do not support it by default. 106 + * OTOH - the original driver written by colleagues at Embest did support 107 + * controlling this second GPO. It is thus possible this is used in some of the 108 + * products. 109 + * 110 + * This driver does not by default support configuring this second GPO 111 + * but allows using it by providing the DT property 112 + * "rohm,enable-hidden-gpo". 113 + */ 114 + static int bd71815_init_valid_mask(struct gpio_chip *gc, 115 + unsigned long *valid_mask, 116 + unsigned int ngpios) 117 + { 118 + if (ngpios != 2) 119 + return 0; 120 + 121 + if (gc->parent && device_property_present(gc->parent, 122 + "rohm,enable-hidden-gpo")) 123 + *valid_mask = BD71815_TWO_GPIOS; 124 + else 125 + *valid_mask = BD71815_ONE_GPIO; 126 + 127 + return 0; 128 + } 129 + 130 + static int gpo_bd71815_probe(struct platform_device *pdev) 131 + { 132 + struct bd71815_gpio *g; 133 + struct device *parent, *dev; 134 + 135 + /* 136 + * Bind devm lifetime to this platform device => use dev for devm. 137 + * also the prints should originate from this device. 138 + */ 139 + dev = &pdev->dev; 140 + /* The device-tree and regmap come from MFD => use parent for that */ 141 + parent = dev->parent; 142 + 143 + g = devm_kzalloc(dev, sizeof(*g), GFP_KERNEL); 144 + if (!g) 145 + return -ENOMEM; 146 + 147 + g->chip = bd71815gpo_chip; 148 + 149 + /* 150 + * FIXME: As writing of this the sysfs interface for GPIO control does 151 + * not respect the valid_mask. Do not trust it but rather set the ngpios 152 + * to 1 if "rohm,enable-hidden-gpo" is not given. 153 + * 154 + * This check can be removed later if the sysfs export is fixed and 155 + * if the fix is backported. 156 + * 157 + * For now it is safest to just set the ngpios though. 158 + */ 159 + if (device_property_present(parent, "rohm,enable-hidden-gpo")) 160 + g->chip.ngpio = 2; 161 + else 162 + g->chip.ngpio = 1; 163 + 164 + g->chip.init_valid_mask = bd71815_init_valid_mask; 165 + g->chip.base = -1; 166 + g->chip.parent = parent; 167 + g->regmap = dev_get_regmap(parent, NULL); 168 + g->dev = dev; 169 + 170 + return devm_gpiochip_add_data(dev, &g->chip, g); 171 + } 172 + 173 + static struct platform_driver gpo_bd71815_driver = { 174 + .driver = { 175 + .name = "bd71815-gpo", 176 + }, 177 + .probe = gpo_bd71815_probe, 178 + }; 179 + module_platform_driver(gpo_bd71815_driver); 180 + 181 + MODULE_ALIAS("platform:bd71815-gpo"); 182 + MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); 183 + MODULE_AUTHOR("Peter Yang <yanglsh@embest-tech.com>"); 184 + MODULE_DESCRIPTION("GPO interface for BD71815"); 185 + MODULE_LICENSE("GPL");
+1 -6
drivers/i2c/busses/i2c-designware-platdrv.c
··· 22 22 #include <linux/mfd/syscon.h> 23 23 #include <linux/module.h> 24 24 #include <linux/of.h> 25 - #include <linux/platform_data/i2c-designware.h> 26 25 #include <linux/platform_device.h> 27 26 #include <linux/pm.h> 28 27 #include <linux/pm_runtime.h> ··· 205 206 206 207 static int dw_i2c_plat_probe(struct platform_device *pdev) 207 208 { 208 - struct dw_i2c_platform_data *pdata = dev_get_platdata(&pdev->dev); 209 209 struct i2c_adapter *adap; 210 210 struct dw_i2c_dev *dev; 211 211 struct i2c_timings *t; ··· 234 236 reset_control_deassert(dev->rst); 235 237 236 238 t = &dev->timings; 237 - if (pdata) 238 - t->bus_freq_hz = pdata->i2c_scl_freq; 239 - else 240 - i2c_parse_fw_timings(&pdev->dev, t, false); 239 + i2c_parse_fw_timings(&pdev->dev, t, false); 241 240 242 241 i2c_dw_adjust_bus_speed(dev); 243 242
+11
drivers/input/misc/Kconfig
··· 94 94 To compile this driver as a module, choose M here: the 95 95 module will be called arizona-haptics. 96 96 97 + config INPUT_ATC260X_ONKEY 98 + tristate "Actions Semi ATC260x PMIC ONKEY" 99 + depends on MFD_ATC260X 100 + help 101 + Support the ONKEY of ATC260x PMICs as an input device reporting 102 + power button status. ONKEY can be used to wakeup from low power 103 + modes and force a reset on long press. 104 + 105 + To compile this driver as a module, choose M here: the 106 + module will be called atc260x-onkey. 107 + 97 108 config INPUT_ATMEL_CAPTOUCH 98 109 tristate "Atmel Capacitive Touch Button Driver" 99 110 depends on OF || COMPILE_TEST
+1 -1
drivers/input/misc/Makefile
··· 17 17 obj-$(CONFIG_INPUT_APANEL) += apanel.o 18 18 obj-$(CONFIG_INPUT_ARIEL_PWRBUTTON) += ariel-pwrbutton.o 19 19 obj-$(CONFIG_INPUT_ARIZONA_HAPTICS) += arizona-haptics.o 20 + obj-$(CONFIG_INPUT_ATC260X_ONKEY) += atc260x-onkey.o 20 21 obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o 21 22 obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o 22 23 obj-$(CONFIG_INPUT_ATMEL_CAPTOUCH) += atmel_captouch.o ··· 87 86 obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o 88 87 obj-$(CONFIG_INPUT_YEALINK) += yealink.o 89 88 obj-$(CONFIG_INPUT_IDEAPAD_SLIDEBAR) += ideapad_slidebar.o 90 -
+305
drivers/input/misc/atc260x-onkey.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Onkey driver for Actions Semi ATC260x PMICs. 4 + * 5 + * Copyright (c) 2020 Cristian Ciocaltea <cristian.ciocaltea@gmail.com> 6 + */ 7 + 8 + #include <linux/bitfield.h> 9 + #include <linux/input.h> 10 + #include <linux/interrupt.h> 11 + #include <linux/mfd/atc260x/core.h> 12 + #include <linux/module.h> 13 + #include <linux/of.h> 14 + #include <linux/platform_device.h> 15 + #include <linux/regmap.h> 16 + 17 + /* <2s for short press, >2s for long press */ 18 + #define KEY_PRESS_TIME_SEC 2 19 + 20 + /* Driver internals */ 21 + enum atc260x_onkey_reset_status { 22 + KEY_RESET_HW_DEFAULT, 23 + KEY_RESET_DISABLED, 24 + KEY_RESET_USER_SEL, 25 + }; 26 + 27 + struct atc260x_onkey_params { 28 + u32 reg_int_ctl; 29 + u32 kdwn_state_bm; 30 + u32 long_int_pnd_bm; 31 + u32 short_int_pnd_bm; 32 + u32 kdwn_int_pnd_bm; 33 + u32 press_int_en_bm; 34 + u32 kdwn_int_en_bm; 35 + u32 press_time_bm; 36 + u32 reset_en_bm; 37 + u32 reset_time_bm; 38 + }; 39 + 40 + struct atc260x_onkey { 41 + struct atc260x *atc260x; 42 + const struct atc260x_onkey_params *params; 43 + struct input_dev *input_dev; 44 + struct delayed_work work; 45 + int irq; 46 + }; 47 + 48 + static const struct atc260x_onkey_params atc2603c_onkey_params = { 49 + .reg_int_ctl = ATC2603C_PMU_SYS_CTL2, 50 + .long_int_pnd_bm = ATC2603C_PMU_SYS_CTL2_ONOFF_LONG_PRESS, 51 + .short_int_pnd_bm = ATC2603C_PMU_SYS_CTL2_ONOFF_SHORT_PRESS, 52 + .kdwn_int_pnd_bm = ATC2603C_PMU_SYS_CTL2_ONOFF_PRESS_PD, 53 + .press_int_en_bm = ATC2603C_PMU_SYS_CTL2_ONOFF_INT_EN, 54 + .kdwn_int_en_bm = ATC2603C_PMU_SYS_CTL2_ONOFF_PRESS_INT_EN, 55 + .kdwn_state_bm = ATC2603C_PMU_SYS_CTL2_ONOFF_PRESS, 56 + .press_time_bm = ATC2603C_PMU_SYS_CTL2_ONOFF_PRESS_TIME, 57 + .reset_en_bm = ATC2603C_PMU_SYS_CTL2_ONOFF_PRESS_RESET_EN, 58 + .reset_time_bm = ATC2603C_PMU_SYS_CTL2_ONOFF_RESET_TIME_SEL, 59 + }; 60 + 61 + static const struct atc260x_onkey_params atc2609a_onkey_params = { 62 + .reg_int_ctl = ATC2609A_PMU_SYS_CTL2, 63 + .long_int_pnd_bm = ATC2609A_PMU_SYS_CTL2_ONOFF_LONG_PRESS, 64 + .short_int_pnd_bm = ATC2609A_PMU_SYS_CTL2_ONOFF_SHORT_PRESS, 65 + .kdwn_int_pnd_bm = ATC2609A_PMU_SYS_CTL2_ONOFF_PRESS_PD, 66 + .press_int_en_bm = ATC2609A_PMU_SYS_CTL2_ONOFF_LSP_INT_EN, 67 + .kdwn_int_en_bm = ATC2609A_PMU_SYS_CTL2_ONOFF_PRESS_INT_EN, 68 + .kdwn_state_bm = ATC2609A_PMU_SYS_CTL2_ONOFF_PRESS, 69 + .press_time_bm = ATC2609A_PMU_SYS_CTL2_ONOFF_PRESS_TIME, 70 + .reset_en_bm = ATC2609A_PMU_SYS_CTL2_ONOFF_RESET_EN, 71 + .reset_time_bm = ATC2609A_PMU_SYS_CTL2_ONOFF_RESET_TIME_SEL, 72 + }; 73 + 74 + static int atc2603x_onkey_hw_init(struct atc260x_onkey *onkey, 75 + enum atc260x_onkey_reset_status reset_status, 76 + u32 reset_time, u32 press_time) 77 + { 78 + u32 reg_bm, reg_val; 79 + 80 + reg_bm = onkey->params->long_int_pnd_bm | 81 + onkey->params->short_int_pnd_bm | 82 + onkey->params->kdwn_int_pnd_bm | 83 + onkey->params->press_int_en_bm | 84 + onkey->params->kdwn_int_en_bm; 85 + 86 + reg_val = reg_bm | press_time; 87 + reg_bm |= onkey->params->press_time_bm; 88 + 89 + if (reset_status == KEY_RESET_DISABLED) { 90 + reg_bm |= onkey->params->reset_en_bm; 91 + } else if (reset_status == KEY_RESET_USER_SEL) { 92 + reg_bm |= onkey->params->reset_en_bm | 93 + onkey->params->reset_time_bm; 94 + reg_val |= onkey->params->reset_en_bm | reset_time; 95 + } 96 + 97 + return regmap_update_bits(onkey->atc260x->regmap, 98 + onkey->params->reg_int_ctl, reg_bm, reg_val); 99 + } 100 + 101 + static void atc260x_onkey_query(struct atc260x_onkey *onkey) 102 + { 103 + u32 reg_bits; 104 + int ret, key_down; 105 + 106 + ret = regmap_read(onkey->atc260x->regmap, 107 + onkey->params->reg_int_ctl, &key_down); 108 + if (ret) { 109 + key_down = 1; 110 + dev_err(onkey->atc260x->dev, 111 + "Failed to read onkey status: %d\n", ret); 112 + } else { 113 + key_down &= onkey->params->kdwn_state_bm; 114 + } 115 + 116 + /* 117 + * The hardware generates interrupt only when the onkey pin is 118 + * asserted. Hence, the deassertion of the pin is simulated through 119 + * work queue. 120 + */ 121 + if (key_down) { 122 + schedule_delayed_work(&onkey->work, msecs_to_jiffies(200)); 123 + return; 124 + } 125 + 126 + /* 127 + * The key-down status bit is cleared when the On/Off button 128 + * is released. 129 + */ 130 + input_report_key(onkey->input_dev, KEY_POWER, 0); 131 + input_sync(onkey->input_dev); 132 + 133 + reg_bits = onkey->params->long_int_pnd_bm | 134 + onkey->params->short_int_pnd_bm | 135 + onkey->params->kdwn_int_pnd_bm | 136 + onkey->params->press_int_en_bm | 137 + onkey->params->kdwn_int_en_bm; 138 + 139 + /* Clear key press pending events and enable key press interrupts. */ 140 + regmap_update_bits(onkey->atc260x->regmap, onkey->params->reg_int_ctl, 141 + reg_bits, reg_bits); 142 + } 143 + 144 + static void atc260x_onkey_work(struct work_struct *work) 145 + { 146 + struct atc260x_onkey *onkey = container_of(work, struct atc260x_onkey, 147 + work.work); 148 + atc260x_onkey_query(onkey); 149 + } 150 + 151 + static irqreturn_t atc260x_onkey_irq(int irq, void *data) 152 + { 153 + struct atc260x_onkey *onkey = data; 154 + int ret; 155 + 156 + /* Disable key press interrupts. */ 157 + ret = regmap_update_bits(onkey->atc260x->regmap, 158 + onkey->params->reg_int_ctl, 159 + onkey->params->press_int_en_bm | 160 + onkey->params->kdwn_int_en_bm, 0); 161 + if (ret) 162 + dev_err(onkey->atc260x->dev, 163 + "Failed to disable interrupts: %d\n", ret); 164 + 165 + input_report_key(onkey->input_dev, KEY_POWER, 1); 166 + input_sync(onkey->input_dev); 167 + 168 + atc260x_onkey_query(onkey); 169 + 170 + return IRQ_HANDLED; 171 + } 172 + 173 + static int atc260x_onkey_open(struct input_dev *dev) 174 + { 175 + struct atc260x_onkey *onkey = input_get_drvdata(dev); 176 + 177 + enable_irq(onkey->irq); 178 + 179 + return 0; 180 + } 181 + 182 + static void atc260x_onkey_close(struct input_dev *dev) 183 + { 184 + struct atc260x_onkey *onkey = input_get_drvdata(dev); 185 + 186 + disable_irq(onkey->irq); 187 + cancel_delayed_work_sync(&onkey->work); 188 + } 189 + 190 + static int atc260x_onkey_probe(struct platform_device *pdev) 191 + { 192 + struct atc260x *atc260x = dev_get_drvdata(pdev->dev.parent); 193 + struct atc260x_onkey *onkey; 194 + struct input_dev *input_dev; 195 + enum atc260x_onkey_reset_status reset_status; 196 + u32 press_time = KEY_PRESS_TIME_SEC, reset_time = 0; 197 + int val, error; 198 + 199 + onkey = devm_kzalloc(&pdev->dev, sizeof(*onkey), GFP_KERNEL); 200 + if (!onkey) 201 + return -ENOMEM; 202 + 203 + error = device_property_read_u32(pdev->dev.parent, 204 + "reset-time-sec", &val); 205 + if (error) { 206 + reset_status = KEY_RESET_HW_DEFAULT; 207 + } else if (val) { 208 + if (val < 6 || val > 12) { 209 + dev_err(&pdev->dev, "reset-time-sec out of range\n"); 210 + return -EINVAL; 211 + } 212 + 213 + reset_status = KEY_RESET_USER_SEL; 214 + reset_time = (val - 6) / 2; 215 + } else { 216 + reset_status = KEY_RESET_DISABLED; 217 + dev_dbg(&pdev->dev, "Disabled reset on long-press\n"); 218 + } 219 + 220 + switch (atc260x->ic_type) { 221 + case ATC2603C: 222 + onkey->params = &atc2603c_onkey_params; 223 + press_time = FIELD_PREP(ATC2603C_PMU_SYS_CTL2_ONOFF_PRESS_TIME, 224 + press_time); 225 + reset_time = FIELD_PREP(ATC2603C_PMU_SYS_CTL2_ONOFF_RESET_TIME_SEL, 226 + reset_time); 227 + break; 228 + case ATC2609A: 229 + onkey->params = &atc2609a_onkey_params; 230 + press_time = FIELD_PREP(ATC2609A_PMU_SYS_CTL2_ONOFF_PRESS_TIME, 231 + press_time); 232 + reset_time = FIELD_PREP(ATC2609A_PMU_SYS_CTL2_ONOFF_RESET_TIME_SEL, 233 + reset_time); 234 + break; 235 + default: 236 + dev_err(&pdev->dev, 237 + "OnKey not supported for ATC260x PMIC type: %u\n", 238 + atc260x->ic_type); 239 + return -EINVAL; 240 + } 241 + 242 + input_dev = devm_input_allocate_device(&pdev->dev); 243 + if (!input_dev) { 244 + dev_err(&pdev->dev, "Failed to allocate input device\n"); 245 + return -ENOMEM; 246 + } 247 + 248 + onkey->input_dev = input_dev; 249 + onkey->atc260x = atc260x; 250 + 251 + input_dev->name = "atc260x-onkey"; 252 + input_dev->phys = "atc260x-onkey/input0"; 253 + input_dev->open = atc260x_onkey_open; 254 + input_dev->close = atc260x_onkey_close; 255 + 256 + input_set_capability(input_dev, EV_KEY, KEY_POWER); 257 + input_set_drvdata(input_dev, onkey); 258 + 259 + INIT_DELAYED_WORK(&onkey->work, atc260x_onkey_work); 260 + 261 + onkey->irq = platform_get_irq(pdev, 0); 262 + if (onkey->irq < 0) 263 + return onkey->irq; 264 + 265 + error = devm_request_threaded_irq(&pdev->dev, onkey->irq, NULL, 266 + atc260x_onkey_irq, IRQF_ONESHOT, 267 + dev_name(&pdev->dev), onkey); 268 + if (error) { 269 + dev_err(&pdev->dev, 270 + "Failed to register IRQ %d: %d\n", onkey->irq, error); 271 + return error; 272 + } 273 + 274 + /* Keep IRQ disabled until atc260x_onkey_open() is called. */ 275 + disable_irq(onkey->irq); 276 + 277 + error = input_register_device(input_dev); 278 + if (error) { 279 + dev_err(&pdev->dev, 280 + "Failed to register input device: %d\n", error); 281 + return error; 282 + } 283 + 284 + error = atc2603x_onkey_hw_init(onkey, reset_status, 285 + reset_time, press_time); 286 + if (error) 287 + return error; 288 + 289 + device_init_wakeup(&pdev->dev, true); 290 + 291 + return 0; 292 + } 293 + 294 + static struct platform_driver atc260x_onkey_driver = { 295 + .probe = atc260x_onkey_probe, 296 + .driver = { 297 + .name = "atc260x-onkey", 298 + }, 299 + }; 300 + 301 + module_platform_driver(atc260x_onkey_driver); 302 + 303 + MODULE_DESCRIPTION("Onkey driver for ATC260x PMICs"); 304 + MODULE_AUTHOR("Cristian Ciocaltea <cristian.ciocaltea@gmail.com>"); 305 + MODULE_LICENSE("GPL");
+50 -32
drivers/mfd/Kconfig
··· 967 967 You need to select the mfd cell drivers separately. 968 968 The drivers do not support all features the board exposes. 969 969 970 + config MFD_NTXEC 971 + tristate "Netronix embedded controller (EC)" 972 + depends on OF || COMPILE_TEST 973 + depends on I2C 974 + select REGMAP_I2C 975 + select MFD_CORE 976 + help 977 + Say yes here if you want to support the embedded controller found in 978 + certain e-book readers designed by the original design manufacturer 979 + Netronix. 980 + 970 981 config MFD_RETU 971 982 tristate "Nokia Retu and Tahvo multi-function device" 972 983 select MFD_CORE ··· 1235 1224 1236 1225 config ABX500_CORE 1237 1226 bool "ST-Ericsson ABX500 Mixed Signal Circuit register functions" 1238 - default y if ARCH_U300 || ARCH_U8500 || COMPILE_TEST 1227 + depends on ARCH_U8500 || COMPILE_TEST 1228 + default y if ARCH_U8500 1239 1229 help 1240 1230 Say yes here if you have the ABX500 Mixed Signal IC family 1241 1231 chips. This core driver expose register access functions. 1242 1232 Functionality specific drivers using these functions can 1243 1233 remain unchanged when IC changes. Binding of the functions to 1244 1234 actual register access is done by the IC core driver. 1245 - 1246 - config AB3100_CORE 1247 - bool "ST-Ericsson AB3100 Mixed Signal Circuit core functions" 1248 - depends on I2C=y && ABX500_CORE 1249 - select MFD_CORE 1250 - default y if ARCH_U300 1251 - help 1252 - Select this to enable the AB3100 Mixed Signal IC core 1253 - functionality. This connects to a AB3100 on the I2C bus 1254 - and expose a number of symbols needed for dependent devices 1255 - to read and write registers and subscribe to events from 1256 - this multi-functional IC. This is needed to use other features 1257 - of the AB3100 such as battery-backed RTC, charging control, 1258 - LEDs, vibrator, system power and temperature, power management 1259 - and ALSA sound. 1260 - 1261 - config AB3100_OTP 1262 - tristate "ST-Ericsson AB3100 OTP functions" 1263 - depends on AB3100_CORE 1264 - default y if AB3100_CORE 1265 - help 1266 - Select this to enable the AB3100 Mixed Signal IC OTP (one-time 1267 - programmable memory) support. This exposes a sysfs file to read 1268 - out OTP values. 1269 1235 1270 1236 config AB8500_CORE 1271 1237 bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" ··· 1963 1975 charger. 1964 1976 1965 1977 config MFD_ROHM_BD71828 1966 - tristate "ROHM BD71828 Power Management IC" 1978 + tristate "ROHM BD71828 and BD71815 Power Management IC" 1967 1979 depends on I2C=y 1968 1980 depends on OF 1969 1981 select REGMAP_I2C 1970 1982 select REGMAP_IRQ 1971 1983 select MFD_CORE 1972 1984 help 1973 - Select this option to get support for the ROHM BD71828 Power 1974 - Management IC. BD71828GW is a single-chip power management IC for 1975 - battery-powered portable devices. The IC integrates 7 buck 1976 - converters, 7 LDOs, and a 1500 mA single-cell linear charger. 1977 - Also included is a Coulomb counter, a real-time clock (RTC), and 1978 - a 32.768 kHz clock gate. 1985 + Select this option to get support for the ROHM BD71828 and BD71815 1986 + Power Management ICs. BD71828GW and BD71815AGW are single-chip power 1987 + management ICs mainly for battery-powered portable devices. 1988 + The BD71828 integrates 7 buck converters and 7 LDOs. The BD71815 1989 + has 5 bucks, 7 LDOs, and a boost for driving LEDs. Both ICs provide 1990 + also a single-cell linear charger, a Coulomb counter, a real-time 1991 + clock (RTC), GPIOs and a 32.768 kHz clock gate. 1992 + 1993 + config MFD_ROHM_BD957XMUF 1994 + tristate "ROHM BD9576MUF and BD9573MUF Power Management ICs" 1995 + depends on I2C=y 1996 + depends on OF 1997 + select REGMAP_I2C 1998 + select MFD_CORE 1999 + help 2000 + Select this option to get support for the ROHM BD9576MUF and 2001 + BD9573MUF Power Management ICs. BD9576 and BD9573 are primarily 2002 + designed to be used to power R-Car series processors. 1979 2003 1980 2004 config MFD_STM32_LPTIMER 1981 2005 tristate "Support for STM32 Low-Power Timer" ··· 2054 2054 Support for the Qualcomm WCD9340/WCD9341 Codec. 2055 2055 This driver provides common support WCD934x audio codec and its 2056 2056 associated Pin Controller, Soundwire Controller and Audio codec. 2057 + 2058 + config MFD_ATC260X 2059 + tristate 2060 + select MFD_CORE 2061 + select REGMAP 2062 + select REGMAP_IRQ 2063 + 2064 + config MFD_ATC260X_I2C 2065 + tristate "Actions Semi ATC260x PMICs with I2C" 2066 + select MFD_ATC260X 2067 + select REGMAP_I2C 2068 + depends on I2C 2069 + help 2070 + Support for the Actions Semi ATC260x PMICs controlled via I2C. 2071 + 2072 + This driver provides common support for accessing the ATC2603C 2073 + and ATC2609A chip variants, additional drivers must be enabled 2074 + in order to use the functionality of the device. 2057 2075 2058 2076 config MFD_KHADAS_MCU 2059 2077 tristate "Support for Khadas System control Microcontroller"
+5 -2
drivers/mfd/Makefile
··· 178 178 obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o 179 179 obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o 180 180 obj-$(CONFIG_ABX500_CORE) += abx500-core.o 181 - obj-$(CONFIG_AB3100_CORE) += ab3100-core.o 182 - obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o 183 181 obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o 184 182 obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o 185 183 # ab8500-core need to come after db8500-prcmu (which provides the channel) ··· 216 218 obj-$(CONFIG_MFD_INTEL_PMT) += intel_pmt.o 217 219 obj-$(CONFIG_MFD_PALMAS) += palmas.o 218 220 obj-$(CONFIG_MFD_VIPERBOARD) += viperboard.o 221 + obj-$(CONFIG_MFD_NTXEC) += ntxec.o 219 222 obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o 220 223 obj-$(CONFIG_MFD_RK808) += rk808.o 221 224 obj-$(CONFIG_MFD_RN5T618) += rn5t618.o ··· 260 261 obj-$(CONFIG_MFD_ROHM_BD70528) += rohm-bd70528.o 261 262 obj-$(CONFIG_MFD_ROHM_BD71828) += rohm-bd71828.o 262 263 obj-$(CONFIG_MFD_ROHM_BD718XX) += rohm-bd718x7.o 264 + obj-$(CONFIG_MFD_ROHM_BD957XMUF) += rohm-bd9576.o 263 265 obj-$(CONFIG_MFD_STMFX) += stmfx.o 264 266 obj-$(CONFIG_MFD_KHADAS_MCU) += khadas-mcu.o 265 267 obj-$(CONFIG_MFD_ACER_A500_EC) += acer-ec-a500.o ··· 268 268 obj-$(CONFIG_SGI_MFD_IOC3) += ioc3.o 269 269 obj-$(CONFIG_MFD_SIMPLE_MFD_I2C) += simple-mfd-i2c.o 270 270 obj-$(CONFIG_MFD_INTEL_M10_BMC) += intel-m10-bmc.o 271 + 272 + obj-$(CONFIG_MFD_ATC260X) += atc260x-core.o 273 + obj-$(CONFIG_MFD_ATC260X_I2C) += atc260x-i2c.o
-929
drivers/mfd/ab3100-core.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) 2007-2010 ST-Ericsson 4 - * Low-level core for exclusive access to the AB3100 IC on the I2C bus 5 - * and some basic chip-configuration. 6 - * Author: Linus Walleij <linus.walleij@stericsson.com> 7 - */ 8 - 9 - #include <linux/i2c.h> 10 - #include <linux/mutex.h> 11 - #include <linux/list.h> 12 - #include <linux/notifier.h> 13 - #include <linux/slab.h> 14 - #include <linux/err.h> 15 - #include <linux/init.h> 16 - #include <linux/platform_device.h> 17 - #include <linux/device.h> 18 - #include <linux/interrupt.h> 19 - #include <linux/random.h> 20 - #include <linux/debugfs.h> 21 - #include <linux/seq_file.h> 22 - #include <linux/uaccess.h> 23 - #include <linux/mfd/core.h> 24 - #include <linux/mfd/ab3100.h> 25 - #include <linux/mfd/abx500.h> 26 - 27 - /* These are the only registers inside AB3100 used in this main file */ 28 - 29 - /* Interrupt event registers */ 30 - #define AB3100_EVENTA1 0x21 31 - #define AB3100_EVENTA2 0x22 32 - #define AB3100_EVENTA3 0x23 33 - 34 - /* AB3100 DAC converter registers */ 35 - #define AB3100_DIS 0x00 36 - #define AB3100_D0C 0x01 37 - #define AB3100_D1C 0x02 38 - #define AB3100_D2C 0x03 39 - #define AB3100_D3C 0x04 40 - 41 - /* Chip ID register */ 42 - #define AB3100_CID 0x20 43 - 44 - /* AB3100 interrupt registers */ 45 - #define AB3100_IMRA1 0x24 46 - #define AB3100_IMRA2 0x25 47 - #define AB3100_IMRA3 0x26 48 - #define AB3100_IMRB1 0x2B 49 - #define AB3100_IMRB2 0x2C 50 - #define AB3100_IMRB3 0x2D 51 - 52 - /* System Power Monitoring and control registers */ 53 - #define AB3100_MCA 0x2E 54 - #define AB3100_MCB 0x2F 55 - 56 - /* SIM power up */ 57 - #define AB3100_SUP 0x50 58 - 59 - /* 60 - * I2C communication 61 - * 62 - * The AB3100 is usually assigned address 0x48 (7-bit) 63 - * The chip is defined in the platform i2c_board_data section. 64 - */ 65 - static int ab3100_get_chip_id(struct device *dev) 66 - { 67 - struct ab3100 *ab3100 = dev_get_drvdata(dev->parent); 68 - 69 - return (int)ab3100->chip_id; 70 - } 71 - 72 - static int ab3100_set_register_interruptible(struct ab3100 *ab3100, 73 - u8 reg, u8 regval) 74 - { 75 - u8 regandval[2] = {reg, regval}; 76 - int err; 77 - 78 - err = mutex_lock_interruptible(&ab3100->access_mutex); 79 - if (err) 80 - return err; 81 - 82 - /* 83 - * A two-byte write message with the first byte containing the register 84 - * number and the second byte containing the value to be written 85 - * effectively sets a register in the AB3100. 86 - */ 87 - err = i2c_master_send(ab3100->i2c_client, regandval, 2); 88 - if (err < 0) { 89 - dev_err(ab3100->dev, 90 - "write error (write register): %d\n", 91 - err); 92 - } else if (err != 2) { 93 - dev_err(ab3100->dev, 94 - "write error (write register)\n" 95 - " %d bytes transferred (expected 2)\n", 96 - err); 97 - err = -EIO; 98 - } else { 99 - /* All is well */ 100 - err = 0; 101 - } 102 - mutex_unlock(&ab3100->access_mutex); 103 - return err; 104 - } 105 - 106 - static int set_register_interruptible(struct device *dev, 107 - u8 bank, u8 reg, u8 value) 108 - { 109 - struct ab3100 *ab3100 = dev_get_drvdata(dev->parent); 110 - 111 - return ab3100_set_register_interruptible(ab3100, reg, value); 112 - } 113 - 114 - /* 115 - * The test registers exist at an I2C bus address up one 116 - * from the ordinary base. They are not supposed to be used 117 - * in production code, but sometimes you have to do that 118 - * anyway. It's currently only used from this file so declare 119 - * it static and do not export. 120 - */ 121 - static int ab3100_set_test_register_interruptible(struct ab3100 *ab3100, 122 - u8 reg, u8 regval) 123 - { 124 - u8 regandval[2] = {reg, regval}; 125 - int err; 126 - 127 - err = mutex_lock_interruptible(&ab3100->access_mutex); 128 - if (err) 129 - return err; 130 - 131 - err = i2c_master_send(ab3100->testreg_client, regandval, 2); 132 - if (err < 0) { 133 - dev_err(ab3100->dev, 134 - "write error (write test register): %d\n", 135 - err); 136 - } else if (err != 2) { 137 - dev_err(ab3100->dev, 138 - "write error (write test register)\n" 139 - " %d bytes transferred (expected 2)\n", 140 - err); 141 - err = -EIO; 142 - } else { 143 - /* All is well */ 144 - err = 0; 145 - } 146 - mutex_unlock(&ab3100->access_mutex); 147 - 148 - return err; 149 - } 150 - 151 - static int ab3100_get_register_interruptible(struct ab3100 *ab3100, 152 - u8 reg, u8 *regval) 153 - { 154 - int err; 155 - 156 - err = mutex_lock_interruptible(&ab3100->access_mutex); 157 - if (err) 158 - return err; 159 - 160 - /* 161 - * AB3100 require an I2C "stop" command between each message, else 162 - * it will not work. The only way of achieveing this with the 163 - * message transport layer is to send the read and write messages 164 - * separately. 165 - */ 166 - err = i2c_master_send(ab3100->i2c_client, &reg, 1); 167 - if (err < 0) { 168 - dev_err(ab3100->dev, 169 - "write error (send register address): %d\n", 170 - err); 171 - goto get_reg_out_unlock; 172 - } else if (err != 1) { 173 - dev_err(ab3100->dev, 174 - "write error (send register address)\n" 175 - " %d bytes transferred (expected 1)\n", 176 - err); 177 - err = -EIO; 178 - goto get_reg_out_unlock; 179 - } else { 180 - /* All is well */ 181 - err = 0; 182 - } 183 - 184 - err = i2c_master_recv(ab3100->i2c_client, regval, 1); 185 - if (err < 0) { 186 - dev_err(ab3100->dev, 187 - "write error (read register): %d\n", 188 - err); 189 - goto get_reg_out_unlock; 190 - } else if (err != 1) { 191 - dev_err(ab3100->dev, 192 - "write error (read register)\n" 193 - " %d bytes transferred (expected 1)\n", 194 - err); 195 - err = -EIO; 196 - goto get_reg_out_unlock; 197 - } else { 198 - /* All is well */ 199 - err = 0; 200 - } 201 - 202 - get_reg_out_unlock: 203 - mutex_unlock(&ab3100->access_mutex); 204 - return err; 205 - } 206 - 207 - static int get_register_interruptible(struct device *dev, u8 bank, u8 reg, 208 - u8 *value) 209 - { 210 - struct ab3100 *ab3100 = dev_get_drvdata(dev->parent); 211 - 212 - return ab3100_get_register_interruptible(ab3100, reg, value); 213 - } 214 - 215 - static int ab3100_get_register_page_interruptible(struct ab3100 *ab3100, 216 - u8 first_reg, u8 *regvals, u8 numregs) 217 - { 218 - int err; 219 - 220 - if (ab3100->chip_id == 0xa0 || 221 - ab3100->chip_id == 0xa1) 222 - /* These don't support paged reads */ 223 - return -EIO; 224 - 225 - err = mutex_lock_interruptible(&ab3100->access_mutex); 226 - if (err) 227 - return err; 228 - 229 - /* 230 - * Paged read also require an I2C "stop" command. 231 - */ 232 - err = i2c_master_send(ab3100->i2c_client, &first_reg, 1); 233 - if (err < 0) { 234 - dev_err(ab3100->dev, 235 - "write error (send first register address): %d\n", 236 - err); 237 - goto get_reg_page_out_unlock; 238 - } else if (err != 1) { 239 - dev_err(ab3100->dev, 240 - "write error (send first register address)\n" 241 - " %d bytes transferred (expected 1)\n", 242 - err); 243 - err = -EIO; 244 - goto get_reg_page_out_unlock; 245 - } 246 - 247 - err = i2c_master_recv(ab3100->i2c_client, regvals, numregs); 248 - if (err < 0) { 249 - dev_err(ab3100->dev, 250 - "write error (read register page): %d\n", 251 - err); 252 - goto get_reg_page_out_unlock; 253 - } else if (err != numregs) { 254 - dev_err(ab3100->dev, 255 - "write error (read register page)\n" 256 - " %d bytes transferred (expected %d)\n", 257 - err, numregs); 258 - err = -EIO; 259 - goto get_reg_page_out_unlock; 260 - } 261 - 262 - /* All is well */ 263 - err = 0; 264 - 265 - get_reg_page_out_unlock: 266 - mutex_unlock(&ab3100->access_mutex); 267 - return err; 268 - } 269 - 270 - static int get_register_page_interruptible(struct device *dev, u8 bank, 271 - u8 first_reg, u8 *regvals, u8 numregs) 272 - { 273 - struct ab3100 *ab3100 = dev_get_drvdata(dev->parent); 274 - 275 - return ab3100_get_register_page_interruptible(ab3100, 276 - first_reg, regvals, numregs); 277 - } 278 - 279 - static int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100, 280 - u8 reg, u8 andmask, u8 ormask) 281 - { 282 - u8 regandval[2] = {reg, 0}; 283 - int err; 284 - 285 - err = mutex_lock_interruptible(&ab3100->access_mutex); 286 - if (err) 287 - return err; 288 - 289 - /* First read out the target register */ 290 - err = i2c_master_send(ab3100->i2c_client, &reg, 1); 291 - if (err < 0) { 292 - dev_err(ab3100->dev, 293 - "write error (maskset send address): %d\n", 294 - err); 295 - goto get_maskset_unlock; 296 - } else if (err != 1) { 297 - dev_err(ab3100->dev, 298 - "write error (maskset send address)\n" 299 - " %d bytes transferred (expected 1)\n", 300 - err); 301 - err = -EIO; 302 - goto get_maskset_unlock; 303 - } 304 - 305 - err = i2c_master_recv(ab3100->i2c_client, &regandval[1], 1); 306 - if (err < 0) { 307 - dev_err(ab3100->dev, 308 - "write error (maskset read register): %d\n", 309 - err); 310 - goto get_maskset_unlock; 311 - } else if (err != 1) { 312 - dev_err(ab3100->dev, 313 - "write error (maskset read register)\n" 314 - " %d bytes transferred (expected 1)\n", 315 - err); 316 - err = -EIO; 317 - goto get_maskset_unlock; 318 - } 319 - 320 - /* Modify the register */ 321 - regandval[1] &= andmask; 322 - regandval[1] |= ormask; 323 - 324 - /* Write the register */ 325 - err = i2c_master_send(ab3100->i2c_client, regandval, 2); 326 - if (err < 0) { 327 - dev_err(ab3100->dev, 328 - "write error (write register): %d\n", 329 - err); 330 - goto get_maskset_unlock; 331 - } else if (err != 2) { 332 - dev_err(ab3100->dev, 333 - "write error (write register)\n" 334 - " %d bytes transferred (expected 2)\n", 335 - err); 336 - err = -EIO; 337 - goto get_maskset_unlock; 338 - } 339 - 340 - /* All is well */ 341 - err = 0; 342 - 343 - get_maskset_unlock: 344 - mutex_unlock(&ab3100->access_mutex); 345 - return err; 346 - } 347 - 348 - static int mask_and_set_register_interruptible(struct device *dev, u8 bank, 349 - u8 reg, u8 bitmask, u8 bitvalues) 350 - { 351 - struct ab3100 *ab3100 = dev_get_drvdata(dev->parent); 352 - 353 - return ab3100_mask_and_set_register_interruptible(ab3100, 354 - reg, bitmask, (bitmask & bitvalues)); 355 - } 356 - 357 - /* 358 - * Register a simple callback for handling any AB3100 events. 359 - */ 360 - int ab3100_event_register(struct ab3100 *ab3100, 361 - struct notifier_block *nb) 362 - { 363 - return blocking_notifier_chain_register(&ab3100->event_subscribers, 364 - nb); 365 - } 366 - EXPORT_SYMBOL(ab3100_event_register); 367 - 368 - /* 369 - * Remove a previously registered callback. 370 - */ 371 - int ab3100_event_unregister(struct ab3100 *ab3100, 372 - struct notifier_block *nb) 373 - { 374 - return blocking_notifier_chain_unregister(&ab3100->event_subscribers, 375 - nb); 376 - } 377 - EXPORT_SYMBOL(ab3100_event_unregister); 378 - 379 - 380 - static int ab3100_event_registers_startup_state_get(struct device *dev, 381 - u8 *event) 382 - { 383 - struct ab3100 *ab3100 = dev_get_drvdata(dev->parent); 384 - 385 - if (!ab3100->startup_events_read) 386 - return -EAGAIN; /* Try again later */ 387 - memcpy(event, ab3100->startup_events, 3); 388 - 389 - return 0; 390 - } 391 - 392 - static struct abx500_ops ab3100_ops = { 393 - .get_chip_id = ab3100_get_chip_id, 394 - .set_register = set_register_interruptible, 395 - .get_register = get_register_interruptible, 396 - .get_register_page = get_register_page_interruptible, 397 - .set_register_page = NULL, 398 - .mask_and_set_register = mask_and_set_register_interruptible, 399 - .event_registers_startup_state_get = 400 - ab3100_event_registers_startup_state_get, 401 - .startup_irq_enabled = NULL, 402 - }; 403 - 404 - /* 405 - * This is a threaded interrupt handler so we can make some 406 - * I2C calls etc. 407 - */ 408 - static irqreturn_t ab3100_irq_handler(int irq, void *data) 409 - { 410 - struct ab3100 *ab3100 = data; 411 - u8 event_regs[3]; 412 - u32 fatevent; 413 - int err; 414 - 415 - err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1, 416 - event_regs, 3); 417 - if (err) 418 - goto err_event; 419 - 420 - fatevent = (event_regs[0] << 16) | 421 - (event_regs[1] << 8) | 422 - event_regs[2]; 423 - 424 - if (!ab3100->startup_events_read) { 425 - ab3100->startup_events[0] = event_regs[0]; 426 - ab3100->startup_events[1] = event_regs[1]; 427 - ab3100->startup_events[2] = event_regs[2]; 428 - ab3100->startup_events_read = true; 429 - } 430 - /* 431 - * The notified parties will have to mask out the events 432 - * they're interested in and react to them. They will be 433 - * notified on all events, then they use the fatevent value 434 - * to determine if they're interested. 435 - */ 436 - blocking_notifier_call_chain(&ab3100->event_subscribers, 437 - fatevent, NULL); 438 - 439 - dev_dbg(ab3100->dev, 440 - "IRQ Event: 0x%08x\n", fatevent); 441 - 442 - return IRQ_HANDLED; 443 - 444 - err_event: 445 - dev_dbg(ab3100->dev, 446 - "error reading event status\n"); 447 - return IRQ_HANDLED; 448 - } 449 - 450 - #ifdef CONFIG_DEBUG_FS 451 - /* 452 - * Some debugfs entries only exposed if we're using debug 453 - */ 454 - static int ab3100_registers_print(struct seq_file *s, void *p) 455 - { 456 - struct ab3100 *ab3100 = s->private; 457 - u8 value; 458 - u8 reg; 459 - 460 - seq_puts(s, "AB3100 registers:\n"); 461 - 462 - for (reg = 0; reg < 0xff; reg++) { 463 - ab3100_get_register_interruptible(ab3100, reg, &value); 464 - seq_printf(s, "[0x%x]: 0x%x\n", reg, value); 465 - } 466 - return 0; 467 - } 468 - 469 - static int ab3100_registers_open(struct inode *inode, struct file *file) 470 - { 471 - return single_open(file, ab3100_registers_print, inode->i_private); 472 - } 473 - 474 - static const struct file_operations ab3100_registers_fops = { 475 - .open = ab3100_registers_open, 476 - .read = seq_read, 477 - .llseek = seq_lseek, 478 - .release = single_release, 479 - .owner = THIS_MODULE, 480 - }; 481 - 482 - struct ab3100_get_set_reg_priv { 483 - struct ab3100 *ab3100; 484 - bool mode; 485 - }; 486 - 487 - static ssize_t ab3100_get_set_reg(struct file *file, 488 - const char __user *user_buf, 489 - size_t count, loff_t *ppos) 490 - { 491 - struct ab3100_get_set_reg_priv *priv = file->private_data; 492 - struct ab3100 *ab3100 = priv->ab3100; 493 - char buf[32]; 494 - ssize_t buf_size; 495 - int regp; 496 - u8 user_reg; 497 - int err; 498 - int i = 0; 499 - 500 - /* Get userspace string and assure termination */ 501 - buf_size = min((ssize_t)count, (ssize_t)(sizeof(buf)-1)); 502 - if (copy_from_user(buf, user_buf, buf_size)) 503 - return -EFAULT; 504 - buf[buf_size] = 0; 505 - 506 - /* 507 - * The idea is here to parse a string which is either 508 - * "0xnn" for reading a register, or "0xaa 0xbb" for 509 - * writing 0xbb to the register 0xaa. First move past 510 - * whitespace and then begin to parse the register. 511 - */ 512 - while ((i < buf_size) && (buf[i] == ' ')) 513 - i++; 514 - regp = i; 515 - 516 - /* 517 - * Advance pointer to end of string then terminate 518 - * the register string. This is needed to satisfy 519 - * the kstrtou8() function. 520 - */ 521 - while ((i < buf_size) && (buf[i] != ' ')) 522 - i++; 523 - buf[i] = '\0'; 524 - 525 - err = kstrtou8(&buf[regp], 16, &user_reg); 526 - if (err) 527 - return err; 528 - 529 - /* Either we read or we write a register here */ 530 - if (!priv->mode) { 531 - /* Reading */ 532 - u8 regvalue; 533 - 534 - ab3100_get_register_interruptible(ab3100, user_reg, &regvalue); 535 - 536 - dev_info(ab3100->dev, 537 - "debug read AB3100 reg[0x%02x]: 0x%02x\n", 538 - user_reg, regvalue); 539 - } else { 540 - int valp; 541 - u8 user_value; 542 - u8 regvalue; 543 - 544 - /* 545 - * Writing, we need some value to write to 546 - * the register so keep parsing the string 547 - * from userspace. 548 - */ 549 - i++; 550 - while ((i < buf_size) && (buf[i] == ' ')) 551 - i++; 552 - valp = i; 553 - while ((i < buf_size) && (buf[i] != ' ')) 554 - i++; 555 - buf[i] = '\0'; 556 - 557 - err = kstrtou8(&buf[valp], 16, &user_value); 558 - if (err) 559 - return err; 560 - 561 - ab3100_set_register_interruptible(ab3100, user_reg, user_value); 562 - ab3100_get_register_interruptible(ab3100, user_reg, &regvalue); 563 - 564 - dev_info(ab3100->dev, 565 - "debug write reg[0x%02x]\n" 566 - " with 0x%02x, after readback: 0x%02x\n", 567 - user_reg, user_value, regvalue); 568 - } 569 - return buf_size; 570 - } 571 - 572 - static const struct file_operations ab3100_get_set_reg_fops = { 573 - .open = simple_open, 574 - .write = ab3100_get_set_reg, 575 - .llseek = noop_llseek, 576 - }; 577 - 578 - static struct ab3100_get_set_reg_priv ab3100_get_priv; 579 - static struct ab3100_get_set_reg_priv ab3100_set_priv; 580 - 581 - static void ab3100_setup_debugfs(struct ab3100 *ab3100) 582 - { 583 - struct dentry *ab3100_dir; 584 - 585 - ab3100_dir = debugfs_create_dir("ab3100", NULL); 586 - 587 - debugfs_create_file("registers", S_IRUGO, ab3100_dir, ab3100, 588 - &ab3100_registers_fops); 589 - 590 - ab3100_get_priv.ab3100 = ab3100; 591 - ab3100_get_priv.mode = false; 592 - debugfs_create_file("get_reg", S_IWUSR, ab3100_dir, &ab3100_get_priv, 593 - &ab3100_get_set_reg_fops); 594 - 595 - ab3100_set_priv.ab3100 = ab3100; 596 - ab3100_set_priv.mode = true; 597 - debugfs_create_file("set_reg", S_IWUSR, ab3100_dir, &ab3100_set_priv, 598 - &ab3100_get_set_reg_fops); 599 - } 600 - #else 601 - static inline void ab3100_setup_debugfs(struct ab3100 *ab3100) 602 - { 603 - } 604 - #endif 605 - 606 - /* 607 - * Basic set-up, datastructure creation/destruction and I2C interface. 608 - * This sets up a default config in the AB3100 chip so that it 609 - * will work as expected. 610 - */ 611 - 612 - struct ab3100_init_setting { 613 - u8 abreg; 614 - u8 setting; 615 - }; 616 - 617 - static const struct ab3100_init_setting ab3100_init_settings[] = { 618 - { 619 - .abreg = AB3100_MCA, 620 - .setting = 0x01 621 - }, { 622 - .abreg = AB3100_MCB, 623 - .setting = 0x30 624 - }, { 625 - .abreg = AB3100_IMRA1, 626 - .setting = 0x00 627 - }, { 628 - .abreg = AB3100_IMRA2, 629 - .setting = 0xFF 630 - }, { 631 - .abreg = AB3100_IMRA3, 632 - .setting = 0x01 633 - }, { 634 - .abreg = AB3100_IMRB1, 635 - .setting = 0xBF 636 - }, { 637 - .abreg = AB3100_IMRB2, 638 - .setting = 0xFF 639 - }, { 640 - .abreg = AB3100_IMRB3, 641 - .setting = 0xFF 642 - }, { 643 - .abreg = AB3100_SUP, 644 - .setting = 0x00 645 - }, { 646 - .abreg = AB3100_DIS, 647 - .setting = 0xF0 648 - }, { 649 - .abreg = AB3100_D0C, 650 - .setting = 0x00 651 - }, { 652 - .abreg = AB3100_D1C, 653 - .setting = 0x00 654 - }, { 655 - .abreg = AB3100_D2C, 656 - .setting = 0x00 657 - }, { 658 - .abreg = AB3100_D3C, 659 - .setting = 0x00 660 - }, 661 - }; 662 - 663 - static int ab3100_setup(struct ab3100 *ab3100) 664 - { 665 - int err = 0; 666 - int i; 667 - 668 - for (i = 0; i < ARRAY_SIZE(ab3100_init_settings); i++) { 669 - err = ab3100_set_register_interruptible(ab3100, 670 - ab3100_init_settings[i].abreg, 671 - ab3100_init_settings[i].setting); 672 - if (err) 673 - goto exit_no_setup; 674 - } 675 - 676 - /* 677 - * Special trick to make the AB3100 use the 32kHz clock (RTC) 678 - * bit 3 in test register 0x02 is a special, undocumented test 679 - * register bit that only exist in AB3100 P1E 680 - */ 681 - if (ab3100->chip_id == 0xc4) { 682 - dev_warn(ab3100->dev, 683 - "AB3100 P1E variant detected forcing chip to 32KHz\n"); 684 - err = ab3100_set_test_register_interruptible(ab3100, 685 - 0x02, 0x08); 686 - } 687 - 688 - exit_no_setup: 689 - return err; 690 - } 691 - 692 - /* The subdevices of the AB3100 */ 693 - static struct mfd_cell ab3100_devs[] = { 694 - { 695 - .name = "ab3100-dac", 696 - .id = -1, 697 - }, 698 - { 699 - .name = "ab3100-leds", 700 - .id = -1, 701 - }, 702 - { 703 - .name = "ab3100-power", 704 - .id = -1, 705 - }, 706 - { 707 - .name = "ab3100-regulators", 708 - .of_compatible = "stericsson,ab3100-regulators", 709 - .id = -1, 710 - }, 711 - { 712 - .name = "ab3100-sim", 713 - .id = -1, 714 - }, 715 - { 716 - .name = "ab3100-uart", 717 - .id = -1, 718 - }, 719 - { 720 - .name = "ab3100-rtc", 721 - .id = -1, 722 - }, 723 - { 724 - .name = "ab3100-charger", 725 - .id = -1, 726 - }, 727 - { 728 - .name = "ab3100-boost", 729 - .id = -1, 730 - }, 731 - { 732 - .name = "ab3100-adc", 733 - .id = -1, 734 - }, 735 - { 736 - .name = "ab3100-fuelgauge", 737 - .id = -1, 738 - }, 739 - { 740 - .name = "ab3100-vibrator", 741 - .id = -1, 742 - }, 743 - { 744 - .name = "ab3100-otp", 745 - .id = -1, 746 - }, 747 - { 748 - .name = "ab3100-codec", 749 - .id = -1, 750 - }, 751 - }; 752 - 753 - struct ab_family_id { 754 - u8 id; 755 - char *name; 756 - }; 757 - 758 - static const struct ab_family_id ids[] = { 759 - /* AB3100 */ 760 - { 761 - .id = 0xc0, 762 - .name = "P1A" 763 - }, { 764 - .id = 0xc1, 765 - .name = "P1B" 766 - }, { 767 - .id = 0xc2, 768 - .name = "P1C" 769 - }, { 770 - .id = 0xc3, 771 - .name = "P1D" 772 - }, { 773 - .id = 0xc4, 774 - .name = "P1E" 775 - }, { 776 - .id = 0xc5, 777 - .name = "P1F/R1A" 778 - }, { 779 - .id = 0xc6, 780 - .name = "P1G/R1A" 781 - }, { 782 - .id = 0xc7, 783 - .name = "P2A/R2A" 784 - }, { 785 - .id = 0xc8, 786 - .name = "P2B/R2B" 787 - }, 788 - /* AB3000 variants, not supported */ 789 - { 790 - .id = 0xa0 791 - }, { 792 - .id = 0xa1 793 - }, { 794 - .id = 0xa2 795 - }, { 796 - .id = 0xa3 797 - }, { 798 - .id = 0xa4 799 - }, { 800 - .id = 0xa5 801 - }, { 802 - .id = 0xa6 803 - }, { 804 - .id = 0xa7 805 - }, 806 - /* Terminator */ 807 - { 808 - .id = 0x00, 809 - }, 810 - }; 811 - 812 - static int ab3100_probe(struct i2c_client *client, 813 - const struct i2c_device_id *id) 814 - { 815 - struct ab3100 *ab3100; 816 - struct ab3100_platform_data *ab3100_plf_data = 817 - dev_get_platdata(&client->dev); 818 - int err; 819 - int i; 820 - 821 - ab3100 = devm_kzalloc(&client->dev, sizeof(struct ab3100), GFP_KERNEL); 822 - if (!ab3100) 823 - return -ENOMEM; 824 - 825 - /* Initialize data structure */ 826 - mutex_init(&ab3100->access_mutex); 827 - BLOCKING_INIT_NOTIFIER_HEAD(&ab3100->event_subscribers); 828 - 829 - ab3100->i2c_client = client; 830 - ab3100->dev = &ab3100->i2c_client->dev; 831 - 832 - i2c_set_clientdata(client, ab3100); 833 - 834 - /* Read chip ID register */ 835 - err = ab3100_get_register_interruptible(ab3100, AB3100_CID, 836 - &ab3100->chip_id); 837 - if (err) { 838 - dev_err(&client->dev, 839 - "failed to communicate with AB3100 chip\n"); 840 - goto exit_no_detect; 841 - } 842 - 843 - for (i = 0; ids[i].id != 0x0; i++) { 844 - if (ids[i].id == ab3100->chip_id) { 845 - if (ids[i].name) 846 - break; 847 - 848 - dev_err(&client->dev, "AB3000 is not supported\n"); 849 - goto exit_no_detect; 850 - } 851 - } 852 - 853 - snprintf(&ab3100->chip_name[0], 854 - sizeof(ab3100->chip_name) - 1, "AB3100 %s", ids[i].name); 855 - 856 - if (ids[i].id == 0x0) { 857 - dev_err(&client->dev, "unknown analog baseband chip id: 0x%x\n", 858 - ab3100->chip_id); 859 - dev_err(&client->dev, 860 - "accepting it anyway. Please update the driver.\n"); 861 - goto exit_no_detect; 862 - } 863 - 864 - dev_info(&client->dev, "Detected chip: %s\n", 865 - &ab3100->chip_name[0]); 866 - 867 - /* Attach a second dummy i2c_client to the test register address */ 868 - ab3100->testreg_client = i2c_new_dummy_device(client->adapter, 869 - client->addr + 1); 870 - if (IS_ERR(ab3100->testreg_client)) { 871 - err = PTR_ERR(ab3100->testreg_client); 872 - goto exit_no_testreg_client; 873 - } 874 - 875 - err = ab3100_setup(ab3100); 876 - if (err) 877 - goto exit_no_setup; 878 - 879 - err = devm_request_threaded_irq(&client->dev, 880 - client->irq, NULL, ab3100_irq_handler, 881 - IRQF_ONESHOT, "ab3100-core", ab3100); 882 - if (err) 883 - goto exit_no_irq; 884 - 885 - err = abx500_register_ops(&client->dev, &ab3100_ops); 886 - if (err) 887 - goto exit_no_ops; 888 - 889 - /* Set up and register the platform devices. */ 890 - for (i = 0; i < ARRAY_SIZE(ab3100_devs); i++) { 891 - ab3100_devs[i].platform_data = ab3100_plf_data; 892 - ab3100_devs[i].pdata_size = sizeof(struct ab3100_platform_data); 893 - } 894 - 895 - err = mfd_add_devices(&client->dev, 0, ab3100_devs, 896 - ARRAY_SIZE(ab3100_devs), NULL, 0, NULL); 897 - 898 - ab3100_setup_debugfs(ab3100); 899 - 900 - return 0; 901 - 902 - exit_no_ops: 903 - exit_no_irq: 904 - exit_no_setup: 905 - i2c_unregister_device(ab3100->testreg_client); 906 - exit_no_testreg_client: 907 - exit_no_detect: 908 - return err; 909 - } 910 - 911 - static const struct i2c_device_id ab3100_id[] = { 912 - { "ab3100", 0 }, 913 - { } 914 - }; 915 - 916 - static struct i2c_driver ab3100_driver = { 917 - .driver = { 918 - .name = "ab3100", 919 - .suppress_bind_attrs = true, 920 - }, 921 - .id_table = ab3100_id, 922 - .probe = ab3100_probe, 923 - }; 924 - 925 - static int __init ab3100_i2c_init(void) 926 - { 927 - return i2c_add_driver(&ab3100_driver); 928 - } 929 - subsys_initcall(ab3100_i2c_init);
-240
drivers/mfd/ab3100-otp.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * drivers/mfd/ab3100_otp.c 4 - * 5 - * Copyright (C) 2007-2009 ST-Ericsson AB 6 - * Driver to read out OTP from the AB3100 Mixed-signal circuit 7 - * Author: Linus Walleij <linus.walleij@stericsson.com> 8 - */ 9 - 10 - #include <linux/module.h> 11 - #include <linux/kernel.h> 12 - #include <linux/slab.h> 13 - #include <linux/init.h> 14 - #include <linux/platform_device.h> 15 - #include <linux/mfd/abx500.h> 16 - #include <linux/debugfs.h> 17 - #include <linux/seq_file.h> 18 - 19 - /* The OTP registers */ 20 - #define AB3100_OTP0 0xb0 21 - #define AB3100_OTP1 0xb1 22 - #define AB3100_OTP2 0xb2 23 - #define AB3100_OTP3 0xb3 24 - #define AB3100_OTP4 0xb4 25 - #define AB3100_OTP5 0xb5 26 - #define AB3100_OTP6 0xb6 27 - #define AB3100_OTP7 0xb7 28 - #define AB3100_OTPP 0xbf 29 - 30 - /** 31 - * struct ab3100_otp 32 - * @dev: containing device 33 - * @locked: whether the OTP is locked, after locking, no more bits 34 - * can be changed but before locking it is still possible 35 - * to change bits from 1->0. 36 - * @freq: clocking frequency for the OTP, this frequency is either 37 - * 32768Hz or 1MHz/30 38 - * @paf: product activation flag, indicates whether this is a real 39 - * product (paf true) or a lab board etc (paf false) 40 - * @imeich: if this is set it is possible to override the 41 - * IMEI number found in the tac, fac and svn fields with 42 - * (secured) software 43 - * @cid: customer ID 44 - * @tac: type allocation code of the IMEI 45 - * @fac: final assembly code of the IMEI 46 - * @svn: software version number of the IMEI 47 - * @debugfs: a debugfs file used when dumping to file 48 - */ 49 - struct ab3100_otp { 50 - struct device *dev; 51 - bool locked; 52 - u32 freq; 53 - bool paf; 54 - bool imeich; 55 - u16 cid:14; 56 - u32 tac:20; 57 - u8 fac; 58 - u32 svn:20; 59 - struct dentry *debugfs; 60 - }; 61 - 62 - static int __init ab3100_otp_read(struct ab3100_otp *otp) 63 - { 64 - u8 otpval[8]; 65 - u8 otpp; 66 - int err; 67 - 68 - err = abx500_get_register_interruptible(otp->dev, 0, 69 - AB3100_OTPP, &otpp); 70 - if (err) { 71 - dev_err(otp->dev, "unable to read OTPP register\n"); 72 - return err; 73 - } 74 - 75 - err = abx500_get_register_page_interruptible(otp->dev, 0, 76 - AB3100_OTP0, otpval, 8); 77 - if (err) { 78 - dev_err(otp->dev, "unable to read OTP register page\n"); 79 - return err; 80 - } 81 - 82 - /* Cache OTP properties, they never change by nature */ 83 - otp->locked = (otpp & 0x80); 84 - otp->freq = (otpp & 0x40) ? 32768 : 34100; 85 - otp->paf = (otpval[1] & 0x80); 86 - otp->imeich = (otpval[1] & 0x40); 87 - otp->cid = ((otpval[1] << 8) | otpval[0]) & 0x3fff; 88 - otp->tac = ((otpval[4] & 0x0f) << 16) | (otpval[3] << 8) | otpval[2]; 89 - otp->fac = ((otpval[5] & 0x0f) << 4) | (otpval[4] >> 4); 90 - otp->svn = (otpval[7] << 12) | (otpval[6] << 4) | (otpval[5] >> 4); 91 - return 0; 92 - } 93 - 94 - /* 95 - * This is a simple debugfs human-readable file that dumps out 96 - * the contents of the OTP. 97 - */ 98 - #ifdef CONFIG_DEBUG_FS 99 - static int ab3100_show_otp(struct seq_file *s, void *v) 100 - { 101 - struct ab3100_otp *otp = s->private; 102 - 103 - seq_printf(s, "OTP is %s\n", otp->locked ? "LOCKED" : "UNLOCKED"); 104 - seq_printf(s, "OTP clock switch startup is %uHz\n", otp->freq); 105 - seq_printf(s, "PAF is %s\n", otp->paf ? "SET" : "NOT SET"); 106 - seq_printf(s, "IMEI is %s\n", otp->imeich ? 107 - "CHANGEABLE" : "NOT CHANGEABLE"); 108 - seq_printf(s, "CID: 0x%04x (decimal: %d)\n", otp->cid, otp->cid); 109 - seq_printf(s, "IMEI: %u-%u-%u\n", otp->tac, otp->fac, otp->svn); 110 - return 0; 111 - } 112 - 113 - static int ab3100_otp_open(struct inode *inode, struct file *file) 114 - { 115 - return single_open(file, ab3100_show_otp, inode->i_private); 116 - } 117 - 118 - static const struct file_operations ab3100_otp_operations = { 119 - .open = ab3100_otp_open, 120 - .read = seq_read, 121 - .llseek = seq_lseek, 122 - .release = single_release, 123 - }; 124 - 125 - static void __init ab3100_otp_init_debugfs(struct device *dev, 126 - struct ab3100_otp *otp) 127 - { 128 - otp->debugfs = debugfs_create_file("ab3100_otp", S_IFREG | S_IRUGO, 129 - NULL, otp, &ab3100_otp_operations); 130 - } 131 - 132 - static void __exit ab3100_otp_exit_debugfs(struct ab3100_otp *otp) 133 - { 134 - debugfs_remove(otp->debugfs); 135 - } 136 - #else 137 - /* Compile this out if debugfs not selected */ 138 - static inline void __init ab3100_otp_init_debugfs(struct device *dev, 139 - struct ab3100_otp *otp) 140 - { 141 - } 142 - 143 - static inline void __exit ab3100_otp_exit_debugfs(struct ab3100_otp *otp) 144 - { 145 - } 146 - #endif 147 - 148 - #define SHOW_AB3100_ATTR(name) \ 149 - static ssize_t ab3100_otp_##name##_show(struct device *dev, \ 150 - struct device_attribute *attr, \ 151 - char *buf) \ 152 - {\ 153 - struct ab3100_otp *otp = dev_get_drvdata(dev); \ 154 - return sprintf(buf, "%u\n", otp->name); \ 155 - } 156 - 157 - SHOW_AB3100_ATTR(locked) 158 - SHOW_AB3100_ATTR(freq) 159 - SHOW_AB3100_ATTR(paf) 160 - SHOW_AB3100_ATTR(imeich) 161 - SHOW_AB3100_ATTR(cid) 162 - SHOW_AB3100_ATTR(fac) 163 - SHOW_AB3100_ATTR(tac) 164 - SHOW_AB3100_ATTR(svn) 165 - 166 - static struct device_attribute ab3100_otp_attrs[] = { 167 - __ATTR(locked, S_IRUGO, ab3100_otp_locked_show, NULL), 168 - __ATTR(freq, S_IRUGO, ab3100_otp_freq_show, NULL), 169 - __ATTR(paf, S_IRUGO, ab3100_otp_paf_show, NULL), 170 - __ATTR(imeich, S_IRUGO, ab3100_otp_imeich_show, NULL), 171 - __ATTR(cid, S_IRUGO, ab3100_otp_cid_show, NULL), 172 - __ATTR(fac, S_IRUGO, ab3100_otp_fac_show, NULL), 173 - __ATTR(tac, S_IRUGO, ab3100_otp_tac_show, NULL), 174 - __ATTR(svn, S_IRUGO, ab3100_otp_svn_show, NULL), 175 - }; 176 - 177 - static int __init ab3100_otp_probe(struct platform_device *pdev) 178 - { 179 - struct ab3100_otp *otp; 180 - int err = 0; 181 - int i; 182 - 183 - otp = devm_kzalloc(&pdev->dev, sizeof(struct ab3100_otp), GFP_KERNEL); 184 - if (!otp) 185 - return -ENOMEM; 186 - 187 - otp->dev = &pdev->dev; 188 - 189 - /* Replace platform data coming in with a local struct */ 190 - platform_set_drvdata(pdev, otp); 191 - 192 - err = ab3100_otp_read(otp); 193 - if (err) 194 - return err; 195 - 196 - dev_info(&pdev->dev, "AB3100 OTP readout registered\n"); 197 - 198 - /* sysfs entries */ 199 - for (i = 0; i < ARRAY_SIZE(ab3100_otp_attrs); i++) { 200 - err = device_create_file(&pdev->dev, 201 - &ab3100_otp_attrs[i]); 202 - if (err) 203 - goto err; 204 - } 205 - 206 - /* debugfs entries */ 207 - ab3100_otp_init_debugfs(&pdev->dev, otp); 208 - 209 - return 0; 210 - 211 - err: 212 - while (--i >= 0) 213 - device_remove_file(&pdev->dev, &ab3100_otp_attrs[i]); 214 - return err; 215 - } 216 - 217 - static int __exit ab3100_otp_remove(struct platform_device *pdev) 218 - { 219 - struct ab3100_otp *otp = platform_get_drvdata(pdev); 220 - int i; 221 - 222 - for (i = 0; i < ARRAY_SIZE(ab3100_otp_attrs); i++) 223 - device_remove_file(&pdev->dev, 224 - &ab3100_otp_attrs[i]); 225 - ab3100_otp_exit_debugfs(otp); 226 - return 0; 227 - } 228 - 229 - static struct platform_driver ab3100_otp_driver = { 230 - .driver = { 231 - .name = "ab3100-otp", 232 - }, 233 - .remove = __exit_p(ab3100_otp_remove), 234 - }; 235 - 236 - module_platform_driver_probe(ab3100_otp_driver, ab3100_otp_probe); 237 - 238 - MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>"); 239 - MODULE_DESCRIPTION("AB3100 OTP Readout Driver"); 240 - MODULE_LICENSE("GPL");
+6 -14
drivers/mfd/ab8500-core.c
··· 120 120 static DEFINE_SPINLOCK(on_stat_lock); 121 121 static u8 turn_on_stat_mask = 0xFF; 122 122 static u8 turn_on_stat_set; 123 - static bool no_bm; /* No battery management */ 124 - /* 125 - * not really modular, but the easiest way to keep compat with existing 126 - * bootargs behaviour is to continue using module_param here. 127 - */ 128 - module_param(no_bm, bool, S_IRUGO); 129 123 130 124 #define AB9540_MODEM_CTRL2_REG 0x23 131 125 #define AB9540_MODEM_CTRL2_SWDBBRSTN_BIT BIT(2) ··· 1248 1254 if (ret) 1249 1255 return ret; 1250 1256 1251 - if (!no_bm) { 1252 - /* Add battery management devices */ 1253 - ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs, 1254 - ARRAY_SIZE(ab8500_bm_devs), NULL, 1255 - 0, ab8500->domain); 1256 - if (ret) 1257 - dev_err(ab8500->dev, "error adding bm devices\n"); 1258 - } 1257 + /* Add battery management devices */ 1258 + ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs, 1259 + ARRAY_SIZE(ab8500_bm_devs), NULL, 1260 + 0, ab8500->domain); 1261 + if (ret) 1262 + dev_err(ab8500->dev, "error adding bm devices\n"); 1259 1263 1260 1264 if (((is_ab8505(ab8500) || is_ab9540(ab8500)) && 1261 1265 ab8500->chip_id >= AB8500_CUT2P0) || is_ab8540(ab8500))
-20
drivers/mfd/arizona-core.c
··· 881 881 static const struct mfd_cell wm5102_devs[] = { 882 882 { .name = "arizona-micsupp" }, 883 883 { .name = "arizona-gpio" }, 884 - { 885 - .name = "arizona-extcon", 886 - .parent_supplies = wm5102_supplies, 887 - .num_parent_supplies = 1, /* We only need MICVDD */ 888 - }, 889 884 { .name = "arizona-haptics" }, 890 885 { .name = "arizona-pwm" }, 891 886 { ··· 893 898 static const struct mfd_cell wm5110_devs[] = { 894 899 { .name = "arizona-micsupp" }, 895 900 { .name = "arizona-gpio" }, 896 - { 897 - .name = "arizona-extcon", 898 - .parent_supplies = wm5102_supplies, 899 - .num_parent_supplies = 1, /* We only need MICVDD */ 900 - }, 901 901 { .name = "arizona-haptics" }, 902 902 { .name = "arizona-pwm" }, 903 903 { ··· 929 939 static const struct mfd_cell wm8997_devs[] = { 930 940 { .name = "arizona-micsupp" }, 931 941 { .name = "arizona-gpio" }, 932 - { 933 - .name = "arizona-extcon", 934 - .parent_supplies = wm8997_supplies, 935 - .num_parent_supplies = 1, /* We only need MICVDD */ 936 - }, 937 942 { .name = "arizona-haptics" }, 938 943 { .name = "arizona-pwm" }, 939 944 { ··· 941 956 static const struct mfd_cell wm8998_devs[] = { 942 957 { .name = "arizona-micsupp" }, 943 958 { .name = "arizona-gpio" }, 944 - { 945 - .name = "arizona-extcon", 946 - .parent_supplies = wm5102_supplies, 947 - .num_parent_supplies = 1, /* We only need MICVDD */ 948 - }, 949 959 { .name = "arizona-haptics" }, 950 960 { .name = "arizona-pwm" }, 951 961 {
+1 -1
drivers/mfd/arizona-irq.c
··· 100 100 unsigned int val; 101 101 int ret; 102 102 103 - ret = pm_runtime_get_sync(arizona->dev); 103 + ret = pm_runtime_resume_and_get(arizona->dev); 104 104 if (ret < 0) { 105 105 dev_err(arizona->dev, "Failed to resume device: %d\n", ret); 106 106 return IRQ_NONE;
+2 -2
drivers/mfd/arizona-spi.c
··· 25 25 #include "arizona.h" 26 26 27 27 #ifdef CONFIG_ACPI 28 - const struct acpi_gpio_params reset_gpios = { 1, 0, false }; 29 - const struct acpi_gpio_params ldoena_gpios = { 2, 0, false }; 28 + static const struct acpi_gpio_params reset_gpios = { 1, 0, false }; 29 + static const struct acpi_gpio_params ldoena_gpios = { 2, 0, false }; 30 30 31 31 static const struct acpi_gpio_mapping arizona_acpi_gpios[] = { 32 32 { "reset-gpios", &reset_gpios, 1, },
+310
drivers/mfd/atc260x-core.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Core support for ATC260x PMICs 4 + * 5 + * Copyright (C) 2019 Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> 6 + * Copyright (C) 2020 Cristian Ciocaltea <cristian.ciocaltea@gmail.com> 7 + */ 8 + 9 + #include <linux/interrupt.h> 10 + #include <linux/mfd/atc260x/core.h> 11 + #include <linux/mfd/core.h> 12 + #include <linux/module.h> 13 + #include <linux/of.h> 14 + #include <linux/of_device.h> 15 + #include <linux/regmap.h> 16 + 17 + #define ATC260X_CHIP_REV_MAX 31 18 + 19 + struct atc260x_init_regs { 20 + unsigned int cmu_devrst; 21 + unsigned int cmu_devrst_ints; 22 + unsigned int ints_msk; 23 + unsigned int pad_en; 24 + unsigned int pad_en_extirq; 25 + }; 26 + 27 + static void regmap_lock_mutex(void *__mutex) 28 + { 29 + struct mutex *mutex = __mutex; 30 + 31 + /* 32 + * Using regmap within an atomic context (e.g. accessing a PMIC when 33 + * powering system down) is normally allowed only if the regmap type 34 + * is MMIO and the regcache type is either REGCACHE_NONE or 35 + * REGCACHE_FLAT. For slow buses like I2C and SPI, the regmap is 36 + * internally protected by a mutex which is acquired non-atomically. 37 + * 38 + * Let's improve this by using a customized locking scheme inspired 39 + * from I2C atomic transfer. See i2c_in_atomic_xfer_mode() for a 40 + * starting point. 41 + */ 42 + if (system_state > SYSTEM_RUNNING && irqs_disabled()) 43 + mutex_trylock(mutex); 44 + else 45 + mutex_lock(mutex); 46 + } 47 + 48 + static void regmap_unlock_mutex(void *__mutex) 49 + { 50 + struct mutex *mutex = __mutex; 51 + 52 + mutex_unlock(mutex); 53 + } 54 + 55 + static const struct regmap_config atc2603c_regmap_config = { 56 + .reg_bits = 8, 57 + .val_bits = 16, 58 + .max_register = ATC2603C_SADDR, 59 + .cache_type = REGCACHE_NONE, 60 + }; 61 + 62 + static const struct regmap_config atc2609a_regmap_config = { 63 + .reg_bits = 8, 64 + .val_bits = 16, 65 + .max_register = ATC2609A_SADDR, 66 + .cache_type = REGCACHE_NONE, 67 + }; 68 + 69 + static const struct regmap_irq atc2603c_regmap_irqs[] = { 70 + REGMAP_IRQ_REG(ATC2603C_IRQ_AUDIO, 0, ATC2603C_INTS_MSK_AUDIO), 71 + REGMAP_IRQ_REG(ATC2603C_IRQ_OV, 0, ATC2603C_INTS_MSK_OV), 72 + REGMAP_IRQ_REG(ATC2603C_IRQ_OC, 0, ATC2603C_INTS_MSK_OC), 73 + REGMAP_IRQ_REG(ATC2603C_IRQ_OT, 0, ATC2603C_INTS_MSK_OT), 74 + REGMAP_IRQ_REG(ATC2603C_IRQ_UV, 0, ATC2603C_INTS_MSK_UV), 75 + REGMAP_IRQ_REG(ATC2603C_IRQ_ALARM, 0, ATC2603C_INTS_MSK_ALARM), 76 + REGMAP_IRQ_REG(ATC2603C_IRQ_ONOFF, 0, ATC2603C_INTS_MSK_ONOFF), 77 + REGMAP_IRQ_REG(ATC2603C_IRQ_SGPIO, 0, ATC2603C_INTS_MSK_SGPIO), 78 + REGMAP_IRQ_REG(ATC2603C_IRQ_IR, 0, ATC2603C_INTS_MSK_IR), 79 + REGMAP_IRQ_REG(ATC2603C_IRQ_REMCON, 0, ATC2603C_INTS_MSK_REMCON), 80 + REGMAP_IRQ_REG(ATC2603C_IRQ_POWER_IN, 0, ATC2603C_INTS_MSK_POWERIN), 81 + }; 82 + 83 + static const struct regmap_irq atc2609a_regmap_irqs[] = { 84 + REGMAP_IRQ_REG(ATC2609A_IRQ_AUDIO, 0, ATC2609A_INTS_MSK_AUDIO), 85 + REGMAP_IRQ_REG(ATC2609A_IRQ_OV, 0, ATC2609A_INTS_MSK_OV), 86 + REGMAP_IRQ_REG(ATC2609A_IRQ_OC, 0, ATC2609A_INTS_MSK_OC), 87 + REGMAP_IRQ_REG(ATC2609A_IRQ_OT, 0, ATC2609A_INTS_MSK_OT), 88 + REGMAP_IRQ_REG(ATC2609A_IRQ_UV, 0, ATC2609A_INTS_MSK_UV), 89 + REGMAP_IRQ_REG(ATC2609A_IRQ_ALARM, 0, ATC2609A_INTS_MSK_ALARM), 90 + REGMAP_IRQ_REG(ATC2609A_IRQ_ONOFF, 0, ATC2609A_INTS_MSK_ONOFF), 91 + REGMAP_IRQ_REG(ATC2609A_IRQ_WKUP, 0, ATC2609A_INTS_MSK_WKUP), 92 + REGMAP_IRQ_REG(ATC2609A_IRQ_IR, 0, ATC2609A_INTS_MSK_IR), 93 + REGMAP_IRQ_REG(ATC2609A_IRQ_REMCON, 0, ATC2609A_INTS_MSK_REMCON), 94 + REGMAP_IRQ_REG(ATC2609A_IRQ_POWER_IN, 0, ATC2609A_INTS_MSK_POWERIN), 95 + }; 96 + 97 + static const struct regmap_irq_chip atc2603c_regmap_irq_chip = { 98 + .name = "atc2603c", 99 + .irqs = atc2603c_regmap_irqs, 100 + .num_irqs = ARRAY_SIZE(atc2603c_regmap_irqs), 101 + .num_regs = 1, 102 + .status_base = ATC2603C_INTS_PD, 103 + .mask_base = ATC2603C_INTS_MSK, 104 + .mask_invert = true, 105 + }; 106 + 107 + static const struct regmap_irq_chip atc2609a_regmap_irq_chip = { 108 + .name = "atc2609a", 109 + .irqs = atc2609a_regmap_irqs, 110 + .num_irqs = ARRAY_SIZE(atc2609a_regmap_irqs), 111 + .num_regs = 1, 112 + .status_base = ATC2609A_INTS_PD, 113 + .mask_base = ATC2609A_INTS_MSK, 114 + .mask_invert = true, 115 + }; 116 + 117 + static const struct resource atc2603c_onkey_resources[] = { 118 + DEFINE_RES_IRQ(ATC2603C_IRQ_ONOFF), 119 + }; 120 + 121 + static const struct resource atc2609a_onkey_resources[] = { 122 + DEFINE_RES_IRQ(ATC2609A_IRQ_ONOFF), 123 + }; 124 + 125 + static const struct mfd_cell atc2603c_mfd_cells[] = { 126 + { .name = "atc260x-regulator" }, 127 + { .name = "atc260x-pwrc" }, 128 + { 129 + .name = "atc260x-onkey", 130 + .num_resources = ARRAY_SIZE(atc2603c_onkey_resources), 131 + .resources = atc2603c_onkey_resources, 132 + }, 133 + }; 134 + 135 + static const struct mfd_cell atc2609a_mfd_cells[] = { 136 + { .name = "atc260x-regulator" }, 137 + { .name = "atc260x-pwrc" }, 138 + { 139 + .name = "atc260x-onkey", 140 + .num_resources = ARRAY_SIZE(atc2609a_onkey_resources), 141 + .resources = atc2609a_onkey_resources, 142 + }, 143 + }; 144 + 145 + static const struct atc260x_init_regs atc2603c_init_regs = { 146 + .cmu_devrst = ATC2603C_CMU_DEVRST, 147 + .cmu_devrst_ints = ATC2603C_CMU_DEVRST_INTS, 148 + .ints_msk = ATC2603C_INTS_MSK, 149 + .pad_en = ATC2603C_PAD_EN, 150 + .pad_en_extirq = ATC2603C_PAD_EN_EXTIRQ, 151 + }; 152 + 153 + static const struct atc260x_init_regs atc2609a_init_regs = { 154 + .cmu_devrst = ATC2609A_CMU_DEVRST, 155 + .cmu_devrst_ints = ATC2609A_CMU_DEVRST_INTS, 156 + .ints_msk = ATC2609A_INTS_MSK, 157 + .pad_en = ATC2609A_PAD_EN, 158 + .pad_en_extirq = ATC2609A_PAD_EN_EXTIRQ, 159 + }; 160 + 161 + static void atc260x_cmu_reset(struct atc260x *atc260x) 162 + { 163 + const struct atc260x_init_regs *regs = atc260x->init_regs; 164 + 165 + /* Assert reset */ 166 + regmap_update_bits(atc260x->regmap, regs->cmu_devrst, 167 + regs->cmu_devrst_ints, ~regs->cmu_devrst_ints); 168 + 169 + /* De-assert reset */ 170 + regmap_update_bits(atc260x->regmap, regs->cmu_devrst, 171 + regs->cmu_devrst_ints, regs->cmu_devrst_ints); 172 + } 173 + 174 + static void atc260x_dev_init(struct atc260x *atc260x) 175 + { 176 + const struct atc260x_init_regs *regs = atc260x->init_regs; 177 + 178 + /* Initialize interrupt block */ 179 + atc260x_cmu_reset(atc260x); 180 + 181 + /* Disable all interrupt sources */ 182 + regmap_write(atc260x->regmap, regs->ints_msk, 0); 183 + 184 + /* Enable EXTIRQ pad */ 185 + regmap_update_bits(atc260x->regmap, regs->pad_en, 186 + regs->pad_en_extirq, regs->pad_en_extirq); 187 + } 188 + 189 + /** 190 + * atc260x_match_device(): Setup ATC260x variant related fields 191 + * 192 + * @atc260x: ATC260x device to setup (.dev field must be set) 193 + * @regmap_cfg: regmap config associated with this ATC260x device 194 + * 195 + * This lets the ATC260x core configure the MFD cells and register maps 196 + * for later use. 197 + */ 198 + int atc260x_match_device(struct atc260x *atc260x, struct regmap_config *regmap_cfg) 199 + { 200 + struct device *dev = atc260x->dev; 201 + const void *of_data; 202 + 203 + of_data = of_device_get_match_data(dev); 204 + if (!of_data) 205 + return -ENODEV; 206 + 207 + atc260x->ic_type = (unsigned long)of_data; 208 + 209 + switch (atc260x->ic_type) { 210 + case ATC2603C: 211 + *regmap_cfg = atc2603c_regmap_config; 212 + atc260x->regmap_irq_chip = &atc2603c_regmap_irq_chip; 213 + atc260x->cells = atc2603c_mfd_cells; 214 + atc260x->nr_cells = ARRAY_SIZE(atc2603c_mfd_cells); 215 + atc260x->type_name = "atc2603c"; 216 + atc260x->rev_reg = ATC2603C_CHIP_VER; 217 + atc260x->init_regs = &atc2603c_init_regs; 218 + break; 219 + case ATC2609A: 220 + *regmap_cfg = atc2609a_regmap_config; 221 + atc260x->regmap_irq_chip = &atc2609a_regmap_irq_chip; 222 + atc260x->cells = atc2609a_mfd_cells; 223 + atc260x->nr_cells = ARRAY_SIZE(atc2609a_mfd_cells); 224 + atc260x->type_name = "atc2609a"; 225 + atc260x->rev_reg = ATC2609A_CHIP_VER; 226 + atc260x->init_regs = &atc2609a_init_regs; 227 + break; 228 + default: 229 + dev_err(dev, "Unsupported ATC260x device type: %u\n", 230 + atc260x->ic_type); 231 + return -EINVAL; 232 + } 233 + 234 + atc260x->regmap_mutex = devm_kzalloc(dev, sizeof(*atc260x->regmap_mutex), 235 + GFP_KERNEL); 236 + if (!atc260x->regmap_mutex) 237 + return -ENOMEM; 238 + 239 + mutex_init(atc260x->regmap_mutex); 240 + 241 + regmap_cfg->lock = regmap_lock_mutex, 242 + regmap_cfg->unlock = regmap_unlock_mutex, 243 + regmap_cfg->lock_arg = atc260x->regmap_mutex; 244 + 245 + return 0; 246 + } 247 + EXPORT_SYMBOL_GPL(atc260x_match_device); 248 + 249 + /** 250 + * atc260x_device_probe(): Probe a configured ATC260x device 251 + * 252 + * @atc260x: ATC260x device to probe (must be configured) 253 + * 254 + * This function lets the ATC260x core register the ATC260x MFD devices 255 + * and IRQCHIP. The ATC260x device passed in must be fully configured 256 + * with atc260x_match_device, its IRQ set, and regmap created. 257 + */ 258 + int atc260x_device_probe(struct atc260x *atc260x) 259 + { 260 + struct device *dev = atc260x->dev; 261 + unsigned int chip_rev; 262 + int ret; 263 + 264 + if (!atc260x->irq) { 265 + dev_err(dev, "No interrupt support\n"); 266 + return -EINVAL; 267 + } 268 + 269 + /* Initialize the hardware */ 270 + atc260x_dev_init(atc260x); 271 + 272 + ret = regmap_read(atc260x->regmap, atc260x->rev_reg, &chip_rev); 273 + if (ret) { 274 + dev_err(dev, "Failed to get chip revision\n"); 275 + return ret; 276 + } 277 + 278 + if (chip_rev > ATC260X_CHIP_REV_MAX) { 279 + dev_err(dev, "Unknown chip revision: %u\n", chip_rev); 280 + return -EINVAL; 281 + } 282 + 283 + atc260x->ic_ver = __ffs(chip_rev + 1U); 284 + 285 + dev_info(dev, "Detected chip type %s rev.%c\n", 286 + atc260x->type_name, 'A' + atc260x->ic_ver); 287 + 288 + ret = devm_regmap_add_irq_chip(dev, atc260x->regmap, atc260x->irq, IRQF_ONESHOT, 289 + -1, atc260x->regmap_irq_chip, &atc260x->irq_data); 290 + if (ret) { 291 + dev_err(dev, "Failed to add IRQ chip: %d\n", ret); 292 + return ret; 293 + } 294 + 295 + ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, 296 + atc260x->cells, atc260x->nr_cells, NULL, 0, 297 + regmap_irq_get_domain(atc260x->irq_data)); 298 + if (ret) { 299 + dev_err(dev, "Failed to add child devices: %d\n", ret); 300 + regmap_del_irq_chip(atc260x->irq, atc260x->irq_data); 301 + } 302 + 303 + return ret; 304 + } 305 + EXPORT_SYMBOL_GPL(atc260x_device_probe); 306 + 307 + MODULE_DESCRIPTION("ATC260x PMICs Core support"); 308 + MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>"); 309 + MODULE_AUTHOR("Cristian Ciocaltea <cristian.ciocaltea@gmail.com>"); 310 + MODULE_LICENSE("GPL");
+64
drivers/mfd/atc260x-i2c.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * I2C bus interface for ATC260x PMICs 4 + * 5 + * Copyright (C) 2019 Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> 6 + * Copyright (C) 2020 Cristian Ciocaltea <cristian.ciocaltea@gmail.com> 7 + */ 8 + 9 + #include <linux/i2c.h> 10 + #include <linux/mfd/atc260x/core.h> 11 + #include <linux/module.h> 12 + #include <linux/of.h> 13 + #include <linux/regmap.h> 14 + 15 + static int atc260x_i2c_probe(struct i2c_client *client, 16 + const struct i2c_device_id *id) 17 + { 18 + struct atc260x *atc260x; 19 + struct regmap_config regmap_cfg; 20 + int ret; 21 + 22 + atc260x = devm_kzalloc(&client->dev, sizeof(*atc260x), GFP_KERNEL); 23 + if (!atc260x) 24 + return -ENOMEM; 25 + 26 + atc260x->dev = &client->dev; 27 + atc260x->irq = client->irq; 28 + 29 + ret = atc260x_match_device(atc260x, &regmap_cfg); 30 + if (ret) 31 + return ret; 32 + 33 + i2c_set_clientdata(client, atc260x); 34 + 35 + atc260x->regmap = devm_regmap_init_i2c(client, &regmap_cfg); 36 + if (IS_ERR(atc260x->regmap)) { 37 + ret = PTR_ERR(atc260x->regmap); 38 + dev_err(&client->dev, "failed to init regmap: %d\n", ret); 39 + return ret; 40 + } 41 + 42 + return atc260x_device_probe(atc260x); 43 + } 44 + 45 + static const struct of_device_id atc260x_i2c_of_match[] = { 46 + { .compatible = "actions,atc2603c", .data = (void *)ATC2603C }, 47 + { .compatible = "actions,atc2609a", .data = (void *)ATC2609A }, 48 + { } 49 + }; 50 + MODULE_DEVICE_TABLE(of, atc260x_i2c_of_match); 51 + 52 + static struct i2c_driver atc260x_i2c_driver = { 53 + .driver = { 54 + .name = "atc260x", 55 + .of_match_table = of_match_ptr(atc260x_i2c_of_match), 56 + }, 57 + .probe = atc260x_i2c_probe, 58 + }; 59 + module_i2c_driver(atc260x_i2c_driver); 60 + 61 + MODULE_DESCRIPTION("ATC260x PMICs I2C bus interface"); 62 + MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>"); 63 + MODULE_AUTHOR("Cristian Ciocaltea <cristian.ciocaltea@gmail.com>"); 64 + MODULE_LICENSE("GPL");
+10
drivers/mfd/da9063-i2c.c
··· 442 442 return ret; 443 443 } 444 444 445 + /* If SMBus is not available and only I2C is possible, enter I2C mode */ 446 + if (i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) { 447 + ret = regmap_clear_bits(da9063->regmap, DA9063_REG_CONFIG_J, 448 + DA9063_TWOWIRE_TO); 449 + if (ret < 0) { 450 + dev_err(da9063->dev, "Failed to set Two-Wire Bus Mode.\n"); 451 + return -EIO; 452 + } 453 + } 454 + 445 455 return da9063_device_init(da9063, i2c->irq); 446 456 } 447 457
+1 -1
drivers/mfd/ene-kb3930.c
··· 33 33 struct gpio_descs *off_gpios; 34 34 }; 35 35 36 - struct kb3930 *kb3930_power_off; 36 + static struct kb3930 *kb3930_power_off; 37 37 38 38 #define EC_GPIO_WAVE 0 39 39 #define EC_GPIO_OFF_MODE 1
+26 -10
drivers/mfd/intel-lpss-acpi.c
··· 22 22 .clk_rate = 120000000, 23 23 }; 24 24 25 - static struct property_entry spt_i2c_properties[] = { 25 + static const struct property_entry spt_i2c_properties[] = { 26 26 PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 230), 27 27 { }, 28 28 }; 29 29 30 - static const struct intel_lpss_platform_info spt_i2c_info = { 31 - .clk_rate = 120000000, 30 + static const struct software_node spt_i2c_node = { 32 31 .properties = spt_i2c_properties, 33 32 }; 34 33 35 - static struct property_entry uart_properties[] = { 34 + static const struct intel_lpss_platform_info spt_i2c_info = { 35 + .clk_rate = 120000000, 36 + .swnode = &spt_i2c_node, 37 + }; 38 + 39 + static const struct property_entry uart_properties[] = { 36 40 PROPERTY_ENTRY_U32("reg-io-width", 4), 37 41 PROPERTY_ENTRY_U32("reg-shift", 2), 38 42 PROPERTY_ENTRY_BOOL("snps,uart-16550-compatible"), 39 43 { }, 40 44 }; 41 45 46 + static const struct software_node uart_node = { 47 + .properties = uart_properties, 48 + }; 49 + 42 50 static const struct intel_lpss_platform_info spt_uart_info = { 43 51 .clk_rate = 120000000, 44 52 .clk_con_id = "baudclk", 45 - .properties = uart_properties, 53 + .swnode = &uart_node, 46 54 }; 47 55 48 56 static const struct intel_lpss_platform_info bxt_info = { 49 57 .clk_rate = 100000000, 50 58 }; 51 59 52 - static struct property_entry bxt_i2c_properties[] = { 60 + static const struct property_entry bxt_i2c_properties[] = { 53 61 PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 42), 54 62 PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171), 55 63 PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 208), 56 64 { }, 57 65 }; 58 66 59 - static const struct intel_lpss_platform_info bxt_i2c_info = { 60 - .clk_rate = 133000000, 67 + static const struct software_node bxt_i2c_node = { 61 68 .properties = bxt_i2c_properties, 62 69 }; 63 70 64 - static struct property_entry apl_i2c_properties[] = { 71 + static const struct intel_lpss_platform_info bxt_i2c_info = { 72 + .clk_rate = 133000000, 73 + .swnode = &bxt_i2c_node, 74 + }; 75 + 76 + static const struct property_entry apl_i2c_properties[] = { 65 77 PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 207), 66 78 PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171), 67 79 PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 208), 68 80 { }, 69 81 }; 70 82 83 + static const struct software_node apl_i2c_node = { 84 + .properties = apl_i2c_properties, 85 + }; 86 + 71 87 static const struct intel_lpss_platform_info apl_i2c_info = { 72 88 .clk_rate = 133000000, 73 - .properties = apl_i2c_properties, 89 + .swnode = &apl_i2c_node, 74 90 }; 75 91 76 92 static const struct acpi_device_id intel_lpss_acpi_ids[] = {
+36 -16
drivers/mfd/intel-lpss-pci.c
··· 65 65 .clk_rate = 120000000, 66 66 }; 67 67 68 - static struct property_entry spt_i2c_properties[] = { 68 + static const struct property_entry spt_i2c_properties[] = { 69 69 PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 230), 70 70 { }, 71 71 }; 72 72 73 - static const struct intel_lpss_platform_info spt_i2c_info = { 74 - .clk_rate = 120000000, 73 + static const struct software_node spt_i2c_node = { 75 74 .properties = spt_i2c_properties, 76 75 }; 77 76 78 - static struct property_entry uart_properties[] = { 77 + static const struct intel_lpss_platform_info spt_i2c_info = { 78 + .clk_rate = 120000000, 79 + .swnode = &spt_i2c_node, 80 + }; 81 + 82 + static const struct property_entry uart_properties[] = { 79 83 PROPERTY_ENTRY_U32("reg-io-width", 4), 80 84 PROPERTY_ENTRY_U32("reg-shift", 2), 81 85 PROPERTY_ENTRY_BOOL("snps,uart-16550-compatible"), 82 86 { }, 83 87 }; 84 88 89 + static const struct software_node uart_node = { 90 + .properties = uart_properties, 91 + }; 92 + 85 93 static const struct intel_lpss_platform_info spt_uart_info = { 86 94 .clk_rate = 120000000, 87 95 .clk_con_id = "baudclk", 88 - .properties = uart_properties, 96 + .swnode = &uart_node, 89 97 }; 90 98 91 99 static const struct intel_lpss_platform_info bxt_info = { ··· 103 95 static const struct intel_lpss_platform_info bxt_uart_info = { 104 96 .clk_rate = 100000000, 105 97 .clk_con_id = "baudclk", 106 - .properties = uart_properties, 98 + .swnode = &uart_node, 107 99 }; 108 100 109 - static struct property_entry bxt_i2c_properties[] = { 101 + static const struct property_entry bxt_i2c_properties[] = { 110 102 PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 42), 111 103 PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171), 112 104 PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 208), 113 105 { }, 114 106 }; 115 107 116 - static const struct intel_lpss_platform_info bxt_i2c_info = { 117 - .clk_rate = 133000000, 108 + static const struct software_node bxt_i2c_node = { 118 109 .properties = bxt_i2c_properties, 119 110 }; 120 111 121 - static struct property_entry apl_i2c_properties[] = { 112 + static const struct intel_lpss_platform_info bxt_i2c_info = { 113 + .clk_rate = 133000000, 114 + .swnode = &bxt_i2c_node, 115 + }; 116 + 117 + static const struct property_entry apl_i2c_properties[] = { 122 118 PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 207), 123 119 PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171), 124 120 PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 208), 125 121 { }, 126 122 }; 127 123 128 - static const struct intel_lpss_platform_info apl_i2c_info = { 129 - .clk_rate = 133000000, 124 + static const struct software_node apl_i2c_node = { 130 125 .properties = apl_i2c_properties, 131 126 }; 132 127 133 - static struct property_entry glk_i2c_properties[] = { 128 + static const struct intel_lpss_platform_info apl_i2c_info = { 129 + .clk_rate = 133000000, 130 + .swnode = &apl_i2c_node, 131 + }; 132 + 133 + static const struct property_entry glk_i2c_properties[] = { 134 134 PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 313), 135 135 PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171), 136 136 PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 290), 137 137 { }, 138 138 }; 139 139 140 + static const struct software_node glk_i2c_node = { 141 + .properties = glk_i2c_properties, 142 + }; 143 + 140 144 static const struct intel_lpss_platform_info glk_i2c_info = { 141 145 .clk_rate = 133000000, 142 - .properties = glk_i2c_properties, 146 + .swnode = &glk_i2c_node, 143 147 }; 144 148 145 149 static const struct intel_lpss_platform_info cnl_i2c_info = { 146 150 .clk_rate = 216000000, 147 - .properties = spt_i2c_properties, 151 + .swnode = &spt_i2c_node, 148 152 }; 149 153 150 154 static const struct intel_lpss_platform_info ehl_i2c_info = { 151 155 .clk_rate = 100000000, 152 - .properties = bxt_i2c_properties, 156 + .swnode = &bxt_i2c_node, 153 157 }; 154 158 155 159 static const struct pci_device_id intel_lpss_pci_ids[] = {
+1 -1
drivers/mfd/intel-lpss.c
··· 399 399 if (ret) 400 400 return ret; 401 401 402 - lpss->cell->properties = info->properties; 402 + lpss->cell->swnode = info->swnode; 403 403 404 404 intel_lpss_init_dev(lpss); 405 405
+2 -2
drivers/mfd/intel-lpss.h
··· 15 15 16 16 struct device; 17 17 struct resource; 18 - struct property_entry; 18 + struct software_node; 19 19 20 20 struct intel_lpss_platform_info { 21 21 struct resource *mem; 22 22 int irq; 23 23 unsigned long clk_rate; 24 24 const char *clk_con_id; 25 - struct property_entry *properties; 25 + const struct software_node *swnode; 26 26 }; 27 27 28 28 int intel_lpss_probe(struct device *dev,
+20 -10
drivers/mfd/intel-m10-bmc.c
··· 28 28 { .name = "n3000bmc-secure" }, 29 29 }; 30 30 31 + static const struct regmap_range m10bmc_regmap_range[] = { 32 + regmap_reg_range(M10BMC_LEGACY_BUILD_VER, M10BMC_LEGACY_BUILD_VER), 33 + regmap_reg_range(M10BMC_SYS_BASE, M10BMC_SYS_END), 34 + regmap_reg_range(M10BMC_FLASH_BASE, M10BMC_FLASH_END), 35 + }; 36 + 37 + static const struct regmap_access_table m10bmc_access_table = { 38 + .yes_ranges = m10bmc_regmap_range, 39 + .n_yes_ranges = ARRAY_SIZE(m10bmc_regmap_range), 40 + }; 41 + 31 42 static struct regmap_config intel_m10bmc_regmap_config = { 32 43 .reg_bits = 32, 33 44 .val_bits = 32, 34 45 .reg_stride = 4, 46 + .wr_table = &m10bmc_access_table, 47 + .rd_table = &m10bmc_access_table, 35 48 .max_register = M10BMC_MEM_END, 36 49 }; 37 50 ··· 134 121 int ret; 135 122 136 123 /* 137 - * This check is to filter out the very old legacy BMC versions, 138 - * M10BMC_LEGACY_SYS_BASE is the offset to this old block of mmio 139 - * registers. In the old BMC chips, the BMC version info is stored 140 - * in this old version register (M10BMC_LEGACY_SYS_BASE + 141 - * M10BMC_BUILD_VER), so its read out value would have not been 142 - * LEGACY_INVALID (0xffffffff). But in new BMC chips that the 143 - * driver supports, the value of this register should be 144 - * LEGACY_INVALID. 124 + * This check is to filter out the very old legacy BMC versions. In the 125 + * old BMC chips, the BMC version info is stored in the old version 126 + * register (M10BMC_LEGACY_BUILD_VER), so its read out value would have 127 + * not been M10BMC_VER_LEGACY_INVALID (0xffffffff). But in new BMC 128 + * chips that the driver supports, the value of this register should be 129 + * M10BMC_VER_LEGACY_INVALID. 145 130 */ 146 - ret = m10bmc_raw_read(ddata, 147 - M10BMC_LEGACY_SYS_BASE + M10BMC_BUILD_VER, &v); 131 + ret = m10bmc_raw_read(ddata, M10BMC_LEGACY_BUILD_VER, &v); 148 132 if (ret) 149 133 return -ENODEV; 150 134
+65 -47
drivers/mfd/intel_quark_i2c_gpio.c
··· 16 16 #include <linux/clkdev.h> 17 17 #include <linux/clk-provider.h> 18 18 #include <linux/dmi.h> 19 + #include <linux/i2c.h> 19 20 #include <linux/platform_data/gpio-dwapb.h> 20 - #include <linux/platform_data/i2c-designware.h> 21 + #include <linux/property.h> 21 22 22 23 /* PCI BAR for register base address */ 23 24 #define MFD_I2C_BAR 0 ··· 46 45 #define INTEL_QUARK_I2C_CLK_HZ 33000000 47 46 48 47 struct intel_quark_mfd { 49 - struct device *dev; 50 48 struct clk *i2c_clk; 51 49 struct clk_lookup *i2c_clk_lookup; 50 + }; 51 + 52 + static const struct property_entry intel_quark_i2c_controller_standard_properties[] = { 53 + PROPERTY_ENTRY_U32("clock-frequency", I2C_MAX_STANDARD_MODE_FREQ), 54 + { } 55 + }; 56 + 57 + static const struct software_node intel_quark_i2c_controller_standard_node = { 58 + .name = "intel-quark-i2c-controller", 59 + .properties = intel_quark_i2c_controller_standard_properties, 60 + }; 61 + 62 + static const struct property_entry intel_quark_i2c_controller_fast_properties[] = { 63 + PROPERTY_ENTRY_U32("clock-frequency", I2C_MAX_FAST_MODE_FREQ), 64 + { } 65 + }; 66 + 67 + static const struct software_node intel_quark_i2c_controller_fast_node = { 68 + .name = "intel-quark-i2c-controller", 69 + .properties = intel_quark_i2c_controller_fast_properties, 52 70 }; 53 71 54 72 static const struct dmi_system_id dmi_platform_info[] = { ··· 75 55 .matches = { 76 56 DMI_EXACT_MATCH(DMI_BOARD_NAME, "Galileo"), 77 57 }, 78 - .driver_data = (void *)100000, 58 + .driver_data = (void *)&intel_quark_i2c_controller_standard_node, 79 59 }, 80 60 { 81 61 .matches = { 82 62 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GalileoGen2"), 83 63 }, 84 - .driver_data = (void *)400000, 64 + .driver_data = (void *)&intel_quark_i2c_controller_fast_node, 85 65 }, 86 66 { 87 67 .matches = { 88 68 DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"), 89 69 }, 90 - .driver_data = (void *)400000, 70 + .driver_data = (void *)&intel_quark_i2c_controller_fast_node, 91 71 }, 92 72 {} 93 73 }; ··· 118 98 }; 119 99 120 100 static struct mfd_cell intel_quark_mfd_cells[] = { 121 - { 122 - .id = MFD_GPIO_BAR, 123 - .name = "gpio-dwapb", 124 - .acpi_match = &intel_quark_acpi_match_gpio, 125 - .num_resources = ARRAY_SIZE(intel_quark_gpio_res), 126 - .resources = intel_quark_gpio_res, 127 - .ignore_resource_conflicts = true, 128 - }, 129 - { 101 + [MFD_I2C_BAR] = { 130 102 .id = MFD_I2C_BAR, 131 103 .name = "i2c_designware", 132 104 .acpi_match = &intel_quark_acpi_match_i2c, 133 105 .num_resources = ARRAY_SIZE(intel_quark_i2c_res), 134 106 .resources = intel_quark_i2c_res, 107 + .ignore_resource_conflicts = true, 108 + }, 109 + [MFD_GPIO_BAR] = { 110 + .id = MFD_GPIO_BAR, 111 + .name = "gpio-dwapb", 112 + .acpi_match = &intel_quark_acpi_match_gpio, 113 + .num_resources = ARRAY_SIZE(intel_quark_gpio_res), 114 + .resources = intel_quark_gpio_res, 135 115 .ignore_resource_conflicts = true, 136 116 }, 137 117 }; ··· 177 157 clk_unregister(quark_mfd->i2c_clk); 178 158 } 179 159 180 - static int intel_quark_i2c_setup(struct pci_dev *pdev, struct mfd_cell *cell) 160 + static int intel_quark_i2c_setup(struct pci_dev *pdev) 181 161 { 162 + struct mfd_cell *cell = &intel_quark_mfd_cells[MFD_I2C_BAR]; 163 + struct resource *res = intel_quark_i2c_res; 182 164 const struct dmi_system_id *dmi_id; 183 - struct dw_i2c_platform_data *pdata; 184 - struct resource *res = (struct resource *)cell->resources; 185 - struct device *dev = &pdev->dev; 186 165 187 - res[INTEL_QUARK_IORES_MEM].start = 188 - pci_resource_start(pdev, MFD_I2C_BAR); 189 - res[INTEL_QUARK_IORES_MEM].end = 190 - pci_resource_end(pdev, MFD_I2C_BAR); 166 + res[INTEL_QUARK_IORES_MEM].start = pci_resource_start(pdev, MFD_I2C_BAR); 167 + res[INTEL_QUARK_IORES_MEM].end = pci_resource_end(pdev, MFD_I2C_BAR); 191 168 192 - res[INTEL_QUARK_IORES_IRQ].start = pdev->irq; 193 - res[INTEL_QUARK_IORES_IRQ].end = pdev->irq; 194 - 195 - pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 196 - if (!pdata) 197 - return -ENOMEM; 169 + res[INTEL_QUARK_IORES_IRQ].start = pci_irq_vector(pdev, 0); 170 + res[INTEL_QUARK_IORES_IRQ].end = pci_irq_vector(pdev, 0); 198 171 199 172 /* Normal mode by default */ 200 - pdata->i2c_scl_freq = 100000; 173 + cell->swnode = &intel_quark_i2c_controller_standard_node; 201 174 202 175 dmi_id = dmi_first_match(dmi_platform_info); 203 176 if (dmi_id) 204 - pdata->i2c_scl_freq = (uintptr_t)dmi_id->driver_data; 205 - 206 - cell->platform_data = pdata; 207 - cell->pdata_size = sizeof(*pdata); 177 + cell->swnode = (struct software_node *)dmi_id->driver_data; 208 178 209 179 return 0; 210 180 } 211 181 212 - static int intel_quark_gpio_setup(struct pci_dev *pdev, struct mfd_cell *cell) 182 + static int intel_quark_gpio_setup(struct pci_dev *pdev) 213 183 { 184 + struct mfd_cell *cell = &intel_quark_mfd_cells[MFD_GPIO_BAR]; 185 + struct resource *res = intel_quark_gpio_res; 214 186 struct dwapb_platform_data *pdata; 215 - struct resource *res = (struct resource *)cell->resources; 216 187 struct device *dev = &pdev->dev; 217 188 218 - res[INTEL_QUARK_IORES_MEM].start = 219 - pci_resource_start(pdev, MFD_GPIO_BAR); 220 - res[INTEL_QUARK_IORES_MEM].end = 221 - pci_resource_end(pdev, MFD_GPIO_BAR); 189 + res[INTEL_QUARK_IORES_MEM].start = pci_resource_start(pdev, MFD_GPIO_BAR); 190 + res[INTEL_QUARK_IORES_MEM].end = pci_resource_end(pdev, MFD_GPIO_BAR); 222 191 223 192 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 224 193 if (!pdata) ··· 226 217 pdata->properties->idx = 0; 227 218 pdata->properties->ngpio = INTEL_QUARK_MFD_NGPIO; 228 219 pdata->properties->gpio_base = INTEL_QUARK_MFD_GPIO_BASE; 229 - pdata->properties->irq[0] = pdev->irq; 220 + pdata->properties->irq[0] = pci_irq_vector(pdev, 0); 230 221 pdata->properties->irq_shared = true; 231 222 232 223 cell->platform_data = pdata; ··· 249 240 if (!quark_mfd) 250 241 return -ENOMEM; 251 242 252 - quark_mfd->dev = &pdev->dev; 253 243 dev_set_drvdata(&pdev->dev, quark_mfd); 254 244 255 245 ret = intel_quark_register_i2c_clk(&pdev->dev); 256 246 if (ret) 257 247 return ret; 258 248 259 - ret = intel_quark_i2c_setup(pdev, &intel_quark_mfd_cells[1]); 260 - if (ret) 249 + pci_set_master(pdev); 250 + 251 + /* This driver only requires 1 IRQ vector */ 252 + ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); 253 + if (ret < 0) 261 254 goto err_unregister_i2c_clk; 262 255 263 - ret = intel_quark_gpio_setup(pdev, &intel_quark_mfd_cells[0]); 256 + ret = intel_quark_i2c_setup(pdev); 264 257 if (ret) 265 - goto err_unregister_i2c_clk; 258 + goto err_free_irq_vectors; 259 + 260 + ret = intel_quark_gpio_setup(pdev); 261 + if (ret) 262 + goto err_free_irq_vectors; 266 263 267 264 ret = mfd_add_devices(&pdev->dev, 0, intel_quark_mfd_cells, 268 265 ARRAY_SIZE(intel_quark_mfd_cells), NULL, 0, 269 266 NULL); 270 267 if (ret) 271 - goto err_unregister_i2c_clk; 268 + goto err_free_irq_vectors; 272 269 273 270 return 0; 274 271 272 + err_free_irq_vectors: 273 + pci_free_irq_vectors(pdev); 275 274 err_unregister_i2c_clk: 276 275 intel_quark_unregister_i2c_clk(&pdev->dev); 277 276 return ret; ··· 287 270 288 271 static void intel_quark_mfd_remove(struct pci_dev *pdev) 289 272 { 290 - intel_quark_unregister_i2c_clk(&pdev->dev); 291 273 mfd_remove_devices(&pdev->dev); 274 + pci_free_irq_vectors(pdev); 275 + intel_quark_unregister_i2c_clk(&pdev->dev); 292 276 } 293 277 294 278 static struct pci_driver intel_quark_mfd_driver = {
+1 -1
drivers/mfd/lm3533-core.c
··· 358 358 static umode_t lm3533_attr_is_visible(struct kobject *kobj, 359 359 struct attribute *attr, int n) 360 360 { 361 - struct device *dev = container_of(kobj, struct device, kobj); 361 + struct device *dev = kobj_to_dev(kobj); 362 362 struct lm3533 *lm3533 = dev_get_drvdata(dev); 363 363 struct device_attribute *dattr = to_dev_attr(attr); 364 364 struct lm3533_device_attribute *lattr = to_lm3533_dev_attr(dattr);
+6 -26
drivers/mfd/lpc_sch.c
··· 26 26 #define GPIO_IO_SIZE 64 27 27 #define GPIO_IO_SIZE_CENTERTON 128 28 28 29 - /* Intel Quark X1000 GPIO IRQ Number */ 30 - #define GPIO_IRQ_QUARK_X1000 9 31 - 32 29 #define WDTBASE 0x84 33 30 #define WDT_IO_SIZE 64 34 31 ··· 40 43 unsigned int io_size_smbus; 41 44 unsigned int io_size_gpio; 42 45 unsigned int io_size_wdt; 43 - int irq_gpio; 44 46 }; 45 47 46 48 static struct lpc_sch_info sch_chipset_info[] = { 47 49 [LPC_SCH] = { 48 50 .io_size_smbus = SMBUS_IO_SIZE, 49 51 .io_size_gpio = GPIO_IO_SIZE, 50 - .irq_gpio = -1, 51 52 }, 52 53 [LPC_ITC] = { 53 54 .io_size_smbus = SMBUS_IO_SIZE, 54 55 .io_size_gpio = GPIO_IO_SIZE, 55 56 .io_size_wdt = WDT_IO_SIZE, 56 - .irq_gpio = -1, 57 57 }, 58 58 [LPC_CENTERTON] = { 59 59 .io_size_smbus = SMBUS_IO_SIZE, 60 60 .io_size_gpio = GPIO_IO_SIZE_CENTERTON, 61 61 .io_size_wdt = WDT_IO_SIZE, 62 - .irq_gpio = -1, 63 62 }, 64 63 [LPC_QUARK_X1000] = { 65 64 .io_size_gpio = GPIO_IO_SIZE, 66 - .irq_gpio = GPIO_IRQ_QUARK_X1000, 67 65 .io_size_wdt = WDT_IO_SIZE, 68 66 }, 69 67 }; ··· 105 113 } 106 114 107 115 static int lpc_sch_populate_cell(struct pci_dev *pdev, int where, 108 - const char *name, int size, int irq, 109 - int id, struct mfd_cell *cell) 116 + const char *name, int size, int id, 117 + struct mfd_cell *cell) 110 118 { 111 119 struct resource *res; 112 120 int ret; 113 121 114 - res = devm_kcalloc(&pdev->dev, 2, sizeof(*res), GFP_KERNEL); 122 + res = devm_kzalloc(&pdev->dev, sizeof(*res), GFP_KERNEL); 115 123 if (!res) 116 124 return -ENOMEM; 117 125 ··· 127 135 cell->ignore_resource_conflicts = true; 128 136 cell->id = id; 129 137 130 - /* Check if we need to add an IRQ resource */ 131 - if (irq < 0) 132 - return 0; 133 - 134 - res++; 135 - 136 - res->start = irq; 137 - res->end = irq; 138 - res->flags = IORESOURCE_IRQ; 139 - 140 - cell->num_resources++; 141 - 142 138 return 0; 143 139 } 144 140 ··· 138 158 int ret; 139 159 140 160 ret = lpc_sch_populate_cell(dev, SMBASE, "isch_smbus", 141 - info->io_size_smbus, -1, 161 + info->io_size_smbus, 142 162 id->device, &lpc_sch_cells[cells]); 143 163 if (ret < 0) 144 164 return ret; ··· 146 166 cells++; 147 167 148 168 ret = lpc_sch_populate_cell(dev, GPIOBASE, "sch_gpio", 149 - info->io_size_gpio, info->irq_gpio, 169 + info->io_size_gpio, 150 170 id->device, &lpc_sch_cells[cells]); 151 171 if (ret < 0) 152 172 return ret; ··· 154 174 cells++; 155 175 156 176 ret = lpc_sch_populate_cell(dev, WDTBASE, "ie6xx_wdt", 157 - info->io_size_wdt, -1, 177 + info->io_size_wdt, 158 178 id->device, &lpc_sch_cells[cells]); 159 179 if (ret < 0) 160 180 return ret;
+2 -2
drivers/mfd/max8997.c
··· 29 29 static const struct mfd_cell max8997_devs[] = { 30 30 { .name = "max8997-pmic", }, 31 31 { .name = "max8997-rtc", }, 32 - { .name = "max8997-battery", .of_compatible = "maxim,max8997-battery", }, 32 + { .name = "max8997-battery", }, 33 33 { .name = "max8997-haptic", }, 34 - { .name = "max8997-muic", .of_compatible = "maxim,max8997-muic", }, 34 + { .name = "max8997-muic", }, 35 35 { .name = "max8997-led", .id = 1 }, 36 36 { .name = "max8997-led", .id = 2 }, 37 37 };
+10 -19
drivers/mfd/mfd-core.c
··· 65 65 { 66 66 const struct mfd_cell_acpi_match *match = cell->acpi_match; 67 67 struct acpi_device *parent, *child; 68 - struct acpi_device *adev; 68 + struct acpi_device *adev = NULL; 69 69 70 70 parent = ACPI_COMPANION(pdev->dev.parent); 71 71 if (!parent) ··· 77 77 * _ADR or it will use the parent handle if is no ID is given. 78 78 * 79 79 * Note that use of _ADR is a grey area in the ACPI specification, 80 - * though Intel Galileo Gen2 is using it to distinguish the children 81 - * devices. 80 + * though at least Intel Galileo Gen 2 is using it to distinguish 81 + * the children devices. 82 82 */ 83 - adev = parent; 84 83 if (match) { 85 84 if (match->pnpid) { 86 85 struct acpi_device_id ids[2] = {}; ··· 92 93 } 93 94 } 94 95 } else { 95 - unsigned long long adr; 96 - acpi_status status; 97 - 98 - list_for_each_entry(child, &parent->children, node) { 99 - status = acpi_evaluate_integer(child->handle, 100 - "_ADR", NULL, 101 - &adr); 102 - if (ACPI_SUCCESS(status) && match->adr == adr) { 103 - adev = child; 104 - break; 105 - } 106 - } 96 + adev = acpi_find_child_device(parent, match->adr, false); 107 97 } 108 98 } 109 99 110 - ACPI_COMPANION_SET(&pdev->dev, adev); 100 + ACPI_COMPANION_SET(&pdev->dev, adev ?: parent); 111 101 } 112 102 #else 113 103 static inline void mfd_acpi_add_device(const struct mfd_cell *cell, ··· 226 238 goto fail_of_entry; 227 239 } 228 240 229 - if (cell->properties) { 230 - ret = platform_device_add_properties(pdev, cell->properties); 241 + if (cell->swnode) { 242 + ret = device_add_software_node(&pdev->dev, cell->swnode); 231 243 if (ret) 232 244 goto fail_of_entry; 233 245 } ··· 292 304 list_del(&of_entry->list); 293 305 kfree(of_entry); 294 306 } 307 + device_remove_software_node(&pdev->dev); 295 308 fail_alias: 296 309 regulator_bulk_unregister_supply_alias(&pdev->dev, 297 310 cell->parent_supplies, ··· 360 371 361 372 regulator_bulk_unregister_supply_alias(dev, cell->parent_supplies, 362 373 cell->num_parent_supplies); 374 + 375 + device_remove_software_node(&pdev->dev); 363 376 364 377 platform_device_unregister(pdev); 365 378 return 0;
+271
drivers/mfd/ntxec.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * The Netronix embedded controller is a microcontroller found in some 4 + * e-book readers designed by the original design manufacturer Netronix, Inc. 5 + * It contains RTC, battery monitoring, system power management, and PWM 6 + * functionality. 7 + * 8 + * This driver implements register access, version detection, and system 9 + * power-off/reset. 10 + * 11 + * Copyright 2020 Jonathan Neuschäfer <j.neuschaefer@gmx.net> 12 + */ 13 + 14 + #include <linux/delay.h> 15 + #include <linux/errno.h> 16 + #include <linux/i2c.h> 17 + #include <linux/mfd/core.h> 18 + #include <linux/mfd/ntxec.h> 19 + #include <linux/module.h> 20 + #include <linux/pm.h> 21 + #include <linux/reboot.h> 22 + #include <linux/regmap.h> 23 + #include <linux/types.h> 24 + #include <asm/unaligned.h> 25 + 26 + #define NTXEC_REG_VERSION 0x00 27 + #define NTXEC_REG_POWEROFF 0x50 28 + #define NTXEC_REG_POWERKEEP 0x70 29 + #define NTXEC_REG_RESET 0x90 30 + 31 + #define NTXEC_POWEROFF_VALUE 0x0100 32 + #define NTXEC_POWERKEEP_VALUE 0x0800 33 + #define NTXEC_RESET_VALUE 0xff00 34 + 35 + static struct i2c_client *poweroff_restart_client; 36 + 37 + static void ntxec_poweroff(void) 38 + { 39 + int res; 40 + u8 buf[3] = { NTXEC_REG_POWEROFF }; 41 + struct i2c_msg msgs[] = { 42 + { 43 + .addr = poweroff_restart_client->addr, 44 + .flags = 0, 45 + .len = sizeof(buf), 46 + .buf = buf, 47 + }, 48 + }; 49 + 50 + put_unaligned_be16(NTXEC_POWEROFF_VALUE, buf + 1); 51 + 52 + res = i2c_transfer(poweroff_restart_client->adapter, msgs, ARRAY_SIZE(msgs)); 53 + if (res < 0) 54 + dev_warn(&poweroff_restart_client->dev, 55 + "Failed to power off (err = %d)\n", res); 56 + 57 + /* 58 + * The time from the register write until the host CPU is powered off 59 + * has been observed to be about 2.5 to 3 seconds. Sleep long enough to 60 + * safely avoid returning from the poweroff handler. 61 + */ 62 + msleep(5000); 63 + } 64 + 65 + static int ntxec_restart(struct notifier_block *nb, 66 + unsigned long action, void *data) 67 + { 68 + int res; 69 + u8 buf[3] = { NTXEC_REG_RESET }; 70 + /* 71 + * NOTE: The lower half of the reset value is not sent, because sending 72 + * it causes an I2C error. (The reset handler in the downstream driver 73 + * does send the full two-byte value, but doesn't check the result). 74 + */ 75 + struct i2c_msg msgs[] = { 76 + { 77 + .addr = poweroff_restart_client->addr, 78 + .flags = 0, 79 + .len = sizeof(buf) - 1, 80 + .buf = buf, 81 + }, 82 + }; 83 + 84 + put_unaligned_be16(NTXEC_RESET_VALUE, buf + 1); 85 + 86 + res = i2c_transfer(poweroff_restart_client->adapter, msgs, ARRAY_SIZE(msgs)); 87 + if (res < 0) 88 + dev_warn(&poweroff_restart_client->dev, 89 + "Failed to restart (err = %d)\n", res); 90 + 91 + return NOTIFY_DONE; 92 + } 93 + 94 + static struct notifier_block ntxec_restart_handler = { 95 + .notifier_call = ntxec_restart, 96 + .priority = 128, 97 + }; 98 + 99 + static int regmap_ignore_write(void *context, 100 + unsigned int reg, unsigned int val) 101 + 102 + { 103 + struct regmap *regmap = context; 104 + 105 + regmap_write(regmap, reg, val); 106 + 107 + return 0; 108 + } 109 + 110 + static int regmap_wrap_read(void *context, unsigned int reg, 111 + unsigned int *val) 112 + { 113 + struct regmap *regmap = context; 114 + 115 + return regmap_read(regmap, reg, val); 116 + } 117 + 118 + /* 119 + * Some firmware versions do not ack written data, add a wrapper. It 120 + * is used to stack another regmap on top. 121 + */ 122 + static const struct regmap_config regmap_config_noack = { 123 + .name = "ntxec_noack", 124 + .reg_bits = 8, 125 + .val_bits = 16, 126 + .cache_type = REGCACHE_NONE, 127 + .reg_write = regmap_ignore_write, 128 + .reg_read = regmap_wrap_read 129 + }; 130 + 131 + static const struct regmap_config regmap_config = { 132 + .name = "ntxec", 133 + .reg_bits = 8, 134 + .val_bits = 16, 135 + .cache_type = REGCACHE_NONE, 136 + .val_format_endian = REGMAP_ENDIAN_BIG, 137 + }; 138 + 139 + static const struct mfd_cell ntxec_subdev[] = { 140 + { .name = "ntxec-rtc" }, 141 + { .name = "ntxec-pwm" }, 142 + }; 143 + 144 + static const struct mfd_cell ntxec_subdev_pwm[] = { 145 + { .name = "ntxec-pwm" }, 146 + }; 147 + 148 + static int ntxec_probe(struct i2c_client *client) 149 + { 150 + struct ntxec *ec; 151 + unsigned int version; 152 + int res; 153 + const struct mfd_cell *subdevs; 154 + size_t n_subdevs; 155 + 156 + ec = devm_kmalloc(&client->dev, sizeof(*ec), GFP_KERNEL); 157 + if (!ec) 158 + return -ENOMEM; 159 + 160 + ec->dev = &client->dev; 161 + 162 + ec->regmap = devm_regmap_init_i2c(client, &regmap_config); 163 + if (IS_ERR(ec->regmap)) { 164 + dev_err(ec->dev, "Failed to set up regmap for device\n"); 165 + return PTR_ERR(ec->regmap); 166 + } 167 + 168 + /* Determine the firmware version */ 169 + res = regmap_read(ec->regmap, NTXEC_REG_VERSION, &version); 170 + if (res < 0) { 171 + dev_err(ec->dev, "Failed to read firmware version number\n"); 172 + return res; 173 + } 174 + 175 + /* Bail out if we encounter an unknown firmware version */ 176 + switch (version) { 177 + case NTXEC_VERSION_KOBO_AURA: 178 + subdevs = ntxec_subdev; 179 + n_subdevs = ARRAY_SIZE(ntxec_subdev); 180 + break; 181 + case NTXEC_VERSION_TOLINO_SHINE2: 182 + subdevs = ntxec_subdev_pwm; 183 + n_subdevs = ARRAY_SIZE(ntxec_subdev_pwm); 184 + /* Another regmap stacked on top of the other */ 185 + ec->regmap = devm_regmap_init(ec->dev, NULL, 186 + ec->regmap, 187 + &regmap_config_noack); 188 + if (IS_ERR(ec->regmap)) 189 + return PTR_ERR(ec->regmap); 190 + break; 191 + default: 192 + dev_err(ec->dev, 193 + "Netronix embedded controller version %04x is not supported.\n", 194 + version); 195 + return -ENODEV; 196 + } 197 + 198 + dev_info(ec->dev, 199 + "Netronix embedded controller version %04x detected.\n", version); 200 + 201 + if (of_device_is_system_power_controller(ec->dev->of_node)) { 202 + /* 203 + * Set the 'powerkeep' bit. This is necessary on some boards 204 + * in order to keep the system running. 205 + */ 206 + res = regmap_write(ec->regmap, NTXEC_REG_POWERKEEP, 207 + NTXEC_POWERKEEP_VALUE); 208 + if (res < 0) 209 + return res; 210 + 211 + if (poweroff_restart_client) 212 + /* 213 + * Another instance of the driver already took 214 + * poweroff/restart duties. 215 + */ 216 + dev_err(ec->dev, "poweroff_restart_client already assigned\n"); 217 + else 218 + poweroff_restart_client = client; 219 + 220 + if (pm_power_off) 221 + /* Another driver already registered a poweroff handler. */ 222 + dev_err(ec->dev, "pm_power_off already assigned\n"); 223 + else 224 + pm_power_off = ntxec_poweroff; 225 + 226 + res = register_restart_handler(&ntxec_restart_handler); 227 + if (res) 228 + dev_err(ec->dev, 229 + "Failed to register restart handler: %d\n", res); 230 + } 231 + 232 + i2c_set_clientdata(client, ec); 233 + 234 + res = devm_mfd_add_devices(ec->dev, PLATFORM_DEVID_NONE, 235 + subdevs, n_subdevs, NULL, 0, NULL); 236 + if (res) 237 + dev_err(ec->dev, "Failed to add subdevices: %d\n", res); 238 + 239 + return res; 240 + } 241 + 242 + static int ntxec_remove(struct i2c_client *client) 243 + { 244 + if (client == poweroff_restart_client) { 245 + poweroff_restart_client = NULL; 246 + pm_power_off = NULL; 247 + unregister_restart_handler(&ntxec_restart_handler); 248 + } 249 + 250 + return 0; 251 + } 252 + 253 + static const struct of_device_id of_ntxec_match_table[] = { 254 + { .compatible = "netronix,ntxec", }, 255 + {} 256 + }; 257 + MODULE_DEVICE_TABLE(of, of_ntxec_match_table); 258 + 259 + static struct i2c_driver ntxec_driver = { 260 + .driver = { 261 + .name = "ntxec", 262 + .of_match_table = of_ntxec_match_table, 263 + }, 264 + .probe_new = ntxec_probe, 265 + .remove = ntxec_remove, 266 + }; 267 + module_i2c_driver(ntxec_driver); 268 + 269 + MODULE_AUTHOR("Jonathan Neuschäfer <j.neuschaefer@gmx.net>"); 270 + MODULE_DESCRIPTION("Core driver for Netronix EC"); 271 + MODULE_LICENSE("GPL");
+3
drivers/mfd/rn5t618.c
··· 45 45 case RN5T618_INTMON: 46 46 case RN5T618_RTC_CTRL1 ... RN5T618_RTC_CTRL2: 47 47 case RN5T618_RTC_SECONDS ... RN5T618_RTC_YEAR: 48 + case RN5T618_CHGCTL1: 49 + case RN5T618_REGISET1 ... RN5T618_REGISET2: 48 50 case RN5T618_CHGSTATE: 49 51 case RN5T618_CHGCTRL_IRR ... RN5T618_CHGERR_MONI: 52 + case RN5T618_GCHGDET: 50 53 case RN5T618_CONTROL ... RN5T618_CC_AVEREG0: 51 54 return true; 52 55 default:
+362 -128
drivers/mfd/rohm-bd71828.c
··· 2 2 // 3 3 // Copyright (C) 2019 ROHM Semiconductors 4 4 // 5 - // ROHM BD71828 PMIC driver 5 + // ROHM BD71828/BD71815 PMIC driver 6 6 7 7 #include <linux/gpio_keys.h> 8 8 #include <linux/i2c.h> ··· 11 11 #include <linux/ioport.h> 12 12 #include <linux/irq.h> 13 13 #include <linux/mfd/core.h> 14 + #include <linux/mfd/rohm-bd71815.h> 14 15 #include <linux/mfd/rohm-bd71828.h> 16 + #include <linux/mfd/rohm-generic.h> 15 17 #include <linux/module.h> 16 18 #include <linux/of_device.h> 17 19 #include <linux/regmap.h> ··· 31 29 .name = "bd71828-pwrkey", 32 30 }; 33 31 34 - static const struct resource rtc_irqs[] = { 32 + static const struct resource bd71815_rtc_irqs[] = { 33 + DEFINE_RES_IRQ_NAMED(BD71815_INT_RTC0, "bd71815-rtc-alm-0"), 34 + DEFINE_RES_IRQ_NAMED(BD71815_INT_RTC1, "bd71815-rtc-alm-1"), 35 + DEFINE_RES_IRQ_NAMED(BD71815_INT_RTC2, "bd71815-rtc-alm-2"), 36 + }; 37 + 38 + static const struct resource bd71828_rtc_irqs[] = { 35 39 DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC0, "bd71828-rtc-alm-0"), 36 40 DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC1, "bd71828-rtc-alm-1"), 37 41 DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC2, "bd71828-rtc-alm-2"), 42 + }; 43 + 44 + static struct resource bd71815_power_irqs[] = { 45 + DEFINE_RES_IRQ_NAMED(BD71815_INT_DCIN_RMV, "bd71815-dcin-rmv"), 46 + DEFINE_RES_IRQ_NAMED(BD71815_INT_CLPS_OUT, "bd71815-clps-out"), 47 + DEFINE_RES_IRQ_NAMED(BD71815_INT_CLPS_IN, "bd71815-clps-in"), 48 + DEFINE_RES_IRQ_NAMED(BD71815_INT_DCIN_OVP_RES, "bd71815-dcin-ovp-res"), 49 + DEFINE_RES_IRQ_NAMED(BD71815_INT_DCIN_OVP_DET, "bd71815-dcin-ovp-det"), 50 + DEFINE_RES_IRQ_NAMED(BD71815_INT_DCIN_MON_RES, "bd71815-dcin-mon-res"), 51 + DEFINE_RES_IRQ_NAMED(BD71815_INT_DCIN_MON_DET, "bd71815-dcin-mon-det"), 52 + DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_UV_RES, "bd71815-vsys-uv-res"), 53 + DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_UV_DET, "bd71815-vsys-uv-det"), 54 + DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_LOW_RES, "bd71815-vsys-low-res"), 55 + DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_LOW_DET, "bd71815-vsys-low-det"), 56 + DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_MON_RES, "bd71815-vsys-mon-res"), 57 + DEFINE_RES_IRQ_NAMED(BD71815_INT_VSYS_MON_RES, "bd71815-vsys-mon-det"), 58 + DEFINE_RES_IRQ_NAMED(BD71815_INT_CHG_WDG_TEMP, "bd71815-chg-wdg-temp"), 59 + DEFINE_RES_IRQ_NAMED(BD71815_INT_CHG_WDG_TIME, "bd71815-chg-wdg"), 60 + DEFINE_RES_IRQ_NAMED(BD71815_INT_CHG_RECHARGE_RES, "bd71815-rechg-res"), 61 + DEFINE_RES_IRQ_NAMED(BD71815_INT_CHG_RECHARGE_DET, "bd71815-rechg-det"), 62 + DEFINE_RES_IRQ_NAMED(BD71815_INT_CHG_RANGED_TEMP_TRANSITION, "bd71815-ranged-temp-transit"), 63 + DEFINE_RES_IRQ_NAMED(BD71815_INT_CHG_STATE_TRANSITION, "bd71815-chg-state-change"), 64 + DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_TEMP_NORMAL, "bd71815-bat-temp-normal"), 65 + DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_TEMP_ERANGE, "bd71815-bat-temp-erange"), 66 + DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_REMOVED, "bd71815-bat-rmv"), 67 + DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_DETECTED, "bd71815-bat-det"), 68 + DEFINE_RES_IRQ_NAMED(BD71815_INT_THERM_REMOVED, "bd71815-therm-rmv"), 69 + DEFINE_RES_IRQ_NAMED(BD71815_INT_THERM_DETECTED, "bd71815-therm-det"), 70 + DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_DEAD, "bd71815-bat-dead"), 71 + DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_SHORTC_RES, "bd71815-bat-short-res"), 72 + DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_SHORTC_DET, "bd71815-bat-short-det"), 73 + DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_LOW_VOLT_RES, "bd71815-bat-low-res"), 74 + DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_LOW_VOLT_DET, "bd71815-bat-low-det"), 75 + DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_VOLT_RES, "bd71815-bat-over-res"), 76 + DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_VOLT_DET, "bd71815-bat-over-det"), 77 + DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_MON_RES, "bd71815-bat-mon-res"), 78 + DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_MON_DET, "bd71815-bat-mon-det"), 79 + DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_CC_MON1, "bd71815-bat-cc-mon1"), 80 + DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_CC_MON2, "bd71815-bat-cc-mon2"), 81 + DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_CC_MON3, "bd71815-bat-cc-mon3"), 82 + DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_CURR_1_RES, "bd71815-bat-oc1-res"), 83 + DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_CURR_1_DET, "bd71815-bat-oc1-det"), 84 + DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_CURR_2_RES, "bd71815-bat-oc2-res"), 85 + DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_CURR_2_DET, "bd71815-bat-oc2-det"), 86 + DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_CURR_3_RES, "bd71815-bat-oc3-res"), 87 + DEFINE_RES_IRQ_NAMED(BD71815_INT_BAT_OVER_CURR_3_DET, "bd71815-bat-oc3-det"), 88 + DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_LOW_RES, "bd71815-bat-low-res"), 89 + DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_LOW_DET, "bd71815-bat-low-det"), 90 + DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_HI_RES, "bd71815-bat-hi-res"), 91 + DEFINE_RES_IRQ_NAMED(BD71815_INT_TEMP_BAT_HI_DET, "bd71815-bat-hi-det"), 92 + }; 93 + 94 + static struct mfd_cell bd71815_mfd_cells[] = { 95 + { .name = "bd71815-pmic", }, 96 + { .name = "bd71815-clk", }, 97 + { .name = "bd71815-gpo", }, 98 + { 99 + .name = "bd71815-power", 100 + .num_resources = ARRAY_SIZE(bd71815_power_irqs), 101 + .resources = &bd71815_power_irqs[0], 102 + }, 103 + { 104 + .name = "bd71815-rtc", 105 + .num_resources = ARRAY_SIZE(bd71815_rtc_irqs), 106 + .resources = &bd71815_rtc_irqs[0], 107 + }, 38 108 }; 39 109 40 110 static struct mfd_cell bd71828_mfd_cells[] = { ··· 121 47 { .name = "bd71827-power", }, 122 48 { 123 49 .name = "bd71828-rtc", 124 - .resources = rtc_irqs, 125 - .num_resources = ARRAY_SIZE(rtc_irqs), 50 + .resources = bd71828_rtc_irqs, 51 + .num_resources = ARRAY_SIZE(bd71828_rtc_irqs), 126 52 }, { 127 53 .name = "gpio-keys", 128 54 .platform_data = &bd71828_powerkey_data, ··· 130 56 }, 131 57 }; 132 58 133 - static const struct regmap_range volatile_ranges[] = { 59 + static const struct regmap_range bd71815_volatile_ranges[] = { 60 + { 61 + .range_min = BD71815_REG_SEC, 62 + .range_max = BD71815_REG_YEAR, 63 + }, { 64 + .range_min = BD71815_REG_CONF, 65 + .range_max = BD71815_REG_BAT_TEMP, 66 + }, { 67 + .range_min = BD71815_REG_VM_IBAT_U, 68 + .range_max = BD71815_REG_CC_CTRL, 69 + }, { 70 + .range_min = BD71815_REG_CC_STAT, 71 + .range_max = BD71815_REG_CC_CURCD_L, 72 + }, { 73 + .range_min = BD71815_REG_VM_BTMP_MON, 74 + .range_max = BD71815_REG_VM_BTMP_MON, 75 + }, { 76 + .range_min = BD71815_REG_INT_STAT, 77 + .range_max = BD71815_REG_INT_UPDATE, 78 + }, { 79 + .range_min = BD71815_REG_VM_VSYS_U, 80 + .range_max = BD71815_REG_REX_CTRL_1, 81 + }, { 82 + .range_min = BD71815_REG_FULL_CCNTD_3, 83 + .range_max = BD71815_REG_CCNTD_CHG_2, 84 + }, 85 + }; 86 + 87 + static const struct regmap_range bd71828_volatile_ranges[] = { 134 88 { 135 89 .range_min = BD71828_REG_PS_CTRL_1, 136 90 .range_max = BD71828_REG_PS_CTRL_1, ··· 182 80 }, 183 81 }; 184 82 185 - static const struct regmap_access_table volatile_regs = { 186 - .yes_ranges = &volatile_ranges[0], 187 - .n_yes_ranges = ARRAY_SIZE(volatile_ranges), 83 + static const struct regmap_access_table bd71815_volatile_regs = { 84 + .yes_ranges = &bd71815_volatile_ranges[0], 85 + .n_yes_ranges = ARRAY_SIZE(bd71815_volatile_ranges), 188 86 }; 189 87 190 - static struct regmap_config bd71828_regmap = { 88 + static const struct regmap_access_table bd71828_volatile_regs = { 89 + .yes_ranges = &bd71828_volatile_ranges[0], 90 + .n_yes_ranges = ARRAY_SIZE(bd71828_volatile_ranges), 91 + }; 92 + 93 + static const struct regmap_config bd71815_regmap = { 191 94 .reg_bits = 8, 192 95 .val_bits = 8, 193 - .volatile_table = &volatile_regs, 96 + .volatile_table = &bd71815_volatile_regs, 97 + .max_register = BD71815_MAX_REGISTER - 1, 98 + .cache_type = REGCACHE_RBTREE, 99 + }; 100 + 101 + static const struct regmap_config bd71828_regmap = { 102 + .reg_bits = 8, 103 + .val_bits = 8, 104 + .volatile_table = &bd71828_volatile_regs, 194 105 .max_register = BD71828_MAX_REGISTER, 195 106 .cache_type = REGCACHE_RBTREE, 196 107 }; ··· 211 96 /* 212 97 * Mapping of main IRQ register bits to sub-IRQ register offsets so that we can 213 98 * access corect sub-IRQ registers based on bits that are set in main IRQ 214 - * register. 99 + * register. BD71815 and BD71828 have same sub-register-block offests. 215 100 */ 216 101 217 102 static unsigned int bit0_offsets[] = {11}; /* RTC IRQ */ ··· 223 108 static unsigned int bit6_offsets[] = {1, 2}; /* DCIN IRQ */ 224 109 static unsigned int bit7_offsets[] = {0}; /* BUCK IRQ */ 225 110 226 - static struct regmap_irq_sub_irq_map bd71828_sub_irq_offsets[] = { 111 + static struct regmap_irq_sub_irq_map bd718xx_sub_irq_offsets[] = { 227 112 REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets), 228 113 REGMAP_IRQ_MAIN_REG_OFFSET(bit1_offsets), 229 114 REGMAP_IRQ_MAIN_REG_OFFSET(bit2_offsets), ··· 232 117 REGMAP_IRQ_MAIN_REG_OFFSET(bit5_offsets), 233 118 REGMAP_IRQ_MAIN_REG_OFFSET(bit6_offsets), 234 119 REGMAP_IRQ_MAIN_REG_OFFSET(bit7_offsets), 120 + }; 121 + 122 + static const struct regmap_irq bd71815_irqs[] = { 123 + REGMAP_IRQ_REG(BD71815_INT_BUCK1_OCP, 0, BD71815_INT_BUCK1_OCP_MASK), 124 + REGMAP_IRQ_REG(BD71815_INT_BUCK2_OCP, 0, BD71815_INT_BUCK2_OCP_MASK), 125 + REGMAP_IRQ_REG(BD71815_INT_BUCK3_OCP, 0, BD71815_INT_BUCK3_OCP_MASK), 126 + REGMAP_IRQ_REG(BD71815_INT_BUCK4_OCP, 0, BD71815_INT_BUCK4_OCP_MASK), 127 + REGMAP_IRQ_REG(BD71815_INT_BUCK5_OCP, 0, BD71815_INT_BUCK5_OCP_MASK), 128 + REGMAP_IRQ_REG(BD71815_INT_LED_OVP, 0, BD71815_INT_LED_OVP_MASK), 129 + REGMAP_IRQ_REG(BD71815_INT_LED_OCP, 0, BD71815_INT_LED_OCP_MASK), 130 + REGMAP_IRQ_REG(BD71815_INT_LED_SCP, 0, BD71815_INT_LED_SCP_MASK), 131 + /* DCIN1 interrupts */ 132 + REGMAP_IRQ_REG(BD71815_INT_DCIN_RMV, 1, BD71815_INT_DCIN_RMV_MASK), 133 + REGMAP_IRQ_REG(BD71815_INT_CLPS_OUT, 1, BD71815_INT_CLPS_OUT_MASK), 134 + REGMAP_IRQ_REG(BD71815_INT_CLPS_IN, 1, BD71815_INT_CLPS_IN_MASK), 135 + REGMAP_IRQ_REG(BD71815_INT_DCIN_OVP_RES, 1, BD71815_INT_DCIN_OVP_RES_MASK), 136 + REGMAP_IRQ_REG(BD71815_INT_DCIN_OVP_DET, 1, BD71815_INT_DCIN_OVP_DET_MASK), 137 + /* DCIN2 interrupts */ 138 + REGMAP_IRQ_REG(BD71815_INT_DCIN_MON_RES, 2, BD71815_INT_DCIN_MON_RES_MASK), 139 + REGMAP_IRQ_REG(BD71815_INT_DCIN_MON_DET, 2, BD71815_INT_DCIN_MON_DET_MASK), 140 + REGMAP_IRQ_REG(BD71815_INT_WDOG, 2, BD71815_INT_WDOG_MASK), 141 + /* Vsys */ 142 + REGMAP_IRQ_REG(BD71815_INT_VSYS_UV_RES, 3, BD71815_INT_VSYS_UV_RES_MASK), 143 + REGMAP_IRQ_REG(BD71815_INT_VSYS_UV_DET, 3, BD71815_INT_VSYS_UV_DET_MASK), 144 + REGMAP_IRQ_REG(BD71815_INT_VSYS_LOW_RES, 3, BD71815_INT_VSYS_LOW_RES_MASK), 145 + REGMAP_IRQ_REG(BD71815_INT_VSYS_LOW_DET, 3, BD71815_INT_VSYS_LOW_DET_MASK), 146 + REGMAP_IRQ_REG(BD71815_INT_VSYS_MON_RES, 3, BD71815_INT_VSYS_MON_RES_MASK), 147 + REGMAP_IRQ_REG(BD71815_INT_VSYS_MON_DET, 3, BD71815_INT_VSYS_MON_DET_MASK), 148 + /* Charger */ 149 + REGMAP_IRQ_REG(BD71815_INT_CHG_WDG_TEMP, 4, BD71815_INT_CHG_WDG_TEMP_MASK), 150 + REGMAP_IRQ_REG(BD71815_INT_CHG_WDG_TIME, 4, BD71815_INT_CHG_WDG_TIME_MASK), 151 + REGMAP_IRQ_REG(BD71815_INT_CHG_RECHARGE_RES, 4, BD71815_INT_CHG_RECHARGE_RES_MASK), 152 + REGMAP_IRQ_REG(BD71815_INT_CHG_RECHARGE_DET, 4, BD71815_INT_CHG_RECHARGE_DET_MASK), 153 + REGMAP_IRQ_REG(BD71815_INT_CHG_RANGED_TEMP_TRANSITION, 4, 154 + BD71815_INT_CHG_RANGED_TEMP_TRANSITION_MASK), 155 + REGMAP_IRQ_REG(BD71815_INT_CHG_STATE_TRANSITION, 4, BD71815_INT_CHG_STATE_TRANSITION_MASK), 156 + /* Battery */ 157 + REGMAP_IRQ_REG(BD71815_INT_BAT_TEMP_NORMAL, 5, BD71815_INT_BAT_TEMP_NORMAL_MASK), 158 + REGMAP_IRQ_REG(BD71815_INT_BAT_TEMP_ERANGE, 5, BD71815_INT_BAT_TEMP_ERANGE_MASK), 159 + REGMAP_IRQ_REG(BD71815_INT_BAT_REMOVED, 5, BD71815_INT_BAT_REMOVED_MASK), 160 + REGMAP_IRQ_REG(BD71815_INT_BAT_DETECTED, 5, BD71815_INT_BAT_DETECTED_MASK), 161 + REGMAP_IRQ_REG(BD71815_INT_THERM_REMOVED, 5, BD71815_INT_THERM_REMOVED_MASK), 162 + REGMAP_IRQ_REG(BD71815_INT_THERM_DETECTED, 5, BD71815_INT_THERM_DETECTED_MASK), 163 + /* Battery Mon 1 */ 164 + REGMAP_IRQ_REG(BD71815_INT_BAT_DEAD, 6, BD71815_INT_BAT_DEAD_MASK), 165 + REGMAP_IRQ_REG(BD71815_INT_BAT_SHORTC_RES, 6, BD71815_INT_BAT_SHORTC_RES_MASK), 166 + REGMAP_IRQ_REG(BD71815_INT_BAT_SHORTC_DET, 6, BD71815_INT_BAT_SHORTC_DET_MASK), 167 + REGMAP_IRQ_REG(BD71815_INT_BAT_LOW_VOLT_RES, 6, BD71815_INT_BAT_LOW_VOLT_RES_MASK), 168 + REGMAP_IRQ_REG(BD71815_INT_BAT_LOW_VOLT_DET, 6, BD71815_INT_BAT_LOW_VOLT_DET_MASK), 169 + REGMAP_IRQ_REG(BD71815_INT_BAT_OVER_VOLT_RES, 6, BD71815_INT_BAT_OVER_VOLT_RES_MASK), 170 + REGMAP_IRQ_REG(BD71815_INT_BAT_OVER_VOLT_DET, 6, BD71815_INT_BAT_OVER_VOLT_DET_MASK), 171 + /* Battery Mon 2 */ 172 + REGMAP_IRQ_REG(BD71815_INT_BAT_MON_RES, 7, BD71815_INT_BAT_MON_RES_MASK), 173 + REGMAP_IRQ_REG(BD71815_INT_BAT_MON_DET, 7, BD71815_INT_BAT_MON_DET_MASK), 174 + /* Battery Mon 3 (Coulomb counter) */ 175 + REGMAP_IRQ_REG(BD71815_INT_BAT_CC_MON1, 8, BD71815_INT_BAT_CC_MON1_MASK), 176 + REGMAP_IRQ_REG(BD71815_INT_BAT_CC_MON2, 8, BD71815_INT_BAT_CC_MON2_MASK), 177 + REGMAP_IRQ_REG(BD71815_INT_BAT_CC_MON3, 8, BD71815_INT_BAT_CC_MON3_MASK), 178 + /* Battery Mon 4 */ 179 + REGMAP_IRQ_REG(BD71815_INT_BAT_OVER_CURR_1_RES, 9, BD71815_INT_BAT_OVER_CURR_1_RES_MASK), 180 + REGMAP_IRQ_REG(BD71815_INT_BAT_OVER_CURR_1_DET, 9, BD71815_INT_BAT_OVER_CURR_1_DET_MASK), 181 + REGMAP_IRQ_REG(BD71815_INT_BAT_OVER_CURR_2_RES, 9, BD71815_INT_BAT_OVER_CURR_2_RES_MASK), 182 + REGMAP_IRQ_REG(BD71815_INT_BAT_OVER_CURR_2_DET, 9, BD71815_INT_BAT_OVER_CURR_2_DET_MASK), 183 + REGMAP_IRQ_REG(BD71815_INT_BAT_OVER_CURR_3_RES, 9, BD71815_INT_BAT_OVER_CURR_3_RES_MASK), 184 + REGMAP_IRQ_REG(BD71815_INT_BAT_OVER_CURR_3_DET, 9, BD71815_INT_BAT_OVER_CURR_3_DET_MASK), 185 + /* Temperature */ 186 + REGMAP_IRQ_REG(BD71815_INT_TEMP_BAT_LOW_RES, 10, BD71815_INT_TEMP_BAT_LOW_RES_MASK), 187 + REGMAP_IRQ_REG(BD71815_INT_TEMP_BAT_LOW_DET, 10, BD71815_INT_TEMP_BAT_LOW_DET_MASK), 188 + REGMAP_IRQ_REG(BD71815_INT_TEMP_BAT_HI_RES, 10, BD71815_INT_TEMP_BAT_HI_RES_MASK), 189 + REGMAP_IRQ_REG(BD71815_INT_TEMP_BAT_HI_DET, 10, BD71815_INT_TEMP_BAT_HI_DET_MASK), 190 + REGMAP_IRQ_REG(BD71815_INT_TEMP_CHIP_OVER_125_RES, 10, 191 + BD71815_INT_TEMP_CHIP_OVER_125_RES_MASK), 192 + REGMAP_IRQ_REG(BD71815_INT_TEMP_CHIP_OVER_125_DET, 10, 193 + BD71815_INT_TEMP_CHIP_OVER_125_DET_MASK), 194 + REGMAP_IRQ_REG(BD71815_INT_TEMP_CHIP_OVER_VF_RES, 10, 195 + BD71815_INT_TEMP_CHIP_OVER_VF_RES_MASK), 196 + REGMAP_IRQ_REG(BD71815_INT_TEMP_CHIP_OVER_VF_DET, 10, 197 + BD71815_INT_TEMP_CHIP_OVER_VF_DET_MASK), 198 + /* RTC Alarm */ 199 + REGMAP_IRQ_REG(BD71815_INT_RTC0, 11, BD71815_INT_RTC0_MASK), 200 + REGMAP_IRQ_REG(BD71815_INT_RTC1, 11, BD71815_INT_RTC1_MASK), 201 + REGMAP_IRQ_REG(BD71815_INT_RTC2, 11, BD71815_INT_RTC2_MASK), 235 202 }; 236 203 237 204 static struct regmap_irq bd71828_irqs[] = { ··· 331 134 REGMAP_IRQ_REG(BD71828_INT_CLPS_OUT, 1, BD71828_INT_CLPS_OUT_MASK), 332 135 REGMAP_IRQ_REG(BD71828_INT_CLPS_IN, 1, BD71828_INT_CLPS_IN_MASK), 333 136 /* DCIN2 interrupts */ 334 - REGMAP_IRQ_REG(BD71828_INT_DCIN_MON_RES, 2, 335 - BD71828_INT_DCIN_MON_RES_MASK), 336 - REGMAP_IRQ_REG(BD71828_INT_DCIN_MON_DET, 2, 337 - BD71828_INT_DCIN_MON_DET_MASK), 137 + REGMAP_IRQ_REG(BD71828_INT_DCIN_MON_RES, 2, BD71828_INT_DCIN_MON_RES_MASK), 138 + REGMAP_IRQ_REG(BD71828_INT_DCIN_MON_DET, 2, BD71828_INT_DCIN_MON_DET_MASK), 338 139 REGMAP_IRQ_REG(BD71828_INT_LONGPUSH, 2, BD71828_INT_LONGPUSH_MASK), 339 140 REGMAP_IRQ_REG(BD71828_INT_MIDPUSH, 2, BD71828_INT_MIDPUSH_MASK), 340 141 REGMAP_IRQ_REG(BD71828_INT_SHORTPUSH, 2, BD71828_INT_SHORTPUSH_MASK), ··· 340 145 REGMAP_IRQ_REG(BD71828_INT_WDOG, 2, BD71828_INT_WDOG_MASK), 341 146 REGMAP_IRQ_REG(BD71828_INT_SWRESET, 2, BD71828_INT_SWRESET_MASK), 342 147 /* Vsys */ 343 - REGMAP_IRQ_REG(BD71828_INT_VSYS_UV_RES, 3, 344 - BD71828_INT_VSYS_UV_RES_MASK), 345 - REGMAP_IRQ_REG(BD71828_INT_VSYS_UV_DET, 3, 346 - BD71828_INT_VSYS_UV_DET_MASK), 347 - REGMAP_IRQ_REG(BD71828_INT_VSYS_LOW_RES, 3, 348 - BD71828_INT_VSYS_LOW_RES_MASK), 349 - REGMAP_IRQ_REG(BD71828_INT_VSYS_LOW_DET, 3, 350 - BD71828_INT_VSYS_LOW_DET_MASK), 351 - REGMAP_IRQ_REG(BD71828_INT_VSYS_HALL_IN, 3, 352 - BD71828_INT_VSYS_HALL_IN_MASK), 353 - REGMAP_IRQ_REG(BD71828_INT_VSYS_HALL_TOGGLE, 3, 354 - BD71828_INT_VSYS_HALL_TOGGLE_MASK), 355 - REGMAP_IRQ_REG(BD71828_INT_VSYS_MON_RES, 3, 356 - BD71828_INT_VSYS_MON_RES_MASK), 357 - REGMAP_IRQ_REG(BD71828_INT_VSYS_MON_DET, 3, 358 - BD71828_INT_VSYS_MON_DET_MASK), 148 + REGMAP_IRQ_REG(BD71828_INT_VSYS_UV_RES, 3, BD71828_INT_VSYS_UV_RES_MASK), 149 + REGMAP_IRQ_REG(BD71828_INT_VSYS_UV_DET, 3, BD71828_INT_VSYS_UV_DET_MASK), 150 + REGMAP_IRQ_REG(BD71828_INT_VSYS_LOW_RES, 3, BD71828_INT_VSYS_LOW_RES_MASK), 151 + REGMAP_IRQ_REG(BD71828_INT_VSYS_LOW_DET, 3, BD71828_INT_VSYS_LOW_DET_MASK), 152 + REGMAP_IRQ_REG(BD71828_INT_VSYS_HALL_IN, 3, BD71828_INT_VSYS_HALL_IN_MASK), 153 + REGMAP_IRQ_REG(BD71828_INT_VSYS_HALL_TOGGLE, 3, BD71828_INT_VSYS_HALL_TOGGLE_MASK), 154 + REGMAP_IRQ_REG(BD71828_INT_VSYS_MON_RES, 3, BD71828_INT_VSYS_MON_RES_MASK), 155 + REGMAP_IRQ_REG(BD71828_INT_VSYS_MON_DET, 3, BD71828_INT_VSYS_MON_DET_MASK), 359 156 /* Charger */ 360 - REGMAP_IRQ_REG(BD71828_INT_CHG_DCIN_ILIM, 4, 361 - BD71828_INT_CHG_DCIN_ILIM_MASK), 362 - REGMAP_IRQ_REG(BD71828_INT_CHG_TOPOFF_TO_DONE, 4, 363 - BD71828_INT_CHG_TOPOFF_TO_DONE_MASK), 364 - REGMAP_IRQ_REG(BD71828_INT_CHG_WDG_TEMP, 4, 365 - BD71828_INT_CHG_WDG_TEMP_MASK), 366 - REGMAP_IRQ_REG(BD71828_INT_CHG_WDG_TIME, 4, 367 - BD71828_INT_CHG_WDG_TIME_MASK), 368 - REGMAP_IRQ_REG(BD71828_INT_CHG_RECHARGE_RES, 4, 369 - BD71828_INT_CHG_RECHARGE_RES_MASK), 370 - REGMAP_IRQ_REG(BD71828_INT_CHG_RECHARGE_DET, 4, 371 - BD71828_INT_CHG_RECHARGE_DET_MASK), 157 + REGMAP_IRQ_REG(BD71828_INT_CHG_DCIN_ILIM, 4, BD71828_INT_CHG_DCIN_ILIM_MASK), 158 + REGMAP_IRQ_REG(BD71828_INT_CHG_TOPOFF_TO_DONE, 4, BD71828_INT_CHG_TOPOFF_TO_DONE_MASK), 159 + REGMAP_IRQ_REG(BD71828_INT_CHG_WDG_TEMP, 4, BD71828_INT_CHG_WDG_TEMP_MASK), 160 + REGMAP_IRQ_REG(BD71828_INT_CHG_WDG_TIME, 4, BD71828_INT_CHG_WDG_TIME_MASK), 161 + REGMAP_IRQ_REG(BD71828_INT_CHG_RECHARGE_RES, 4, BD71828_INT_CHG_RECHARGE_RES_MASK), 162 + REGMAP_IRQ_REG(BD71828_INT_CHG_RECHARGE_DET, 4, BD71828_INT_CHG_RECHARGE_DET_MASK), 372 163 REGMAP_IRQ_REG(BD71828_INT_CHG_RANGED_TEMP_TRANSITION, 4, 373 164 BD71828_INT_CHG_RANGED_TEMP_TRANSITION_MASK), 374 - REGMAP_IRQ_REG(BD71828_INT_CHG_STATE_TRANSITION, 4, 375 - BD71828_INT_CHG_STATE_TRANSITION_MASK), 165 + REGMAP_IRQ_REG(BD71828_INT_CHG_STATE_TRANSITION, 4, BD71828_INT_CHG_STATE_TRANSITION_MASK), 376 166 /* Battery */ 377 - REGMAP_IRQ_REG(BD71828_INT_BAT_TEMP_NORMAL, 5, 378 - BD71828_INT_BAT_TEMP_NORMAL_MASK), 379 - REGMAP_IRQ_REG(BD71828_INT_BAT_TEMP_ERANGE, 5, 380 - BD71828_INT_BAT_TEMP_ERANGE_MASK), 381 - REGMAP_IRQ_REG(BD71828_INT_BAT_TEMP_WARN, 5, 382 - BD71828_INT_BAT_TEMP_WARN_MASK), 383 - REGMAP_IRQ_REG(BD71828_INT_BAT_REMOVED, 5, 384 - BD71828_INT_BAT_REMOVED_MASK), 385 - REGMAP_IRQ_REG(BD71828_INT_BAT_DETECTED, 5, 386 - BD71828_INT_BAT_DETECTED_MASK), 387 - REGMAP_IRQ_REG(BD71828_INT_THERM_REMOVED, 5, 388 - BD71828_INT_THERM_REMOVED_MASK), 389 - REGMAP_IRQ_REG(BD71828_INT_THERM_DETECTED, 5, 390 - BD71828_INT_THERM_DETECTED_MASK), 167 + REGMAP_IRQ_REG(BD71828_INT_BAT_TEMP_NORMAL, 5, BD71828_INT_BAT_TEMP_NORMAL_MASK), 168 + REGMAP_IRQ_REG(BD71828_INT_BAT_TEMP_ERANGE, 5, BD71828_INT_BAT_TEMP_ERANGE_MASK), 169 + REGMAP_IRQ_REG(BD71828_INT_BAT_TEMP_WARN, 5, BD71828_INT_BAT_TEMP_WARN_MASK), 170 + REGMAP_IRQ_REG(BD71828_INT_BAT_REMOVED, 5, BD71828_INT_BAT_REMOVED_MASK), 171 + REGMAP_IRQ_REG(BD71828_INT_BAT_DETECTED, 5, BD71828_INT_BAT_DETECTED_MASK), 172 + REGMAP_IRQ_REG(BD71828_INT_THERM_REMOVED, 5, BD71828_INT_THERM_REMOVED_MASK), 173 + REGMAP_IRQ_REG(BD71828_INT_THERM_DETECTED, 5, BD71828_INT_THERM_DETECTED_MASK), 391 174 /* Battery Mon 1 */ 392 175 REGMAP_IRQ_REG(BD71828_INT_BAT_DEAD, 6, BD71828_INT_BAT_DEAD_MASK), 393 - REGMAP_IRQ_REG(BD71828_INT_BAT_SHORTC_RES, 6, 394 - BD71828_INT_BAT_SHORTC_RES_MASK), 395 - REGMAP_IRQ_REG(BD71828_INT_BAT_SHORTC_DET, 6, 396 - BD71828_INT_BAT_SHORTC_DET_MASK), 397 - REGMAP_IRQ_REG(BD71828_INT_BAT_LOW_VOLT_RES, 6, 398 - BD71828_INT_BAT_LOW_VOLT_RES_MASK), 399 - REGMAP_IRQ_REG(BD71828_INT_BAT_LOW_VOLT_DET, 6, 400 - BD71828_INT_BAT_LOW_VOLT_DET_MASK), 401 - REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_VOLT_RES, 6, 402 - BD71828_INT_BAT_OVER_VOLT_RES_MASK), 403 - REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_VOLT_DET, 6, 404 - BD71828_INT_BAT_OVER_VOLT_DET_MASK), 176 + REGMAP_IRQ_REG(BD71828_INT_BAT_SHORTC_RES, 6, BD71828_INT_BAT_SHORTC_RES_MASK), 177 + REGMAP_IRQ_REG(BD71828_INT_BAT_SHORTC_DET, 6, BD71828_INT_BAT_SHORTC_DET_MASK), 178 + REGMAP_IRQ_REG(BD71828_INT_BAT_LOW_VOLT_RES, 6, BD71828_INT_BAT_LOW_VOLT_RES_MASK), 179 + REGMAP_IRQ_REG(BD71828_INT_BAT_LOW_VOLT_DET, 6, BD71828_INT_BAT_LOW_VOLT_DET_MASK), 180 + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_VOLT_RES, 6, BD71828_INT_BAT_OVER_VOLT_RES_MASK), 181 + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_VOLT_DET, 6, BD71828_INT_BAT_OVER_VOLT_DET_MASK), 405 182 /* Battery Mon 2 */ 406 - REGMAP_IRQ_REG(BD71828_INT_BAT_MON_RES, 7, 407 - BD71828_INT_BAT_MON_RES_MASK), 408 - REGMAP_IRQ_REG(BD71828_INT_BAT_MON_DET, 7, 409 - BD71828_INT_BAT_MON_DET_MASK), 183 + REGMAP_IRQ_REG(BD71828_INT_BAT_MON_RES, 7, BD71828_INT_BAT_MON_RES_MASK), 184 + REGMAP_IRQ_REG(BD71828_INT_BAT_MON_DET, 7, BD71828_INT_BAT_MON_DET_MASK), 410 185 /* Battery Mon 3 (Coulomb counter) */ 411 - REGMAP_IRQ_REG(BD71828_INT_BAT_CC_MON1, 8, 412 - BD71828_INT_BAT_CC_MON1_MASK), 413 - REGMAP_IRQ_REG(BD71828_INT_BAT_CC_MON2, 8, 414 - BD71828_INT_BAT_CC_MON2_MASK), 415 - REGMAP_IRQ_REG(BD71828_INT_BAT_CC_MON3, 8, 416 - BD71828_INT_BAT_CC_MON3_MASK), 186 + REGMAP_IRQ_REG(BD71828_INT_BAT_CC_MON1, 8, BD71828_INT_BAT_CC_MON1_MASK), 187 + REGMAP_IRQ_REG(BD71828_INT_BAT_CC_MON2, 8, BD71828_INT_BAT_CC_MON2_MASK), 188 + REGMAP_IRQ_REG(BD71828_INT_BAT_CC_MON3, 8, BD71828_INT_BAT_CC_MON3_MASK), 417 189 /* Battery Mon 4 */ 418 - REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_1_RES, 9, 419 - BD71828_INT_BAT_OVER_CURR_1_RES_MASK), 420 - REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_1_DET, 9, 421 - BD71828_INT_BAT_OVER_CURR_1_DET_MASK), 422 - REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_2_RES, 9, 423 - BD71828_INT_BAT_OVER_CURR_2_RES_MASK), 424 - REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_2_DET, 9, 425 - BD71828_INT_BAT_OVER_CURR_2_DET_MASK), 426 - REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_3_RES, 9, 427 - BD71828_INT_BAT_OVER_CURR_3_RES_MASK), 428 - REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_3_DET, 9, 429 - BD71828_INT_BAT_OVER_CURR_3_DET_MASK), 190 + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_1_RES, 9, BD71828_INT_BAT_OVER_CURR_1_RES_MASK), 191 + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_1_DET, 9, BD71828_INT_BAT_OVER_CURR_1_DET_MASK), 192 + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_2_RES, 9, BD71828_INT_BAT_OVER_CURR_2_RES_MASK), 193 + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_2_DET, 9, BD71828_INT_BAT_OVER_CURR_2_DET_MASK), 194 + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_3_RES, 9, BD71828_INT_BAT_OVER_CURR_3_RES_MASK), 195 + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_3_DET, 9, BD71828_INT_BAT_OVER_CURR_3_DET_MASK), 430 196 /* Temperature */ 431 - REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_LOW_RES, 10, 432 - BD71828_INT_TEMP_BAT_LOW_RES_MASK), 433 - REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_LOW_DET, 10, 434 - BD71828_INT_TEMP_BAT_LOW_DET_MASK), 435 - REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_HI_RES, 10, 436 - BD71828_INT_TEMP_BAT_HI_RES_MASK), 437 - REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_HI_DET, 10, 438 - BD71828_INT_TEMP_BAT_HI_DET_MASK), 197 + REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_LOW_RES, 10, BD71828_INT_TEMP_BAT_LOW_RES_MASK), 198 + REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_LOW_DET, 10, BD71828_INT_TEMP_BAT_LOW_DET_MASK), 199 + REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_HI_RES, 10, BD71828_INT_TEMP_BAT_HI_RES_MASK), 200 + REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_HI_DET, 10, BD71828_INT_TEMP_BAT_HI_DET_MASK), 439 201 REGMAP_IRQ_REG(BD71828_INT_TEMP_CHIP_OVER_125_RES, 10, 440 202 BD71828_INT_TEMP_CHIP_OVER_125_RES_MASK), 441 203 REGMAP_IRQ_REG(BD71828_INT_TEMP_CHIP_OVER_125_DET, 10, ··· 419 267 .init_ack_masked = true, 420 268 .num_regs = 12, 421 269 .num_main_regs = 1, 422 - .sub_reg_offsets = &bd71828_sub_irq_offsets[0], 270 + .sub_reg_offsets = &bd718xx_sub_irq_offsets[0], 423 271 .num_main_status_bits = 8, 424 272 .irq_reg_stride = 1, 425 273 }; 426 274 275 + static struct regmap_irq_chip bd71815_irq_chip = { 276 + .name = "bd71815_irq", 277 + .main_status = BD71815_REG_INT_STAT, 278 + .irqs = &bd71815_irqs[0], 279 + .num_irqs = ARRAY_SIZE(bd71815_irqs), 280 + .status_base = BD71815_REG_INT_STAT_01, 281 + .mask_base = BD71815_REG_INT_EN_01, 282 + .ack_base = BD71815_REG_INT_STAT_01, 283 + .mask_invert = true, 284 + .init_ack_masked = true, 285 + .num_regs = 12, 286 + .num_main_regs = 1, 287 + .sub_reg_offsets = &bd718xx_sub_irq_offsets[0], 288 + .num_main_status_bits = 8, 289 + .irq_reg_stride = 1, 290 + }; 291 + 292 + static int set_clk_mode(struct device *dev, struct regmap *regmap, 293 + int clkmode_reg) 294 + { 295 + int ret; 296 + unsigned int open_drain; 297 + 298 + ret = of_property_read_u32(dev->of_node, "rohm,clkout-open-drain", &open_drain); 299 + if (ret) { 300 + if (ret == -EINVAL) 301 + return 0; 302 + return ret; 303 + } 304 + if (open_drain > 1) { 305 + dev_err(dev, "bad clk32kout mode configuration"); 306 + return -EINVAL; 307 + } 308 + 309 + if (open_drain) 310 + return regmap_update_bits(regmap, clkmode_reg, OUT32K_MODE, 311 + OUT32K_MODE_OPEN_DRAIN); 312 + 313 + return regmap_update_bits(regmap, clkmode_reg, OUT32K_MODE, 314 + OUT32K_MODE_CMOS); 315 + } 316 + 427 317 static int bd71828_i2c_probe(struct i2c_client *i2c) 428 318 { 429 - struct rohm_regmap_dev *chip; 430 319 struct regmap_irq_chip_data *irq_data; 431 320 int ret; 321 + struct regmap *regmap; 322 + const struct regmap_config *regmap_config; 323 + struct regmap_irq_chip *irqchip; 324 + unsigned int chip_type; 325 + struct mfd_cell *mfd; 326 + int cells; 327 + int button_irq; 328 + int clkmode_reg; 432 329 433 330 if (!i2c->irq) { 434 331 dev_err(&i2c->dev, "No IRQ configured\n"); 435 332 return -EINVAL; 436 333 } 437 334 438 - chip = devm_kzalloc(&i2c->dev, sizeof(*chip), GFP_KERNEL); 439 - if (!chip) 440 - return -ENOMEM; 441 - 442 - dev_set_drvdata(&i2c->dev, chip); 443 - 444 - chip->regmap = devm_regmap_init_i2c(i2c, &bd71828_regmap); 445 - if (IS_ERR(chip->regmap)) { 446 - dev_err(&i2c->dev, "Failed to initialize Regmap\n"); 447 - return PTR_ERR(chip->regmap); 335 + chip_type = (unsigned int)(uintptr_t) 336 + of_device_get_match_data(&i2c->dev); 337 + switch (chip_type) { 338 + case ROHM_CHIP_TYPE_BD71828: 339 + mfd = bd71828_mfd_cells; 340 + cells = ARRAY_SIZE(bd71828_mfd_cells); 341 + regmap_config = &bd71828_regmap; 342 + irqchip = &bd71828_irq_chip; 343 + clkmode_reg = BD71828_REG_OUT32K; 344 + button_irq = BD71828_INT_SHORTPUSH; 345 + break; 346 + case ROHM_CHIP_TYPE_BD71815: 347 + mfd = bd71815_mfd_cells; 348 + cells = ARRAY_SIZE(bd71815_mfd_cells); 349 + regmap_config = &bd71815_regmap; 350 + irqchip = &bd71815_irq_chip; 351 + clkmode_reg = BD71815_REG_OUT32K; 352 + /* 353 + * If BD71817 support is needed we should be able to handle it 354 + * with proper DT configs + BD71815 drivers + power-button. 355 + * BD71815 data-sheet does not list the power-button IRQ so we 356 + * don't use it. 357 + */ 358 + button_irq = 0; 359 + break; 360 + default: 361 + dev_err(&i2c->dev, "Unknown device type"); 362 + return -EINVAL; 448 363 } 449 364 450 - ret = devm_regmap_add_irq_chip(&i2c->dev, chip->regmap, 451 - i2c->irq, IRQF_ONESHOT, 0, 452 - &bd71828_irq_chip, &irq_data); 365 + regmap = devm_regmap_init_i2c(i2c, regmap_config); 366 + if (IS_ERR(regmap)) { 367 + dev_err(&i2c->dev, "Failed to initialize Regmap\n"); 368 + return PTR_ERR(regmap); 369 + } 370 + 371 + ret = devm_regmap_add_irq_chip(&i2c->dev, regmap, i2c->irq, 372 + IRQF_ONESHOT, 0, irqchip, &irq_data); 453 373 if (ret) { 454 374 dev_err(&i2c->dev, "Failed to add IRQ chip\n"); 455 375 return ret; 456 376 } 457 377 458 378 dev_dbg(&i2c->dev, "Registered %d IRQs for chip\n", 459 - bd71828_irq_chip.num_irqs); 379 + irqchip->num_irqs); 460 380 461 - ret = regmap_irq_get_virq(irq_data, BD71828_INT_SHORTPUSH); 462 - if (ret < 0) { 463 - dev_err(&i2c->dev, "Failed to get the power-key IRQ\n"); 464 - return ret; 381 + if (button_irq) { 382 + ret = regmap_irq_get_virq(irq_data, button_irq); 383 + if (ret < 0) { 384 + dev_err(&i2c->dev, "Failed to get the power-key IRQ\n"); 385 + return ret; 386 + } 387 + 388 + button.irq = ret; 465 389 } 466 390 467 - button.irq = ret; 391 + ret = set_clk_mode(&i2c->dev, regmap, clkmode_reg); 392 + if (ret) 393 + return ret; 468 394 469 - ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO, 470 - bd71828_mfd_cells, 471 - ARRAY_SIZE(bd71828_mfd_cells), NULL, 0, 472 - regmap_irq_get_domain(irq_data)); 395 + ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO, mfd, cells, 396 + NULL, 0, regmap_irq_get_domain(irq_data)); 473 397 if (ret) 474 398 dev_err(&i2c->dev, "Failed to create subdevices\n"); 475 399 ··· 553 325 } 554 326 555 327 static const struct of_device_id bd71828_of_match[] = { 556 - { .compatible = "rohm,bd71828", }, 328 + { 329 + .compatible = "rohm,bd71828", 330 + .data = (void *)ROHM_CHIP_TYPE_BD71828, 331 + }, { 332 + .compatible = "rohm,bd71815", 333 + .data = (void *)ROHM_CHIP_TYPE_BD71815, 334 + }, 557 335 { }, 558 336 }; 559 337 MODULE_DEVICE_TABLE(of, bd71828_of_match);
+16 -27
drivers/mfd/rohm-bd718x7.c
··· 91 91 .cache_type = REGCACHE_RBTREE, 92 92 }; 93 93 94 - static int bd718xx_init_press_duration(struct bd718xx *bd718xx) 94 + static int bd718xx_init_press_duration(struct regmap *regmap, 95 + struct device *dev) 95 96 { 96 - struct device* dev = bd718xx->chip.dev; 97 97 u32 short_press_ms, long_press_ms; 98 98 u32 short_press_value, long_press_value; 99 99 int ret; ··· 102 102 &short_press_ms); 103 103 if (!ret) { 104 104 short_press_value = min(15u, (short_press_ms + 250) / 500); 105 - ret = regmap_update_bits(bd718xx->chip.regmap, 106 - BD718XX_REG_PWRONCONFIG0, 105 + ret = regmap_update_bits(regmap, BD718XX_REG_PWRONCONFIG0, 107 106 BD718XX_PWRBTN_PRESS_DURATION_MASK, 108 107 short_press_value); 109 108 if (ret) { ··· 115 116 &long_press_ms); 116 117 if (!ret) { 117 118 long_press_value = min(15u, (long_press_ms + 500) / 1000); 118 - ret = regmap_update_bits(bd718xx->chip.regmap, 119 - BD718XX_REG_PWRONCONFIG1, 119 + ret = regmap_update_bits(regmap, BD718XX_REG_PWRONCONFIG1, 120 120 BD718XX_PWRBTN_PRESS_DURATION_MASK, 121 121 long_press_value); 122 122 if (ret) { ··· 130 132 static int bd718xx_i2c_probe(struct i2c_client *i2c, 131 133 const struct i2c_device_id *id) 132 134 { 133 - struct bd718xx *bd718xx; 135 + struct regmap *regmap; 136 + struct regmap_irq_chip_data *irq_data; 134 137 int ret; 135 138 unsigned int chip_type; 136 139 struct mfd_cell *mfd; ··· 141 142 dev_err(&i2c->dev, "No IRQ configured\n"); 142 143 return -EINVAL; 143 144 } 144 - 145 - bd718xx = devm_kzalloc(&i2c->dev, sizeof(struct bd718xx), GFP_KERNEL); 146 - 147 - if (!bd718xx) 148 - return -ENOMEM; 149 - 150 - bd718xx->chip_irq = i2c->irq; 151 145 chip_type = (unsigned int)(uintptr_t) 152 146 of_device_get_match_data(&i2c->dev); 153 147 switch (chip_type) { ··· 156 164 dev_err(&i2c->dev, "Unknown device type"); 157 165 return -EINVAL; 158 166 } 159 - bd718xx->chip.dev = &i2c->dev; 160 - dev_set_drvdata(&i2c->dev, bd718xx); 161 167 162 - bd718xx->chip.regmap = devm_regmap_init_i2c(i2c, 163 - &bd718xx_regmap_config); 164 - if (IS_ERR(bd718xx->chip.regmap)) { 168 + regmap = devm_regmap_init_i2c(i2c, &bd718xx_regmap_config); 169 + if (IS_ERR(regmap)) { 165 170 dev_err(&i2c->dev, "regmap initialization failed\n"); 166 - return PTR_ERR(bd718xx->chip.regmap); 171 + return PTR_ERR(regmap); 167 172 } 168 173 169 - ret = devm_regmap_add_irq_chip(&i2c->dev, bd718xx->chip.regmap, 170 - bd718xx->chip_irq, IRQF_ONESHOT, 0, 171 - &bd718xx_irq_chip, &bd718xx->irq_data); 174 + ret = devm_regmap_add_irq_chip(&i2c->dev, regmap, i2c->irq, 175 + IRQF_ONESHOT, 0, &bd718xx_irq_chip, 176 + &irq_data); 172 177 if (ret) { 173 178 dev_err(&i2c->dev, "Failed to add irq_chip\n"); 174 179 return ret; 175 180 } 176 181 177 - ret = bd718xx_init_press_duration(bd718xx); 182 + ret = bd718xx_init_press_duration(regmap, &i2c->dev); 178 183 if (ret) 179 184 return ret; 180 185 181 - ret = regmap_irq_get_virq(bd718xx->irq_data, BD718XX_INT_PWRBTN_S); 186 + ret = regmap_irq_get_virq(irq_data, BD718XX_INT_PWRBTN_S); 182 187 183 188 if (ret < 0) { 184 189 dev_err(&i2c->dev, "Failed to get the IRQ\n"); ··· 184 195 185 196 button.irq = ret; 186 197 187 - ret = devm_mfd_add_devices(bd718xx->chip.dev, PLATFORM_DEVID_AUTO, 198 + ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO, 188 199 mfd, cells, NULL, 0, 189 - regmap_irq_get_domain(bd718xx->irq_data)); 200 + regmap_irq_get_domain(irq_data)); 190 201 if (ret) 191 202 dev_err(&i2c->dev, "Failed to create subdevices\n"); 192 203
+189
drivers/mfd/rohm-bd9576.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Copyright (C) 2021 ROHM Semiconductors 4 + * 5 + * ROHM BD9576MUF and BD9573MUF PMIC driver 6 + */ 7 + 8 + #include <linux/i2c.h> 9 + #include <linux/interrupt.h> 10 + #include <linux/ioport.h> 11 + #include <linux/irq.h> 12 + #include <linux/mfd/core.h> 13 + #include <linux/mfd/rohm-bd957x.h> 14 + #include <linux/mfd/rohm-generic.h> 15 + #include <linux/module.h> 16 + #include <linux/of_device.h> 17 + #include <linux/regmap.h> 18 + #include <linux/types.h> 19 + 20 + enum { 21 + BD957X_REGULATOR_CELL, 22 + BD957X_WDT_CELL, 23 + }; 24 + 25 + /* 26 + * Due to the BD9576MUF nasty IRQ behaiour we don't always populate IRQs. 27 + * These will be added to regulator resources only if IRQ information for the 28 + * PMIC is populated in device-tree. 29 + */ 30 + static const struct resource bd9576_regulator_irqs[] = { 31 + DEFINE_RES_IRQ_NAMED(BD9576_INT_THERM, "bd9576-temp"), 32 + DEFINE_RES_IRQ_NAMED(BD9576_INT_OVD, "bd9576-ovd"), 33 + DEFINE_RES_IRQ_NAMED(BD9576_INT_UVD, "bd9576-uvd"), 34 + }; 35 + 36 + static struct mfd_cell bd9573_mfd_cells[] = { 37 + [BD957X_REGULATOR_CELL] = { .name = "bd9573-regulator", }, 38 + [BD957X_WDT_CELL] = { .name = "bd9576-wdt", }, 39 + }; 40 + 41 + static struct mfd_cell bd9576_mfd_cells[] = { 42 + [BD957X_REGULATOR_CELL] = { .name = "bd9576-regulator", }, 43 + [BD957X_WDT_CELL] = { .name = "bd9576-wdt", }, 44 + }; 45 + 46 + static const struct regmap_range volatile_ranges[] = { 47 + regmap_reg_range(BD957X_REG_SMRB_ASSERT, BD957X_REG_SMRB_ASSERT), 48 + regmap_reg_range(BD957X_REG_PMIC_INTERNAL_STAT, 49 + BD957X_REG_PMIC_INTERNAL_STAT), 50 + regmap_reg_range(BD957X_REG_INT_THERM_STAT, BD957X_REG_INT_THERM_STAT), 51 + regmap_reg_range(BD957X_REG_INT_OVP_STAT, BD957X_REG_INT_SYS_STAT), 52 + regmap_reg_range(BD957X_REG_INT_MAIN_STAT, BD957X_REG_INT_MAIN_STAT), 53 + }; 54 + 55 + static const struct regmap_access_table volatile_regs = { 56 + .yes_ranges = &volatile_ranges[0], 57 + .n_yes_ranges = ARRAY_SIZE(volatile_ranges), 58 + }; 59 + 60 + static struct regmap_config bd957x_regmap = { 61 + .reg_bits = 8, 62 + .val_bits = 8, 63 + .volatile_table = &volatile_regs, 64 + .max_register = BD957X_MAX_REGISTER, 65 + .cache_type = REGCACHE_RBTREE, 66 + }; 67 + 68 + static struct regmap_irq bd9576_irqs[] = { 69 + REGMAP_IRQ_REG(BD9576_INT_THERM, 0, BD957X_MASK_INT_MAIN_THERM), 70 + REGMAP_IRQ_REG(BD9576_INT_OVP, 0, BD957X_MASK_INT_MAIN_OVP), 71 + REGMAP_IRQ_REG(BD9576_INT_SCP, 0, BD957X_MASK_INT_MAIN_SCP), 72 + REGMAP_IRQ_REG(BD9576_INT_OCP, 0, BD957X_MASK_INT_MAIN_OCP), 73 + REGMAP_IRQ_REG(BD9576_INT_OVD, 0, BD957X_MASK_INT_MAIN_OVD), 74 + REGMAP_IRQ_REG(BD9576_INT_UVD, 0, BD957X_MASK_INT_MAIN_UVD), 75 + REGMAP_IRQ_REG(BD9576_INT_UVP, 0, BD957X_MASK_INT_MAIN_UVP), 76 + REGMAP_IRQ_REG(BD9576_INT_SYS, 0, BD957X_MASK_INT_MAIN_SYS), 77 + }; 78 + 79 + static struct regmap_irq_chip bd9576_irq_chip = { 80 + .name = "bd9576_irq", 81 + .irqs = &bd9576_irqs[0], 82 + .num_irqs = ARRAY_SIZE(bd9576_irqs), 83 + .status_base = BD957X_REG_INT_MAIN_STAT, 84 + .mask_base = BD957X_REG_INT_MAIN_MASK, 85 + .ack_base = BD957X_REG_INT_MAIN_STAT, 86 + .init_ack_masked = true, 87 + .num_regs = 1, 88 + .irq_reg_stride = 1, 89 + }; 90 + 91 + static int bd957x_i2c_probe(struct i2c_client *i2c, 92 + const struct i2c_device_id *id) 93 + { 94 + int ret; 95 + struct regmap *regmap; 96 + struct mfd_cell *cells; 97 + int num_cells; 98 + unsigned long chip_type; 99 + struct irq_domain *domain; 100 + bool usable_irqs; 101 + 102 + chip_type = (unsigned long)of_device_get_match_data(&i2c->dev); 103 + 104 + switch (chip_type) { 105 + case ROHM_CHIP_TYPE_BD9576: 106 + cells = bd9576_mfd_cells; 107 + num_cells = ARRAY_SIZE(bd9576_mfd_cells); 108 + usable_irqs = !!i2c->irq; 109 + break; 110 + case ROHM_CHIP_TYPE_BD9573: 111 + cells = bd9573_mfd_cells; 112 + num_cells = ARRAY_SIZE(bd9573_mfd_cells); 113 + /* 114 + * BD9573 only supports fatal IRQs which we can not handle 115 + * because SoC is going to lose the power. 116 + */ 117 + usable_irqs = false; 118 + break; 119 + default: 120 + dev_err(&i2c->dev, "Unknown device type"); 121 + return -EINVAL; 122 + } 123 + 124 + regmap = devm_regmap_init_i2c(i2c, &bd957x_regmap); 125 + if (IS_ERR(regmap)) { 126 + dev_err(&i2c->dev, "Failed to initialize Regmap\n"); 127 + return PTR_ERR(regmap); 128 + } 129 + 130 + /* 131 + * BD9576 behaves badly. It kepts IRQ line asserted for the whole 132 + * duration of detected HW condition (like over temperature). So we 133 + * don't require IRQ to be populated. 134 + * If IRQ information is not given, then we mask all IRQs and do not 135 + * provide IRQ resources to regulator driver - which then just omits 136 + * the notifiers. 137 + */ 138 + if (usable_irqs) { 139 + struct regmap_irq_chip_data *irq_data; 140 + struct mfd_cell *regulators; 141 + 142 + regulators = &bd9576_mfd_cells[BD957X_REGULATOR_CELL]; 143 + regulators->resources = bd9576_regulator_irqs; 144 + regulators->num_resources = ARRAY_SIZE(bd9576_regulator_irqs); 145 + 146 + ret = devm_regmap_add_irq_chip(&i2c->dev, regmap, i2c->irq, 147 + IRQF_ONESHOT, 0, 148 + &bd9576_irq_chip, &irq_data); 149 + if (ret) { 150 + dev_err(&i2c->dev, "Failed to add IRQ chip\n"); 151 + return ret; 152 + } 153 + domain = regmap_irq_get_domain(irq_data); 154 + } else { 155 + ret = regmap_update_bits(regmap, BD957X_REG_INT_MAIN_MASK, 156 + BD957X_MASK_INT_ALL, 157 + BD957X_MASK_INT_ALL); 158 + if (ret) 159 + return ret; 160 + domain = NULL; 161 + } 162 + 163 + ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO, cells, 164 + num_cells, NULL, 0, domain); 165 + if (ret) 166 + dev_err(&i2c->dev, "Failed to create subdevices\n"); 167 + 168 + return ret; 169 + } 170 + 171 + static const struct of_device_id bd957x_of_match[] = { 172 + { .compatible = "rohm,bd9576", .data = (void *)ROHM_CHIP_TYPE_BD9576, }, 173 + { .compatible = "rohm,bd9573", .data = (void *)ROHM_CHIP_TYPE_BD9573, }, 174 + { }, 175 + }; 176 + MODULE_DEVICE_TABLE(of, bd957x_of_match); 177 + 178 + static struct i2c_driver bd957x_drv = { 179 + .driver = { 180 + .name = "rohm-bd957x", 181 + .of_match_table = bd957x_of_match, 182 + }, 183 + .probe = &bd957x_i2c_probe, 184 + }; 185 + module_i2c_driver(bd957x_drv); 186 + 187 + MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); 188 + MODULE_DESCRIPTION("ROHM BD9576MUF and BD9573MUF Power Management IC driver"); 189 + MODULE_LICENSE("GPL");
+1 -13
drivers/mfd/sec-core.c
··· 549 549 .shutdown = sec_pmic_shutdown, 550 550 .id_table = sec_pmic_id, 551 551 }; 552 - 553 - static int __init sec_pmic_init(void) 554 - { 555 - return i2c_add_driver(&sec_pmic_driver); 556 - } 557 - 558 - subsys_initcall(sec_pmic_init); 559 - 560 - static void __exit sec_pmic_exit(void) 561 - { 562 - i2c_del_driver(&sec_pmic_driver); 563 - } 564 - module_exit(sec_pmic_exit); 552 + module_i2c_driver(sec_pmic_driver); 565 553 566 554 MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>"); 567 555 MODULE_DESCRIPTION("Core support for the S5M MFD");
+6 -1
drivers/mfd/stm32-timers.c
··· 158 158 159 159 static void stm32_timers_get_arr_size(struct stm32_timers *ddata) 160 160 { 161 + u32 arr; 162 + 163 + /* Backup ARR to restore it after getting the maximum value */ 164 + regmap_read(ddata->regmap, TIM_ARR, &arr); 165 + 161 166 /* 162 167 * Only the available bits will be written so when readback 163 168 * we get the maximum value of auto reload register 164 169 */ 165 170 regmap_write(ddata->regmap, TIM_ARR, ~0L); 166 171 regmap_read(ddata->regmap, TIM_ARR, &ddata->max_arr); 167 - regmap_write(ddata->regmap, TIM_ARR, 0x0); 172 + regmap_write(ddata->regmap, TIM_ARR, arr); 168 173 } 169 174 170 175 static int stm32_timers_dma_probe(struct device *dev,
+9 -5
drivers/mfd/stmpe.c
··· 312 312 * GPIO (all variants) 313 313 */ 314 314 315 - static const struct resource stmpe_gpio_resources[] = { 315 + static struct resource stmpe_gpio_resources[] = { 316 316 /* Start and end filled dynamically */ 317 317 { 318 318 .flags = IORESOURCE_IRQ, ··· 336 336 * Keypad (1601, 2401, 2403) 337 337 */ 338 338 339 - static const struct resource stmpe_keypad_resources[] = { 339 + static struct resource stmpe_keypad_resources[] = { 340 + /* Start and end filled dynamically */ 340 341 { 341 342 .name = "KEYPAD", 342 343 .flags = IORESOURCE_IRQ, ··· 358 357 /* 359 358 * PWM (1601, 2401, 2403) 360 359 */ 361 - static const struct resource stmpe_pwm_resources[] = { 360 + static struct resource stmpe_pwm_resources[] = { 361 + /* Start and end filled dynamically */ 362 362 { 363 363 .name = "PWM0", 364 364 .flags = IORESOURCE_IRQ, ··· 447 445 * Touchscreen (STMPE811 or STMPE610) 448 446 */ 449 447 450 - static const struct resource stmpe_ts_resources[] = { 448 + static struct resource stmpe_ts_resources[] = { 449 + /* Start and end filled dynamically */ 451 450 { 452 451 .name = "TOUCH_DET", 453 452 .flags = IORESOURCE_IRQ, ··· 470 467 * ADC (STMPE811) 471 468 */ 472 469 473 - static const struct resource stmpe_adc_resources[] = { 470 + static struct resource stmpe_adc_resources[] = { 471 + /* Start and end filled dynamically */ 474 472 { 475 473 .name = "STMPE_TEMP_SENS", 476 474 .flags = IORESOURCE_IRQ,
+8
drivers/pwm/Kconfig
··· 393 393 To compile this driver as a module, choose M here: the module 394 394 will be called pwm-mxs. 395 395 396 + config PWM_NTXEC 397 + tristate "Netronix embedded controller PWM support" 398 + depends on MFD_NTXEC 399 + help 400 + Say yes here if you want to support the PWM output of the embedded 401 + controller found in certain e-book readers designed by the original 402 + design manufacturer Netronix. 403 + 396 404 config PWM_OMAP_DMTIMER 397 405 tristate "OMAP Dual-Mode Timer PWM support" 398 406 depends on OF
+1
drivers/pwm/Makefile
··· 35 35 obj-$(CONFIG_PWM_MEDIATEK) += pwm-mediatek.o 36 36 obj-$(CONFIG_PWM_MTK_DISP) += pwm-mtk-disp.o 37 37 obj-$(CONFIG_PWM_MXS) += pwm-mxs.o 38 + obj-$(CONFIG_PWM_NTXEC) += pwm-ntxec.o 38 39 obj-$(CONFIG_PWM_OMAP_DMTIMER) += pwm-omap-dmtimer.o 39 40 obj-$(CONFIG_PWM_PCA9685) += pwm-pca9685.o 40 41 obj-$(CONFIG_PWM_PXA) += pwm-pxa.o
+184
drivers/pwm/pwm-ntxec.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * The Netronix embedded controller is a microcontroller found in some 4 + * e-book readers designed by the original design manufacturer Netronix, Inc. 5 + * It contains RTC, battery monitoring, system power management, and PWM 6 + * functionality. 7 + * 8 + * This driver implements PWM output. 9 + * 10 + * Copyright 2020 Jonathan Neuschäfer <j.neuschaefer@gmx.net> 11 + * 12 + * Limitations: 13 + * - The get_state callback is not implemented, because the current state of 14 + * the PWM output can't be read back from the hardware. 15 + * - The hardware can only generate normal polarity output. 16 + * - The period and duty cycle can't be changed together in one atomic action. 17 + */ 18 + 19 + #include <linux/mfd/ntxec.h> 20 + #include <linux/module.h> 21 + #include <linux/platform_device.h> 22 + #include <linux/pwm.h> 23 + #include <linux/regmap.h> 24 + #include <linux/types.h> 25 + 26 + struct ntxec_pwm { 27 + struct device *dev; 28 + struct ntxec *ec; 29 + struct pwm_chip chip; 30 + }; 31 + 32 + static struct ntxec_pwm *ntxec_pwm_from_chip(struct pwm_chip *chip) 33 + { 34 + return container_of(chip, struct ntxec_pwm, chip); 35 + } 36 + 37 + #define NTXEC_REG_AUTO_OFF_HI 0xa1 38 + #define NTXEC_REG_AUTO_OFF_LO 0xa2 39 + #define NTXEC_REG_ENABLE 0xa3 40 + #define NTXEC_REG_PERIOD_LOW 0xa4 41 + #define NTXEC_REG_PERIOD_HIGH 0xa5 42 + #define NTXEC_REG_DUTY_LOW 0xa6 43 + #define NTXEC_REG_DUTY_HIGH 0xa7 44 + 45 + /* 46 + * The time base used in the EC is 8MHz, or 125ns. Period and duty cycle are 47 + * measured in this unit. 48 + */ 49 + #define TIME_BASE_NS 125 50 + 51 + /* 52 + * The maximum input value (in nanoseconds) is determined by the time base and 53 + * the range of the hardware registers that hold the converted value. 54 + * It fits into 32 bits, so we can do our calculations in 32 bits as well. 55 + */ 56 + #define MAX_PERIOD_NS (TIME_BASE_NS * 0xffff) 57 + 58 + static int ntxec_pwm_set_raw_period_and_duty_cycle(struct pwm_chip *chip, 59 + int period, int duty) 60 + { 61 + struct ntxec_pwm *priv = ntxec_pwm_from_chip(chip); 62 + 63 + /* 64 + * Changes to the period and duty cycle take effect as soon as the 65 + * corresponding low byte is written, so the hardware may be configured 66 + * to an inconsistent state after the period is written and before the 67 + * duty cycle is fully written. If, in such a case, the old duty cycle 68 + * is longer than the new period, the EC may output 100% for a moment. 69 + * 70 + * To minimize the time between the changes to period and duty cycle 71 + * taking effect, the writes are interleaved. 72 + */ 73 + 74 + struct reg_sequence regs[] = { 75 + { NTXEC_REG_PERIOD_HIGH, ntxec_reg8(period >> 8) }, 76 + { NTXEC_REG_DUTY_HIGH, ntxec_reg8(duty >> 8) }, 77 + { NTXEC_REG_PERIOD_LOW, ntxec_reg8(period) }, 78 + { NTXEC_REG_DUTY_LOW, ntxec_reg8(duty) }, 79 + }; 80 + 81 + return regmap_multi_reg_write(priv->ec->regmap, regs, ARRAY_SIZE(regs)); 82 + } 83 + 84 + static int ntxec_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm_dev, 85 + const struct pwm_state *state) 86 + { 87 + struct ntxec_pwm *priv = ntxec_pwm_from_chip(chip); 88 + unsigned int period, duty; 89 + int res; 90 + 91 + if (state->polarity != PWM_POLARITY_NORMAL) 92 + return -EINVAL; 93 + 94 + period = min_t(u64, state->period, MAX_PERIOD_NS); 95 + duty = min_t(u64, state->duty_cycle, period); 96 + 97 + period /= TIME_BASE_NS; 98 + duty /= TIME_BASE_NS; 99 + 100 + /* 101 + * Writing a duty cycle of zero puts the device into a state where 102 + * writing a higher duty cycle doesn't result in the brightness that it 103 + * usually results in. This can be fixed by cycling the ENABLE register. 104 + * 105 + * As a workaround, write ENABLE=0 when the duty cycle is zero. 106 + * The case that something has previously set the duty cycle to zero 107 + * but ENABLE=1, is not handled. 108 + */ 109 + if (state->enabled && duty != 0) { 110 + res = ntxec_pwm_set_raw_period_and_duty_cycle(chip, period, duty); 111 + if (res) 112 + return res; 113 + 114 + res = regmap_write(priv->ec->regmap, NTXEC_REG_ENABLE, ntxec_reg8(1)); 115 + if (res) 116 + return res; 117 + 118 + /* Disable the auto-off timer */ 119 + res = regmap_write(priv->ec->regmap, NTXEC_REG_AUTO_OFF_HI, ntxec_reg8(0xff)); 120 + if (res) 121 + return res; 122 + 123 + return regmap_write(priv->ec->regmap, NTXEC_REG_AUTO_OFF_LO, ntxec_reg8(0xff)); 124 + } else { 125 + return regmap_write(priv->ec->regmap, NTXEC_REG_ENABLE, ntxec_reg8(0)); 126 + } 127 + } 128 + 129 + static const struct pwm_ops ntxec_pwm_ops = { 130 + .owner = THIS_MODULE, 131 + .apply = ntxec_pwm_apply, 132 + /* 133 + * No .get_state callback, because the current state cannot be read 134 + * back from the hardware. 135 + */ 136 + }; 137 + 138 + static int ntxec_pwm_probe(struct platform_device *pdev) 139 + { 140 + struct ntxec *ec = dev_get_drvdata(pdev->dev.parent); 141 + struct ntxec_pwm *priv; 142 + struct pwm_chip *chip; 143 + 144 + pdev->dev.of_node = pdev->dev.parent->of_node; 145 + 146 + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 147 + if (!priv) 148 + return -ENOMEM; 149 + 150 + priv->ec = ec; 151 + priv->dev = &pdev->dev; 152 + 153 + platform_set_drvdata(pdev, priv); 154 + 155 + chip = &priv->chip; 156 + chip->dev = &pdev->dev; 157 + chip->ops = &ntxec_pwm_ops; 158 + chip->base = -1; 159 + chip->npwm = 1; 160 + 161 + return pwmchip_add(chip); 162 + } 163 + 164 + static int ntxec_pwm_remove(struct platform_device *pdev) 165 + { 166 + struct ntxec_pwm *priv = platform_get_drvdata(pdev); 167 + struct pwm_chip *chip = &priv->chip; 168 + 169 + return pwmchip_remove(chip); 170 + } 171 + 172 + static struct platform_driver ntxec_pwm_driver = { 173 + .driver = { 174 + .name = "ntxec-pwm", 175 + }, 176 + .probe = ntxec_pwm_probe, 177 + .remove = ntxec_pwm_remove, 178 + }; 179 + module_platform_driver(ntxec_pwm_driver); 180 + 181 + MODULE_AUTHOR("Jonathan Neuschäfer <j.neuschaefer@gmx.net>"); 182 + MODULE_DESCRIPTION("PWM driver for Netronix EC"); 183 + MODULE_LICENSE("GPL"); 184 + MODULE_ALIAS("platform:ntxec-pwm");
+11
drivers/regulator/Kconfig
··· 204 204 This driver can also be built as a module. If so, the module 205 205 will be called bd70528-regulator. 206 206 207 + config REGULATOR_BD71815 208 + tristate "ROHM BD71815 Power Regulator" 209 + depends on MFD_ROHM_BD71828 210 + help 211 + This driver supports voltage regulators on ROHM BD71815 PMIC. 212 + This will enable support for the software controllable buck 213 + and LDO regulators and a current regulator for LEDs. 214 + 215 + This driver can also be built as a module. If so, the module 216 + will be called bd71815-regulator. 217 + 207 218 config REGULATOR_BD71828 208 219 tristate "ROHM BD71828 Power Regulator" 209 220 depends on MFD_ROHM_BD71828
+1
drivers/regulator/Makefile
··· 30 30 obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o 31 31 obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o 32 32 obj-$(CONFIG_REGULATOR_BD70528) += bd70528-regulator.o 33 + obj-$(CONFIG_REGULATOR_BD71815) += bd71815-regulator.o 33 34 obj-$(CONFIG_REGULATOR_BD71828) += bd71828-regulator.o 34 35 obj-$(CONFIG_REGULATOR_BD718XX) += bd718x7-regulator.o 35 36 obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o
+652
drivers/regulator/bd71815-regulator.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + // 3 + // Copyright 2014 Embest Technology Co. Ltd. Inc. 4 + // bd71815-regulator.c ROHM BD71815 regulator driver 5 + // 6 + // Author: Tony Luo <luofc@embedinfo.com> 7 + // 8 + // Partially rewritten at 2021 by 9 + // Matti Vaittinen <matti.vaitinen@fi.rohmeurope.com> 10 + 11 + #include <linux/kernel.h> 12 + #include <linux/module.h> 13 + #include <linux/init.h> 14 + #include <linux/err.h> 15 + #include <linux/platform_device.h> 16 + #include <linux/regulator/driver.h> 17 + #include <linux/delay.h> 18 + #include <linux/slab.h> 19 + #include <linux/gpio.h> 20 + #include <linux/mfd/rohm-generic.h> 21 + #include <linux/mfd/rohm-bd71815.h> 22 + #include <linux/regulator/of_regulator.h> 23 + 24 + struct bd71815_regulator { 25 + struct regulator_desc desc; 26 + const struct rohm_dvs_config *dvs; 27 + }; 28 + 29 + struct bd71815_pmic { 30 + struct bd71815_regulator descs[BD71815_REGULATOR_CNT]; 31 + struct regmap *regmap; 32 + struct device *dev; 33 + struct gpio_descs *gps; 34 + struct regulator_dev *rdev[BD71815_REGULATOR_CNT]; 35 + }; 36 + 37 + static const int bd7181x_wled_currents[] = { 38 + 10, 20, 30, 50, 70, 100, 200, 300, 500, 700, 1000, 2000, 3000, 4000, 39 + 5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 13000, 14000, 15000, 40 + 16000, 17000, 18000, 19000, 20000, 21000, 22000, 23000, 24000, 25000, 41 + }; 42 + 43 + static const struct rohm_dvs_config buck1_dvs = { 44 + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS | 45 + ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR, 46 + .run_reg = BD71815_REG_BUCK1_VOLT_H, 47 + .run_mask = BD71815_VOLT_MASK, 48 + .run_on_mask = BD71815_BUCK_RUN_ON, 49 + .snvs_on_mask = BD71815_BUCK_SNVS_ON, 50 + .suspend_reg = BD71815_REG_BUCK1_VOLT_L, 51 + .suspend_mask = BD71815_VOLT_MASK, 52 + .suspend_on_mask = BD71815_BUCK_SUSP_ON, 53 + .lpsr_reg = BD71815_REG_BUCK1_VOLT_L, 54 + .lpsr_mask = BD71815_VOLT_MASK, 55 + .lpsr_on_mask = BD71815_BUCK_LPSR_ON, 56 + }; 57 + 58 + static const struct rohm_dvs_config buck2_dvs = { 59 + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS | 60 + ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR, 61 + .run_reg = BD71815_REG_BUCK2_VOLT_H, 62 + .run_mask = BD71815_VOLT_MASK, 63 + .run_on_mask = BD71815_BUCK_RUN_ON, 64 + .snvs_on_mask = BD71815_BUCK_SNVS_ON, 65 + .suspend_reg = BD71815_REG_BUCK2_VOLT_L, 66 + .suspend_mask = BD71815_VOLT_MASK, 67 + .suspend_on_mask = BD71815_BUCK_SUSP_ON, 68 + .lpsr_reg = BD71815_REG_BUCK2_VOLT_L, 69 + .lpsr_mask = BD71815_VOLT_MASK, 70 + .lpsr_on_mask = BD71815_BUCK_LPSR_ON, 71 + }; 72 + 73 + static const struct rohm_dvs_config buck3_dvs = { 74 + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS | 75 + ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR, 76 + .run_reg = BD71815_REG_BUCK3_VOLT, 77 + .run_mask = BD71815_VOLT_MASK, 78 + .run_on_mask = BD71815_BUCK_RUN_ON, 79 + .snvs_on_mask = BD71815_BUCK_SNVS_ON, 80 + .suspend_on_mask = BD71815_BUCK_SUSP_ON, 81 + .lpsr_on_mask = BD71815_BUCK_LPSR_ON, 82 + }; 83 + 84 + static const struct rohm_dvs_config buck4_dvs = { 85 + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS | 86 + ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR, 87 + .run_reg = BD71815_REG_BUCK4_VOLT, 88 + .run_mask = BD71815_VOLT_MASK, 89 + .run_on_mask = BD71815_BUCK_RUN_ON, 90 + .snvs_on_mask = BD71815_BUCK_SNVS_ON, 91 + .suspend_on_mask = BD71815_BUCK_SUSP_ON, 92 + .lpsr_on_mask = BD71815_BUCK_LPSR_ON, 93 + }; 94 + 95 + static const struct rohm_dvs_config ldo1_dvs = { 96 + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS | 97 + ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR, 98 + .run_reg = BD71815_REG_LDO_MODE1, 99 + .run_mask = BD71815_VOLT_MASK, 100 + .run_on_mask = LDO1_RUN_ON, 101 + .snvs_on_mask = LDO1_SNVS_ON, 102 + .suspend_on_mask = LDO1_SUSP_ON, 103 + .lpsr_on_mask = LDO1_LPSR_ON, 104 + }; 105 + 106 + static const struct rohm_dvs_config ldo2_dvs = { 107 + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS | 108 + ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR, 109 + .run_reg = BD71815_REG_LDO_MODE2, 110 + .run_mask = BD71815_VOLT_MASK, 111 + .run_on_mask = LDO2_RUN_ON, 112 + .snvs_on_mask = LDO2_SNVS_ON, 113 + .suspend_on_mask = LDO2_SUSP_ON, 114 + .lpsr_on_mask = LDO2_LPSR_ON, 115 + }; 116 + 117 + static const struct rohm_dvs_config ldo3_dvs = { 118 + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS | 119 + ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR, 120 + .run_reg = BD71815_REG_LDO_MODE2, 121 + .run_mask = BD71815_VOLT_MASK, 122 + .run_on_mask = LDO3_RUN_ON, 123 + .snvs_on_mask = LDO3_SNVS_ON, 124 + .suspend_on_mask = LDO3_SUSP_ON, 125 + .lpsr_on_mask = LDO3_LPSR_ON, 126 + }; 127 + 128 + static const struct rohm_dvs_config ldo4_dvs = { 129 + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS | 130 + ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR, 131 + .run_reg = BD71815_REG_LDO_MODE3, 132 + .run_mask = BD71815_VOLT_MASK, 133 + .run_on_mask = LDO4_RUN_ON, 134 + .snvs_on_mask = LDO4_SNVS_ON, 135 + .suspend_on_mask = LDO4_SUSP_ON, 136 + .lpsr_on_mask = LDO4_LPSR_ON, 137 + }; 138 + 139 + static const struct rohm_dvs_config ldo5_dvs = { 140 + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS | 141 + ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR, 142 + .run_reg = BD71815_REG_LDO_MODE3, 143 + .run_mask = BD71815_VOLT_MASK, 144 + .run_on_mask = LDO5_RUN_ON, 145 + .snvs_on_mask = LDO5_SNVS_ON, 146 + .suspend_on_mask = LDO5_SUSP_ON, 147 + .lpsr_on_mask = LDO5_LPSR_ON, 148 + }; 149 + 150 + static const struct rohm_dvs_config dvref_dvs = { 151 + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS | 152 + ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR, 153 + .run_on_mask = DVREF_RUN_ON, 154 + .snvs_on_mask = DVREF_SNVS_ON, 155 + .suspend_on_mask = DVREF_SUSP_ON, 156 + .lpsr_on_mask = DVREF_LPSR_ON, 157 + }; 158 + 159 + static const struct rohm_dvs_config ldolpsr_dvs = { 160 + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS | 161 + ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR, 162 + .run_on_mask = DVREF_RUN_ON, 163 + .snvs_on_mask = DVREF_SNVS_ON, 164 + .suspend_on_mask = DVREF_SUSP_ON, 165 + .lpsr_on_mask = DVREF_LPSR_ON, 166 + }; 167 + 168 + static const struct rohm_dvs_config buck5_dvs = { 169 + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS | 170 + ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR, 171 + .run_reg = BD71815_REG_BUCK5_VOLT, 172 + .run_mask = BD71815_VOLT_MASK, 173 + .run_on_mask = BD71815_BUCK_RUN_ON, 174 + .snvs_on_mask = BD71815_BUCK_SNVS_ON, 175 + .suspend_on_mask = BD71815_BUCK_SUSP_ON, 176 + .lpsr_on_mask = BD71815_BUCK_LPSR_ON, 177 + }; 178 + 179 + static int set_hw_dvs_levels(struct device_node *np, 180 + const struct regulator_desc *desc, 181 + struct regulator_config *cfg) 182 + { 183 + struct bd71815_regulator *data; 184 + 185 + data = container_of(desc, struct bd71815_regulator, desc); 186 + return rohm_regulator_set_dvs_levels(data->dvs, np, desc, cfg->regmap); 187 + } 188 + 189 + /* 190 + * Bucks 1 and 2 have two voltage selection registers where selected 191 + * voltage can be set. Which of the registers is used can be either controlled 192 + * by a control bit in register - or by HW state. If HW state specific voltages 193 + * are given - then we assume HW state based control should be used. 194 + * 195 + * If volatge value is updated to currently selected register - then output 196 + * voltage is immediately changed no matter what is set as ramp rate. Thus we 197 + * default changing voltage by writing new value to inactive register and 198 + * then updating the 'register selection' bit. This naturally only works when 199 + * HW state machine is not used to select the voltage. 200 + */ 201 + static int buck12_set_hw_dvs_levels(struct device_node *np, 202 + const struct regulator_desc *desc, 203 + struct regulator_config *cfg) 204 + { 205 + struct bd71815_regulator *data; 206 + int ret = 0, val; 207 + 208 + data = container_of(desc, struct bd71815_regulator, desc); 209 + 210 + if (of_find_property(np, "rohm,dvs-run-voltage", NULL) || 211 + of_find_property(np, "rohm,dvs-suspend-voltage", NULL) || 212 + of_find_property(np, "rohm,dvs-lpsr-voltage", NULL) || 213 + of_find_property(np, "rohm,dvs-snvs-voltage", NULL)) { 214 + ret = regmap_read(cfg->regmap, desc->vsel_reg, &val); 215 + if (ret) 216 + return ret; 217 + 218 + if (!(BD71815_BUCK_STBY_DVS & val) && 219 + !(BD71815_BUCK_DVSSEL & val)) { 220 + int val2; 221 + 222 + /* 223 + * We are currently using voltage from _L. 224 + * We'd better copy it to _H and switch to it to 225 + * avoid shutting us down if LPSR or SUSPEND is set to 226 + * disabled. _L value is at reg _H + 1 227 + */ 228 + ret = regmap_read(cfg->regmap, desc->vsel_reg + 1, 229 + &val2); 230 + if (ret) 231 + return ret; 232 + 233 + ret = regmap_update_bits(cfg->regmap, desc->vsel_reg, 234 + BD71815_VOLT_MASK | 235 + BD71815_BUCK_DVSSEL, 236 + val2 | BD71815_BUCK_DVSSEL); 237 + if (ret) 238 + return ret; 239 + } 240 + ret = rohm_regulator_set_dvs_levels(data->dvs, np, desc, 241 + cfg->regmap); 242 + if (ret) 243 + return ret; 244 + /* 245 + * DVS levels were given => use HW-state machine for voltage 246 + * controls. NOTE: AFAIK, This means that if voltage is changed 247 + * by SW the ramp-rate is not respected. Should we disable 248 + * SW voltage control when the HW state machine is used? 249 + */ 250 + ret = regmap_update_bits(cfg->regmap, desc->vsel_reg, 251 + BD71815_BUCK_STBY_DVS, 252 + BD71815_BUCK_STBY_DVS); 253 + } 254 + 255 + return ret; 256 + } 257 + 258 + /* 259 + * BUCK1/2 260 + * BUCK1RAMPRATE[1:0] BUCK1 DVS ramp rate setting 261 + * 00: 10.00mV/usec 10mV 1uS 262 + * 01: 5.00mV/usec 10mV 2uS 263 + * 10: 2.50mV/usec 10mV 4uS 264 + * 11: 1.25mV/usec 10mV 8uS 265 + */ 266 + static const unsigned int bd7181x_ramp_table[] = { 1250, 2500, 5000, 10000 }; 267 + 268 + static int bd7181x_led_set_current_limit(struct regulator_dev *rdev, 269 + int min_uA, int max_uA) 270 + { 271 + int ret; 272 + int onstatus; 273 + 274 + onstatus = regulator_is_enabled_regmap(rdev); 275 + 276 + ret = regulator_set_current_limit_regmap(rdev, min_uA, max_uA); 277 + if (!ret) { 278 + int newstatus; 279 + 280 + newstatus = regulator_is_enabled_regmap(rdev); 281 + if (onstatus != newstatus) { 282 + /* 283 + * HW FIX: spurious led status change detected. Toggle 284 + * state as a workaround 285 + */ 286 + if (onstatus) 287 + ret = regulator_enable_regmap(rdev); 288 + else 289 + ret = regulator_disable_regmap(rdev); 290 + 291 + if (ret) 292 + dev_err(rdev_get_dev(rdev), 293 + "failed to revert the LED state (%d)\n", 294 + ret); 295 + } 296 + } 297 + 298 + return ret; 299 + } 300 + 301 + static int bd7181x_buck12_get_voltage_sel(struct regulator_dev *rdev) 302 + { 303 + struct bd71815_pmic *pmic = rdev_get_drvdata(rdev); 304 + int rid = rdev_get_id(rdev); 305 + int ret, regh, regl, val; 306 + 307 + regh = BD71815_REG_BUCK1_VOLT_H + rid * 0x2; 308 + regl = BD71815_REG_BUCK1_VOLT_L + rid * 0x2; 309 + 310 + ret = regmap_read(pmic->regmap, regh, &val); 311 + if (ret) 312 + return ret; 313 + 314 + /* 315 + * If we use HW state machine based voltage reg selection - then we 316 + * return BD71815_REG_BUCK1_VOLT_H which is used at RUN. 317 + * Else we do return the BD71815_REG_BUCK1_VOLT_H or 318 + * BD71815_REG_BUCK1_VOLT_L depending on which is selected to be used 319 + * by BD71815_BUCK_DVSSEL bit 320 + */ 321 + if ((!(val & BD71815_BUCK_STBY_DVS)) && (!(val & BD71815_BUCK_DVSSEL))) 322 + ret = regmap_read(pmic->regmap, regl, &val); 323 + 324 + if (ret) 325 + return ret; 326 + 327 + return val & BD71815_VOLT_MASK; 328 + } 329 + 330 + /* 331 + * For Buck 1/2. 332 + */ 333 + static int bd7181x_buck12_set_voltage_sel(struct regulator_dev *rdev, 334 + unsigned int sel) 335 + { 336 + struct bd71815_pmic *pmic = rdev_get_drvdata(rdev); 337 + int rid = rdev_get_id(rdev); 338 + int ret, val, reg, regh, regl; 339 + 340 + regh = BD71815_REG_BUCK1_VOLT_H + rid*0x2; 341 + regl = BD71815_REG_BUCK1_VOLT_L + rid*0x2; 342 + 343 + ret = regmap_read(pmic->regmap, regh, &val); 344 + if (ret) 345 + return ret; 346 + 347 + /* 348 + * If bucks 1 & 2 are controlled by state machine - then the RUN state 349 + * voltage is set to BD71815_REG_BUCK1_VOLT_H. Changing SUSPEND/LPSR 350 + * voltages at runtime is not supported by this driver. 351 + */ 352 + if (((val & BD71815_BUCK_STBY_DVS))) { 353 + return regmap_update_bits(pmic->regmap, regh, BD71815_VOLT_MASK, 354 + sel); 355 + } 356 + /* Update new voltage to the register which is not selected now */ 357 + if (val & BD71815_BUCK_DVSSEL) 358 + reg = regl; 359 + else 360 + reg = regh; 361 + 362 + ret = regmap_update_bits(pmic->regmap, reg, BD71815_VOLT_MASK, sel); 363 + if (ret) 364 + return ret; 365 + 366 + /* Select the other DVS register to be used */ 367 + return regmap_update_bits(pmic->regmap, regh, BD71815_BUCK_DVSSEL, ~val); 368 + } 369 + 370 + static const struct regulator_ops bd7181x_ldo_regulator_ops = { 371 + .enable = regulator_enable_regmap, 372 + .disable = regulator_disable_regmap, 373 + .is_enabled = regulator_is_enabled_regmap, 374 + .list_voltage = regulator_list_voltage_linear, 375 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 376 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 377 + }; 378 + 379 + static const struct regulator_ops bd7181x_fixed_regulator_ops = { 380 + .enable = regulator_enable_regmap, 381 + .disable = regulator_disable_regmap, 382 + .is_enabled = regulator_is_enabled_regmap, 383 + .list_voltage = regulator_list_voltage_linear, 384 + }; 385 + 386 + static const struct regulator_ops bd7181x_buck_regulator_ops = { 387 + .enable = regulator_enable_regmap, 388 + .disable = regulator_disable_regmap, 389 + .is_enabled = regulator_is_enabled_regmap, 390 + .list_voltage = regulator_list_voltage_linear, 391 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 392 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 393 + .set_voltage_time_sel = regulator_set_voltage_time_sel, 394 + }; 395 + 396 + static const struct regulator_ops bd7181x_buck12_regulator_ops = { 397 + .enable = regulator_enable_regmap, 398 + .disable = regulator_disable_regmap, 399 + .is_enabled = regulator_is_enabled_regmap, 400 + .list_voltage = regulator_list_voltage_linear, 401 + .set_voltage_sel = bd7181x_buck12_set_voltage_sel, 402 + .get_voltage_sel = bd7181x_buck12_get_voltage_sel, 403 + .set_voltage_time_sel = regulator_set_voltage_time_sel, 404 + .set_ramp_delay = regulator_set_ramp_delay_regmap, 405 + }; 406 + 407 + static const struct regulator_ops bd7181x_led_regulator_ops = { 408 + .enable = regulator_enable_regmap, 409 + .disable = regulator_disable_regmap, 410 + .is_enabled = regulator_is_enabled_regmap, 411 + .set_current_limit = bd7181x_led_set_current_limit, 412 + .get_current_limit = regulator_get_current_limit_regmap, 413 + }; 414 + 415 + #define BD71815_FIXED_REG(_name, _id, ereg, emsk, voltage, _dvs) \ 416 + [(_id)] = { \ 417 + .desc = { \ 418 + .name = #_name, \ 419 + .of_match = of_match_ptr(#_name), \ 420 + .regulators_node = of_match_ptr("regulators"), \ 421 + .n_voltages = 1, \ 422 + .ops = &bd7181x_fixed_regulator_ops, \ 423 + .type = REGULATOR_VOLTAGE, \ 424 + .id = (_id), \ 425 + .owner = THIS_MODULE, \ 426 + .min_uV = (voltage), \ 427 + .enable_reg = (ereg), \ 428 + .enable_mask = (emsk), \ 429 + .of_parse_cb = set_hw_dvs_levels, \ 430 + }, \ 431 + .dvs = (_dvs), \ 432 + } 433 + 434 + #define BD71815_BUCK_REG(_name, _id, vsel, ereg, min, max, step, _dvs) \ 435 + [(_id)] = { \ 436 + .desc = { \ 437 + .name = #_name, \ 438 + .of_match = of_match_ptr(#_name), \ 439 + .regulators_node = of_match_ptr("regulators"), \ 440 + .n_voltages = ((max) - (min)) / (step) + 1, \ 441 + .ops = &bd7181x_buck_regulator_ops, \ 442 + .type = REGULATOR_VOLTAGE, \ 443 + .id = (_id), \ 444 + .owner = THIS_MODULE, \ 445 + .min_uV = (min), \ 446 + .uV_step = (step), \ 447 + .vsel_reg = (vsel), \ 448 + .vsel_mask = BD71815_VOLT_MASK, \ 449 + .enable_reg = (ereg), \ 450 + .enable_mask = BD71815_BUCK_RUN_ON, \ 451 + .of_parse_cb = set_hw_dvs_levels, \ 452 + }, \ 453 + .dvs = (_dvs), \ 454 + } 455 + 456 + #define BD71815_BUCK12_REG(_name, _id, vsel, ereg, min, max, step, \ 457 + _dvs) \ 458 + [(_id)] = { \ 459 + .desc = { \ 460 + .name = #_name, \ 461 + .of_match = of_match_ptr(#_name), \ 462 + .regulators_node = of_match_ptr("regulators"), \ 463 + .n_voltages = ((max) - (min)) / (step) + 1, \ 464 + .ops = &bd7181x_buck12_regulator_ops, \ 465 + .type = REGULATOR_VOLTAGE, \ 466 + .id = (_id), \ 467 + .owner = THIS_MODULE, \ 468 + .min_uV = (min), \ 469 + .uV_step = (step), \ 470 + .vsel_reg = (vsel), \ 471 + .vsel_mask = 0x3f, \ 472 + .enable_reg = (ereg), \ 473 + .enable_mask = 0x04, \ 474 + .ramp_reg = (ereg), \ 475 + .ramp_mask = BD71815_BUCK_RAMPRATE_MASK, \ 476 + .ramp_delay_table = bd7181x_ramp_table, \ 477 + .n_ramp_values = ARRAY_SIZE(bd7181x_ramp_table),\ 478 + .of_parse_cb = buck12_set_hw_dvs_levels, \ 479 + }, \ 480 + .dvs = (_dvs), \ 481 + } 482 + 483 + #define BD71815_LED_REG(_name, _id, csel, mask, ereg, emsk, currents) \ 484 + [(_id)] = { \ 485 + .desc = { \ 486 + .name = #_name, \ 487 + .of_match = of_match_ptr(#_name), \ 488 + .regulators_node = of_match_ptr("regulators"), \ 489 + .n_current_limits = ARRAY_SIZE(currents), \ 490 + .ops = &bd7181x_led_regulator_ops, \ 491 + .type = REGULATOR_CURRENT, \ 492 + .id = (_id), \ 493 + .owner = THIS_MODULE, \ 494 + .curr_table = currents, \ 495 + .csel_reg = (csel), \ 496 + .csel_mask = (mask), \ 497 + .enable_reg = (ereg), \ 498 + .enable_mask = (emsk), \ 499 + }, \ 500 + } 501 + 502 + #define BD71815_LDO_REG(_name, _id, vsel, ereg, emsk, min, max, step, \ 503 + _dvs) \ 504 + [(_id)] = { \ 505 + .desc = { \ 506 + .name = #_name, \ 507 + .of_match = of_match_ptr(#_name), \ 508 + .regulators_node = of_match_ptr("regulators"), \ 509 + .n_voltages = ((max) - (min)) / (step) + 1, \ 510 + .ops = &bd7181x_ldo_regulator_ops, \ 511 + .type = REGULATOR_VOLTAGE, \ 512 + .id = (_id), \ 513 + .owner = THIS_MODULE, \ 514 + .min_uV = (min), \ 515 + .uV_step = (step), \ 516 + .vsel_reg = (vsel), \ 517 + .vsel_mask = BD71815_VOLT_MASK, \ 518 + .enable_reg = (ereg), \ 519 + .enable_mask = (emsk), \ 520 + .of_parse_cb = set_hw_dvs_levels, \ 521 + }, \ 522 + .dvs = (_dvs), \ 523 + } 524 + 525 + static struct bd71815_regulator bd71815_regulators[] = { 526 + BD71815_BUCK12_REG(buck1, BD71815_BUCK1, BD71815_REG_BUCK1_VOLT_H, 527 + BD71815_REG_BUCK1_MODE, 800000, 2000000, 25000, 528 + &buck1_dvs), 529 + BD71815_BUCK12_REG(buck2, BD71815_BUCK2, BD71815_REG_BUCK2_VOLT_H, 530 + BD71815_REG_BUCK2_MODE, 800000, 2000000, 25000, 531 + &buck2_dvs), 532 + BD71815_BUCK_REG(buck3, BD71815_BUCK3, BD71815_REG_BUCK3_VOLT, 533 + BD71815_REG_BUCK3_MODE, 1200000, 2700000, 50000, 534 + &buck3_dvs), 535 + BD71815_BUCK_REG(buck4, BD71815_BUCK4, BD71815_REG_BUCK4_VOLT, 536 + BD71815_REG_BUCK4_MODE, 1100000, 1850000, 25000, 537 + &buck4_dvs), 538 + BD71815_BUCK_REG(buck5, BD71815_BUCK5, BD71815_REG_BUCK5_VOLT, 539 + BD71815_REG_BUCK5_MODE, 1800000, 3300000, 50000, 540 + &buck5_dvs), 541 + BD71815_LDO_REG(ldo1, BD71815_LDO1, BD71815_REG_LDO1_VOLT, 542 + BD71815_REG_LDO_MODE1, LDO1_RUN_ON, 800000, 3300000, 543 + 50000, &ldo1_dvs), 544 + BD71815_LDO_REG(ldo2, BD71815_LDO2, BD71815_REG_LDO2_VOLT, 545 + BD71815_REG_LDO_MODE2, LDO2_RUN_ON, 800000, 3300000, 546 + 50000, &ldo2_dvs), 547 + /* 548 + * Let's default LDO3 to be enabled by SW. We can override ops if DT 549 + * says LDO3 should be enabled by HW when DCIN is connected. 550 + */ 551 + BD71815_LDO_REG(ldo3, BD71815_LDO3, BD71815_REG_LDO3_VOLT, 552 + BD71815_REG_LDO_MODE2, LDO3_RUN_ON, 800000, 3300000, 553 + 50000, &ldo3_dvs), 554 + BD71815_LDO_REG(ldo4, BD71815_LDO4, BD71815_REG_LDO4_VOLT, 555 + BD71815_REG_LDO_MODE3, LDO4_RUN_ON, 800000, 3300000, 556 + 50000, &ldo4_dvs), 557 + BD71815_LDO_REG(ldo5, BD71815_LDO5, BD71815_REG_LDO5_VOLT_H, 558 + BD71815_REG_LDO_MODE3, LDO5_RUN_ON, 800000, 3300000, 559 + 50000, &ldo5_dvs), 560 + BD71815_FIXED_REG(ldodvref, BD71815_LDODVREF, BD71815_REG_LDO_MODE4, 561 + DVREF_RUN_ON, 3000000, &dvref_dvs), 562 + BD71815_FIXED_REG(ldolpsr, BD71815_LDOLPSR, BD71815_REG_LDO_MODE4, 563 + LDO_LPSR_RUN_ON, 1800000, &ldolpsr_dvs), 564 + BD71815_LED_REG(wled, BD71815_WLED, BD71815_REG_LED_DIMM, LED_DIMM_MASK, 565 + BD71815_REG_LED_CTRL, LED_RUN_ON, 566 + bd7181x_wled_currents), 567 + }; 568 + 569 + static int bd7181x_probe(struct platform_device *pdev) 570 + { 571 + struct bd71815_pmic *pmic; 572 + struct regulator_config config = {}; 573 + int i, ret; 574 + struct gpio_desc *ldo4_en; 575 + 576 + pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); 577 + if (!pmic) 578 + return -ENOMEM; 579 + 580 + memcpy(pmic->descs, bd71815_regulators, sizeof(pmic->descs)); 581 + 582 + pmic->dev = &pdev->dev; 583 + pmic->regmap = dev_get_regmap(pdev->dev.parent, NULL); 584 + if (!pmic->regmap) { 585 + dev_err(pmic->dev, "No parent regmap\n"); 586 + return -ENODEV; 587 + } 588 + platform_set_drvdata(pdev, pmic); 589 + ldo4_en = devm_gpiod_get_from_of_node(&pdev->dev, 590 + pdev->dev.parent->of_node, 591 + "rohm,vsel-gpios", 0, 592 + GPIOD_ASIS, "ldo4-en"); 593 + 594 + if (IS_ERR(ldo4_en)) { 595 + ret = PTR_ERR(ldo4_en); 596 + if (ret != -ENOENT) 597 + return ret; 598 + ldo4_en = NULL; 599 + } 600 + 601 + /* Disable to go to ship-mode */ 602 + ret = regmap_update_bits(pmic->regmap, BD71815_REG_PWRCTRL, 603 + RESTARTEN, 0); 604 + if (ret) 605 + return ret; 606 + 607 + config.dev = pdev->dev.parent; 608 + config.regmap = pmic->regmap; 609 + 610 + for (i = 0; i < BD71815_REGULATOR_CNT; i++) { 611 + struct regulator_desc *desc; 612 + struct regulator_dev *rdev; 613 + 614 + desc = &pmic->descs[i].desc; 615 + if (i == BD71815_LDO4) 616 + config.ena_gpiod = ldo4_en; 617 + 618 + config.driver_data = pmic; 619 + 620 + rdev = devm_regulator_register(&pdev->dev, desc, &config); 621 + if (IS_ERR(rdev)) { 622 + dev_err(&pdev->dev, 623 + "failed to register %s regulator\n", 624 + desc->name); 625 + return PTR_ERR(rdev); 626 + } 627 + config.ena_gpiod = NULL; 628 + pmic->rdev[i] = rdev; 629 + } 630 + return 0; 631 + } 632 + 633 + static const struct platform_device_id bd7181x_pmic_id[] = { 634 + { "bd71815-pmic", ROHM_CHIP_TYPE_BD71815 }, 635 + { }, 636 + }; 637 + MODULE_DEVICE_TABLE(platform, bd7181x_pmic_id); 638 + 639 + static struct platform_driver bd7181x_regulator = { 640 + .driver = { 641 + .name = "bd7181x-pmic", 642 + .owner = THIS_MODULE, 643 + }, 644 + .probe = bd7181x_probe, 645 + .id_table = bd7181x_pmic_id, 646 + }; 647 + module_platform_driver(bd7181x_regulator); 648 + 649 + MODULE_AUTHOR("Tony Luo <luofc@embedinfo.com>"); 650 + MODULE_DESCRIPTION("BD71815 voltage regulator driver"); 651 + MODULE_LICENSE("GPL v2"); 652 + MODULE_ALIAS("platform:bd7181x-pmic");
+18 -33
drivers/regulator/bd71828-regulator.c
··· 90 90 REGULATOR_LINEAR_RANGE(3300000, 0x32, 0x3f, 0), 91 91 }; 92 92 93 - static int bd71828_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) 94 - { 95 - unsigned int val; 96 - 97 - switch (ramp_delay) { 98 - case 1 ... 2500: 99 - val = 0; 100 - break; 101 - case 2501 ... 5000: 102 - val = 1; 103 - break; 104 - case 5001 ... 10000: 105 - val = 2; 106 - break; 107 - case 10001 ... 20000: 108 - val = 3; 109 - break; 110 - default: 111 - val = 3; 112 - dev_err(&rdev->dev, 113 - "ramp_delay: %d not supported, setting 20mV/uS", 114 - ramp_delay); 115 - } 116 - 117 - /* 118 - * On BD71828 the ramp delay level control reg is at offset +2 to 119 - * enable reg 120 - */ 121 - return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg + 2, 122 - BD71828_MASK_RAMP_DELAY, 123 - val << (ffs(BD71828_MASK_RAMP_DELAY) - 1)); 124 - } 93 + static const unsigned int bd71828_ramp_delay[] = { 2500, 5000, 10000, 20000 }; 125 94 126 95 static int buck_set_hw_dvs_levels(struct device_node *np, 127 96 const struct regulator_desc *desc, ··· 154 185 .set_voltage_sel = regulator_set_voltage_sel_regmap, 155 186 .get_voltage_sel = regulator_get_voltage_sel_regmap, 156 187 .set_voltage_time_sel = regulator_set_voltage_time_sel, 157 - .set_ramp_delay = bd71828_set_ramp_delay, 188 + .set_ramp_delay = regulator_set_ramp_delay_regmap, 158 189 }; 159 190 160 191 static const struct regulator_ops bd71828_ldo_ops = { ··· 188 219 .enable_mask = BD71828_MASK_RUN_EN, 189 220 .vsel_reg = BD71828_REG_BUCK1_VOLT, 190 221 .vsel_mask = BD71828_MASK_BUCK1267_VOLT, 222 + .ramp_delay_table = bd71828_ramp_delay, 223 + .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay), 224 + .ramp_reg = BD71828_REG_BUCK1_MODE, 225 + .ramp_mask = BD71828_MASK_RAMP_DELAY, 191 226 .owner = THIS_MODULE, 192 227 .of_parse_cb = buck_set_hw_dvs_levels, 193 228 }, ··· 234 261 .enable_mask = BD71828_MASK_RUN_EN, 235 262 .vsel_reg = BD71828_REG_BUCK2_VOLT, 236 263 .vsel_mask = BD71828_MASK_BUCK1267_VOLT, 264 + .ramp_delay_table = bd71828_ramp_delay, 265 + .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay), 266 + .ramp_reg = BD71828_REG_BUCK2_MODE, 267 + .ramp_mask = BD71828_MASK_RAMP_DELAY, 237 268 .owner = THIS_MODULE, 238 269 .of_parse_cb = buck_set_hw_dvs_levels, 239 270 }, ··· 398 421 .enable_mask = BD71828_MASK_RUN_EN, 399 422 .vsel_reg = BD71828_REG_BUCK6_VOLT, 400 423 .vsel_mask = BD71828_MASK_BUCK1267_VOLT, 424 + .ramp_delay_table = bd71828_ramp_delay, 425 + .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay), 426 + .ramp_reg = BD71828_REG_BUCK6_MODE, 427 + .ramp_mask = BD71828_MASK_RAMP_DELAY, 401 428 .owner = THIS_MODULE, 402 429 .of_parse_cb = buck_set_hw_dvs_levels, 403 430 }, ··· 439 458 .enable_mask = BD71828_MASK_RUN_EN, 440 459 .vsel_reg = BD71828_REG_BUCK7_VOLT, 441 460 .vsel_mask = BD71828_MASK_BUCK1267_VOLT, 461 + .ramp_delay_table = bd71828_ramp_delay, 462 + .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay), 463 + .ramp_reg = BD71828_REG_BUCK7_MODE, 464 + .ramp_mask = BD71828_MASK_RAMP_DELAY, 442 465 .owner = THIS_MODULE, 443 466 .of_parse_cb = buck_set_hw_dvs_levels, 444 467 },
+27 -33
drivers/regulator/bd718x7-regulator.c
··· 86 86 * 10: 2.50mV/usec 10mV 4uS 87 87 * 11: 1.25mV/usec 10mV 8uS 88 88 */ 89 - static int bd718xx_buck1234_set_ramp_delay(struct regulator_dev *rdev, 90 - int ramp_delay) 91 - { 92 - int id = rdev_get_id(rdev); 93 - unsigned int ramp_value; 94 - 95 - dev_dbg(&rdev->dev, "Buck[%d] Set Ramp = %d\n", id + 1, 96 - ramp_delay); 97 - switch (ramp_delay) { 98 - case 1 ... 1250: 99 - ramp_value = BUCK_RAMPRATE_1P25MV; 100 - break; 101 - case 1251 ... 2500: 102 - ramp_value = BUCK_RAMPRATE_2P50MV; 103 - break; 104 - case 2501 ... 5000: 105 - ramp_value = BUCK_RAMPRATE_5P00MV; 106 - break; 107 - case 5001 ... 10000: 108 - ramp_value = BUCK_RAMPRATE_10P00MV; 109 - break; 110 - default: 111 - ramp_value = BUCK_RAMPRATE_10P00MV; 112 - dev_err(&rdev->dev, 113 - "%s: ramp_delay: %d not supported, setting 10000mV//us\n", 114 - rdev->desc->name, ramp_delay); 115 - } 116 - 117 - return regmap_update_bits(rdev->regmap, BD718XX_REG_BUCK1_CTRL + id, 118 - BUCK_RAMPRATE_MASK, ramp_value << 6); 119 - } 89 + static const unsigned int bd718xx_ramp_delay[] = { 10000, 5000, 2500, 1250 }; 120 90 121 91 /* These functions are used when regulators are under HW state machine control. 122 92 * We assume PMIC is in RUN state because SW running and able to query the ··· 348 378 .set_voltage_sel = regulator_set_voltage_sel_regmap, 349 379 .get_voltage_sel = regulator_get_voltage_sel_regmap, 350 380 .set_voltage_time_sel = regulator_set_voltage_time_sel, 351 - .set_ramp_delay = bd718xx_buck1234_set_ramp_delay, 381 + .set_ramp_delay = regulator_set_ramp_delay_regmap, 352 382 }; 353 383 354 384 /* ··· 357 387 BD718XX_OPS(bd718xx_dvs_buck_regulator_ops, regulator_list_voltage_linear_range, 358 388 NULL, regulator_set_voltage_sel_regmap, 359 389 regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel, 360 - bd718xx_buck1234_set_ramp_delay); 390 + /* bd718xx_buck1234_set_ramp_delay */ regulator_set_ramp_delay_regmap); 361 391 362 392 /* 363 393 * BD71837 BUCK1/2/3/4 ··· 615 645 .enable_mask = BD718XX_BUCK_EN, 616 646 .enable_time = BD71847_BUCK1_STARTUP_TIME, 617 647 .owner = THIS_MODULE, 648 + .ramp_delay_table = bd718xx_ramp_delay, 649 + .n_ramp_values = ARRAY_SIZE(bd718xx_ramp_delay), 650 + .ramp_reg = BD718XX_REG_BUCK1_CTRL, 651 + .ramp_mask = BUCK_RAMPRATE_MASK, 618 652 .of_parse_cb = buck_set_hw_dvs_levels, 619 653 }, 620 654 .dvs = { ··· 652 678 .enable_reg = BD718XX_REG_BUCK2_CTRL, 653 679 .enable_mask = BD718XX_BUCK_EN, 654 680 .enable_time = BD71847_BUCK2_STARTUP_TIME, 681 + .ramp_delay_table = bd718xx_ramp_delay, 682 + .n_ramp_values = ARRAY_SIZE(bd718xx_ramp_delay), 683 + .ramp_reg = BD718XX_REG_BUCK2_CTRL, 684 + .ramp_mask = BUCK_RAMPRATE_MASK, 655 685 .owner = THIS_MODULE, 656 686 .of_parse_cb = buck_set_hw_dvs_levels, 657 687 }, ··· 963 985 .enable_reg = BD718XX_REG_BUCK1_CTRL, 964 986 .enable_mask = BD718XX_BUCK_EN, 965 987 .enable_time = BD71837_BUCK1_STARTUP_TIME, 988 + .ramp_delay_table = bd718xx_ramp_delay, 989 + .n_ramp_values = ARRAY_SIZE(bd718xx_ramp_delay), 990 + .ramp_reg = BD718XX_REG_BUCK1_CTRL, 991 + .ramp_mask = BUCK_RAMPRATE_MASK, 966 992 .owner = THIS_MODULE, 967 993 .of_parse_cb = buck_set_hw_dvs_levels, 968 994 }, ··· 1001 1019 .enable_reg = BD718XX_REG_BUCK2_CTRL, 1002 1020 .enable_mask = BD718XX_BUCK_EN, 1003 1021 .enable_time = BD71837_BUCK2_STARTUP_TIME, 1022 + .ramp_delay_table = bd718xx_ramp_delay, 1023 + .n_ramp_values = ARRAY_SIZE(bd718xx_ramp_delay), 1024 + .ramp_reg = BD718XX_REG_BUCK2_CTRL, 1025 + .ramp_mask = BUCK_RAMPRATE_MASK, 1004 1026 .owner = THIS_MODULE, 1005 1027 .of_parse_cb = buck_set_hw_dvs_levels, 1006 1028 }, ··· 1036 1050 .enable_reg = BD71837_REG_BUCK3_CTRL, 1037 1051 .enable_mask = BD718XX_BUCK_EN, 1038 1052 .enable_time = BD71837_BUCK3_STARTUP_TIME, 1053 + .ramp_delay_table = bd718xx_ramp_delay, 1054 + .n_ramp_values = ARRAY_SIZE(bd718xx_ramp_delay), 1055 + .ramp_reg = BD71837_REG_BUCK3_CTRL, 1056 + .ramp_mask = BUCK_RAMPRATE_MASK, 1039 1057 .owner = THIS_MODULE, 1040 1058 .of_parse_cb = buck_set_hw_dvs_levels, 1041 1059 }, ··· 1069 1079 .enable_reg = BD71837_REG_BUCK4_CTRL, 1070 1080 .enable_mask = BD718XX_BUCK_EN, 1071 1081 .enable_time = BD71837_BUCK4_STARTUP_TIME, 1082 + .ramp_delay_table = bd718xx_ramp_delay, 1083 + .n_ramp_values = ARRAY_SIZE(bd718xx_ramp_delay), 1084 + .ramp_reg = BD71837_REG_BUCK4_CTRL, 1085 + .ramp_mask = BUCK_RAMPRATE_MASK, 1072 1086 .owner = THIS_MODULE, 1073 1087 .of_parse_cb = buck_set_hw_dvs_levels, 1074 1088 },
+21 -2
drivers/regulator/rohm-regulator.c
··· 22 22 return ret; 23 23 return 0; 24 24 } 25 - 25 + /* If voltage is set to 0 => disable */ 26 26 if (uv == 0) { 27 27 if (omask) 28 28 return regmap_update_bits(regmap, oreg, omask, 0); 29 29 } 30 + /* Some setups don't allow setting own voltage but do allow enabling */ 31 + if (!mask) { 32 + if (omask) 33 + return regmap_update_bits(regmap, oreg, omask, omask); 34 + 35 + return -EINVAL; 36 + } 30 37 for (i = 0; i < desc->n_voltages; i++) { 31 - ret = regulator_desc_list_voltage_linear_range(desc, i); 38 + /* NOTE to next hacker - Does not support pickable ranges */ 39 + if (desc->linear_range_selectors) 40 + return -EINVAL; 41 + if (desc->n_linear_ranges) 42 + ret = regulator_desc_list_voltage_linear_range(desc, i); 43 + else 44 + ret = regulator_desc_list_voltage_linear(desc, i); 32 45 if (ret < 0) 33 46 continue; 34 47 if (ret == uv) { ··· 94 81 reg = dvs->lpsr_reg; 95 82 mask = dvs->lpsr_mask; 96 83 omask = dvs->lpsr_on_mask; 84 + break; 85 + case ROHM_DVS_LEVEL_SNVS: 86 + prop = "rohm,dvs-snvs-voltage"; 87 + reg = dvs->snvs_reg; 88 + mask = dvs->snvs_mask; 89 + omask = dvs->snvs_on_mask; 97 90 break; 98 91 default: 99 92 return -EINVAL;
+11 -3
drivers/rtc/Kconfig
··· 501 501 watchdog timer in the ST M41T60 and M41T80 RTC chips series. 502 502 503 503 config RTC_DRV_BD70528 504 - tristate "ROHM BD70528 PMIC RTC" 505 - depends on MFD_ROHM_BD70528 && (BD70528_WATCHDOG || !BD70528_WATCHDOG) 504 + tristate "ROHM BD70528, BD71815 and BD71828 PMIC RTC" 505 + depends on MFD_ROHM_BD71828 || MFD_ROHM_BD70528 && (BD70528_WATCHDOG || !BD70528_WATCHDOG) 506 506 help 507 507 If you say Y here you will get support for the RTC 508 - block on ROHM BD70528 and BD71828 Power Management IC. 508 + block on ROHM BD70528, BD71815 and BD71828 Power Management IC. 509 509 510 510 This driver can also be built as a module. If so, the module 511 511 will be called rtc-bd70528. ··· 1295 1295 1296 1296 This driver can also be built as a module. If so, the module 1297 1297 will be called rtc-cros-ec. 1298 + 1299 + config RTC_DRV_NTXEC 1300 + tristate "Netronix embedded controller RTC" 1301 + depends on MFD_NTXEC 1302 + help 1303 + Say yes here if you want to support the RTC functionality of the 1304 + embedded controller found in certain e-book readers designed by the 1305 + original design manufacturer Netronix. 1298 1306 1299 1307 comment "on-CPU RTC drivers" 1300 1308
+1
drivers/rtc/Makefile
··· 108 108 obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o 109 109 obj-$(CONFIG_RTC_DRV_MXC) += rtc-mxc.o 110 110 obj-$(CONFIG_RTC_DRV_MXC_V2) += rtc-mxc_v2.o 111 + obj-$(CONFIG_RTC_DRV_NTXEC) += rtc-ntxec.o 111 112 obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o 112 113 obj-$(CONFIG_RTC_DRV_OPAL) += rtc-opal.o 113 114 obj-$(CONFIG_RTC_DRV_PALMAS) += rtc-palmas.o
+64 -40
drivers/rtc/rtc-bd70528.c
··· 6 6 7 7 #include <linux/bcd.h> 8 8 #include <linux/mfd/rohm-bd70528.h> 9 + #include <linux/mfd/rohm-bd71815.h> 9 10 #include <linux/mfd/rohm-bd71828.h> 10 11 #include <linux/module.h> 11 12 #include <linux/of.h> 12 13 #include <linux/platform_device.h> 13 14 #include <linux/regmap.h> 14 15 #include <linux/rtc.h> 16 + 17 + /* 18 + * On BD71828 and BD71815 the ALM0 MASK is 14 bytes after the ALM0 19 + * block start 20 + */ 21 + #define BD718XX_ALM_EN_OFFSET 14 15 22 16 23 /* 17 24 * We read regs RTC_SEC => RTC_YEAR ··· 59 52 60 53 struct bd70528_rtc { 61 54 struct rohm_regmap_dev *parent; 55 + struct regmap *regmap; 62 56 struct device *dev; 63 57 u8 reg_time_start; 58 + u8 bd718xx_alm_block_start; 64 59 bool has_rtc_timers; 65 60 }; 66 61 ··· 243 234 int ret; 244 235 struct bd71828_rtc_alm alm; 245 236 struct bd70528_rtc *r = dev_get_drvdata(dev); 246 - struct rohm_regmap_dev *parent = r->parent; 247 237 248 - ret = regmap_bulk_read(parent->regmap, BD71828_REG_RTC_ALM_START, 249 - &alm, sizeof(alm)); 238 + ret = regmap_bulk_read(r->regmap, r->bd718xx_alm_block_start, &alm, 239 + sizeof(alm)); 250 240 if (ret) { 251 241 dev_err(dev, "Failed to read alarm regs\n"); 252 242 return ret; ··· 258 250 else 259 251 alm.alm_mask |= BD70528_MASK_ALM_EN; 260 252 261 - ret = regmap_bulk_write(parent->regmap, BD71828_REG_RTC_ALM_START, 262 - &alm, sizeof(alm)); 253 + ret = regmap_bulk_write(r->regmap, r->bd718xx_alm_block_start, &alm, 254 + sizeof(alm)); 263 255 if (ret) 264 256 dev_err(dev, "Failed to set alarm time\n"); 265 257 ··· 273 265 struct bd70528_rtc_alm alm; 274 266 int ret; 275 267 struct bd70528_rtc *r = dev_get_drvdata(dev); 276 - struct rohm_regmap_dev *parent = r->parent; 277 268 278 - ret = regmap_bulk_read(parent->regmap, BD70528_REG_RTC_WAKE_START, 279 - &wake, sizeof(wake)); 269 + ret = regmap_bulk_read(r->regmap, BD70528_REG_RTC_WAKE_START, &wake, 270 + sizeof(wake)); 280 271 if (ret) { 281 272 dev_err(dev, "Failed to read wake regs\n"); 282 273 return ret; 283 274 } 284 275 285 - ret = regmap_bulk_read(parent->regmap, BD70528_REG_RTC_ALM_START, 286 - &alm, sizeof(alm)); 276 + ret = regmap_bulk_read(r->regmap, BD70528_REG_RTC_ALM_START, &alm, 277 + sizeof(alm)); 287 278 if (ret) { 288 279 dev_err(dev, "Failed to read alarm regs\n"); 289 280 return ret; ··· 299 292 wake.ctrl &= ~BD70528_MASK_WAKE_EN; 300 293 } 301 294 302 - ret = regmap_bulk_write(parent->regmap, 303 - BD70528_REG_RTC_WAKE_START, &wake, 295 + ret = regmap_bulk_write(r->regmap, BD70528_REG_RTC_WAKE_START, &wake, 304 296 sizeof(wake)); 305 297 if (ret) { 306 298 dev_err(dev, "Failed to set wake time\n"); 307 299 return ret; 308 300 } 309 - ret = regmap_bulk_write(parent->regmap, BD70528_REG_RTC_ALM_START, 310 - &alm, sizeof(alm)); 301 + ret = regmap_bulk_write(r->regmap, BD70528_REG_RTC_ALM_START, &alm, 302 + sizeof(alm)); 311 303 if (ret) 312 304 dev_err(dev, "Failed to set alarm time\n"); 313 305 ··· 318 312 int ret; 319 313 struct bd71828_rtc_alm alm; 320 314 struct bd70528_rtc *r = dev_get_drvdata(dev); 321 - struct rohm_regmap_dev *parent = r->parent; 322 315 323 - ret = regmap_bulk_read(parent->regmap, BD71828_REG_RTC_ALM_START, 324 - &alm, sizeof(alm)); 316 + ret = regmap_bulk_read(r->regmap, r->bd718xx_alm_block_start, &alm, 317 + sizeof(alm)); 325 318 if (ret) { 326 319 dev_err(dev, "Failed to read alarm regs\n"); 327 320 return ret; ··· 341 336 struct bd70528_rtc_alm alm; 342 337 int ret; 343 338 struct bd70528_rtc *r = dev_get_drvdata(dev); 344 - struct rohm_regmap_dev *parent = r->parent; 345 339 346 - ret = regmap_bulk_read(parent->regmap, BD70528_REG_RTC_ALM_START, 347 - &alm, sizeof(alm)); 340 + ret = regmap_bulk_read(r->regmap, BD70528_REG_RTC_ALM_START, &alm, 341 + sizeof(alm)); 348 342 if (ret) { 349 343 dev_err(dev, "Failed to read alarm regs\n"); 350 344 return ret; ··· 364 360 int ret, tmpret, old_states; 365 361 struct bd70528_rtc_data rtc_data; 366 362 struct bd70528_rtc *r = dev_get_drvdata(dev); 367 - struct rohm_regmap_dev *parent = r->parent; 368 363 369 364 ret = bd70528_disable_rtc_based_timers(r, &old_states); 370 365 if (ret) 371 366 return ret; 372 367 373 - tmpret = regmap_bulk_read(parent->regmap, 374 - r->reg_time_start, &rtc_data, 368 + tmpret = regmap_bulk_read(r->regmap, r->reg_time_start, &rtc_data, 375 369 sizeof(rtc_data)); 376 370 if (tmpret) { 377 371 dev_err(dev, "Failed to read RTC time registers\n"); ··· 377 375 } 378 376 tm2rtc(t, &rtc_data); 379 377 380 - tmpret = regmap_bulk_write(parent->regmap, 381 - r->reg_time_start, &rtc_data, 378 + tmpret = regmap_bulk_write(r->regmap, r->reg_time_start, &rtc_data, 382 379 sizeof(rtc_data)); 383 380 if (tmpret) { 384 381 dev_err(dev, "Failed to set RTC time\n"); ··· 411 410 static int bd70528_get_time(struct device *dev, struct rtc_time *t) 412 411 { 413 412 struct bd70528_rtc *r = dev_get_drvdata(dev); 414 - struct rohm_regmap_dev *parent = r->parent; 415 413 struct bd70528_rtc_data rtc_data; 416 414 int ret; 417 415 418 416 /* read the RTC date and time registers all at once */ 419 - ret = regmap_bulk_read(parent->regmap, 420 - r->reg_time_start, &rtc_data, 417 + ret = regmap_bulk_read(r->regmap, r->reg_time_start, &rtc_data, 421 418 sizeof(rtc_data)); 422 419 if (ret) { 423 420 dev_err(dev, "Failed to read RTC time (err %d)\n", ret); ··· 442 443 dev_err(dev, "Failed to change wake state\n"); 443 444 goto out_unlock; 444 445 } 445 - ret = regmap_update_bits(r->parent->regmap, BD70528_REG_RTC_ALM_MASK, 446 + ret = regmap_update_bits(r->regmap, BD70528_REG_RTC_ALM_MASK, 446 447 BD70528_MASK_ALM_EN, enableval); 447 448 if (ret) 448 449 dev_err(dev, "Failed to change alarm state\n"); ··· 461 462 if (!enabled) 462 463 enableval = 0; 463 464 464 - ret = regmap_update_bits(r->parent->regmap, BD71828_REG_RTC_ALM0_MASK, 465 - BD70528_MASK_ALM_EN, enableval); 465 + ret = regmap_update_bits(r->regmap, r->bd718xx_alm_block_start + 466 + BD718XX_ALM_EN_OFFSET, BD70528_MASK_ALM_EN, 467 + enableval); 466 468 if (ret) 467 469 dev_err(dev, "Failed to change alarm state\n"); 468 470 ··· 498 498 { 499 499 struct bd70528_rtc *bd_rtc; 500 500 const struct rtc_class_ops *rtc_ops; 501 - struct rohm_regmap_dev *parent; 502 501 const char *irq_name; 503 502 int ret; 504 503 struct rtc_device *rtc; ··· 507 508 u8 hour_reg; 508 509 enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data; 509 510 510 - parent = dev_get_drvdata(pdev->dev.parent); 511 - if (!parent) { 512 - dev_err(&pdev->dev, "No MFD driver data\n"); 513 - return -EINVAL; 514 - } 515 511 bd_rtc = devm_kzalloc(&pdev->dev, sizeof(*bd_rtc), GFP_KERNEL); 516 512 if (!bd_rtc) 517 513 return -ENOMEM; 518 514 519 - bd_rtc->parent = parent; 515 + bd_rtc->regmap = dev_get_regmap(pdev->dev.parent, NULL); 516 + if (!bd_rtc->regmap) { 517 + dev_err(&pdev->dev, "No regmap\n"); 518 + return -EINVAL; 519 + } 520 + 520 521 bd_rtc->dev = &pdev->dev; 521 522 522 523 switch (chip) { 523 524 case ROHM_CHIP_TYPE_BD70528: 525 + bd_rtc->parent = dev_get_drvdata(pdev->dev.parent); 526 + if (!bd_rtc->parent) { 527 + dev_err(&pdev->dev, "No MFD data\n"); 528 + return -EINVAL; 529 + } 524 530 irq_name = "bd70528-rtc-alm"; 525 531 bd_rtc->has_rtc_timers = true; 526 532 bd_rtc->reg_time_start = BD70528_REG_RTC_START; ··· 533 529 enable_main_irq = true; 534 530 rtc_ops = &bd70528_rtc_ops; 535 531 break; 532 + case ROHM_CHIP_TYPE_BD71815: 533 + irq_name = "bd71815-rtc-alm-0"; 534 + bd_rtc->reg_time_start = BD71815_REG_RTC_START; 535 + 536 + /* 537 + * See also BD718XX_ALM_EN_OFFSET: 538 + * This works for BD71828 and BD71815 as they have same offset 539 + * between ALM0 start and ALM0_MASK. If new ICs are to be 540 + * added this requires proper check as ALM0_MASK is not located 541 + * at the end of ALM0 block - but after all ALM blocks so if 542 + * amount of ALMs differ the offset to enable/disable is likely 543 + * to be incorrect and enable/disable must be given as own 544 + * reg address here. 545 + */ 546 + bd_rtc->bd718xx_alm_block_start = BD71815_REG_RTC_ALM_START; 547 + hour_reg = BD71815_REG_HOUR; 548 + rtc_ops = &bd71828_rtc_ops; 549 + break; 536 550 case ROHM_CHIP_TYPE_BD71828: 537 551 irq_name = "bd71828-rtc-alm-0"; 538 552 bd_rtc->reg_time_start = BD71828_REG_RTC_START; 553 + bd_rtc->bd718xx_alm_block_start = BD71828_REG_RTC_ALM_START; 539 554 hour_reg = BD71828_REG_RTC_HOUR; 540 555 rtc_ops = &bd71828_rtc_ops; 541 556 break; ··· 570 547 571 548 platform_set_drvdata(pdev, bd_rtc); 572 549 573 - ret = regmap_read(parent->regmap, hour_reg, &hr); 550 + ret = regmap_read(bd_rtc->regmap, hour_reg, &hr); 574 551 575 552 if (ret) { 576 553 dev_err(&pdev->dev, "Failed to reag RTC clock\n"); ··· 618 595 * from sub-registers when IRQ is disabled or freed. 619 596 */ 620 597 if (enable_main_irq) { 621 - ret = regmap_update_bits(parent->regmap, 598 + ret = regmap_update_bits(bd_rtc->regmap, 622 599 BD70528_REG_INT_MAIN_MASK, 623 600 BD70528_INT_RTC_MASK, 0); 624 601 if (ret) { ··· 633 610 static const struct platform_device_id bd718x7_rtc_id[] = { 634 611 { "bd70528-rtc", ROHM_CHIP_TYPE_BD70528 }, 635 612 { "bd71828-rtc", ROHM_CHIP_TYPE_BD71828 }, 613 + { "bd71815-rtc", ROHM_CHIP_TYPE_BD71815 }, 636 614 { }, 637 615 }; 638 616 MODULE_DEVICE_TABLE(platform, bd718x7_rtc_id);
+145
drivers/rtc/rtc-ntxec.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * The Netronix embedded controller is a microcontroller found in some 4 + * e-book readers designed by the original design manufacturer Netronix, Inc. 5 + * It contains RTC, battery monitoring, system power management, and PWM 6 + * functionality. 7 + * 8 + * This driver implements access to the RTC time and date. 9 + * 10 + * Copyright 2020 Jonathan Neuschäfer <j.neuschaefer@gmx.net> 11 + */ 12 + 13 + #include <linux/mfd/ntxec.h> 14 + #include <linux/module.h> 15 + #include <linux/platform_device.h> 16 + #include <linux/regmap.h> 17 + #include <linux/rtc.h> 18 + #include <linux/types.h> 19 + 20 + struct ntxec_rtc { 21 + struct device *dev; 22 + struct ntxec *ec; 23 + }; 24 + 25 + #define NTXEC_REG_WRITE_YEAR 0x10 26 + #define NTXEC_REG_WRITE_MONTH 0x11 27 + #define NTXEC_REG_WRITE_DAY 0x12 28 + #define NTXEC_REG_WRITE_HOUR 0x13 29 + #define NTXEC_REG_WRITE_MINUTE 0x14 30 + #define NTXEC_REG_WRITE_SECOND 0x15 31 + 32 + #define NTXEC_REG_READ_YEAR_MONTH 0x20 33 + #define NTXEC_REG_READ_MDAY_HOUR 0x21 34 + #define NTXEC_REG_READ_MINUTE_SECOND 0x23 35 + 36 + static int ntxec_read_time(struct device *dev, struct rtc_time *tm) 37 + { 38 + struct ntxec_rtc *rtc = dev_get_drvdata(dev); 39 + unsigned int value; 40 + int res; 41 + 42 + retry: 43 + res = regmap_read(rtc->ec->regmap, NTXEC_REG_READ_MINUTE_SECOND, &value); 44 + if (res < 0) 45 + return res; 46 + 47 + tm->tm_min = value >> 8; 48 + tm->tm_sec = value & 0xff; 49 + 50 + res = regmap_read(rtc->ec->regmap, NTXEC_REG_READ_MDAY_HOUR, &value); 51 + if (res < 0) 52 + return res; 53 + 54 + tm->tm_mday = value >> 8; 55 + tm->tm_hour = value & 0xff; 56 + 57 + res = regmap_read(rtc->ec->regmap, NTXEC_REG_READ_YEAR_MONTH, &value); 58 + if (res < 0) 59 + return res; 60 + 61 + tm->tm_year = (value >> 8) + 100; 62 + tm->tm_mon = (value & 0xff) - 1; 63 + 64 + /* 65 + * Read the minutes/seconds field again. If it changed since the first 66 + * read, we can't assume that the values read so far are consistent, 67 + * and should start from the beginning. 68 + */ 69 + res = regmap_read(rtc->ec->regmap, NTXEC_REG_READ_MINUTE_SECOND, &value); 70 + if (res < 0) 71 + return res; 72 + 73 + if (tm->tm_min != value >> 8 || tm->tm_sec != (value & 0xff)) 74 + goto retry; 75 + 76 + return 0; 77 + } 78 + 79 + static int ntxec_set_time(struct device *dev, struct rtc_time *tm) 80 + { 81 + struct ntxec_rtc *rtc = dev_get_drvdata(dev); 82 + 83 + /* 84 + * To avoid time overflows while we're writing the full date/time, 85 + * set the seconds field to zero before doing anything else. For the 86 + * next 59 seconds (plus however long it takes until the RTC's next 87 + * update of the second field), the seconds field will not overflow 88 + * into the other fields. 89 + */ 90 + struct reg_sequence regs[] = { 91 + { NTXEC_REG_WRITE_SECOND, ntxec_reg8(0) }, 92 + { NTXEC_REG_WRITE_YEAR, ntxec_reg8(tm->tm_year - 100) }, 93 + { NTXEC_REG_WRITE_MONTH, ntxec_reg8(tm->tm_mon + 1) }, 94 + { NTXEC_REG_WRITE_DAY, ntxec_reg8(tm->tm_mday) }, 95 + { NTXEC_REG_WRITE_HOUR, ntxec_reg8(tm->tm_hour) }, 96 + { NTXEC_REG_WRITE_MINUTE, ntxec_reg8(tm->tm_min) }, 97 + { NTXEC_REG_WRITE_SECOND, ntxec_reg8(tm->tm_sec) }, 98 + }; 99 + 100 + return regmap_multi_reg_write(rtc->ec->regmap, regs, ARRAY_SIZE(regs)); 101 + } 102 + 103 + static const struct rtc_class_ops ntxec_rtc_ops = { 104 + .read_time = ntxec_read_time, 105 + .set_time = ntxec_set_time, 106 + }; 107 + 108 + static int ntxec_rtc_probe(struct platform_device *pdev) 109 + { 110 + struct rtc_device *dev; 111 + struct ntxec_rtc *rtc; 112 + 113 + pdev->dev.of_node = pdev->dev.parent->of_node; 114 + 115 + rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); 116 + if (!rtc) 117 + return -ENOMEM; 118 + 119 + rtc->dev = &pdev->dev; 120 + rtc->ec = dev_get_drvdata(pdev->dev.parent); 121 + platform_set_drvdata(pdev, rtc); 122 + 123 + dev = devm_rtc_allocate_device(&pdev->dev); 124 + if (IS_ERR(dev)) 125 + return PTR_ERR(dev); 126 + 127 + dev->ops = &ntxec_rtc_ops; 128 + dev->range_min = RTC_TIMESTAMP_BEGIN_2000; 129 + dev->range_max = 9025257599LL; /* 2255-12-31 23:59:59 */ 130 + 131 + return devm_rtc_register_device(dev); 132 + } 133 + 134 + static struct platform_driver ntxec_rtc_driver = { 135 + .driver = { 136 + .name = "ntxec-rtc", 137 + }, 138 + .probe = ntxec_rtc_probe, 139 + }; 140 + module_platform_driver(ntxec_rtc_driver); 141 + 142 + MODULE_AUTHOR("Jonathan Neuschäfer <j.neuschaefer@gmx.net>"); 143 + MODULE_DESCRIPTION("RTC driver for Netronix EC"); 144 + MODULE_LICENSE("GPL"); 145 + MODULE_ALIAS("platform:ntxec-rtc");
+13
drivers/watchdog/Kconfig
··· 172 172 Alternatively say M to compile the driver as a module, 173 173 which will be called bd70528_wdt. 174 174 175 + config BD957XMUF_WATCHDOG 176 + tristate "ROHM BD9576MUF and BD9573MUF PMIC Watchdog" 177 + depends on MFD_ROHM_BD957XMUF 178 + select WATCHDOG_CORE 179 + help 180 + Support for the watchdog in the ROHM BD9576 and BD9573 PMICs. 181 + These PMIC ICs contain watchdog block which can be configured 182 + to toggle reset line if SoC fails to ping watchdog via GPIO. 183 + 184 + Say Y here to include support for the ROHM BD9576 or BD9573 185 + watchdog. Alternatively say M to compile the driver as a module, 186 + which will be called bd9576_wdt. 187 + 175 188 config DA9052_WATCHDOG 176 189 tristate "Dialog DA9052 Watchdog" 177 190 depends on PMIC_DA9052 || COMPILE_TEST
+1
drivers/watchdog/Makefile
··· 204 204 205 205 # Architecture Independent 206 206 obj-$(CONFIG_BD70528_WATCHDOG) += bd70528_wdt.o 207 + obj-$(CONFIG_BD957XMUF_WATCHDOG) += bd9576_wdt.o 207 208 obj-$(CONFIG_DA9052_WATCHDOG) += da9052_wdt.o 208 209 obj-$(CONFIG_DA9055_WATCHDOG) += da9055_wdt.o 209 210 obj-$(CONFIG_DA9062_WATCHDOG) += da9062_wdt.o
+291
drivers/watchdog/bd9576_wdt.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Copyright (C) 2020 ROHM Semiconductors 4 + * 5 + * ROHM BD9576MUF and BD9573MUF Watchdog driver 6 + */ 7 + 8 + #include <linux/err.h> 9 + #include <linux/gpio/consumer.h> 10 + #include <linux/mfd/rohm-bd957x.h> 11 + #include <linux/module.h> 12 + #include <linux/of.h> 13 + #include <linux/platform_device.h> 14 + #include <linux/regmap.h> 15 + #include <linux/watchdog.h> 16 + 17 + static bool nowayout; 18 + module_param(nowayout, bool, 0); 19 + MODULE_PARM_DESC(nowayout, 20 + "Watchdog cannot be stopped once started (default=\"false\")"); 21 + 22 + #define HW_MARGIN_MIN 2 23 + #define HW_MARGIN_MAX 4416 24 + #define BD957X_WDT_DEFAULT_MARGIN 4416 25 + #define WATCHDOG_TIMEOUT 30 26 + 27 + struct bd9576_wdt_priv { 28 + struct gpio_desc *gpiod_ping; 29 + struct gpio_desc *gpiod_en; 30 + struct device *dev; 31 + struct regmap *regmap; 32 + bool always_running; 33 + struct watchdog_device wdd; 34 + }; 35 + 36 + static void bd9576_wdt_disable(struct bd9576_wdt_priv *priv) 37 + { 38 + gpiod_set_value_cansleep(priv->gpiod_en, 0); 39 + } 40 + 41 + static int bd9576_wdt_ping(struct watchdog_device *wdd) 42 + { 43 + struct bd9576_wdt_priv *priv = watchdog_get_drvdata(wdd); 44 + 45 + /* Pulse */ 46 + gpiod_set_value_cansleep(priv->gpiod_ping, 1); 47 + gpiod_set_value_cansleep(priv->gpiod_ping, 0); 48 + 49 + return 0; 50 + } 51 + 52 + static int bd9576_wdt_start(struct watchdog_device *wdd) 53 + { 54 + struct bd9576_wdt_priv *priv = watchdog_get_drvdata(wdd); 55 + 56 + gpiod_set_value_cansleep(priv->gpiod_en, 1); 57 + 58 + return bd9576_wdt_ping(wdd); 59 + } 60 + 61 + static int bd9576_wdt_stop(struct watchdog_device *wdd) 62 + { 63 + struct bd9576_wdt_priv *priv = watchdog_get_drvdata(wdd); 64 + 65 + if (!priv->always_running) 66 + bd9576_wdt_disable(priv); 67 + else 68 + set_bit(WDOG_HW_RUNNING, &wdd->status); 69 + 70 + return 0; 71 + } 72 + 73 + static const struct watchdog_info bd957x_wdt_ident = { 74 + .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | 75 + WDIOF_SETTIMEOUT, 76 + .identity = "BD957x Watchdog", 77 + }; 78 + 79 + static const struct watchdog_ops bd957x_wdt_ops = { 80 + .owner = THIS_MODULE, 81 + .start = bd9576_wdt_start, 82 + .stop = bd9576_wdt_stop, 83 + .ping = bd9576_wdt_ping, 84 + }; 85 + 86 + /* Unit is hundreds of uS */ 87 + #define FASTNG_MIN 23 88 + 89 + static int find_closest_fast(int target, int *sel, int *val) 90 + { 91 + int i; 92 + int window = FASTNG_MIN; 93 + 94 + for (i = 0; i < 8 && window < target; i++) 95 + window <<= 1; 96 + 97 + *val = window; 98 + *sel = i; 99 + 100 + if (i == 8) 101 + return -EINVAL; 102 + 103 + return 0; 104 + 105 + } 106 + 107 + static int find_closest_slow_by_fast(int fast_val, int target, int *slowsel) 108 + { 109 + int sel; 110 + static const int multipliers[] = {2, 3, 7, 15}; 111 + 112 + for (sel = 0; sel < ARRAY_SIZE(multipliers) && 113 + multipliers[sel] * fast_val < target; sel++) 114 + ; 115 + 116 + if (sel == ARRAY_SIZE(multipliers)) 117 + return -EINVAL; 118 + 119 + *slowsel = sel; 120 + 121 + return 0; 122 + } 123 + 124 + static int find_closest_slow(int target, int *slow_sel, int *fast_sel) 125 + { 126 + static const int multipliers[] = {2, 3, 7, 15}; 127 + int i, j; 128 + int val = 0; 129 + int window = FASTNG_MIN; 130 + 131 + for (i = 0; i < 8; i++) { 132 + for (j = 0; j < ARRAY_SIZE(multipliers); j++) { 133 + int slow; 134 + 135 + slow = window * multipliers[j]; 136 + if (slow >= target && (!val || slow < val)) { 137 + val = slow; 138 + *fast_sel = i; 139 + *slow_sel = j; 140 + } 141 + } 142 + window <<= 1; 143 + } 144 + if (!val) 145 + return -EINVAL; 146 + 147 + return 0; 148 + } 149 + 150 + #define BD957X_WDG_TYPE_WINDOW BIT(5) 151 + #define BD957X_WDG_TYPE_SLOW 0 152 + #define BD957X_WDG_TYPE_MASK BIT(5) 153 + #define BD957X_WDG_NG_RATIO_MASK 0x18 154 + #define BD957X_WDG_FASTNG_MASK 0x7 155 + 156 + static int bd957x_set_wdt_mode(struct bd9576_wdt_priv *priv, int hw_margin, 157 + int hw_margin_min) 158 + { 159 + int ret, fastng, slowng, type, reg, mask; 160 + struct device *dev = priv->dev; 161 + 162 + /* convert to 100uS */ 163 + hw_margin *= 10; 164 + hw_margin_min *= 10; 165 + if (hw_margin_min) { 166 + int min; 167 + 168 + type = BD957X_WDG_TYPE_WINDOW; 169 + dev_dbg(dev, "Setting type WINDOW 0x%x\n", type); 170 + ret = find_closest_fast(hw_margin_min, &fastng, &min); 171 + if (ret) { 172 + dev_err(dev, "bad WDT window for fast timeout\n"); 173 + return ret; 174 + } 175 + 176 + ret = find_closest_slow_by_fast(min, hw_margin, &slowng); 177 + if (ret) { 178 + dev_err(dev, "bad WDT window\n"); 179 + return ret; 180 + } 181 + 182 + } else { 183 + type = BD957X_WDG_TYPE_SLOW; 184 + dev_dbg(dev, "Setting type SLOW 0x%x\n", type); 185 + ret = find_closest_slow(hw_margin, &slowng, &fastng); 186 + if (ret) { 187 + dev_err(dev, "bad WDT window\n"); 188 + return ret; 189 + } 190 + } 191 + 192 + slowng <<= ffs(BD957X_WDG_NG_RATIO_MASK) - 1; 193 + reg = type | slowng | fastng; 194 + mask = BD957X_WDG_TYPE_MASK | BD957X_WDG_NG_RATIO_MASK | 195 + BD957X_WDG_FASTNG_MASK; 196 + ret = regmap_update_bits(priv->regmap, BD957X_REG_WDT_CONF, 197 + mask, reg); 198 + 199 + return ret; 200 + } 201 + 202 + static int bd9576_wdt_probe(struct platform_device *pdev) 203 + { 204 + struct device *dev = &pdev->dev; 205 + struct device_node *np = dev->parent->of_node; 206 + struct bd9576_wdt_priv *priv; 207 + u32 hw_margin[2]; 208 + u32 hw_margin_max = BD957X_WDT_DEFAULT_MARGIN, hw_margin_min = 0; 209 + int ret; 210 + 211 + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 212 + if (!priv) 213 + return -ENOMEM; 214 + 215 + platform_set_drvdata(pdev, priv); 216 + 217 + priv->dev = dev; 218 + priv->regmap = dev_get_regmap(dev->parent, NULL); 219 + if (!priv->regmap) { 220 + dev_err(dev, "No regmap found\n"); 221 + return -ENODEV; 222 + } 223 + 224 + priv->gpiod_en = devm_gpiod_get_from_of_node(dev, dev->parent->of_node, 225 + "rohm,watchdog-enable-gpios", 226 + 0, GPIOD_OUT_LOW, 227 + "watchdog-enable"); 228 + if (IS_ERR(priv->gpiod_en)) 229 + return dev_err_probe(dev, PTR_ERR(priv->gpiod_en), 230 + "getting watchdog-enable GPIO failed\n"); 231 + 232 + priv->gpiod_ping = devm_gpiod_get_from_of_node(dev, dev->parent->of_node, 233 + "rohm,watchdog-ping-gpios", 234 + 0, GPIOD_OUT_LOW, 235 + "watchdog-ping"); 236 + if (IS_ERR(priv->gpiod_ping)) 237 + return dev_err_probe(dev, PTR_ERR(priv->gpiod_ping), 238 + "getting watchdog-ping GPIO failed\n"); 239 + 240 + ret = of_property_read_variable_u32_array(np, "rohm,hw-timeout-ms", 241 + &hw_margin[0], 1, 2); 242 + if (ret < 0 && ret != -EINVAL) 243 + return ret; 244 + 245 + if (ret == 1) 246 + hw_margin_max = hw_margin[0]; 247 + 248 + if (ret == 2) { 249 + hw_margin_max = hw_margin[1]; 250 + hw_margin_min = hw_margin[0]; 251 + } 252 + 253 + ret = bd957x_set_wdt_mode(priv, hw_margin_max, hw_margin_min); 254 + if (ret) 255 + return ret; 256 + 257 + priv->always_running = of_property_read_bool(np, "always-running"); 258 + 259 + watchdog_set_drvdata(&priv->wdd, priv); 260 + 261 + priv->wdd.info = &bd957x_wdt_ident; 262 + priv->wdd.ops = &bd957x_wdt_ops; 263 + priv->wdd.min_hw_heartbeat_ms = hw_margin_min; 264 + priv->wdd.max_hw_heartbeat_ms = hw_margin_max; 265 + priv->wdd.parent = dev; 266 + priv->wdd.timeout = WATCHDOG_TIMEOUT; 267 + 268 + watchdog_init_timeout(&priv->wdd, 0, dev); 269 + watchdog_set_nowayout(&priv->wdd, nowayout); 270 + 271 + watchdog_stop_on_reboot(&priv->wdd); 272 + 273 + if (priv->always_running) 274 + bd9576_wdt_start(&priv->wdd); 275 + 276 + return devm_watchdog_register_device(dev, &priv->wdd); 277 + } 278 + 279 + static struct platform_driver bd9576_wdt_driver = { 280 + .driver = { 281 + .name = "bd9576-wdt", 282 + }, 283 + .probe = bd9576_wdt_probe, 284 + }; 285 + 286 + module_platform_driver(bd9576_wdt_driver); 287 + 288 + MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); 289 + MODULE_DESCRIPTION("ROHM BD9576/BD9573 Watchdog driver"); 290 + MODULE_LICENSE("GPL"); 291 + MODULE_ALIAS("platform:bd9576-wdt");
-128
include/linux/mfd/ab3100.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Copyright (C) 2007-2009 ST-Ericsson AB 4 - * AB3100 core access functions 5 - * Author: Linus Walleij <linus.walleij@stericsson.com> 6 - */ 7 - 8 - #include <linux/regulator/machine.h> 9 - 10 - struct device; 11 - 12 - #ifndef MFD_AB3100_H 13 - #define MFD_AB3100_H 14 - 15 - 16 - #define AB3100_P1A 0xc0 17 - #define AB3100_P1B 0xc1 18 - #define AB3100_P1C 0xc2 19 - #define AB3100_P1D 0xc3 20 - #define AB3100_P1E 0xc4 21 - #define AB3100_P1F 0xc5 22 - #define AB3100_P1G 0xc6 23 - #define AB3100_R2A 0xc7 24 - #define AB3100_R2B 0xc8 25 - 26 - /* 27 - * AB3100, EVENTA1, A2 and A3 event register flags 28 - * these are catenated into a single 32-bit flag in the code 29 - * for event notification broadcasts. 30 - */ 31 - #define AB3100_EVENTA1_ONSWA (0x01<<16) 32 - #define AB3100_EVENTA1_ONSWB (0x02<<16) 33 - #define AB3100_EVENTA1_ONSWC (0x04<<16) 34 - #define AB3100_EVENTA1_DCIO (0x08<<16) 35 - #define AB3100_EVENTA1_OVER_TEMP (0x10<<16) 36 - #define AB3100_EVENTA1_SIM_OFF (0x20<<16) 37 - #define AB3100_EVENTA1_VBUS (0x40<<16) 38 - #define AB3100_EVENTA1_VSET_USB (0x80<<16) 39 - 40 - #define AB3100_EVENTA2_READY_TX (0x01<<8) 41 - #define AB3100_EVENTA2_READY_RX (0x02<<8) 42 - #define AB3100_EVENTA2_OVERRUN_ERROR (0x04<<8) 43 - #define AB3100_EVENTA2_FRAMING_ERROR (0x08<<8) 44 - #define AB3100_EVENTA2_CHARG_OVERCURRENT (0x10<<8) 45 - #define AB3100_EVENTA2_MIDR (0x20<<8) 46 - #define AB3100_EVENTA2_BATTERY_REM (0x40<<8) 47 - #define AB3100_EVENTA2_ALARM (0x80<<8) 48 - 49 - #define AB3100_EVENTA3_ADC_TRIG5 (0x01) 50 - #define AB3100_EVENTA3_ADC_TRIG4 (0x02) 51 - #define AB3100_EVENTA3_ADC_TRIG3 (0x04) 52 - #define AB3100_EVENTA3_ADC_TRIG2 (0x08) 53 - #define AB3100_EVENTA3_ADC_TRIGVBAT (0x10) 54 - #define AB3100_EVENTA3_ADC_TRIGVTX (0x20) 55 - #define AB3100_EVENTA3_ADC_TRIG1 (0x40) 56 - #define AB3100_EVENTA3_ADC_TRIG0 (0x80) 57 - 58 - /* AB3100, STR register flags */ 59 - #define AB3100_STR_ONSWA (0x01) 60 - #define AB3100_STR_ONSWB (0x02) 61 - #define AB3100_STR_ONSWC (0x04) 62 - #define AB3100_STR_DCIO (0x08) 63 - #define AB3100_STR_BOOT_MODE (0x10) 64 - #define AB3100_STR_SIM_OFF (0x20) 65 - #define AB3100_STR_BATT_REMOVAL (0x40) 66 - #define AB3100_STR_VBUS (0x80) 67 - 68 - /* 69 - * AB3100 contains 8 regulators, one external regulator controller 70 - * and a buck converter, further the LDO E and buck converter can 71 - * have separate settings if they are in sleep mode, this is 72 - * modeled as a separate regulator. 73 - */ 74 - #define AB3100_NUM_REGULATORS 10 75 - 76 - /** 77 - * struct ab3100 78 - * @access_mutex: lock out concurrent accesses to the AB3100 registers 79 - * @dev: pointer to the containing device 80 - * @i2c_client: I2C client for this chip 81 - * @testreg_client: secondary client for test registers 82 - * @chip_name: name of this chip variant 83 - * @chip_id: 8 bit chip ID for this chip variant 84 - * @event_subscribers: event subscribers are listed here 85 - * @startup_events: a copy of the first reading of the event registers 86 - * @startup_events_read: whether the first events have been read 87 - * 88 - * This struct is PRIVATE and devices using it should NOT 89 - * access ANY fields. It is used as a token for calling the 90 - * AB3100 functions. 91 - */ 92 - struct ab3100 { 93 - struct mutex access_mutex; 94 - struct device *dev; 95 - struct i2c_client *i2c_client; 96 - struct i2c_client *testreg_client; 97 - char chip_name[32]; 98 - u8 chip_id; 99 - struct blocking_notifier_head event_subscribers; 100 - u8 startup_events[3]; 101 - bool startup_events_read; 102 - }; 103 - 104 - /** 105 - * struct ab3100_platform_data 106 - * Data supplied to initialize board connections to the AB3100 107 - * @reg_constraints: regulator constraints for target board 108 - * the order of these constraints are: LDO A, C, D, E, 109 - * F, G, H, K, EXT and BUCK. 110 - * @reg_initvals: initial values for the regulator registers 111 - * plus two sleep settings for LDO E and the BUCK converter. 112 - * exactly AB3100_NUM_REGULATORS+2 values must be sent in. 113 - * Order: LDO A, C, E, E sleep, F, G, H, K, EXT, BUCK, 114 - * BUCK sleep, LDO D. (LDO D need to be initialized last.) 115 - * @external_voltage: voltage level of the external regulator. 116 - */ 117 - struct ab3100_platform_data { 118 - struct regulator_init_data reg_constraints[AB3100_NUM_REGULATORS]; 119 - u8 reg_initvals[AB3100_NUM_REGULATORS+2]; 120 - int external_voltage; 121 - }; 122 - 123 - int ab3100_event_register(struct ab3100 *ab3100, 124 - struct notifier_block *nb); 125 - int ab3100_event_unregister(struct ab3100 *ab3100, 126 - struct notifier_block *nb); 127 - 128 - #endif /* MFD_AB3100_H */
+281
include/linux/mfd/atc260x/atc2603c.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* 3 + * ATC2603C PMIC register definitions 4 + * 5 + * Copyright (C) 2020 Cristian Ciocaltea <cristian.ciocaltea@gmail.com> 6 + */ 7 + 8 + #ifndef __LINUX_MFD_ATC260X_ATC2603C_H 9 + #define __LINUX_MFD_ATC260X_ATC2603C_H 10 + 11 + enum atc2603c_irq_def { 12 + ATC2603C_IRQ_AUDIO = 0, 13 + ATC2603C_IRQ_OV, 14 + ATC2603C_IRQ_OC, 15 + ATC2603C_IRQ_OT, 16 + ATC2603C_IRQ_UV, 17 + ATC2603C_IRQ_ALARM, 18 + ATC2603C_IRQ_ONOFF, 19 + ATC2603C_IRQ_SGPIO, 20 + ATC2603C_IRQ_IR, 21 + ATC2603C_IRQ_REMCON, 22 + ATC2603C_IRQ_POWER_IN, 23 + }; 24 + 25 + /* PMU Registers */ 26 + #define ATC2603C_PMU_SYS_CTL0 0x00 27 + #define ATC2603C_PMU_SYS_CTL1 0x01 28 + #define ATC2603C_PMU_SYS_CTL2 0x02 29 + #define ATC2603C_PMU_SYS_CTL3 0x03 30 + #define ATC2603C_PMU_SYS_CTL4 0x04 31 + #define ATC2603C_PMU_SYS_CTL5 0x05 32 + #define ATC2603C_PMU_SYS_CTL6 0x06 33 + #define ATC2603C_PMU_SYS_CTL7 0x07 34 + #define ATC2603C_PMU_SYS_CTL8 0x08 35 + #define ATC2603C_PMU_SYS_CTL9 0x09 36 + #define ATC2603C_PMU_BAT_CTL0 0x0A 37 + #define ATC2603C_PMU_BAT_CTL1 0x0B 38 + #define ATC2603C_PMU_VBUS_CTL0 0x0C 39 + #define ATC2603C_PMU_VBUS_CTL1 0x0D 40 + #define ATC2603C_PMU_WALL_CTL0 0x0E 41 + #define ATC2603C_PMU_WALL_CTL1 0x0F 42 + #define ATC2603C_PMU_SYS_PENDING 0x10 43 + #define ATC2603C_PMU_DC1_CTL0 0x11 44 + #define ATC2603C_PMU_DC1_CTL1 0x12 // Undocumented 45 + #define ATC2603C_PMU_DC1_CTL2 0x13 // Undocumented 46 + #define ATC2603C_PMU_DC2_CTL0 0x14 47 + #define ATC2603C_PMU_DC2_CTL1 0x15 // Undocumented 48 + #define ATC2603C_PMU_DC2_CTL2 0x16 // Undocumented 49 + #define ATC2603C_PMU_DC3_CTL0 0x17 50 + #define ATC2603C_PMU_DC3_CTL1 0x18 // Undocumented 51 + #define ATC2603C_PMU_DC3_CTL2 0x19 // Undocumented 52 + #define ATC2603C_PMU_DC4_CTL0 0x1A // Undocumented 53 + #define ATC2603C_PMU_DC4_CTL1 0x1B // Undocumented 54 + #define ATC2603C_PMU_DC5_CTL0 0x1C // Undocumented 55 + #define ATC2603C_PMU_DC5_CTL1 0x1D // Undocumented 56 + #define ATC2603C_PMU_LDO1_CTL 0x1E 57 + #define ATC2603C_PMU_LDO2_CTL 0x1F 58 + #define ATC2603C_PMU_LDO3_CTL 0x20 59 + #define ATC2603C_PMU_LDO4_CTL 0x21 // Undocumented 60 + #define ATC2603C_PMU_LDO5_CTL 0x22 61 + #define ATC2603C_PMU_LDO6_CTL 0x23 62 + #define ATC2603C_PMU_LDO7_CTL 0x24 63 + #define ATC2603C_PMU_LDO8_CTL 0x25 // Undocumented 64 + #define ATC2603C_PMU_LDO9_CTL 0x26 // Undocumented 65 + #define ATC2603C_PMU_LDO10_CTL 0x27 // Undocumented 66 + #define ATC2603C_PMU_LDO11_CTL 0x28 67 + #define ATC2603C_PMU_SWITCH_CTL 0x29 68 + #define ATC2603C_PMU_OV_CTL0 0x2A 69 + #define ATC2603C_PMU_OV_CTL1 0x2B 70 + #define ATC2603C_PMU_OV_STATUS 0x2C 71 + #define ATC2603C_PMU_OV_EN 0x2D 72 + #define ATC2603C_PMU_OV_INT_EN 0x2E 73 + #define ATC2603C_PMU_OC_CTL 0x2F 74 + #define ATC2603C_PMU_OC_STATUS 0x30 75 + #define ATC2603C_PMU_OC_EN 0x31 76 + #define ATC2603C_PMU_OC_INT_EN 0x32 77 + #define ATC2603C_PMU_UV_CTL0 0x33 78 + #define ATC2603C_PMU_UV_CTL1 0x34 79 + #define ATC2603C_PMU_UV_STATUS 0x35 80 + #define ATC2603C_PMU_UV_EN 0x36 81 + #define ATC2603C_PMU_UV_INT_EN 0x37 82 + #define ATC2603C_PMU_OT_CTL 0x38 83 + #define ATC2603C_PMU_CHARGER_CTL0 0x39 84 + #define ATC2603C_PMU_CHARGER_CTL1 0x3A 85 + #define ATC2603C_PMU_CHARGER_CTL2 0x3B 86 + #define ATC2603C_PMU_BAKCHARGER_CTL 0x3C // Undocumented 87 + #define ATC2603C_PMU_APDS_CTL 0x3D 88 + #define ATC2603C_PMU_AUXADC_CTL0 0x3E 89 + #define ATC2603C_PMU_AUXADC_CTL1 0x3F 90 + #define ATC2603C_PMU_BATVADC 0x40 91 + #define ATC2603C_PMU_BATIADC 0x41 92 + #define ATC2603C_PMU_WALLVADC 0x42 93 + #define ATC2603C_PMU_WALLIADC 0x43 94 + #define ATC2603C_PMU_VBUSVADC 0x44 95 + #define ATC2603C_PMU_VBUSIADC 0x45 96 + #define ATC2603C_PMU_SYSPWRADC 0x46 97 + #define ATC2603C_PMU_REMCONADC 0x47 98 + #define ATC2603C_PMU_SVCCADC 0x48 99 + #define ATC2603C_PMU_CHGIADC 0x49 100 + #define ATC2603C_PMU_IREFADC 0x4A 101 + #define ATC2603C_PMU_BAKBATADC 0x4B 102 + #define ATC2603C_PMU_ICTEMPADC 0x4C 103 + #define ATC2603C_PMU_AUXADC0 0x4D 104 + #define ATC2603C_PMU_AUXADC1 0x4E 105 + #define ATC2603C_PMU_AUXADC2 0x4F 106 + #define ATC2603C_PMU_ICMADC 0x50 107 + #define ATC2603C_PMU_BDG_CTL 0x51 // Undocumented 108 + #define ATC2603C_RTC_CTL 0x52 109 + #define ATC2603C_RTC_MSALM 0x53 110 + #define ATC2603C_RTC_HALM 0x54 111 + #define ATC2603C_RTC_YMDALM 0x55 112 + #define ATC2603C_RTC_MS 0x56 113 + #define ATC2603C_RTC_H 0x57 114 + #define ATC2603C_RTC_DC 0x58 115 + #define ATC2603C_RTC_YMD 0x59 116 + #define ATC2603C_EFUSE_DAT 0x5A // Undocumented 117 + #define ATC2603C_EFUSECRTL1 0x5B // Undocumented 118 + #define ATC2603C_EFUSECRTL2 0x5C // Undocumented 119 + #define ATC2603C_PMU_FW_USE0 0x5D // Undocumented 120 + #define ATC2603C_PMU_FW_USE1 0x5E // Undocumented 121 + #define ATC2603C_PMU_FW_USE2 0x5F // Undocumented 122 + #define ATC2603C_PMU_FW_USE3 0x60 // Undocumented 123 + #define ATC2603C_PMU_FW_USE4 0x61 // Undocumented 124 + #define ATC2603C_PMU_ABNORMAL_STATUS 0x62 125 + #define ATC2603C_PMU_WALL_APDS_CTL 0x63 126 + #define ATC2603C_PMU_REMCON_CTL0 0x64 127 + #define ATC2603C_PMU_REMCON_CTL1 0x65 128 + #define ATC2603C_PMU_MUX_CTL0 0x66 129 + #define ATC2603C_PMU_SGPIO_CTL0 0x67 130 + #define ATC2603C_PMU_SGPIO_CTL1 0x68 131 + #define ATC2603C_PMU_SGPIO_CTL2 0x69 132 + #define ATC2603C_PMU_SGPIO_CTL3 0x6A 133 + #define ATC2603C_PMU_SGPIO_CTL4 0x6B 134 + #define ATC2603C_PWMCLK_CTL 0x6C 135 + #define ATC2603C_PWM0_CTL 0x6D 136 + #define ATC2603C_PWM1_CTL 0x6E 137 + #define ATC2603C_PMU_ADC_DBG0 0x70 138 + #define ATC2603C_PMU_ADC_DBG1 0x71 139 + #define ATC2603C_PMU_ADC_DBG2 0x72 140 + #define ATC2603C_PMU_ADC_DBG3 0x73 141 + #define ATC2603C_PMU_ADC_DBG4 0x74 142 + #define ATC2603C_IRC_CTL 0x80 143 + #define ATC2603C_IRC_STAT 0x81 144 + #define ATC2603C_IRC_CC 0x82 145 + #define ATC2603C_IRC_KDC 0x83 146 + #define ATC2603C_IRC_WK 0x84 147 + #define ATC2603C_IRC_RCC 0x85 148 + #define ATC2603C_IRC_FILTER 0x86 149 + 150 + /* AUDIO_OUT Registers */ 151 + #define ATC2603C_AUDIOINOUT_CTL 0xA0 152 + #define ATC2603C_AUDIO_DEBUGOUTCTL 0xA1 153 + #define ATC2603C_DAC_DIGITALCTL 0xA2 154 + #define ATC2603C_DAC_VOLUMECTL0 0xA3 155 + #define ATC2603C_DAC_ANALOG0 0xA4 156 + #define ATC2603C_DAC_ANALOG1 0xA5 157 + #define ATC2603C_DAC_ANALOG2 0xA6 158 + #define ATC2603C_DAC_ANALOG3 0xA7 159 + 160 + /* AUDIO_IN Registers */ 161 + #define ATC2603C_ADC_DIGITALCTL 0xA8 162 + #define ATC2603C_ADC_HPFCTL 0xA9 163 + #define ATC2603C_ADC_CTL 0xAA 164 + #define ATC2603C_AGC_CTL0 0xAB 165 + #define ATC2603C_AGC_CTL1 0xAC // Undocumented 166 + #define ATC2603C_AGC_CTL2 0xAD 167 + #define ATC2603C_ADC_ANALOG0 0xAE 168 + #define ATC2603C_ADC_ANALOG1 0xAF 169 + 170 + /* PCM_IF Registers */ 171 + #define ATC2603C_PCM0_CTL 0xB0 // Undocumented 172 + #define ATC2603C_PCM1_CTL 0xB1 // Undocumented 173 + #define ATC2603C_PCM2_CTL 0xB2 // Undocumented 174 + #define ATC2603C_PCMIF_CTL 0xB3 // Undocumented 175 + 176 + /* CMU_CONTROL Registers */ 177 + #define ATC2603C_CMU_DEVRST 0xC1 // Undocumented 178 + 179 + /* INTS Registers */ 180 + #define ATC2603C_INTS_PD 0xC8 181 + #define ATC2603C_INTS_MSK 0xC9 182 + 183 + /* MFP Registers */ 184 + #define ATC2603C_MFP_CTL 0xD0 185 + #define ATC2603C_PAD_VSEL 0xD1 // Undocumented 186 + #define ATC2603C_GPIO_OUTEN 0xD2 187 + #define ATC2603C_GPIO_INEN 0xD3 188 + #define ATC2603C_GPIO_DAT 0xD4 189 + #define ATC2603C_PAD_DRV 0xD5 190 + #define ATC2603C_PAD_EN 0xD6 191 + #define ATC2603C_DEBUG_SEL 0xD7 // Undocumented 192 + #define ATC2603C_DEBUG_IE 0xD8 // Undocumented 193 + #define ATC2603C_DEBUG_OE 0xD9 // Undocumented 194 + #define ATC2603C_BIST_START 0x0A // Undocumented 195 + #define ATC2603C_BIST_RESULT 0x0B // Undocumented 196 + #define ATC2603C_CHIP_VER 0xDC 197 + 198 + /* TWSI Registers */ 199 + #define ATC2603C_SADDR 0xFF 200 + 201 + /* PMU_SYS_CTL0 Register Mask Bits */ 202 + #define ATC2603C_PMU_SYS_CTL0_IR_WK_EN BIT(5) 203 + #define ATC2603C_PMU_SYS_CTL0_RESET_WK_EN BIT(6) 204 + #define ATC2603C_PMU_SYS_CTL0_HDSW_WK_EN BIT(7) 205 + #define ATC2603C_PMU_SYS_CTL0_ALARM_WK_EN BIT(8) 206 + #define ATC2603C_PMU_SYS_CTL0_REM_CON_WK_EN BIT(9) 207 + #define ATC2603C_PMU_SYS_CTL0_RESTART_EN BIT(10) 208 + #define ATC2603C_PMU_SYS_CTL0_SGPIOIRQ_WK_EN BIT(11) 209 + #define ATC2603C_PMU_SYS_CTL0_ONOFF_SHORT_WK_EN BIT(12) 210 + #define ATC2603C_PMU_SYS_CTL0_ONOFF_LONG_WK_EN BIT(13) 211 + #define ATC2603C_PMU_SYS_CTL0_WALL_WK_EN BIT(14) 212 + #define ATC2603C_PMU_SYS_CTL0_USB_WK_EN BIT(15) 213 + #define ATC2603C_PMU_SYS_CTL0_WK_ALL (GENMASK(15, 5) & (~BIT(10))) 214 + 215 + /* PMU_SYS_CTL1 Register Mask Bits */ 216 + #define ATC2603C_PMU_SYS_CTL1_EN_S1 BIT(0) 217 + #define ATC2603C_PMU_SYS_CTL1_LB_S4_EN BIT(2) 218 + #define ATC2603C_PMU_SYS_CTL1_LB_S4 GENMASK(4, 3) 219 + #define ATC2603C_PMU_SYS_CTL1_LB_S4_3_1V BIT(4) 220 + #define ATC2603C_PMU_SYS_CTL1_IR_WK_FLAG BIT(5) 221 + #define ATC2603C_PMU_SYS_CTL1_RESET_WK_FLAG BIT(6) 222 + #define ATC2603C_PMU_SYS_CTL1_HDSW_WK_FLAG BIT(7) 223 + #define ATC2603C_PMU_SYS_CTL1_ALARM_WK_FLAG BIT(8) 224 + #define ATC2603C_PMU_SYS_CTL1_REM_CON_WK_FLAG BIT(9) 225 + #define ATC2603C_PMU_SYS_CTL1_ONOFF_PRESS_RESET_IRQ_PD BIT(10) 226 + #define ATC2603C_PMU_SYS_CTL1_SGPIOIRQ_WK_FLAG BIT(11) 227 + #define ATC2603C_PMU_SYS_CTL1_ONOFF_SHORT_WK_FLAG BIT(12) 228 + #define ATC2603C_PMU_SYS_CTL1_ONOFF_LONG_WK_FLAG BIT(13) 229 + #define ATC2603C_PMU_SYS_CTL1_WALL_WK_FLAG BIT(14) 230 + #define ATC2603C_PMU_SYS_CTL1_USB_WK_FLAG BIT(15) 231 + 232 + /* PMU_SYS_CTL2 Register Mask Bits */ 233 + #define ATC2603C_PMU_SYS_CTL2_PMU_A_EN BIT(0) 234 + #define ATC2603C_PMU_SYS_CTL2_ONOFF_PRESS_INT_EN BIT(1) 235 + #define ATC2603C_PMU_SYS_CTL2_ONOFF_PRESS_PD BIT(2) 236 + #define ATC2603C_PMU_SYS_CTL2_S2TIMER GENMASK(5, 3) 237 + #define ATC2603C_PMU_SYS_CTL2_S2_TIMER_EN BIT(6) 238 + #define ATC2603C_PMU_SYS_CTL2_ONOFF_RESET_TIME_SEL GENMASK(8, 7) 239 + #define ATC2603C_PMU_SYS_CTL2_ONOFF_PRESS_RESET_EN BIT(9) 240 + #define ATC2603C_PMU_SYS_CTL2_ONOFF_PRESS_TIME GENMASK(11, 10) 241 + #define ATC2603C_PMU_SYS_CTL2_ONOFF_INT_EN BIT(12) 242 + #define ATC2603C_PMU_SYS_CTL2_ONOFF_LONG_PRESS BIT(13) 243 + #define ATC2603C_PMU_SYS_CTL2_ONOFF_SHORT_PRESS BIT(14) 244 + #define ATC2603C_PMU_SYS_CTL2_ONOFF_PRESS BIT(15) 245 + 246 + /* PMU_SYS_CTL3 Register Mask Bits */ 247 + #define ATC2603C_PMU_SYS_CTL3_S2S3TOS1_TIMER GENMASK(8, 7) 248 + #define ATC2603C_PMU_SYS_CTL3_S2S3TOS1_TIMER_EN BIT(9) 249 + #define ATC2603C_PMU_SYS_CTL3_S3_TIMER GENMASK(12, 10) 250 + #define ATC2603C_PMU_SYS_CTL3_S3_TIMER_EN BIT(13) 251 + #define ATC2603C_PMU_SYS_CTL3_EN_S3 BIT(14) 252 + #define ATC2603C_PMU_SYS_CTL3_EN_S2 BIT(15) 253 + 254 + /* PMU_SYS_CTL5 Register Mask Bits */ 255 + #define ATC2603C_PMU_SYS_CTL5_WALLWKDTEN BIT(7) 256 + #define ATC2603C_PMU_SYS_CTL5_VBUSWKDTEN BIT(8) 257 + #define ATC2603C_PMU_SYS_CTL5_REMCON_DECT_EN BIT(9) 258 + #define ATC2603C_PMU_SYS_CTL5_ONOFF_8S_SEL BIT(10) 259 + 260 + /* INTS_MSK Register Mask Bits */ 261 + #define ATC2603C_INTS_MSK_AUDIO BIT(0) 262 + #define ATC2603C_INTS_MSK_OV BIT(1) 263 + #define ATC2603C_INTS_MSK_OC BIT(2) 264 + #define ATC2603C_INTS_MSK_OT BIT(3) 265 + #define ATC2603C_INTS_MSK_UV BIT(4) 266 + #define ATC2603C_INTS_MSK_ALARM BIT(5) 267 + #define ATC2603C_INTS_MSK_ONOFF BIT(6) 268 + #define ATC2603C_INTS_MSK_SGPIO BIT(7) 269 + #define ATC2603C_INTS_MSK_IR BIT(8) 270 + #define ATC2603C_INTS_MSK_REMCON BIT(9) 271 + #define ATC2603C_INTS_MSK_POWERIN BIT(10) 272 + 273 + /* CMU_DEVRST Register Mask Bits */ 274 + #define ATC2603C_CMU_DEVRST_MFP BIT(1) 275 + #define ATC2603C_CMU_DEVRST_INTS BIT(2) 276 + #define ATC2603C_CMU_DEVRST_AUDIO BIT(4) 277 + 278 + /* PAD_EN Register Mask Bits */ 279 + #define ATC2603C_PAD_EN_EXTIRQ BIT(0) 280 + 281 + #endif /* __LINUX_MFD_ATC260X_ATC2603C_H */
+308
include/linux/mfd/atc260x/atc2609a.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* 3 + * ATC2609A PMIC register definitions 4 + * 5 + * Copyright (C) 2019 Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> 6 + */ 7 + 8 + #ifndef __LINUX_MFD_ATC260X_ATC2609A_H 9 + #define __LINUX_MFD_ATC260X_ATC2609A_H 10 + 11 + enum atc2609a_irq_def { 12 + ATC2609A_IRQ_AUDIO = 0, 13 + ATC2609A_IRQ_OV, 14 + ATC2609A_IRQ_OC, 15 + ATC2609A_IRQ_OT, 16 + ATC2609A_IRQ_UV, 17 + ATC2609A_IRQ_ALARM, 18 + ATC2609A_IRQ_ONOFF, 19 + ATC2609A_IRQ_WKUP, 20 + ATC2609A_IRQ_IR, 21 + ATC2609A_IRQ_REMCON, 22 + ATC2609A_IRQ_POWER_IN, 23 + }; 24 + 25 + /* PMU Registers */ 26 + #define ATC2609A_PMU_SYS_CTL0 0x00 27 + #define ATC2609A_PMU_SYS_CTL1 0x01 28 + #define ATC2609A_PMU_SYS_CTL2 0x02 29 + #define ATC2609A_PMU_SYS_CTL3 0x03 30 + #define ATC2609A_PMU_SYS_CTL4 0x04 31 + #define ATC2609A_PMU_SYS_CTL5 0x05 32 + #define ATC2609A_PMU_SYS_CTL6 0x06 33 + #define ATC2609A_PMU_SYS_CTL7 0x07 34 + #define ATC2609A_PMU_SYS_CTL8 0x08 35 + #define ATC2609A_PMU_SYS_CTL9 0x09 36 + #define ATC2609A_PMU_BAT_CTL0 0x0A 37 + #define ATC2609A_PMU_BAT_CTL1 0x0B 38 + #define ATC2609A_PMU_VBUS_CTL0 0x0C 39 + #define ATC2609A_PMU_VBUS_CTL1 0x0D 40 + #define ATC2609A_PMU_WALL_CTL0 0x0E 41 + #define ATC2609A_PMU_WALL_CTL1 0x0F 42 + #define ATC2609A_PMU_SYS_PENDING 0x10 43 + #define ATC2609A_PMU_APDS_CTL0 0x11 44 + #define ATC2609A_PMU_APDS_CTL1 0x12 45 + #define ATC2609A_PMU_APDS_CTL2 0x13 46 + #define ATC2609A_PMU_CHARGER_CTL 0x14 47 + #define ATC2609A_PMU_BAKCHARGER_CTL 0x15 48 + #define ATC2609A_PMU_SWCHG_CTL0 0x16 49 + #define ATC2609A_PMU_SWCHG_CTL1 0x17 50 + #define ATC2609A_PMU_SWCHG_CTL2 0x18 51 + #define ATC2609A_PMU_SWCHG_CTL3 0x19 52 + #define ATC2609A_PMU_SWCHG_CTL4 0x1A 53 + #define ATC2609A_PMU_DC_OSC 0x1B 54 + #define ATC2609A_PMU_DC0_CTL0 0x1C 55 + #define ATC2609A_PMU_DC0_CTL1 0x1D 56 + #define ATC2609A_PMU_DC0_CTL2 0x1E 57 + #define ATC2609A_PMU_DC0_CTL3 0x1F 58 + #define ATC2609A_PMU_DC0_CTL4 0x20 59 + #define ATC2609A_PMU_DC0_CTL5 0x21 60 + #define ATC2609A_PMU_DC0_CTL6 0x22 61 + #define ATC2609A_PMU_DC1_CTL0 0x23 62 + #define ATC2609A_PMU_DC1_CTL1 0x24 63 + #define ATC2609A_PMU_DC1_CTL2 0x25 64 + #define ATC2609A_PMU_DC1_CTL3 0x26 65 + #define ATC2609A_PMU_DC1_CTL4 0x27 66 + #define ATC2609A_PMU_DC1_CTL5 0x28 67 + #define ATC2609A_PMU_DC1_CTL6 0x29 68 + #define ATC2609A_PMU_DC2_CTL0 0x2A 69 + #define ATC2609A_PMU_DC2_CTL1 0x2B 70 + #define ATC2609A_PMU_DC2_CTL2 0x2C 71 + #define ATC2609A_PMU_DC2_CTL3 0x2D 72 + #define ATC2609A_PMU_DC2_CTL4 0x2E 73 + #define ATC2609A_PMU_DC2_CTL5 0x2F 74 + #define ATC2609A_PMU_DC2_CTL6 0x30 75 + #define ATC2609A_PMU_DC3_CTL0 0x31 76 + #define ATC2609A_PMU_DC3_CTL1 0x32 77 + #define ATC2609A_PMU_DC3_CTL2 0x33 78 + #define ATC2609A_PMU_DC3_CTL3 0x34 79 + #define ATC2609A_PMU_DC3_CTL4 0x35 80 + #define ATC2609A_PMU_DC3_CTL5 0x36 81 + #define ATC2609A_PMU_DC3_CTL6 0x37 82 + #define ATC2609A_PMU_DC_ZR 0x38 83 + #define ATC2609A_PMU_LDO0_CTL0 0x39 84 + #define ATC2609A_PMU_LDO0_CTL1 0x3A 85 + #define ATC2609A_PMU_LDO1_CTL0 0x3B 86 + #define ATC2609A_PMU_LDO1_CTL1 0x3C 87 + #define ATC2609A_PMU_LDO2_CTL0 0x3D 88 + #define ATC2609A_PMU_LDO2_CTL1 0x3E 89 + #define ATC2609A_PMU_LDO3_CTL0 0x3F 90 + #define ATC2609A_PMU_LDO3_CTL1 0x40 91 + #define ATC2609A_PMU_LDO4_CTL0 0x41 92 + #define ATC2609A_PMU_LDO4_CTL1 0x42 93 + #define ATC2609A_PMU_LDO5_CTL0 0x43 94 + #define ATC2609A_PMU_LDO5_CTL1 0x44 95 + #define ATC2609A_PMU_LDO6_CTL0 0x45 96 + #define ATC2609A_PMU_LDO6_CTL1 0x46 97 + #define ATC2609A_PMU_LDO7_CTL0 0x47 98 + #define ATC2609A_PMU_LDO7_CTL1 0x48 99 + #define ATC2609A_PMU_LDO8_CTL0 0x49 100 + #define ATC2609A_PMU_LDO8_CTL1 0x4A 101 + #define ATC2609A_PMU_LDO9_CTL 0x4B 102 + #define ATC2609A_PMU_OV_INT_EN 0x4C 103 + #define ATC2609A_PMU_OV_STATUS 0x4D 104 + #define ATC2609A_PMU_UV_INT_EN 0x4E 105 + #define ATC2609A_PMU_UV_STATUS 0x4F 106 + #define ATC2609A_PMU_OC_INT_EN 0x50 107 + #define ATC2609A_PMU_OC_STATUS 0x51 108 + #define ATC2609A_PMU_OT_CTL 0x52 109 + #define ATC2609A_PMU_CM_CTL0 0x53 110 + #define ATC2609A_PMU_FW_USE0 0x54 111 + #define ATC2609A_PMU_FW_USE1 0x55 112 + #define ATC2609A_PMU_ADC12B_I 0x56 113 + #define ATC2609A_PMU_ADC12B_V 0x57 114 + #define ATC2609A_PMU_ADC12B_DUMMY 0x58 115 + #define ATC2609A_PMU_AUXADC_CTL0 0x59 116 + #define ATC2609A_PMU_AUXADC_CTL1 0x5A 117 + #define ATC2609A_PMU_BATVADC 0x5B 118 + #define ATC2609A_PMU_BATIADC 0x5C 119 + #define ATC2609A_PMU_WALLVADC 0x5D 120 + #define ATC2609A_PMU_WALLIADC 0x5E 121 + #define ATC2609A_PMU_VBUSVADC 0x5F 122 + #define ATC2609A_PMU_VBUSIADC 0x60 123 + #define ATC2609A_PMU_SYSPWRADC 0x61 124 + #define ATC2609A_PMU_REMCONADC 0x62 125 + #define ATC2609A_PMU_SVCCADC 0x63 126 + #define ATC2609A_PMU_CHGIADC 0x64 127 + #define ATC2609A_PMU_IREFADC 0x65 128 + #define ATC2609A_PMU_BAKBATADC 0x66 129 + #define ATC2609A_PMU_ICTEMPADC 0x67 130 + #define ATC2609A_PMU_AUXADC0 0x68 131 + #define ATC2609A_PMU_AUXADC1 0x69 132 + #define ATC2609A_PMU_AUXADC2 0x6A 133 + #define ATC2609A_PMU_AUXADC3 0x6B 134 + #define ATC2609A_PMU_ICTEMPADC_ADJ 0x6C 135 + #define ATC2609A_PMU_BDG_CTL 0x6D 136 + #define ATC2609A_RTC_CTL 0x6E 137 + #define ATC2609A_RTC_MSALM 0x6F 138 + #define ATC2609A_RTC_HALM 0x70 139 + #define ATC2609A_RTC_YMDALM 0x71 140 + #define ATC2609A_RTC_MS 0x72 141 + #define ATC2609A_RTC_H 0x73 142 + #define ATC2609A_RTC_DC 0x74 143 + #define ATC2609A_RTC_YMD 0x75 144 + #define ATC2609A_EFUSE_DAT 0x76 145 + #define ATC2609A_EFUSECRTL1 0x77 146 + #define ATC2609A_EFUSECRTL2 0x78 147 + #define ATC2609A_PMU_DC4_CTL0 0x79 148 + #define ATC2609A_PMU_DC4_CTL1 0x7A 149 + #define ATC2609A_PMU_DC4_CTL2 0x7B 150 + #define ATC2609A_PMU_DC4_CTL3 0x7C 151 + #define ATC2609A_PMU_DC4_CTL4 0x7D 152 + #define ATC2609A_PMU_DC4_CTL5 0x7E 153 + #define ATC2609A_PMU_DC4_CTL6 0x7F 154 + #define ATC2609A_PMU_PWR_STATUS 0x80 155 + #define ATC2609A_PMU_S2_PWR 0x81 156 + #define ATC2609A_CLMT_CTL0 0x82 157 + #define ATC2609A_CLMT_DATA0 0x83 158 + #define ATC2609A_CLMT_DATA1 0x84 159 + #define ATC2609A_CLMT_DATA2 0x85 160 + #define ATC2609A_CLMT_DATA3 0x86 161 + #define ATC2609A_CLMT_ADD0 0x87 162 + #define ATC2609A_CLMT_ADD1 0x88 163 + #define ATC2609A_CLMT_OCV_TABLE 0x89 164 + #define ATC2609A_CLMT_R_TABLE 0x8A 165 + #define ATC2609A_PMU_PWRON_CTL0 0x8D 166 + #define ATC2609A_PMU_PWRON_CTL1 0x8E 167 + #define ATC2609A_PMU_PWRON_CTL2 0x8F 168 + #define ATC2609A_IRC_CTL 0x90 169 + #define ATC2609A_IRC_STAT 0x91 170 + #define ATC2609A_IRC_CC 0x92 171 + #define ATC2609A_IRC_KDC 0x93 172 + #define ATC2609A_IRC_WK 0x94 173 + #define ATC2609A_IRC_RCC 0x95 174 + 175 + /* AUDIO_OUT Registers */ 176 + #define ATC2609A_AUDIOINOUT_CTL 0xA0 177 + #define ATC2609A_AUDIO_DEBUGOUTCTL 0xA1 178 + #define ATC2609A_DAC_DIGITALCTL 0xA2 179 + #define ATC2609A_DAC_VOLUMECTL0 0xA3 180 + #define ATC2609A_DAC_ANALOG0 0xA4 181 + #define ATC2609A_DAC_ANALOG1 0xA5 182 + #define ATC2609A_DAC_ANALOG2 0xA6 183 + #define ATC2609A_DAC_ANALOG3 0xA7 184 + 185 + /* AUDIO_IN Registers */ 186 + #define ATC2609A_ADC_DIGITALCTL 0xA8 187 + #define ATC2609A_ADC_HPFCTL 0xA9 188 + #define ATC2609A_ADC_CTL 0xAA 189 + #define ATC2609A_AGC_CTL0 0xAB 190 + #define ATC2609A_AGC_CTL1 0xAC 191 + #define ATC2609A_AGC_CTL2 0xAD 192 + #define ATC2609A_ADC_ANALOG0 0xAE 193 + #define ATC2609A_ADC_ANALOG1 0xAF 194 + 195 + /* PCM_IF Registers */ 196 + #define ATC2609A_PCM0_CTL 0xB0 197 + #define ATC2609A_PCM1_CTL 0xB1 198 + #define ATC2609A_PCM2_CTL 0xB2 199 + #define ATC2609A_PCMIF_CTL 0xB3 200 + 201 + /* CMU_CONTROL Registers */ 202 + #define ATC2609A_CMU_DEVRST 0xC1 203 + 204 + /* INTS Registers */ 205 + #define ATC2609A_INTS_PD 0xC8 206 + #define ATC2609A_INTS_MSK 0xC9 207 + 208 + /* MFP Registers */ 209 + #define ATC2609A_MFP_CTL 0xD0 210 + #define ATC2609A_PAD_VSEL 0xD1 211 + #define ATC2609A_GPIO_OUTEN 0xD2 212 + #define ATC2609A_GPIO_INEN 0xD3 213 + #define ATC2609A_GPIO_DAT 0xD4 214 + #define ATC2609A_PAD_DRV 0xD5 215 + #define ATC2609A_PAD_EN 0xD6 216 + #define ATC2609A_DEBUG_SEL 0xD7 217 + #define ATC2609A_DEBUG_IE 0xD8 218 + #define ATC2609A_DEBUG_OE 0xD9 219 + #define ATC2609A_CHIP_VER 0xDC 220 + 221 + /* PWSI Registers */ 222 + #define ATC2609A_PWSI_CTL 0xF0 223 + #define ATC2609A_PWSI_STATUS 0xF1 224 + 225 + /* TWSI Registers */ 226 + #define ATC2609A_SADDR 0xFF 227 + 228 + /* PMU_SYS_CTL0 Register Mask Bits */ 229 + #define ATC2609A_PMU_SYS_CTL0_IR_WK_EN BIT(5) 230 + #define ATC2609A_PMU_SYS_CTL0_RESET_WK_EN BIT(6) 231 + #define ATC2609A_PMU_SYS_CTL0_HDSW_WK_EN BIT(7) 232 + #define ATC2609A_PMU_SYS_CTL0_ALARM_WK_EN BIT(8) 233 + #define ATC2609A_PMU_SYS_CTL0_REM_CON_WK_EN BIT(9) 234 + #define ATC2609A_PMU_SYS_CTL0_RESTART_EN BIT(10) 235 + #define ATC2609A_PMU_SYS_CTL0_WKIRQ_WK_EN BIT(11) 236 + #define ATC2609A_PMU_SYS_CTL0_ONOFF_SHORT_WK_EN BIT(12) 237 + #define ATC2609A_PMU_SYS_CTL0_ONOFF_LONG_WK_EN BIT(13) 238 + #define ATC2609A_PMU_SYS_CTL0_WALL_WK_EN BIT(14) 239 + #define ATC2609A_PMU_SYS_CTL0_USB_WK_EN BIT(15) 240 + #define ATC2609A_PMU_SYS_CTL0_WK_ALL (GENMASK(15, 5) & (~BIT(10))) 241 + 242 + /* PMU_SYS_CTL1 Register Mask Bits */ 243 + #define ATC2609A_PMU_SYS_CTL1_EN_S1 BIT(0) 244 + #define ATC2609A_PMU_SYS_CTL1_LB_S4_EN BIT(2) 245 + #define ATC2609A_PMU_SYS_CTL1_LB_S4 GENMASK(4, 3) 246 + #define ATC2609A_PMU_SYS_CTL1_LB_S4_3_1V BIT(4) 247 + #define ATC2609A_PMU_SYS_CTL1_IR_WK_FLAG BIT(5) 248 + #define ATC2609A_PMU_SYS_CTL1_RESET_WK_FLAG BIT(6) 249 + #define ATC2609A_PMU_SYS_CTL1_HDSW_WK_FLAG BIT(7) 250 + #define ATC2609A_PMU_SYS_CTL1_ALARM_WK_FLAG BIT(8) 251 + #define ATC2609A_PMU_SYS_CTL1_REM_CON_WK_FLAG BIT(9) 252 + #define ATC2609A_PMU_SYS_CTL1_RESTART_WK_FLAG BIT(10) 253 + #define ATC2609A_PMU_SYS_CTL1_WKIRQ_WK_FLAG BIT(11) 254 + #define ATC2609A_PMU_SYS_CTL1_ONOFF_SHORT_WK_FLAG BIT(12) 255 + #define ATC2609A_PMU_SYS_CTL1_ONOFF_LONG_WK_FLAG BIT(13) 256 + #define ATC2609A_PMU_SYS_CTL1_WALL_WK_FLAG BIT(14) 257 + #define ATC2609A_PMU_SYS_CTL1_USB_WK_FLAG BIT(15) 258 + 259 + /* PMU_SYS_CTL2 Register Mask Bits */ 260 + #define ATC2609A_PMU_SYS_CTL2_PMU_A_EN BIT(0) 261 + #define ATC2609A_PMU_SYS_CTL2_ONOFF_PRESS_INT_EN BIT(1) 262 + #define ATC2609A_PMU_SYS_CTL2_ONOFF_PRESS_PD BIT(2) 263 + #define ATC2609A_PMU_SYS_CTL2_S2TIMER GENMASK(5, 3) 264 + #define ATC2609A_PMU_SYS_CTL2_S2_TIMER_EN BIT(6) 265 + #define ATC2609A_PMU_SYS_CTL2_ONOFF_RESET_TIME_SEL GENMASK(8, 7) 266 + #define ATC2609A_PMU_SYS_CTL2_ONOFF_RESET_EN BIT(9) 267 + #define ATC2609A_PMU_SYS_CTL2_ONOFF_PRESS_TIME GENMASK(11, 10) 268 + #define ATC2609A_PMU_SYS_CTL2_ONOFF_LSP_INT_EN BIT(12) 269 + #define ATC2609A_PMU_SYS_CTL2_ONOFF_LONG_PRESS BIT(13) 270 + #define ATC2609A_PMU_SYS_CTL2_ONOFF_SHORT_PRESS BIT(14) 271 + #define ATC2609A_PMU_SYS_CTL2_ONOFF_PRESS BIT(15) 272 + 273 + /* PMU_SYS_CTL3 Register Mask Bits */ 274 + #define ATC2609A_PMU_SYS_CTL3_S2S3TOS1_TIMER GENMASK(8, 7) 275 + #define ATC2609A_PMU_SYS_CTL3_S2S3TOS1_TIMER_EN BIT(9) 276 + #define ATC2609A_PMU_SYS_CTL3_S3_TIMER GENMASK(12, 10) 277 + #define ATC2609A_PMU_SYS_CTL3_S3_TIMER_EN BIT(13) 278 + #define ATC2609A_PMU_SYS_CTL3_EN_S3 BIT(14) 279 + #define ATC2609A_PMU_SYS_CTL3_EN_S2 BIT(15) 280 + 281 + /* PMU_SYS_CTL5 Register Mask Bits */ 282 + #define ATC2609A_PMU_SYS_CTL5_WALLWKDTEN BIT(7) 283 + #define ATC2609A_PMU_SYS_CTL5_VBUSWKDTEN BIT(8) 284 + #define ATC2609A_PMU_SYS_CTL5_REMCON_DECT_EN BIT(9) 285 + #define ATC2609A_PMU_SYS_CTL5_ONOFF_8S_SEL BIT(10) 286 + 287 + /* INTS_MSK Register Mask Bits */ 288 + #define ATC2609A_INTS_MSK_AUDIO BIT(0) 289 + #define ATC2609A_INTS_MSK_OV BIT(1) 290 + #define ATC2609A_INTS_MSK_OC BIT(2) 291 + #define ATC2609A_INTS_MSK_OT BIT(3) 292 + #define ATC2609A_INTS_MSK_UV BIT(4) 293 + #define ATC2609A_INTS_MSK_ALARM BIT(5) 294 + #define ATC2609A_INTS_MSK_ONOFF BIT(6) 295 + #define ATC2609A_INTS_MSK_WKUP BIT(7) 296 + #define ATC2609A_INTS_MSK_IR BIT(8) 297 + #define ATC2609A_INTS_MSK_REMCON BIT(9) 298 + #define ATC2609A_INTS_MSK_POWERIN BIT(10) 299 + 300 + /* CMU_DEVRST Register Mask Bits */ 301 + #define ATC2609A_CMU_DEVRST_AUDIO BIT(0) 302 + #define ATC2609A_CMU_DEVRST_MFP BIT(1) 303 + #define ATC2609A_CMU_DEVRST_INTS BIT(2) 304 + 305 + /* PAD_EN Register Mask Bits */ 306 + #define ATC2609A_PAD_EN_EXTIRQ BIT(0) 307 + 308 + #endif /* __LINUX_MFD_ATC260X_ATC2609A_H */
+58
include/linux/mfd/atc260x/core.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* 3 + * Core MFD defines for ATC260x PMICs 4 + * 5 + * Copyright (C) 2019 Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> 6 + * Copyright (C) 2020 Cristian Ciocaltea <cristian.ciocaltea@gmail.com> 7 + */ 8 + 9 + #ifndef __LINUX_MFD_ATC260X_CORE_H 10 + #define __LINUX_MFD_ATC260X_CORE_H 11 + 12 + #include <linux/mfd/atc260x/atc2603c.h> 13 + #include <linux/mfd/atc260x/atc2609a.h> 14 + 15 + enum atc260x_type { 16 + ATC2603A = 0, 17 + ATC2603C, 18 + ATC2609A, 19 + }; 20 + 21 + enum atc260x_ver { 22 + ATC260X_A = 0, 23 + ATC260X_B, 24 + ATC260X_C, 25 + ATC260X_D, 26 + ATC260X_E, 27 + ATC260X_F, 28 + ATC260X_G, 29 + ATC260X_H, 30 + }; 31 + 32 + struct atc260x { 33 + struct device *dev; 34 + 35 + struct regmap *regmap; 36 + const struct regmap_irq_chip *regmap_irq_chip; 37 + struct regmap_irq_chip_data *irq_data; 38 + 39 + struct mutex *regmap_mutex; /* mutex for custom regmap locking */ 40 + 41 + const struct mfd_cell *cells; 42 + int nr_cells; 43 + int irq; 44 + 45 + enum atc260x_type ic_type; 46 + enum atc260x_ver ic_ver; 47 + const char *type_name; 48 + unsigned int rev_reg; 49 + 50 + const struct atc260x_init_regs *init_regs; /* regs for device init */ 51 + }; 52 + 53 + struct regmap_config; 54 + 55 + int atc260x_match_device(struct atc260x *atc260x, struct regmap_config *regmap_cfg); 56 + int atc260x_device_probe(struct atc260x *atc260x); 57 + 58 + #endif /* __LINUX_MFD_ATC260X_CORE_H */
+3 -3
include/linux/mfd/core.h
··· 50 50 #define MFD_DEP_LEVEL_HIGH 1 51 51 52 52 struct irq_domain; 53 - struct property_entry; 53 + struct software_node; 54 54 55 55 /* Matches ACPI PNP id, either _HID or _CID, or ACPI _ADR */ 56 56 struct mfd_cell_acpi_match { ··· 78 78 void *platform_data; 79 79 size_t pdata_size; 80 80 81 - /* device properties passed to the sub devices drivers */ 82 - const struct property_entry *properties; 81 + /* Software node for the device. */ 82 + const struct software_node *swnode; 83 83 84 84 /* 85 85 * Device Tree compatible string
+3
include/linux/mfd/da9063/registers.h
··· 1037 1037 #define DA9063_NONKEY_PIN_AUTODOWN 0x02 1038 1038 #define DA9063_NONKEY_PIN_AUTOFLPRT 0x03 1039 1039 1040 + /* DA9063_REG_CONFIG_J (addr=0x10F) */ 1041 + #define DA9063_TWOWIRE_TO 0x40 1042 + 1040 1043 /* DA9063_REG_MON_REG_5 (addr=0x116) */ 1041 1044 #define DA9063_MON_A8_IDX_MASK 0x07 1042 1045 #define DA9063_MON_A8_IDX_NONE 0x00
+1 -1
include/linux/mfd/db8500-prcmu.h
··· 720 720 721 721 static inline bool db8500_prcmu_is_ac_wake_requested(void) 722 722 { 723 - return 0; 723 + return false; 724 724 } 725 725 726 726 static inline int db8500_prcmu_set_arm_opp(u8 opp)
+90 -2
include/linux/mfd/intel-m10-bmc.h
··· 9 9 10 10 #include <linux/regmap.h> 11 11 12 - #define M10BMC_LEGACY_SYS_BASE 0x300400 12 + #define M10BMC_LEGACY_BUILD_VER 0x300468 13 13 #define M10BMC_SYS_BASE 0x300800 14 - #define M10BMC_MEM_END 0x200000fc 14 + #define M10BMC_SYS_END 0x300fff 15 + #define M10BMC_FLASH_BASE 0x10000000 16 + #define M10BMC_FLASH_END 0x1fffffff 17 + #define M10BMC_MEM_END M10BMC_FLASH_END 18 + 19 + #define M10BMC_STAGING_BASE 0x18000000 20 + #define M10BMC_STAGING_SIZE 0x3800000 15 21 16 22 /* Register offset of system registers */ 17 23 #define NIOS2_FW_VERSION 0x0 ··· 35 29 #define M10BMC_VER_MAJOR_MSK GENMASK(23, 16) 36 30 #define M10BMC_VER_PCB_INFO_MSK GENMASK(31, 24) 37 31 #define M10BMC_VER_LEGACY_INVALID 0xffffffff 32 + 33 + /* Secure update doorbell register, in system register region */ 34 + #define M10BMC_DOORBELL 0x400 35 + 36 + /* Authorization Result register, in system register region */ 37 + #define M10BMC_AUTH_RESULT 0x404 38 + 39 + /* Doorbell register fields */ 40 + #define DRBL_RSU_REQUEST BIT(0) 41 + #define DRBL_RSU_PROGRESS GENMASK(7, 4) 42 + #define DRBL_HOST_STATUS GENMASK(11, 8) 43 + #define DRBL_RSU_STATUS GENMASK(23, 16) 44 + #define DRBL_PKVL_EEPROM_LOAD_SEC BIT(24) 45 + #define DRBL_PKVL1_POLL_EN BIT(25) 46 + #define DRBL_PKVL2_POLL_EN BIT(26) 47 + #define DRBL_CONFIG_SEL BIT(28) 48 + #define DRBL_REBOOT_REQ BIT(29) 49 + #define DRBL_REBOOT_DISABLED BIT(30) 50 + 51 + /* Progress states */ 52 + #define RSU_PROG_IDLE 0x0 53 + #define RSU_PROG_PREPARE 0x1 54 + #define RSU_PROG_READY 0x3 55 + #define RSU_PROG_AUTHENTICATING 0x4 56 + #define RSU_PROG_COPYING 0x5 57 + #define RSU_PROG_UPDATE_CANCEL 0x6 58 + #define RSU_PROG_PROGRAM_KEY_HASH 0x7 59 + #define RSU_PROG_RSU_DONE 0x8 60 + #define RSU_PROG_PKVL_PROM_DONE 0x9 61 + 62 + /* Device and error states */ 63 + #define RSU_STAT_NORMAL 0x0 64 + #define RSU_STAT_TIMEOUT 0x1 65 + #define RSU_STAT_AUTH_FAIL 0x2 66 + #define RSU_STAT_COPY_FAIL 0x3 67 + #define RSU_STAT_FATAL 0x4 68 + #define RSU_STAT_PKVL_REJECT 0x5 69 + #define RSU_STAT_NON_INC 0x6 70 + #define RSU_STAT_ERASE_FAIL 0x7 71 + #define RSU_STAT_WEAROUT 0x8 72 + #define RSU_STAT_NIOS_OK 0x80 73 + #define RSU_STAT_USER_OK 0x81 74 + #define RSU_STAT_FACTORY_OK 0x82 75 + #define RSU_STAT_USER_FAIL 0x83 76 + #define RSU_STAT_FACTORY_FAIL 0x84 77 + #define RSU_STAT_NIOS_FLASH_ERR 0x85 78 + #define RSU_STAT_FPGA_FLASH_ERR 0x86 79 + 80 + #define HOST_STATUS_IDLE 0x0 81 + #define HOST_STATUS_WRITE_DONE 0x1 82 + #define HOST_STATUS_ABORT_RSU 0x2 83 + 84 + #define rsu_prog(doorbell) FIELD_GET(DRBL_RSU_PROGRESS, doorbell) 85 + #define rsu_stat(doorbell) FIELD_GET(DRBL_RSU_STATUS, doorbell) 86 + 87 + /* interval 100ms and timeout 5s */ 88 + #define NIOS_HANDSHAKE_INTERVAL_US (100 * 1000) 89 + #define NIOS_HANDSHAKE_TIMEOUT_US (5 * 1000 * 1000) 90 + 91 + /* RSU PREP Timeout (2 minutes) to erase flash staging area */ 92 + #define RSU_PREP_INTERVAL_MS 100 93 + #define RSU_PREP_TIMEOUT_MS (2 * 60 * 1000) 94 + 95 + /* RSU Complete Timeout (40 minutes) for full flash update */ 96 + #define RSU_COMPLETE_INTERVAL_MS 1000 97 + #define RSU_COMPLETE_TIMEOUT_MS (40 * 60 * 1000) 98 + 99 + /* Addresses for security related data in FLASH */ 100 + #define BMC_REH_ADDR 0x17ffc004 101 + #define BMC_PROG_ADDR 0x17ffc000 102 + #define BMC_PROG_MAGIC 0x5746 103 + 104 + #define SR_REH_ADDR 0x17ffd004 105 + #define SR_PROG_ADDR 0x17ffd000 106 + #define SR_PROG_MAGIC 0x5253 107 + 108 + #define PR_REH_ADDR 0x17ffe004 109 + #define PR_PROG_ADDR 0x17ffe000 110 + #define PR_PROG_MAGIC 0x5250 111 + 112 + /* Address of 4KB inverted bit vector containing staging area FLASH count */ 113 + #define STAGING_FLASH_COUNT 0x17ffb000 38 114 39 115 /** 40 116 * struct intel_m10bmc - Intel MAX 10 BMC parent driver data structure
-3
include/linux/mfd/lp87565.h
··· 237 237 #define LP87565_GOIO2_OUT BIT(1) 238 238 #define LP87565_GOIO1_OUT BIT(0) 239 239 240 - /* Number of step-down converters available */ 241 - #define LP87565_NUM_BUCK 6 242 - 243 240 enum LP87565_regulator_id { 244 241 /* BUCK's */ 245 242 LP87565_BUCK_0,
+4 -4
include/linux/mfd/max8997.h
··· 14 14 * others and b) it can be enabled simply by using MAX17042 driver. 15 15 */ 16 16 17 - #ifndef __LINUX_MFD_MAX8998_H 18 - #define __LINUX_MFD_MAX8998_H 17 + #ifndef __LINUX_MFD_MAX8997_H 18 + #define __LINUX_MFD_MAX8997_H 19 19 20 20 #include <linux/regulator/consumer.h> 21 21 22 22 /* MAX8997/8966 regulator IDs */ 23 - enum max8998_regulators { 23 + enum max8997_regulators { 24 24 MAX8997_LDO1 = 0, 25 25 MAX8997_LDO2, 26 26 MAX8997_LDO3, ··· 207 207 struct max8997_led_platform_data *led_pdata; 208 208 }; 209 209 210 - #endif /* __LINUX_MFD_MAX8998_H */ 210 + #endif /* __LINUX_MFD_MAX8997_H */
+38
include/linux/mfd/ntxec.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright 2020 Jonathan Neuschäfer 4 + * 5 + * Register access and version information for the Netronix embedded 6 + * controller. 7 + */ 8 + 9 + #ifndef NTXEC_H 10 + #define NTXEC_H 11 + 12 + #include <linux/types.h> 13 + 14 + struct device; 15 + struct regmap; 16 + 17 + struct ntxec { 18 + struct device *dev; 19 + struct regmap *regmap; 20 + }; 21 + 22 + /* 23 + * Some registers, such as the battery status register (0x41), are in 24 + * big-endian, but others only have eight significant bits, which are in the 25 + * first byte transmitted over I2C (the MSB of the big-endian value). 26 + * This convenience function converts an 8-bit value to 16-bit for use in the 27 + * second kind of register. 28 + */ 29 + static inline __be16 ntxec_reg8(u8 value) 30 + { 31 + return value << 8; 32 + } 33 + 34 + /* Known firmware versions */ 35 + #define NTXEC_VERSION_KOBO_AURA 0xd726 /* found in Kobo Aura */ 36 + #define NTXEC_VERSION_TOLINO_SHINE2 0xf110 /* found in Tolino Shine 2 HD */ 37 + 38 + #endif
+1
include/linux/mfd/rn5t618.h
··· 188 188 #define RN5T618_CHGOSCSCORESET3 0xd7 189 189 #define RN5T618_CHGOSCFREQSET1 0xd8 190 190 #define RN5T618_CHGOSCFREQSET2 0xd9 191 + #define RN5T618_GCHGDET 0xda 191 192 #define RN5T618_CONTROL 0xe0 192 193 #define RN5T618_SOC 0xe1 193 194 #define RN5T618_RE_CAP_H 0xe2
+562
include/linux/mfd/rohm-bd71815.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 + /* 3 + * Copyright 2021 ROHM Semiconductors. 4 + * 5 + * Author: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> 6 + * 7 + * Copyright 2014 Embest Technology Co. Ltd. Inc. 8 + * 9 + * Author: yanglsh@embest-tech.com 10 + */ 11 + 12 + #ifndef _MFD_BD71815_H 13 + #define _MFD_BD71815_H 14 + 15 + #include <linux/regmap.h> 16 + 17 + enum { 18 + BD71815_BUCK1 = 0, 19 + BD71815_BUCK2, 20 + BD71815_BUCK3, 21 + BD71815_BUCK4, 22 + BD71815_BUCK5, 23 + /* General Purpose */ 24 + BD71815_LDO1, 25 + BD71815_LDO2, 26 + BD71815_LDO3, 27 + /* LDOs for SD Card and SD Card Interface */ 28 + BD71815_LDO4, 29 + BD71815_LDO5, 30 + /* LDO for DDR Reference Voltage */ 31 + BD71815_LDODVREF, 32 + /* LDO for Low-Power State Retention */ 33 + BD71815_LDOLPSR, 34 + BD71815_WLED, 35 + BD71815_REGULATOR_CNT, 36 + }; 37 + 38 + #define BD71815_SUPPLY_STATE_ENABLED 0x1 39 + 40 + enum { 41 + BD71815_REG_DEVICE = 0, 42 + BD71815_REG_PWRCTRL, 43 + BD71815_REG_BUCK1_MODE, 44 + BD71815_REG_BUCK2_MODE, 45 + BD71815_REG_BUCK3_MODE, 46 + BD71815_REG_BUCK4_MODE, 47 + BD71815_REG_BUCK5_MODE, 48 + BD71815_REG_BUCK1_VOLT_H, 49 + BD71815_REG_BUCK1_VOLT_L, 50 + BD71815_REG_BUCK2_VOLT_H, 51 + BD71815_REG_BUCK2_VOLT_L, 52 + BD71815_REG_BUCK3_VOLT, 53 + BD71815_REG_BUCK4_VOLT, 54 + BD71815_REG_BUCK5_VOLT, 55 + BD71815_REG_LED_CTRL, 56 + BD71815_REG_LED_DIMM, 57 + BD71815_REG_LDO_MODE1, 58 + BD71815_REG_LDO_MODE2, 59 + BD71815_REG_LDO_MODE3, 60 + BD71815_REG_LDO_MODE4, 61 + BD71815_REG_LDO1_VOLT, 62 + BD71815_REG_LDO2_VOLT, 63 + BD71815_REG_LDO3_VOLT, 64 + BD71815_REG_LDO4_VOLT, 65 + BD71815_REG_LDO5_VOLT_H, 66 + BD71815_REG_LDO5_VOLT_L, 67 + BD71815_REG_BUCK_PD_DIS, 68 + BD71815_REG_LDO_PD_DIS, 69 + BD71815_REG_GPO, 70 + BD71815_REG_OUT32K, 71 + BD71815_REG_SEC, 72 + BD71815_REG_MIN, 73 + BD71815_REG_HOUR, 74 + BD71815_REG_WEEK, 75 + BD71815_REG_DAY, 76 + BD71815_REG_MONTH, 77 + BD71815_REG_YEAR, 78 + BD71815_REG_ALM0_SEC, 79 + 80 + BD71815_REG_ALM1_SEC = 0x2C, 81 + 82 + BD71815_REG_ALM0_MASK = 0x33, 83 + BD71815_REG_ALM1_MASK, 84 + BD71815_REG_ALM2, 85 + BD71815_REG_TRIM, 86 + BD71815_REG_CONF, 87 + BD71815_REG_SYS_INIT, 88 + BD71815_REG_CHG_STATE, 89 + BD71815_REG_CHG_LAST_STATE, 90 + BD71815_REG_BAT_STAT, 91 + BD71815_REG_DCIN_STAT, 92 + BD71815_REG_VSYS_STAT, 93 + BD71815_REG_CHG_STAT, 94 + BD71815_REG_CHG_WDT_STAT, 95 + BD71815_REG_BAT_TEMP, 96 + BD71815_REG_IGNORE_0, 97 + BD71815_REG_INHIBIT_0, 98 + BD71815_REG_DCIN_CLPS, 99 + BD71815_REG_VSYS_REG, 100 + BD71815_REG_VSYS_MAX, 101 + BD71815_REG_VSYS_MIN, 102 + BD71815_REG_CHG_SET1, 103 + BD71815_REG_CHG_SET2, 104 + BD71815_REG_CHG_WDT_PRE, 105 + BD71815_REG_CHG_WDT_FST, 106 + BD71815_REG_CHG_IPRE, 107 + BD71815_REG_CHG_IFST, 108 + BD71815_REG_CHG_IFST_TERM, 109 + BD71815_REG_CHG_VPRE, 110 + BD71815_REG_CHG_VBAT_1, 111 + BD71815_REG_CHG_VBAT_2, 112 + BD71815_REG_CHG_VBAT_3, 113 + BD71815_REG_CHG_LED_1, 114 + BD71815_REG_VF_TH, 115 + BD71815_REG_BAT_SET_1, 116 + BD71815_REG_BAT_SET_2, 117 + BD71815_REG_BAT_SET_3, 118 + BD71815_REG_ALM_VBAT_TH_U, 119 + BD71815_REG_ALM_VBAT_TH_L, 120 + BD71815_REG_ALM_DCIN_TH, 121 + BD71815_REG_ALM_VSYS_TH, 122 + BD71815_REG_VM_IBAT_U, 123 + BD71815_REG_VM_IBAT_L, 124 + BD71815_REG_VM_VBAT_U, 125 + BD71815_REG_VM_VBAT_L, 126 + BD71815_REG_VM_BTMP, 127 + BD71815_REG_VM_VTH, 128 + BD71815_REG_VM_DCIN_U, 129 + BD71815_REG_VM_DCIN_L, 130 + BD71815_REG_VM_VSYS, 131 + BD71815_REG_VM_VF, 132 + BD71815_REG_VM_OCI_PRE_U, 133 + BD71815_REG_VM_OCI_PRE_L, 134 + BD71815_REG_VM_OCV_PRE_U, 135 + BD71815_REG_VM_OCV_PRE_L, 136 + BD71815_REG_VM_OCI_PST_U, 137 + BD71815_REG_VM_OCI_PST_L, 138 + BD71815_REG_VM_OCV_PST_U, 139 + BD71815_REG_VM_OCV_PST_L, 140 + BD71815_REG_VM_SA_VBAT_U, 141 + BD71815_REG_VM_SA_VBAT_L, 142 + BD71815_REG_VM_SA_IBAT_U, 143 + BD71815_REG_VM_SA_IBAT_L, 144 + BD71815_REG_CC_CTRL, 145 + BD71815_REG_CC_BATCAP1_TH_U, 146 + BD71815_REG_CC_BATCAP1_TH_L, 147 + BD71815_REG_CC_BATCAP2_TH_U, 148 + BD71815_REG_CC_BATCAP2_TH_L, 149 + BD71815_REG_CC_BATCAP3_TH_U, 150 + BD71815_REG_CC_BATCAP3_TH_L, 151 + BD71815_REG_CC_STAT, 152 + BD71815_REG_CC_CCNTD_3, 153 + BD71815_REG_CC_CCNTD_2, 154 + BD71815_REG_CC_CCNTD_1, 155 + BD71815_REG_CC_CCNTD_0, 156 + BD71815_REG_CC_CURCD_U, 157 + BD71815_REG_CC_CURCD_L, 158 + BD71815_REG_VM_OCUR_THR_1, 159 + BD71815_REG_VM_OCUR_DUR_1, 160 + BD71815_REG_VM_OCUR_THR_2, 161 + BD71815_REG_VM_OCUR_DUR_2, 162 + BD71815_REG_VM_OCUR_THR_3, 163 + BD71815_REG_VM_OCUR_DUR_3, 164 + BD71815_REG_VM_OCUR_MON, 165 + BD71815_REG_VM_BTMP_OV_THR, 166 + BD71815_REG_VM_BTMP_OV_DUR, 167 + BD71815_REG_VM_BTMP_LO_THR, 168 + BD71815_REG_VM_BTMP_LO_DUR, 169 + BD71815_REG_VM_BTMP_MON, 170 + BD71815_REG_INT_EN_01, 171 + 172 + BD71815_REG_INT_EN_11 = 0x95, 173 + BD71815_REG_INT_EN_12, 174 + BD71815_REG_INT_STAT, 175 + BD71815_REG_INT_STAT_01, 176 + BD71815_REG_INT_STAT_02, 177 + BD71815_REG_INT_STAT_03, 178 + BD71815_REG_INT_STAT_04, 179 + BD71815_REG_INT_STAT_05, 180 + BD71815_REG_INT_STAT_06, 181 + BD71815_REG_INT_STAT_07, 182 + BD71815_REG_INT_STAT_08, 183 + BD71815_REG_INT_STAT_09, 184 + BD71815_REG_INT_STAT_10, 185 + BD71815_REG_INT_STAT_11, 186 + BD71815_REG_INT_STAT_12, 187 + BD71815_REG_INT_UPDATE, 188 + 189 + BD71815_REG_VM_VSYS_U = 0xC0, 190 + BD71815_REG_VM_VSYS_L, 191 + BD71815_REG_VM_SA_VSYS_U, 192 + BD71815_REG_VM_SA_VSYS_L, 193 + 194 + BD71815_REG_VM_SA_IBAT_MIN_U = 0xD0, 195 + BD71815_REG_VM_SA_IBAT_MIN_L, 196 + BD71815_REG_VM_SA_IBAT_MAX_U, 197 + BD71815_REG_VM_SA_IBAT_MAX_L, 198 + BD71815_REG_VM_SA_VBAT_MIN_U, 199 + BD71815_REG_VM_SA_VBAT_MIN_L, 200 + BD71815_REG_VM_SA_VBAT_MAX_U, 201 + BD71815_REG_VM_SA_VBAT_MAX_L, 202 + BD71815_REG_VM_SA_VSYS_MIN_U, 203 + BD71815_REG_VM_SA_VSYS_MIN_L, 204 + BD71815_REG_VM_SA_VSYS_MAX_U, 205 + BD71815_REG_VM_SA_VSYS_MAX_L, 206 + BD71815_REG_VM_SA_MINMAX_CLR, 207 + 208 + BD71815_REG_REX_CCNTD_3 = 0xE0, 209 + BD71815_REG_REX_CCNTD_2, 210 + BD71815_REG_REX_CCNTD_1, 211 + BD71815_REG_REX_CCNTD_0, 212 + BD71815_REG_REX_SA_VBAT_U, 213 + BD71815_REG_REX_SA_VBAT_L, 214 + BD71815_REG_REX_CTRL_1, 215 + BD71815_REG_REX_CTRL_2, 216 + BD71815_REG_FULL_CCNTD_3, 217 + BD71815_REG_FULL_CCNTD_2, 218 + BD71815_REG_FULL_CCNTD_1, 219 + BD71815_REG_FULL_CCNTD_0, 220 + BD71815_REG_FULL_CTRL, 221 + 222 + BD71815_REG_CCNTD_CHG_3 = 0xF0, 223 + BD71815_REG_CCNTD_CHG_2, 224 + 225 + BD71815_REG_TEST_MODE = 0xFE, 226 + BD71815_MAX_REGISTER, 227 + }; 228 + 229 + /* BD71815_REG_BUCK1_MODE bits */ 230 + #define BD71815_BUCK_RAMPRATE_MASK 0xC0 231 + #define BD71815_BUCK_RAMPRATE_10P00MV 0x0 232 + #define BD71815_BUCK_RAMPRATE_5P00MV 0x01 233 + #define BD71815_BUCK_RAMPRATE_2P50MV 0x02 234 + #define BD71815_BUCK_RAMPRATE_1P25MV 0x03 235 + 236 + #define BD71815_BUCK_PWM_FIXED BIT(4) 237 + #define BD71815_BUCK_SNVS_ON BIT(3) 238 + #define BD71815_BUCK_RUN_ON BIT(2) 239 + #define BD71815_BUCK_LPSR_ON BIT(1) 240 + #define BD71815_BUCK_SUSP_ON BIT(0) 241 + 242 + /* BD71815_REG_BUCK1_VOLT_H bits */ 243 + #define BD71815_BUCK_DVSSEL BIT(7) 244 + #define BD71815_BUCK_STBY_DVS BIT(6) 245 + #define BD71815_VOLT_MASK 0x3F 246 + #define BD71815_BUCK1_H_DEFAULT 0x14 247 + #define BD71815_BUCK1_L_DEFAULT 0x14 248 + 249 + /* BD71815_REG_BUCK2_VOLT_H bits */ 250 + #define BD71815_BUCK2_H_DEFAULT 0x14 251 + #define BD71815_BUCK2_L_DEFAULT 0x14 252 + 253 + /* WLED output */ 254 + /* current register mask */ 255 + #define LED_DIMM_MASK 0x3f 256 + /* LED enable bits at LED_CTRL reg */ 257 + #define LED_CHGDONE_EN BIT(4) 258 + #define LED_RUN_ON BIT(2) 259 + #define LED_LPSR_ON BIT(1) 260 + #define LED_SUSP_ON BIT(0) 261 + 262 + /* BD71815_REG_LDO1_CTRL bits */ 263 + #define LDO1_EN BIT(0) 264 + #define LDO2_EN BIT(1) 265 + #define LDO3_EN BIT(2) 266 + #define DVREF_EN BIT(3) 267 + #define VOSNVS_SW_EN BIT(4) 268 + 269 + /* LDO_MODE1_register */ 270 + #define LDO1_SNVS_ON BIT(7) 271 + #define LDO1_RUN_ON BIT(6) 272 + #define LDO1_LPSR_ON BIT(5) 273 + #define LDO1_SUSP_ON BIT(4) 274 + /* set => register control, unset => GPIO control */ 275 + #define LDO4_MODE_MASK BIT(3) 276 + #define LDO4_MODE_I2C BIT(3) 277 + #define LDO4_MODE_GPIO 0 278 + /* set => register control, unset => start when DCIN connected */ 279 + #define LDO3_MODE_MASK BIT(2) 280 + #define LDO3_MODE_I2C BIT(2) 281 + #define LDO3_MODE_DCIN 0 282 + 283 + /* LDO_MODE2 register */ 284 + #define LDO3_SNVS_ON BIT(7) 285 + #define LDO3_RUN_ON BIT(6) 286 + #define LDO3_LPSR_ON BIT(5) 287 + #define LDO3_SUSP_ON BIT(4) 288 + #define LDO2_SNVS_ON BIT(3) 289 + #define LDO2_RUN_ON BIT(2) 290 + #define LDO2_LPSR_ON BIT(1) 291 + #define LDO2_SUSP_ON BIT(0) 292 + 293 + 294 + /* LDO_MODE3 register */ 295 + #define LDO5_SNVS_ON BIT(7) 296 + #define LDO5_RUN_ON BIT(6) 297 + #define LDO5_LPSR_ON BIT(5) 298 + #define LDO5_SUSP_ON BIT(4) 299 + #define LDO4_SNVS_ON BIT(3) 300 + #define LDO4_RUN_ON BIT(2) 301 + #define LDO4_LPSR_ON BIT(1) 302 + #define LDO4_SUSP_ON BIT(0) 303 + 304 + /* LDO_MODE4 register */ 305 + #define DVREF_SNVS_ON BIT(7) 306 + #define DVREF_RUN_ON BIT(6) 307 + #define DVREF_LPSR_ON BIT(5) 308 + #define DVREF_SUSP_ON BIT(4) 309 + #define LDO_LPSR_SNVS_ON BIT(3) 310 + #define LDO_LPSR_RUN_ON BIT(2) 311 + #define LDO_LPSR_LPSR_ON BIT(1) 312 + #define LDO_LPSR_SUSP_ON BIT(0) 313 + 314 + /* BD71815_REG_OUT32K bits */ 315 + #define OUT32K_EN BIT(0) 316 + #define OUT32K_MODE BIT(1) 317 + #define OUT32K_MODE_CMOS BIT(1) 318 + #define OUT32K_MODE_OPEN_DRAIN 0 319 + 320 + /* BD71815_REG_BAT_STAT bits */ 321 + #define BAT_DET BIT(5) 322 + #define BAT_DET_OFFSET 5 323 + #define BAT_DET_DONE BIT(4) 324 + #define VBAT_OV BIT(3) 325 + #define DBAT_DET BIT(0) 326 + 327 + /* BD71815_REG_VBUS_STAT bits */ 328 + #define VBUS_DET BIT(0) 329 + 330 + #define BD71815_REG_RTC_START BD71815_REG_SEC 331 + #define BD71815_REG_RTC_ALM_START BD71815_REG_ALM0_SEC 332 + 333 + /* BD71815_REG_ALM0_MASK bits */ 334 + #define A0_ONESEC BIT(7) 335 + 336 + /* BD71815_REG_INT_EN_00 bits */ 337 + #define ALMALE BIT(0) 338 + 339 + /* BD71815_REG_INT_STAT_03 bits */ 340 + #define DCIN_MON_DET BIT(1) 341 + #define DCIN_MON_RES BIT(0) 342 + #define POWERON_LONG BIT(2) 343 + #define POWERON_MID BIT(3) 344 + #define POWERON_SHORT BIT(4) 345 + #define POWERON_PRESS BIT(5) 346 + 347 + /* BD71805_REG_INT_STAT_08 bits */ 348 + #define VBAT_MON_DET BIT(1) 349 + #define VBAT_MON_RES BIT(0) 350 + 351 + /* BD71805_REG_INT_STAT_11 bits */ 352 + #define INT_STAT_11_VF_DET BIT(7) 353 + #define INT_STAT_11_VF_RES BIT(6) 354 + #define INT_STAT_11_VF125_DET BIT(5) 355 + #define INT_STAT_11_VF125_RES BIT(4) 356 + #define INT_STAT_11_OVTMP_DET BIT(3) 357 + #define INT_STAT_11_OVTMP_RES BIT(2) 358 + #define INT_STAT_11_LOTMP_DET BIT(1) 359 + #define INT_STAT_11_LOTMP_RES BIT(0) 360 + 361 + #define VBAT_MON_DET BIT(1) 362 + #define VBAT_MON_RES BIT(0) 363 + 364 + /* BD71815_REG_PWRCTRL bits */ 365 + #define RESTARTEN BIT(0) 366 + 367 + /* BD71815_REG_GPO bits */ 368 + #define READY_FORCE_LOW BIT(2) 369 + #define BD71815_GPIO_DRIVE_MASK BIT(4) 370 + #define BD71815_GPIO_OPEN_DRAIN 0 371 + #define BD71815_GPIO_CMOS BIT(4) 372 + 373 + /* BD71815 interrupt masks */ 374 + enum { 375 + BD71815_INT_EN_01_BUCKAST_MASK = 0x0F, 376 + BD71815_INT_EN_02_DCINAST_MASK = 0x3E, 377 + BD71815_INT_EN_03_DCINAST_MASK = 0x3F, 378 + BD71815_INT_EN_04_VSYSAST_MASK = 0xCF, 379 + BD71815_INT_EN_05_CHGAST_MASK = 0xFC, 380 + BD71815_INT_EN_06_BATAST_MASK = 0xF3, 381 + BD71815_INT_EN_07_BMONAST_MASK = 0xFE, 382 + BD71815_INT_EN_08_BMONAST_MASK = 0x03, 383 + BD71815_INT_EN_09_BMONAST_MASK = 0x07, 384 + BD71815_INT_EN_10_BMONAST_MASK = 0x3F, 385 + BD71815_INT_EN_11_TMPAST_MASK = 0xFF, 386 + BD71815_INT_EN_12_ALMAST_MASK = 0x07, 387 + }; 388 + /* BD71815 interrupt irqs */ 389 + enum { 390 + /* BUCK reg interrupts */ 391 + BD71815_INT_BUCK1_OCP, 392 + BD71815_INT_BUCK2_OCP, 393 + BD71815_INT_BUCK3_OCP, 394 + BD71815_INT_BUCK4_OCP, 395 + BD71815_INT_BUCK5_OCP, 396 + BD71815_INT_LED_OVP, 397 + BD71815_INT_LED_OCP, 398 + BD71815_INT_LED_SCP, 399 + /* DCIN1 interrupts */ 400 + BD71815_INT_DCIN_RMV, 401 + BD71815_INT_CLPS_OUT, 402 + BD71815_INT_CLPS_IN, 403 + BD71815_INT_DCIN_OVP_RES, 404 + BD71815_INT_DCIN_OVP_DET, 405 + /* DCIN2 interrupts */ 406 + BD71815_INT_DCIN_MON_RES, 407 + BD71815_INT_DCIN_MON_DET, 408 + BD71815_INT_WDOG, 409 + /* Vsys INT_STAT_04 */ 410 + BD71815_INT_VSYS_UV_RES, 411 + BD71815_INT_VSYS_UV_DET, 412 + BD71815_INT_VSYS_LOW_RES, 413 + BD71815_INT_VSYS_LOW_DET, 414 + BD71815_INT_VSYS_MON_RES, 415 + BD71815_INT_VSYS_MON_DET, 416 + /* Charger INT_STAT_05 */ 417 + BD71815_INT_CHG_WDG_TEMP, 418 + BD71815_INT_CHG_WDG_TIME, 419 + BD71815_INT_CHG_RECHARGE_RES, 420 + BD71815_INT_CHG_RECHARGE_DET, 421 + BD71815_INT_CHG_RANGED_TEMP_TRANSITION, 422 + BD71815_INT_CHG_STATE_TRANSITION, 423 + /* Battery INT_STAT_06 */ 424 + BD71815_INT_BAT_TEMP_NORMAL, 425 + BD71815_INT_BAT_TEMP_ERANGE, 426 + BD71815_INT_BAT_REMOVED, 427 + BD71815_INT_BAT_DETECTED, 428 + BD71815_INT_THERM_REMOVED, 429 + BD71815_INT_THERM_DETECTED, 430 + /* Battery Mon 1 INT_STAT_07 */ 431 + BD71815_INT_BAT_DEAD, 432 + BD71815_INT_BAT_SHORTC_RES, 433 + BD71815_INT_BAT_SHORTC_DET, 434 + BD71815_INT_BAT_LOW_VOLT_RES, 435 + BD71815_INT_BAT_LOW_VOLT_DET, 436 + BD71815_INT_BAT_OVER_VOLT_RES, 437 + BD71815_INT_BAT_OVER_VOLT_DET, 438 + /* Battery Mon 2 INT_STAT_08 */ 439 + BD71815_INT_BAT_MON_RES, 440 + BD71815_INT_BAT_MON_DET, 441 + /* Battery Mon 3 (Coulomb counter) INT_STAT_09 */ 442 + BD71815_INT_BAT_CC_MON1, 443 + BD71815_INT_BAT_CC_MON2, 444 + BD71815_INT_BAT_CC_MON3, 445 + /* Battery Mon 4 INT_STAT_10 */ 446 + BD71815_INT_BAT_OVER_CURR_1_RES, 447 + BD71815_INT_BAT_OVER_CURR_1_DET, 448 + BD71815_INT_BAT_OVER_CURR_2_RES, 449 + BD71815_INT_BAT_OVER_CURR_2_DET, 450 + BD71815_INT_BAT_OVER_CURR_3_RES, 451 + BD71815_INT_BAT_OVER_CURR_3_DET, 452 + /* Temperature INT_STAT_11 */ 453 + BD71815_INT_TEMP_BAT_LOW_RES, 454 + BD71815_INT_TEMP_BAT_LOW_DET, 455 + BD71815_INT_TEMP_BAT_HI_RES, 456 + BD71815_INT_TEMP_BAT_HI_DET, 457 + BD71815_INT_TEMP_CHIP_OVER_125_RES, 458 + BD71815_INT_TEMP_CHIP_OVER_125_DET, 459 + BD71815_INT_TEMP_CHIP_OVER_VF_RES, 460 + BD71815_INT_TEMP_CHIP_OVER_VF_DET, 461 + /* RTC Alarm INT_STAT_12 */ 462 + BD71815_INT_RTC0, 463 + BD71815_INT_RTC1, 464 + BD71815_INT_RTC2, 465 + }; 466 + 467 + #define BD71815_INT_BUCK1_OCP_MASK BIT(0) 468 + #define BD71815_INT_BUCK2_OCP_MASK BIT(1) 469 + #define BD71815_INT_BUCK3_OCP_MASK BIT(2) 470 + #define BD71815_INT_BUCK4_OCP_MASK BIT(3) 471 + #define BD71815_INT_BUCK5_OCP_MASK BIT(4) 472 + #define BD71815_INT_LED_OVP_MASK BIT(5) 473 + #define BD71815_INT_LED_OCP_MASK BIT(6) 474 + #define BD71815_INT_LED_SCP_MASK BIT(7) 475 + 476 + #define BD71815_INT_DCIN_RMV_MASK BIT(1) 477 + #define BD71815_INT_CLPS_OUT_MASK BIT(2) 478 + #define BD71815_INT_CLPS_IN_MASK BIT(3) 479 + #define BD71815_INT_DCIN_OVP_RES_MASK BIT(4) 480 + #define BD71815_INT_DCIN_OVP_DET_MASK BIT(5) 481 + 482 + #define BD71815_INT_DCIN_MON_RES_MASK BIT(0) 483 + #define BD71815_INT_DCIN_MON_DET_MASK BIT(1) 484 + #define BD71815_INT_WDOG_MASK BIT(6) 485 + 486 + #define BD71815_INT_VSYS_UV_RES_MASK BIT(0) 487 + #define BD71815_INT_VSYS_UV_DET_MASK BIT(1) 488 + #define BD71815_INT_VSYS_LOW_RES_MASK BIT(2) 489 + #define BD71815_INT_VSYS_LOW_DET_MASK BIT(3) 490 + #define BD71815_INT_VSYS_MON_RES_MASK BIT(6) 491 + #define BD71815_INT_VSYS_MON_DET_MASK BIT(7) 492 + 493 + #define BD71815_INT_CHG_WDG_TEMP_MASK BIT(2) 494 + #define BD71815_INT_CHG_WDG_TIME_MASK BIT(3) 495 + #define BD71815_INT_CHG_RECHARGE_RES_MASK BIT(4) 496 + #define BD71815_INT_CHG_RECHARGE_DET_MASK BIT(5) 497 + #define BD71815_INT_CHG_RANGED_TEMP_TRANSITION_MASK BIT(6) 498 + #define BD71815_INT_CHG_STATE_TRANSITION_MASK BIT(7) 499 + 500 + #define BD71815_INT_BAT_TEMP_NORMAL_MASK BIT(0) 501 + #define BD71815_INT_BAT_TEMP_ERANGE_MASK BIT(1) 502 + #define BD71815_INT_BAT_REMOVED_MASK BIT(4) 503 + #define BD71815_INT_BAT_DETECTED_MASK BIT(5) 504 + #define BD71815_INT_THERM_REMOVED_MASK BIT(6) 505 + #define BD71815_INT_THERM_DETECTED_MASK BIT(7) 506 + 507 + #define BD71815_INT_BAT_DEAD_MASK BIT(1) 508 + #define BD71815_INT_BAT_SHORTC_RES_MASK BIT(2) 509 + #define BD71815_INT_BAT_SHORTC_DET_MASK BIT(3) 510 + #define BD71815_INT_BAT_LOW_VOLT_RES_MASK BIT(4) 511 + #define BD71815_INT_BAT_LOW_VOLT_DET_MASK BIT(5) 512 + #define BD71815_INT_BAT_OVER_VOLT_RES_MASK BIT(6) 513 + #define BD71815_INT_BAT_OVER_VOLT_DET_MASK BIT(7) 514 + 515 + #define BD71815_INT_BAT_MON_RES_MASK BIT(0) 516 + #define BD71815_INT_BAT_MON_DET_MASK BIT(1) 517 + 518 + #define BD71815_INT_BAT_CC_MON1_MASK BIT(0) 519 + #define BD71815_INT_BAT_CC_MON2_MASK BIT(1) 520 + #define BD71815_INT_BAT_CC_MON3_MASK BIT(2) 521 + 522 + #define BD71815_INT_BAT_OVER_CURR_1_RES_MASK BIT(0) 523 + #define BD71815_INT_BAT_OVER_CURR_1_DET_MASK BIT(1) 524 + #define BD71815_INT_BAT_OVER_CURR_2_RES_MASK BIT(2) 525 + #define BD71815_INT_BAT_OVER_CURR_2_DET_MASK BIT(3) 526 + #define BD71815_INT_BAT_OVER_CURR_3_RES_MASK BIT(4) 527 + #define BD71815_INT_BAT_OVER_CURR_3_DET_MASK BIT(5) 528 + 529 + #define BD71815_INT_TEMP_BAT_LOW_RES_MASK BIT(0) 530 + #define BD71815_INT_TEMP_BAT_LOW_DET_MASK BIT(1) 531 + #define BD71815_INT_TEMP_BAT_HI_RES_MASK BIT(2) 532 + #define BD71815_INT_TEMP_BAT_HI_DET_MASK BIT(3) 533 + #define BD71815_INT_TEMP_CHIP_OVER_125_RES_MASK BIT(4) 534 + #define BD71815_INT_TEMP_CHIP_OVER_125_DET_MASK BIT(5) 535 + #define BD71815_INT_TEMP_CHIP_OVER_VF_RES_MASK BIT(6) 536 + #define BD71815_INT_TEMP_CHIP_OVER_VF_DET_MASK BIT(7) 537 + 538 + #define BD71815_INT_RTC0_MASK BIT(0) 539 + #define BD71815_INT_RTC1_MASK BIT(1) 540 + #define BD71815_INT_RTC2_MASK BIT(2) 541 + 542 + /* BD71815_REG_CC_CTRL bits */ 543 + #define CCNTRST 0x80 544 + #define CCNTENB 0x40 545 + #define CCCALIB 0x20 546 + 547 + /* BD71815_REG_CC_CURCD */ 548 + #define CURDIR_Discharging 0x8000 549 + 550 + /* BD71815_REG_VM_SA_IBAT */ 551 + #define IBAT_SA_DIR_Discharging 0x8000 552 + 553 + /* BD71815_REG_REX_CTRL_1 bits */ 554 + #define REX_CLR BIT(4) 555 + 556 + /* BD71815_REG_REX_CTRL_1 bits */ 557 + #define REX_PMU_STATE_MASK BIT(2) 558 + 559 + /* BD71815_REG_LED_CTRL bits */ 560 + #define CHGDONE_LED_EN BIT(4) 561 + 562 + #endif /* __LINUX_MFD_BD71815_H */
+3
include/linux/mfd/rohm-bd71828.h
··· 151 151 #define BD71828_REG_GPIO_CTRL3 0x49 152 152 #define BD71828_REG_IO_STAT 0xed 153 153 154 + /* clk */ 155 + #define BD71828_REG_OUT32K 0x4b 156 + 154 157 /* RTC */ 155 158 #define BD71828_REG_RTC_SEC 0x4c 156 159 #define BD71828_REG_RTC_MINUTE 0x4d
-13
include/linux/mfd/rohm-bd718x7.h
··· 310 310 BD718XX_PWRBTN_LONG_PRESS_15S 311 311 }; 312 312 313 - struct bd718xx { 314 - /* 315 - * Please keep this as the first member here as some 316 - * drivers (clk) supporting more than one chip may only know this 317 - * generic struct 'struct rohm_regmap_dev' and assume it is 318 - * the first chunk of parent device's private data. 319 - */ 320 - struct rohm_regmap_dev chip; 321 - 322 - int chip_irq; 323 - struct regmap_irq_chip_data *irq_data; 324 - }; 325 - 326 313 #endif /* __LINUX_MFD_BD718XX_H__ */
+140
include/linux/mfd/rohm-bd957x.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 + /* Copyright (C) 2021 ROHM Semiconductors */ 3 + 4 + #ifndef __LINUX_MFD_BD957X_H__ 5 + #define __LINUX_MFD_BD957X_H__ 6 + 7 + enum { 8 + BD957X_VD50, 9 + BD957X_VD18, 10 + BD957X_VDDDR, 11 + BD957X_VD10, 12 + BD957X_VOUTL1, 13 + BD957X_VOUTS1, 14 + }; 15 + 16 + /* 17 + * The BD9576 has own IRQ 'blocks' for: 18 + * - I2C/thermal, 19 + * - Over voltage protection 20 + * - Short-circuit protection 21 + * - Over current protection 22 + * - Over voltage detection 23 + * - Under voltage detection 24 + * - Under voltage protection 25 + * - 'system interrupt'. 26 + * 27 + * Each of the blocks have a status register giving more accurate IRQ source 28 + * information - for example which of the regulators have over-voltage. 29 + * 30 + * On top of this, there is "main IRQ" status register where each bit indicates 31 + * which of sub-blocks have active IRQs. Fine. That would fit regmap-irq main 32 + * status handling. Except that: 33 + * - Only some sub-IRQs can be masked. 34 + * - The IRQ informs us about fault-condition, not when fault state changes. 35 + * The IRQ line it is kept asserted until the detected condition is acked 36 + * AND cleared in HW. This is annoying for IRQs like the one informing high 37 + * temperature because if IRQ is not disabled it keeps the CPU in IRQ 38 + * handling loop. 39 + * 40 + * For now we do just use the main-IRQ register as source for our IRQ 41 + * information and bind the regmap-irq to this. We leave fine-grained sub-IRQ 42 + * register handling to handlers in sub-devices. The regulator driver shall 43 + * read which regulators are source for problem - or if the detected error is 44 + * regulator temperature error. The sub-drivers do also handle masking of "sub- 45 + * IRQs" if this is supported/needed. 46 + * 47 + * To overcome the problem with HW keeping IRQ asserted we do call 48 + * disable_irq_nosync() from sub-device handler and add a delayed work to 49 + * re-enable IRQ roughly 1 second later. This should keep our CPU out of 50 + * busy-loop. 51 + */ 52 + #define IRQS_SILENT_MS 1000 53 + 54 + enum { 55 + BD9576_INT_THERM, 56 + BD9576_INT_OVP, 57 + BD9576_INT_SCP, 58 + BD9576_INT_OCP, 59 + BD9576_INT_OVD, 60 + BD9576_INT_UVD, 61 + BD9576_INT_UVP, 62 + BD9576_INT_SYS, 63 + }; 64 + 65 + #define BD957X_REG_SMRB_ASSERT 0x15 66 + #define BD957X_REG_PMIC_INTERNAL_STAT 0x20 67 + #define BD957X_REG_INT_THERM_STAT 0x23 68 + #define BD957X_REG_INT_THERM_MASK 0x24 69 + #define BD957X_REG_INT_OVP_STAT 0x25 70 + #define BD957X_REG_INT_SCP_STAT 0x26 71 + #define BD957X_REG_INT_OCP_STAT 0x27 72 + #define BD957X_REG_INT_OVD_STAT 0x28 73 + #define BD957X_REG_INT_UVD_STAT 0x29 74 + #define BD957X_REG_INT_UVP_STAT 0x2a 75 + #define BD957X_REG_INT_SYS_STAT 0x2b 76 + #define BD957X_REG_INT_SYS_MASK 0x2c 77 + #define BD957X_REG_INT_MAIN_STAT 0x30 78 + #define BD957X_REG_INT_MAIN_MASK 0x31 79 + 80 + #define UVD_IRQ_VALID_MASK 0x6F 81 + #define OVD_IRQ_VALID_MASK 0x2F 82 + 83 + #define BD957X_MASK_INT_MAIN_THERM BIT(0) 84 + #define BD957X_MASK_INT_MAIN_OVP BIT(1) 85 + #define BD957X_MASK_INT_MAIN_SCP BIT(2) 86 + #define BD957X_MASK_INT_MAIN_OCP BIT(3) 87 + #define BD957X_MASK_INT_MAIN_OVD BIT(4) 88 + #define BD957X_MASK_INT_MAIN_UVD BIT(5) 89 + #define BD957X_MASK_INT_MAIN_UVP BIT(6) 90 + #define BD957X_MASK_INT_MAIN_SYS BIT(7) 91 + #define BD957X_MASK_INT_ALL 0xff 92 + 93 + #define BD957X_REG_WDT_CONF 0x16 94 + 95 + #define BD957X_REG_POW_TRIGGER1 0x41 96 + #define BD957X_REG_POW_TRIGGER2 0x42 97 + #define BD957X_REG_POW_TRIGGER3 0x43 98 + #define BD957X_REG_POW_TRIGGER4 0x44 99 + #define BD957X_REG_POW_TRIGGERL1 0x45 100 + #define BD957X_REG_POW_TRIGGERS1 0x46 101 + 102 + #define BD957X_REGULATOR_EN_MASK 0xff 103 + #define BD957X_REGULATOR_DIS_VAL 0xff 104 + 105 + #define BD957X_VSEL_REG_MASK 0xff 106 + 107 + #define BD957X_MASK_VOUT1_TUNE 0x87 108 + #define BD957X_MASK_VOUT2_TUNE 0x87 109 + #define BD957X_MASK_VOUT3_TUNE 0x1f 110 + #define BD957X_MASK_VOUT4_TUNE 0x1f 111 + #define BD957X_MASK_VOUTL1_TUNE 0x87 112 + 113 + #define BD957X_REG_VOUT1_TUNE 0x50 114 + #define BD957X_REG_VOUT2_TUNE 0x53 115 + #define BD957X_REG_VOUT3_TUNE 0x56 116 + #define BD957X_REG_VOUT4_TUNE 0x59 117 + #define BD957X_REG_VOUTL1_TUNE 0x5c 118 + 119 + #define BD9576_REG_VOUT1_OVD 0x51 120 + #define BD9576_REG_VOUT1_UVD 0x52 121 + #define BD9576_REG_VOUT2_OVD 0x54 122 + #define BD9576_REG_VOUT2_UVD 0x55 123 + #define BD9576_REG_VOUT3_OVD 0x57 124 + #define BD9576_REG_VOUT3_UVD 0x58 125 + #define BD9576_REG_VOUT4_OVD 0x5a 126 + #define BD9576_REG_VOUT4_UVD 0x5b 127 + #define BD9576_REG_VOUTL1_OVD 0x5d 128 + #define BD9576_REG_VOUTL1_UVD 0x5e 129 + 130 + #define BD9576_MASK_XVD 0x7f 131 + 132 + #define BD9576_REG_VOUT1S_OCW 0x5f 133 + #define BD9576_REG_VOUT1S_OCP 0x60 134 + 135 + #define BD9576_MASK_VOUT1S_OCW 0x3f 136 + #define BD9576_MASK_VOUT1S_OCP 0x3f 137 + 138 + #define BD957X_MAX_REGISTER 0x61 139 + 140 + #endif
+12 -5
include/linux/mfd/rohm-generic.h
··· 8 8 #include <linux/regulator/driver.h> 9 9 10 10 enum rohm_chip_type { 11 - ROHM_CHIP_TYPE_BD71837 = 0, 12 - ROHM_CHIP_TYPE_BD71847, 13 - ROHM_CHIP_TYPE_BD70528, 14 - ROHM_CHIP_TYPE_BD71828, 15 11 ROHM_CHIP_TYPE_BD9571, 12 + ROHM_CHIP_TYPE_BD9573, 16 13 ROHM_CHIP_TYPE_BD9574, 14 + ROHM_CHIP_TYPE_BD9576, 15 + ROHM_CHIP_TYPE_BD70528, 16 + ROHM_CHIP_TYPE_BD71815, 17 + ROHM_CHIP_TYPE_BD71828, 18 + ROHM_CHIP_TYPE_BD71837, 19 + ROHM_CHIP_TYPE_BD71847, 17 20 ROHM_CHIP_TYPE_AMOUNT 18 21 }; 19 22 ··· 29 26 #define ROHM_DVS_LEVEL_IDLE BIT(1) 30 27 #define ROHM_DVS_LEVEL_SUSPEND BIT(2) 31 28 #define ROHM_DVS_LEVEL_LPSR BIT(3) 32 - #define ROHM_DVS_LEVEL_VALID_AMOUNT 4 29 + #define ROHM_DVS_LEVEL_SNVS BIT(4) 30 + #define ROHM_DVS_LEVEL_VALID_AMOUNT 5 33 31 #define ROHM_DVS_LEVEL_UNKNOWN 0 34 32 35 33 /** ··· 69 65 unsigned int lpsr_reg; 70 66 unsigned int lpsr_mask; 71 67 unsigned int lpsr_on_mask; 68 + unsigned int snvs_reg; 69 + unsigned int snvs_mask; 70 + unsigned int snvs_on_mask; 72 71 }; 73 72 74 73 #if IS_ENABLED(CONFIG_REGULATOR_ROHM)
-2
include/linux/mfd/twl.h
··· 781 781 #define TWL4030_VAUX3_DEV_GRP 0x1F 782 782 #define TWL4030_VAUX3_DEDICATED 0x22 783 783 784 - static inline int twl4030charger_usb_en(int enable) { return 0; } 785 - 786 784 /*----------------------------------------------------------------------*/ 787 785 788 786 /* Linux-specific regulator identifiers ... for now, we only support
-13
include/linux/platform_data/i2c-designware.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Copyright(c) 2014 Intel Corporation. 4 - */ 5 - 6 - #ifndef I2C_DESIGNWARE_H 7 - #define I2C_DESIGNWARE_H 8 - 9 - struct dw_i2c_platform_data { 10 - unsigned int i2c_scl_freq; 11 - }; 12 - 13 - #endif