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

Configure Feed

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

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

Pull MFD updates from Lee Jones:
"Core Frameworks:
- Fix 'mfd_of_node_list' OF node entry resource leak

New Drivers:
- Add support for Ocelot VSC7512 Networking Chip
- Add support for MediaTek MT6370 subPMIC
- Add support for Richtek RT5120 (I2C) PMIC

New Device Support:
- Add support for Rockchip RV1126 and RK3588 to Syscon
- Add support for Rockchip RK817 Battery Charger to RK808
- Add support for Silergy SY7636a Voltage Regulator to Simple MFD
- Add support for Qualcomm PMP8074 PMIC to QCOM SPMI
- Add support for Secure Update to Intel M10 BMC

New Functionality:
- Provide SSP type to Intel's LPSS (PCI) SPI driver

Fix-ups:
- Remove legacy / unused code; stmpe, intel_soc_pmic_crc, syscon
- Unify / simplify; intel_soc_pmic_crc
- Trivial reordering / spelling, etc; Makefile, twl-core
- Convert to managed resources; intel_soc_pmic_crc
- Use appropriate APIs; intel_soc_pmic_crc
- strscpy() conversion; htc-i2cpld, lpc_ich, mfd-core
- GPIOD conversion; htc-i2cpld, stmpe
- Add missing header file includes; twl4030-irq
- DT goodies; stmpe, mediatek,mt6370, x-powers,axp152,
aspeed,ast2x00-scu, mediatek,mt8195-scpsys, qcom,spmi-pmic, syscon,
qcom,tcsr, rockchip,rk817, sprd,ums512-glbreg, dlg,da9063

Bug Fixes:
- Properly check return values; sm501, htc-i2cpld
- Repair Two-Wire Bus Mode; da9062-core
- Fix error handling; intel_soc_pmic_core, fsl-imx25-tsadc, lp8788,
lp8788-irq"

* tag 'mfd-next-6.1' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (60 commits)
mfd: syscon: Remove repetition of the regmap_get_val_endian()
mfd: ocelot-spi: Add missing MODULE_DEVICE_TABLE
power: supply: Add charger driver for Rockchip RK817
dt-bindings: mfd: mt6370: Fix the indentation in the example
mfd: da9061: Fix Failed to set Two-Wire Bus Mode.
mfd: htc-i2cpld: Fix an IS_ERR() vs NULL bug in htcpld_core_probe()
dt-bindings: mfd: qcom,tcsr: Drop simple-mfd from IPQ6018
mfd: sm501: Add check for platform_driver_register()
dt-bindings: mfd: mediatek: Add scpsys compatible for mt8186
mfd: twl4030: Add missed linux/device.h header
dt-bindings: mfd: dlg,da9063: Add missing regulator patterns
dt-bindings: mfd: sprd: Add bindings for ums512 global registers
mfd: intel_soc_pmic_chtdc_ti: Switch from __maybe_unused to pm_sleep_ptr() etc
dt-bindings: mfd: syscon: Add rk3588 QoS register compatible
mfd: stmpe: Switch to using gpiod API
mfd: qcom-spmi-pmic: Add pm7250b compatible
dt-bindings: mfd: Add missing (unevaluated|additional)Properties on child nodes
mfd/omap1: htc-i2cpld: Convert to a pure GPIO driver
mfd: intel-m10-bmc: Add d5005 bmc secure update driver
dt-bindings: mfd: syscon: Drop ref from reg-io-width
...

+3274 -433
+40
Documentation/devicetree/bindings/mfd/allwinner,sun6i-a31-prcm.yaml
··· 22 22 patternProperties: 23 23 "^.*_(clk|rst)$": 24 24 type: object 25 + unevaluatedProperties: false 25 26 26 27 properties: 27 28 compatible: ··· 35 34 - fixed-factor-clock 36 35 37 36 allOf: 37 + - if: 38 + properties: 39 + compatible: 40 + contains: 41 + const: fixed-factor-clock 42 + 43 + then: 44 + $ref: /schemas/clock/fixed-factor-clock.yaml# 45 + 46 + - if: 47 + properties: 48 + compatible: 49 + contains: 50 + const: allwinner,sun4i-a10-mod0-clk 51 + 52 + then: 53 + properties: 54 + "#clock-cells": 55 + const: 0 56 + 57 + # Already checked in the main schema 58 + compatible: true 59 + 60 + clocks: 61 + maxItems: 2 62 + 63 + clock-output-names: 64 + maxItems: 1 65 + 66 + phandle: true 67 + 68 + required: 69 + - "#clock-cells" 70 + - compatible 71 + - clocks 72 + - clock-output-names 73 + 74 + additionalProperties: false 75 + 38 76 - if: 39 77 properties: 40 78 compatible:
+10
Documentation/devicetree/bindings/mfd/allwinner,sun8i-a23-prcm.yaml
··· 22 22 patternProperties: 23 23 "^.*(clk|rst|codec).*$": 24 24 type: object 25 + unevaluatedProperties: false 25 26 26 27 properties: 27 28 compatible: ··· 37 36 - compatible 38 37 39 38 allOf: 39 + - if: 40 + properties: 41 + compatible: 42 + contains: 43 + const: fixed-factor-clock 44 + 45 + then: 46 + $ref: /schemas/clock/fixed-factor-clock.yaml# 47 + 40 48 - if: 41 49 properties: 42 50 compatible:
+110
Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/mfd/aspeed,ast2x00-scu.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Aspeed System Control Unit 8 + 9 + description: 10 + The Aspeed System Control Unit manages the global behaviour of the SoC, 11 + configuring elements such as clocks, pinmux, and reset. 12 + 13 + maintainers: 14 + - Joel Stanley <joel@jms.id.au> 15 + - Andrew Jeffery <andrew@aj.id.au> 16 + 17 + properties: 18 + compatible: 19 + items: 20 + - enum: 21 + - aspeed,ast2400-scu 22 + - aspeed,ast2500-scu 23 + - aspeed,ast2600-scu 24 + - const: syscon 25 + - const: simple-mfd 26 + 27 + reg: 28 + maxItems: 1 29 + 30 + ranges: true 31 + 32 + '#address-cells': 33 + const: 1 34 + 35 + '#size-cells': 36 + const: 1 37 + 38 + '#clock-cells': 39 + const: 1 40 + 41 + '#reset-cells': 42 + const: 1 43 + 44 + patternProperties: 45 + '^p2a-control@[0-9a-f]+$': 46 + description: See Documentation/devicetree/bindings/misc/aspeed-p2a-ctrl.txt 47 + type: object 48 + 49 + '^pinctrl(@[0-9a-f]+)?$': 50 + oneOf: 51 + - $ref: /schemas/pinctrl/aspeed,ast2400-pinctrl.yaml 52 + - $ref: /schemas/pinctrl/aspeed,ast2500-pinctrl.yaml 53 + - $ref: /schemas/pinctrl/aspeed,ast2600-pinctrl.yaml 54 + 55 + '^interrupt-controller@[0-9a-f]+$': 56 + description: See Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2xxx-scu-ic.txt 57 + type: object 58 + 59 + '^silicon-id@[0-9a-f]+$': 60 + description: Unique hardware silicon identifiers within the SoC 61 + type: object 62 + additionalProperties: false 63 + 64 + properties: 65 + compatible: 66 + items: 67 + - enum: 68 + - aspeed,ast2400-silicon-id 69 + - aspeed,ast2500-silicon-id 70 + - aspeed,ast2600-silicon-id 71 + - const: aspeed,silicon-id 72 + 73 + reg: 74 + description: 75 + The reg should be the unique silicon id register, and not backwards 76 + compatible one in eg. the 2600. 77 + minItems: 1 78 + items: 79 + - description: silicon id information registers 80 + - description: unique chip id registers 81 + 82 + required: 83 + - compatible 84 + - reg 85 + - ranges 86 + - '#address-cells' 87 + - '#size-cells' 88 + - '#clock-cells' 89 + - '#reset-cells' 90 + 91 + additionalProperties: false 92 + 93 + examples: 94 + - | 95 + syscon@1e6e2000 { 96 + compatible = "aspeed,ast2400-scu", "syscon", "simple-mfd"; 97 + reg = <0x1e6e2000 0x1a8>; 98 + #clock-cells = <1>; 99 + #reset-cells = <1>; 100 + 101 + #address-cells = <1>; 102 + #size-cells = <1>; 103 + ranges = <0x0 0x1e6e2000 0x1000>; 104 + 105 + silicon-id@7c { 106 + compatible = "aspeed,ast2500-silicon-id", "aspeed,silicon-id"; 107 + reg = <0x7c 0x4>, <0x150 0x8>; 108 + }; 109 + }; 110 + ...
-48
Documentation/devicetree/bindings/mfd/aspeed-scu.txt
··· 1 - The Aspeed System Control Unit manages the global behaviour of the SoC, 2 - configuring elements such as clocks, pinmux, and reset. 3 - 4 - Required properties: 5 - - compatible: One of: 6 - "aspeed,ast2400-scu", "syscon", "simple-mfd" 7 - "aspeed,ast2500-scu", "syscon", "simple-mfd" 8 - 9 - - reg: contains the offset and length of the SCU memory region 10 - - #clock-cells: should be set to <1> - the system controller is also a 11 - clock provider 12 - - #reset-cells: should be set to <1> - the system controller is also a 13 - reset line provider 14 - 15 - Example: 16 - 17 - syscon: syscon@1e6e2000 { 18 - compatible = "aspeed,ast2400-scu", "syscon", "simple-mfd"; 19 - reg = <0x1e6e2000 0x1a8>; 20 - #clock-cells = <1>; 21 - #reset-cells = <1>; 22 - }; 23 - 24 - Silicon ID 25 - ----------------- 26 - 27 - Families have unique hardware silicon identifiers within the SoC. 28 - 29 - Required properties: 30 - 31 - - compatible: "aspeed,silicon-id" or: 32 - "aspeed,ast2400-silicon-id" or 33 - "aspeed,ast2500-silicon-id" or 34 - "aspeed,ast2600-silicon-id" 35 - 36 - - reg: offset and length of the silicon id information 37 - optionally, a second offset and length describes the unique chip id 38 - 39 - The reg should be the unique silicon id register, and 40 - not backwards compatible one in eg. the 2600. 41 - 42 - Example: 43 - 44 - 45 - silicon-id@7c { 46 - compatible = "aspeed,ast2500-silicon-id", "aspeed,silicon-id"; 47 - reg = <0x7c 0x4 0x150 0x8>; 48 - };
+5
Documentation/devicetree/bindings/mfd/cirrus,lochnagar.yaml
··· 144 144 CODECs digital core if not being provided by an internal regulator. 145 145 type: object 146 146 $ref: /schemas/regulator/regulator.yaml# 147 + unevaluatedProperties: false 147 148 properties: 148 149 compatible: 149 150 enum: ··· 162 161 CODECs MICVDD. 163 162 type: object 164 163 $ref: /schemas/regulator/regulator.yaml# 164 + unevaluatedProperties: false 165 165 properties: 166 166 compatible: 167 167 enum: ··· 179 177 Initialisation data for the MIC1VDD supplies. 180 178 type: object 181 179 $ref: /schemas/regulator/regulator.yaml# 180 + unevaluatedProperties: false 182 181 properties: 183 182 compatible: 184 183 enum: ··· 205 202 Initialisation data for the MIC2VDD supplies. 206 203 type: object 207 204 $ref: /schemas/regulator/regulator.yaml# 205 + unevaluatedProperties: false 208 206 properties: 209 207 compatible: 210 208 enum: ··· 232 228 the CODECs analog and 1.8V digital supplies. 233 229 type: object 234 230 $ref: /schemas/regulator/regulator.yaml# 231 + unevaluatedProperties: false 235 232 properties: 236 233 compatible: 237 234 enum:
+4 -3
Documentation/devicetree/bindings/mfd/dlg,da9063.yaml
··· 71 71 72 72 regulators: 73 73 type: object 74 + additionalProperties: false 74 75 patternProperties: 75 - "^(ldo[1-11]|bcore[1-2]|bpro|bmem|bio|bperi)$": 76 + "^(ldo([1-9]|1[01])|bcore([1-2]|s-merged)|b(pro|mem|io|peri)|bmem-bio-merged)$": 76 77 $ref: /schemas/regulator/regulator.yaml 77 78 unevaluatedProperties: false 78 79 ··· 113 112 }; 114 113 115 114 regulators { 116 - regulator-bcore1 { 115 + bcore1 { 117 116 regulator-name = "BCORE1"; 118 117 regulator-min-microvolt = <300000>; 119 118 regulator-max-microvolt = <1570000>; ··· 121 120 regulator-max-microamp = <2000000>; 122 121 regulator-boot-on; 123 122 }; 124 - regulator-ldo11 { 123 + ldo11 { 125 124 regulator-name = "LDO_11"; 126 125 regulator-min-microvolt = <900000>; 127 126 regulator-max-microvolt = <3600000>;
+4 -1
Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml
··· 46 46 47 47 adc: 48 48 type: object 49 + additionalProperties: false 49 50 description: Optional hardware monitoring module 50 51 51 52 properties: ··· 60 59 const: 0 61 60 62 61 patternProperties: 63 - "^channel@[0-9]+$": 62 + "^channel@[0-9a-f]+$": 64 63 type: object 64 + additionalProperties: false 65 65 description: | 66 66 Properties for a single ADC which can report cooked values 67 67 (i.e. temperature sensor based on thermister), raw values ··· 115 113 patternProperties: 116 114 "^fan-controller@[0-9a-f]+$": 117 115 type: object 116 + additionalProperties: false 118 117 description: Optional fan controller 119 118 120 119 properties:
+1
Documentation/devicetree/bindings/mfd/maxim,max14577.yaml
··· 39 39 40 40 extcon: 41 41 type: object 42 + additionalProperties: false 42 43 properties: 43 44 compatible: 44 45 enum:
+1
Documentation/devicetree/bindings/mfd/maxim,max77843.yaml
··· 32 32 33 33 motor-driver: 34 34 type: object 35 + additionalProperties: false 35 36 properties: 36 37 compatible: 37 38 const: maxim,max77843-haptic
+280
Documentation/devicetree/bindings/mfd/mediatek,mt6370.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/mediatek,mt6370.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: MediaTek MT6370 SubPMIC 8 + 9 + maintainers: 10 + - ChiYuan Huang <cy_huang@richtek.com> 11 + 12 + description: | 13 + MT6370 is a highly-integrated smart power management IC, which includes a 14 + single cell Li-Ion/Li-Polymer switching battery charger, a USB Type-C & 15 + Power Delivery (PD) controller, dual flash LED current sources, a RGB LED 16 + driver, a backlight WLED driver, a display bias driver and a general LDO for 17 + portable devices. 18 + 19 + properties: 20 + compatible: 21 + const: mediatek,mt6370 22 + 23 + reg: 24 + maxItems: 1 25 + 26 + wakeup-source: true 27 + 28 + interrupts: 29 + maxItems: 1 30 + 31 + interrupt-controller: true 32 + 33 + "#interrupt-cells": 34 + const: 1 35 + 36 + adc: 37 + type: object 38 + description: | 39 + Provides 9 channels for system monitoring, including VBUSDIV5 (lower 40 + accuracy, higher measure range), VBUSDIV2 (higher accuracy, lower 41 + measure range), VBAT, VSYS, CHG_VDDP, TS_BAT, IBUS, IBAT, and TEMP_JC. 42 + 43 + properties: 44 + compatible: 45 + const: mediatek,mt6370-adc 46 + 47 + "#io-channel-cells": 48 + const: 1 49 + 50 + required: 51 + - compatible 52 + - "#io-channel-cells" 53 + 54 + backlight: 55 + type: object 56 + $ref: /schemas/leds/backlight/mediatek,mt6370-backlight.yaml# 57 + 58 + charger: 59 + type: object 60 + $ref: /schemas/power/supply/mediatek,mt6370-charger.yaml# 61 + 62 + tcpc: 63 + type: object 64 + $ref: /schemas/usb/mediatek,mt6370-tcpc.yaml# 65 + 66 + indicator: 67 + type: object 68 + $ref: /schemas/leds/mediatek,mt6370-indicator.yaml# 69 + 70 + flashlight: 71 + type: object 72 + $ref: /schemas/leds/mediatek,mt6370-flashlight.yaml# 73 + 74 + regulators: 75 + type: object 76 + description: | 77 + List all supported regulators, which support the control for DisplayBias 78 + voltages and one general purpose LDO which commonly used to drive the 79 + vibrator. 80 + 81 + patternProperties: 82 + "^(dsvbst|vibldo)$": 83 + $ref: /schemas/regulator/regulator.yaml# 84 + type: object 85 + unevaluatedProperties: false 86 + 87 + "^(dsvpos|dsvneg)$": 88 + $ref: /schemas/regulator/regulator.yaml# 89 + type: object 90 + unevaluatedProperties: false 91 + 92 + properties: 93 + enable-gpios: 94 + maxItems: 1 95 + 96 + required: 97 + - compatible 98 + - reg 99 + - interrupts 100 + - interrupt-controller 101 + - "#interrupt-cells" 102 + - regulators 103 + - adc 104 + - backlight 105 + - indicator 106 + - tcpc 107 + - charger 108 + - flashlight 109 + 110 + additionalProperties: false 111 + 112 + examples: 113 + - | 114 + #include <dt-bindings/interrupt-controller/irq.h> 115 + #include <dt-bindings/leds/common.h> 116 + #include <dt-bindings/iio/adc/mediatek,mt6370_adc.h> 117 + #include <dt-bindings/usb/pd.h> 118 + i2c { 119 + #address-cells = <1>; 120 + #size-cells = <0>; 121 + 122 + pmic@34 { 123 + compatible = "mediatek,mt6370"; 124 + reg = <0x34>; 125 + wakeup-source; 126 + interrupts-extended = <&gpio26 3 IRQ_TYPE_LEVEL_LOW>; 127 + interrupt-controller; 128 + #interrupt-cells = <1>; 129 + 130 + mt6370_adc: adc { 131 + compatible = "mediatek,mt6370-adc"; 132 + #io-channel-cells = <1>; 133 + }; 134 + 135 + backlight { 136 + compatible = "mediatek,mt6370-backlight"; 137 + mediatek,bled-channel-use = /bits/ 8 <15>; 138 + }; 139 + 140 + charger { 141 + compatible = "mediatek,mt6370-charger"; 142 + interrupts = <48>, <68>, <6>; 143 + interrupt-names = "attach_i", "uvp_d_evt", "mivr"; 144 + io-channels = <&mt6370_adc MT6370_CHAN_IBUS>; 145 + 146 + mt6370_otg_vbus: usb-otg-vbus-regulator { 147 + regulator-name = "mt6370-usb-otg-vbus"; 148 + regulator-min-microvolt = <4350000>; 149 + regulator-max-microvolt = <5800000>; 150 + regulator-min-microamp = <500000>; 151 + regulator-max-microamp = <3000000>; 152 + }; 153 + }; 154 + 155 + indicator { 156 + compatible = "mediatek,mt6370-indicator"; 157 + #address-cells = <1>; 158 + #size-cells = <0>; 159 + 160 + multi-led@0 { 161 + reg = <0>; 162 + function = LED_FUNCTION_INDICATOR; 163 + color = <LED_COLOR_ID_RGB>; 164 + led-max-microamp = <24000>; 165 + #address-cells = <1>; 166 + #size-cells = <0>; 167 + led@0 { 168 + reg = <0>; 169 + color = <LED_COLOR_ID_RED>; 170 + }; 171 + led@1 { 172 + reg = <1>; 173 + color = <LED_COLOR_ID_GREEN>; 174 + }; 175 + led@2 { 176 + reg = <2>; 177 + color = <LED_COLOR_ID_BLUE>; 178 + }; 179 + }; 180 + led@3 { 181 + reg = <3>; 182 + function = LED_FUNCTION_INDICATOR; 183 + color = <LED_COLOR_ID_WHITE>; 184 + led-max-microamp = <6000>; 185 + }; 186 + }; 187 + 188 + flashlight { 189 + compatible = "mediatek,mt6370-flashlight"; 190 + #address-cells = <1>; 191 + #size-cells = <0>; 192 + led@0 { 193 + reg = <0>; 194 + led-sources = <0>; 195 + function = LED_FUNCTION_FLASH; 196 + color = <LED_COLOR_ID_WHITE>; 197 + function-enumerator = <1>; 198 + led-max-microamp = <200000>; 199 + flash-max-microamp = <500000>; 200 + flash-max-timeout-us = <1248000>; 201 + }; 202 + led@1 { 203 + reg = <1>; 204 + led-sources = <1>; 205 + function = LED_FUNCTION_FLASH; 206 + color = <LED_COLOR_ID_WHITE>; 207 + function-enumerator = <2>; 208 + led-max-microamp = <200000>; 209 + flash-max-microamp = <500000>; 210 + flash-max-timeout-us = <1248000>; 211 + }; 212 + }; 213 + 214 + tcpc { 215 + compatible = "mediatek,mt6370-tcpc"; 216 + interrupts-extended = <&gpio26 4 IRQ_TYPE_LEVEL_LOW>; 217 + 218 + connector { 219 + compatible = "usb-c-connector"; 220 + label = "USB-C"; 221 + vbus-supply = <&mt6370_otg_vbus>; 222 + data-role = "dual"; 223 + power-role = "dual"; 224 + try-power-role = "sink"; 225 + source-pdos = <PDO_FIXED(5000, 1000, PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP)>; 226 + sink-pdos = <PDO_FIXED(5000, 2000, PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP)>; 227 + op-sink-microwatt = <10000000>; 228 + 229 + ports { 230 + #address-cells = <1>; 231 + #size-cells = <0>; 232 + 233 + port@0 { 234 + reg = <0>; 235 + endpoint { 236 + remote-endpoint = <&usb_hs>; 237 + }; 238 + }; 239 + port@1 { 240 + reg = <1>; 241 + endpoint { 242 + remote-endpoint = <&usb_ss>; 243 + }; 244 + }; 245 + port@2 { 246 + reg = <2>; 247 + endpoint { 248 + remote-endpoint = <&dp_aux>; 249 + }; 250 + }; 251 + }; 252 + }; 253 + }; 254 + 255 + regulators { 256 + dsvbst { 257 + regulator-name = "mt6370-dsv-vbst"; 258 + regulator-min-microvolt = <4000000>; 259 + regulator-max-microvolt = <6200000>; 260 + }; 261 + dsvpos { 262 + regulator-name = "mt6370-dsv-vpos"; 263 + regulator-min-microvolt = <4000000>; 264 + regulator-max-microvolt = <6000000>; 265 + regulator-boot-on; 266 + }; 267 + dsvneg { 268 + regulator-name = "mt6370-dsv-vneg"; 269 + regulator-min-microvolt = <4000000>; 270 + regulator-max-microvolt = <6000000>; 271 + regulator-boot-on; 272 + }; 273 + vibldo { 274 + regulator-name = "mt6370-vib-ldo"; 275 + regulator-min-microvolt = <1600000>; 276 + regulator-max-microvolt = <4000000>; 277 + }; 278 + }; 279 + }; 280 + };
+68
Documentation/devicetree/bindings/mfd/mediatek,mt8195-scpsys.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/mediatek,mt8195-scpsys.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: MediaTek System Control Processor System 8 + 9 + maintainers: 10 + - MandyJH Liu <mandyjh.liu@mediatek.com> 11 + 12 + description: 13 + MediaTek System Control Processor System (SCPSYS) has several 14 + power management tasks. The tasks include MTCMOS power 15 + domain control, thermal measurement, DVFS, etc. 16 + 17 + properties: 18 + compatible: 19 + items: 20 + - enum: 21 + - mediatek,mt8167-scpsys 22 + - mediatek,mt8173-scpsys 23 + - mediatek,mt8183-scpsys 24 + - mediatek,mt8186-scpsys 25 + - mediatek,mt8192-scpsys 26 + - mediatek,mt8195-scpsys 27 + - const: syscon 28 + - const: simple-mfd 29 + 30 + reg: 31 + maxItems: 1 32 + 33 + power-controller: 34 + $ref: /schemas/power/mediatek,power-controller.yaml# 35 + 36 + required: 37 + - compatible 38 + - reg 39 + 40 + additionalProperties: false 41 + 42 + examples: 43 + - | 44 + #include <dt-bindings/clock/mt8195-clk.h> 45 + #include <dt-bindings/power/mt8195-power.h> 46 + 47 + syscon@10006000 { 48 + compatible = "mediatek,mt8195-scpsys", "syscon", "simple-mfd"; 49 + reg = <0x10006000 0x100>; 50 + 51 + spm: power-controller { 52 + compatible = "mediatek,mt8195-power-controller"; 53 + #address-cells = <1>; 54 + #size-cells = <0>; 55 + #power-domain-cells = <1>; 56 + 57 + /* sample of power domain nodes */ 58 + power-domain@MT8195_POWER_DOMAIN_PCIE_PHY { 59 + reg = <MT8195_POWER_DOMAIN_PCIE_PHY>; 60 + #power-domain-cells = <0>; 61 + }; 62 + 63 + power-domain@MT8195_POWER_DOMAIN_SSUSB_PCIE_PHY { 64 + reg = <MT8195_POWER_DOMAIN_SSUSB_PCIE_PHY>; 65 + #power-domain-cells = <0>; 66 + }; 67 + }; 68 + };
+110 -4
Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
··· 33 33 compatible: 34 34 items: 35 35 - enum: 36 - - qcom,pm660 37 - - qcom,pm660l 38 36 - qcom,pm6150 39 37 - qcom,pm6150l 40 38 - qcom,pm6350 39 + - qcom,pm660 40 + - qcom,pm660l 41 + - qcom,pm7250b 41 42 - qcom,pm7325 42 43 - qcom,pm8004 43 44 - qcom,pm8005 44 45 - qcom,pm8009 45 46 - qcom,pm8019 47 + - qcom,pm8028 46 48 - qcom,pm8110 47 49 - qcom,pm8150 48 50 - qcom,pm8150b 51 + - qcom,pm8150c 49 52 - qcom,pm8150l 50 53 - qcom,pm8226 51 54 - qcom,pm8350 ··· 59 56 - qcom,pm8916 60 57 - qcom,pm8941 61 58 - qcom,pm8950 59 + - qcom,pm8953 62 60 - qcom,pm8994 63 61 - qcom,pm8998 64 62 - qcom,pma8084 ··· 68 64 - qcom,pmi8962 69 65 - qcom,pmi8994 70 66 - qcom,pmi8998 67 + - qcom,pmk8002 71 68 - qcom,pmk8350 72 69 - qcom,pmm8155au 70 + - qcom,pmp8074 73 71 - qcom,pmr735a 74 72 - qcom,pmr735b 75 73 - qcom,pms405 ··· 96 90 97 91 regulators: 98 92 type: object 99 - $ref: /schemas/regulator/regulator.yaml# 93 + $ref: /schemas/regulator/qcom,spmi-regulator.yaml# 100 94 101 95 patternProperties: 102 96 "^adc@[0-9a-f]+$": ··· 105 99 106 100 "^adc-tm@[0-9a-f]+$": 107 101 type: object 108 - $ref: /schemas/thermal/qcom-spmi-adc-tm5.yaml# 102 + # ref depends on compatible, see allOf below 109 103 110 104 "^audio-codec@[0-9a-f]+$": 111 105 type: object ··· 152 146 - compatible 153 147 - reg 154 148 149 + allOf: 150 + - if: 151 + properties: 152 + compatible: 153 + contains: 154 + enum: 155 + - qcom,pm8998 156 + then: 157 + patternProperties: 158 + "^adc-tm@[0-9a-f]+$": 159 + $ref: /schemas/thermal/qcom-spmi-adc-tm-hc.yaml# 160 + else: 161 + patternProperties: 162 + "^adc-tm@[0-9a-f]+$": 163 + $ref: /schemas/thermal/qcom-spmi-adc-tm5.yaml# 164 + 155 165 additionalProperties: false 156 166 157 167 examples: ··· 208 186 interrupt-controller; 209 187 #interrupt-cells = <2>; 210 188 }; 189 + }; 190 + }; 191 + 192 + - | 193 + #include <dt-bindings/input/input.h> 194 + #include <dt-bindings/interrupt-controller/irq.h> 195 + #include <dt-bindings/interrupt-controller/arm-gic.h> 196 + #include <dt-bindings/iio/qcom,spmi-vadc.h> 197 + #include <dt-bindings/spmi/spmi.h> 198 + 199 + pmic@0 { 200 + compatible = "qcom,pm6150", "qcom,spmi-pmic"; 201 + reg = <0x0 SPMI_USID>; 202 + #address-cells = <1>; 203 + #size-cells = <0>; 204 + 205 + pon@800 { 206 + compatible = "qcom,pm8998-pon"; 207 + reg = <0x800>; 208 + mode-bootloader = <0x2>; 209 + mode-recovery = <0x1>; 210 + 211 + pwrkey { 212 + compatible = "qcom,pm8941-pwrkey"; 213 + interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>; 214 + debounce = <15625>; 215 + bias-pull-up; 216 + linux,code = <KEY_POWER>; 217 + }; 218 + }; 219 + 220 + temp-alarm@2400 { 221 + compatible = "qcom,spmi-temp-alarm"; 222 + reg = <0x2400>; 223 + interrupts = <0x0 0x24 0x0 IRQ_TYPE_EDGE_RISING>; 224 + io-channels = <&pm6150_adc ADC5_DIE_TEMP>; 225 + io-channel-names = "thermal"; 226 + #thermal-sensor-cells = <0>; 227 + }; 228 + 229 + pm6150_adc: adc@3100 { 230 + compatible = "qcom,spmi-adc5"; 231 + reg = <0x3100>; 232 + interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>; 233 + #address-cells = <1>; 234 + #size-cells = <0>; 235 + #io-channel-cells = <1>; 236 + 237 + adc-chan@6 { 238 + reg = <ADC5_DIE_TEMP>; 239 + label = "die_temp"; 240 + }; 241 + 242 + adc-chan@4f { 243 + reg = <ADC5_AMUX_THM3_100K_PU>; 244 + qcom,ratiometric; 245 + qcom,hw-settle-time = <200>; 246 + }; 247 + }; 248 + 249 + adc-tm@3500 { 250 + compatible = "qcom,spmi-adc-tm5"; 251 + reg = <0x3500>; 252 + interrupts = <0x0 0x35 0x0 IRQ_TYPE_EDGE_RISING>; 253 + #thermal-sensor-cells = <1>; 254 + #address-cells = <1>; 255 + #size-cells = <0>; 256 + 257 + charger-thermistor@0 { 258 + reg = <0>; 259 + io-channels = <&pm6150_adc ADC5_AMUX_THM3_100K_PU>; 260 + qcom,ratiometric; 261 + qcom,hw-settle-time-us = <200>; 262 + }; 263 + }; 264 + 265 + pm6150_gpio: gpios@c000 { 266 + compatible = "qcom,pm6150-gpio", "qcom,spmi-gpio"; 267 + reg = <0xc000>; 268 + gpio-controller; 269 + gpio-ranges = <&pm6150_gpio 0 0 10>; 270 + #gpio-cells = <2>; 271 + interrupt-controller; 272 + #interrupt-cells = <2>; 211 273 }; 212 274 };
+21 -25
Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml
··· 15 15 16 16 properties: 17 17 compatible: 18 - oneOf: 19 - - items: 20 - - enum: 21 - - qcom,msm8998-tcsr 22 - - qcom,qcs404-tcsr 23 - - qcom,sc7180-tcsr 24 - - qcom,sc7280-tcsr 25 - - qcom,sdm630-tcsr 26 - - qcom,sdm845-tcsr 27 - - qcom,sm8150-tcsr 28 - - qcom,tcsr-apq8064 29 - - qcom,tcsr-apq8084 30 - - qcom,tcsr-ipq8064 31 - - qcom,tcsr-mdm9615 32 - - qcom,tcsr-msm8660 33 - - qcom,tcsr-msm8916 34 - - qcom,tcsr-msm8953 35 - - qcom,tcsr-msm8960 36 - - qcom,tcsr-msm8974 37 - - qcom,tcsr-msm8996 38 - - const: syscon 39 - - items: 40 - - const: qcom,tcsr-ipq6018 41 - - const: syscon 42 - - const: simple-mfd 18 + items: 19 + - enum: 20 + - qcom,msm8998-tcsr 21 + - qcom,qcs404-tcsr 22 + - qcom,sc7180-tcsr 23 + - qcom,sc7280-tcsr 24 + - qcom,sdm630-tcsr 25 + - qcom,sdm845-tcsr 26 + - qcom,sm8150-tcsr 27 + - qcom,tcsr-apq8064 28 + - qcom,tcsr-apq8084 29 + - qcom,tcsr-ipq6018 30 + - qcom,tcsr-ipq8064 31 + - qcom,tcsr-mdm9615 32 + - qcom,tcsr-msm8660 33 + - qcom,tcsr-msm8916 34 + - qcom,tcsr-msm8953 35 + - qcom,tcsr-msm8960 36 + - qcom,tcsr-msm8974 37 + - qcom,tcsr-msm8996 38 + - const: syscon 43 39 44 40 reg: 45 41 maxItems: 1
+178
Documentation/devicetree/bindings/mfd/richtek,rt5120.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/richtek,rt5120.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Richtek RT5120 PMIC 8 + 9 + maintainers: 10 + - ChiYuan Huang <cy_huang@richtek.com> 11 + 12 + description: | 13 + The RT5120 provides four high-efficiency buck converters and one LDO voltage 14 + regulator. The device is targeted at providingthe processor voltage, memory, 15 + I/O, and peripheral rails in home entertainment devices. The I2C interface is 16 + used for dynamic voltage scaling of the processor voltage, power rails on/off 17 + sequence control, operation mode selection. 18 + 19 + properties: 20 + compatible: 21 + enum: 22 + - richtek,rt5120 23 + 24 + reg: 25 + maxItems: 1 26 + 27 + interrupts: 28 + maxItems: 1 29 + 30 + interrupt-controller: true 31 + 32 + "#interrupt-cells": 33 + const: 1 34 + 35 + wakeup-source: true 36 + 37 + richtek,enable-undervolt-hiccup: 38 + type: boolean 39 + description: | 40 + If used, under voltage protection trigger hiccup behavior, else latchup as 41 + default 42 + 43 + richtek,enable-overvolt-hiccup: 44 + type: boolean 45 + description: 46 + Like as 'enable-uv-hiccup', it configures over voltage protection to 47 + hiccup, else latchup as default 48 + 49 + vin1-supply: 50 + description: phandle for buck1 input power source 51 + 52 + vin2-supply: 53 + description: phandle for buck2 input power source 54 + 55 + vin3-supply: 56 + description: phandle for buck3 input power source 57 + 58 + vin4-supply: 59 + description: phandle for buck4 input power source 60 + 61 + vinldo-supply: 62 + description: phandle for ldo input power source 63 + 64 + regulators: 65 + type: object 66 + 67 + patternProperties: 68 + "^buck[1-4]$": 69 + type: object 70 + $ref: /schemas/regulator/regulator.yaml# 71 + unevaluatedProperties: false 72 + 73 + properties: 74 + regulator-allowed-modes: 75 + description: | 76 + Used to specify the allowed buck converter operating mode 77 + mode mapping: 78 + 0: auto mode 79 + 1: force pwm mode 80 + items: 81 + enum: [0, 1] 82 + 83 + "^(ldo|exten)$": 84 + type: object 85 + $ref: /schemas/regulator/regulator.yaml# 86 + unevaluatedProperties: false 87 + 88 + additionalProperties: false 89 + 90 + powerkey: 91 + type: object 92 + description: 93 + PON key that connected to RT5120 PMIC. 94 + 95 + properties: 96 + compatible: 97 + enum: 98 + - richtek,rt5120-pwrkey 99 + 100 + required: 101 + - compatible 102 + 103 + additionalProperties: false 104 + 105 + required: 106 + - compatible 107 + - reg 108 + - interrupts 109 + - '#interrupt-cells' 110 + - interrupt-controller 111 + - regulators 112 + - powerkey 113 + 114 + additionalProperties: false 115 + 116 + examples: 117 + - | 118 + #include <dt-bindings/interrupt-controller/irq.h> 119 + 120 + i2c { 121 + #address-cells = <1>; 122 + #size-cells = <0>; 123 + 124 + pmic@62 { 125 + compatible = "richtek,rt5120"; 126 + reg = <0x62>; 127 + interrupts-extended = <&gpio_intc 32 IRQ_TYPE_LEVEL_LOW>; 128 + interrupt-controller; 129 + #interrupt-cells = <1>; 130 + wakeup-source; 131 + 132 + regulators { 133 + buck1 { 134 + regulator-name = "rt5120-buck1"; 135 + regulator-min-microvolt = <600000>; 136 + regulator-max-microvolt = <1393750>; 137 + regulator-allowed-modes = <0 1>; 138 + regulator-boot-on; 139 + }; 140 + buck2 { 141 + regulator-name = "rt5120-buck2"; 142 + regulator-min-microvolt = <1100000>; 143 + regulator-max-microvolt = <1100000>; 144 + regulator-allowed-modes = <0 1>; 145 + regulator-always-on; 146 + }; 147 + buck3 { 148 + regulator-name = "rt5120-buck3"; 149 + regulator-min-microvolt = <1800000>; 150 + regulator-max-microvolt = <1800000>; 151 + regulator-allowed-modes = <0 1>; 152 + regulator-always-on; 153 + }; 154 + buck4 { 155 + regulator-name = "rt5120-buck4"; 156 + regulator-min-microvolt = <3300000>; 157 + regulator-max-microvolt = <3300000>; 158 + regulator-allowed-modes = <0 1>; 159 + regulator-always-on; 160 + }; 161 + ldo { 162 + regulator-name = "rt5120-ldo"; 163 + regulator-min-microvolt = <1800000>; 164 + regulator-max-microvolt = <1800000>; 165 + regulator-always-on; 166 + }; 167 + exten { 168 + regulator-name = "rt5120-exten"; 169 + regulator-min-microvolt = <3000000>; 170 + regulator-max-microvolt = <3000000>; 171 + regulator-always-on; 172 + }; 173 + }; 174 + powerkey { 175 + compatible = "richtek,rt5120-pwrkey"; 176 + }; 177 + }; 178 + };
+52
Documentation/devicetree/bindings/mfd/rockchip,rk817.yaml
··· 87 87 patternProperties: 88 88 "^(LDO_REG[1-9]|DCDC_REG[1-4]|BOOST|OTG_SWITCH)$": 89 89 type: object 90 + unevaluatedProperties: false 90 91 $ref: ../regulator/regulator.yaml# 91 92 unevaluatedProperties: false 92 93 ··· 112 111 additional properties are required for the codec, this node can be 113 112 omitted. 114 113 type: object 114 + additionalProperties: false 115 115 properties: 116 116 rockchip,mic-in-differential: 117 117 type: boolean 118 118 description: 119 119 Describes if the microphone uses differential mode. 120 + 121 + charger: 122 + description: | 123 + The child node for the charger to hold additional properties. If a 124 + battery is not in use, this node can be omitted. 125 + type: object 126 + properties: 127 + monitored-battery: 128 + description: | 129 + A phandle to a monitored battery node that contains a valid 130 + value for: 131 + charge-full-design-microamp-hours, 132 + charge-term-current-microamp, 133 + constant-charge-current-max-microamp, 134 + constant-charge-voltage-max-microvolt, 135 + voltage-max-design-microvolt, 136 + voltage-min-design-microvolt, 137 + and a valid ocv-capacity table. 138 + 139 + rockchip,resistor-sense-micro-ohms: 140 + description: | 141 + Value in microohms of the battery sense resistor. This value is 142 + used by the driver to set the correct divisor value to translate 143 + ADC readings into the proper units of measure. 144 + enum: [10000, 20000] 145 + 146 + rockchip,sleep-enter-current-microamp: 147 + description: | 148 + Value in microamps of the sleep enter current for the charger. 149 + Value is used by the driver to calibrate the relax threshold. 150 + 151 + rockchip,sleep-filter-current-microamp: 152 + description: 153 + Value in microamps of the sleep filter current for the charger. 154 + Value is used by the driver to derive the sleep sample current. 155 + 156 + required: 157 + - monitored-battery 158 + - rockchip,resistor-sense-micro-ohms 159 + - rockchip,sleep-enter-current-microamp 160 + - rockchip,sleep-filter-current-microamp 161 + 162 + additionalProperties: false 120 163 121 164 allOf: 122 165 - if: ··· 366 321 regulator-suspend-microvolt = <3000000>; 367 322 }; 368 323 }; 324 + }; 325 + 326 + rk817_charger: charger { 327 + monitored-battery = <&battery>; 328 + rockchip,resistor-sense-micro-ohms = <10000>; 329 + rockchip,sleep-enter-current-microamp = <300000>; 330 + rockchip,sleep-filter-current-microamp = <100000>; 369 331 }; 370 332 371 333 rk817_codec: codec {
+1
Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml
··· 42 42 vcom: 43 43 type: object 44 44 $ref: /schemas/regulator/regulator.yaml# 45 + unevaluatedProperties: false 45 46 description: 46 47 The regulator for the compenstation voltage. Enabling/disabling this 47 48 enables/disables the entire device.
+71
Documentation/devicetree/bindings/mfd/sprd,ums512-glbreg.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + # Copyright 2022 Unisoc Inc. 3 + %YAML 1.2 4 + --- 5 + $id: http://devicetree.org/schemas/mfd/sprd,ums512-glbreg.yaml# 6 + $schema: http://devicetree.org/meta-schemas/core.yaml# 7 + 8 + title: Unisoc System Global Register 9 + 10 + maintainers: 11 + - Orson Zhai <orsonzhai@gmail.com> 12 + - Baolin Wang <baolin.wang7@gmail.com> 13 + - Chunyan Zhang <zhang.lyra@gmail.com> 14 + 15 + description: 16 + Unisoc system global registers provide register map 17 + for clocks and some multimedia modules of the SoC. 18 + 19 + properties: 20 + compatible: 21 + items: 22 + - const: sprd,ums512-glbregs 23 + - const: syscon 24 + - const: simple-mfd 25 + 26 + "#address-cells": 27 + const: 1 28 + 29 + "#size-cells": 30 + const: 1 31 + 32 + ranges: 33 + maxItems: 1 34 + 35 + reg: 36 + maxItems: 1 37 + 38 + patternProperties: 39 + "^clock-controller@[0-9a-f]+$": 40 + type: object 41 + $ref: /schemas/clock/sprd,ums512-clk.yaml# 42 + description: 43 + Clock controller for the SoC clocks. 44 + 45 + required: 46 + - compatible 47 + - reg 48 + 49 + additionalProperties: false 50 + 51 + examples: 52 + - | 53 + ap_apb_regs: syscon@71000000 { 54 + compatible = "sprd,ums512-glbregs", "syscon", "simple-mfd"; 55 + reg = <0x71000000 0x3000>; 56 + #address-cells = <1>; 57 + #size-cells = <1>; 58 + ranges = <0 0x71000000 0x3000>; 59 + 60 + clock-controller@0 { 61 + compatible = "sprd,ums512-apahb-gate"; 62 + reg = <0x0 0x2000>; 63 + #clock-cells = <1>; 64 + }; 65 + }; 66 + 67 + - | 68 + ap_intc5_regs: syscon@32360000 { 69 + compatible = "sprd,ums512-glbregs", "syscon", "simple-mfd"; 70 + reg = <0x32360000 0x1000>; 71 + };
+4
Documentation/devicetree/bindings/mfd/st,stm32-lptimer.yaml
··· 46 46 47 47 pwm: 48 48 type: object 49 + additionalProperties: false 49 50 50 51 properties: 51 52 compatible: ··· 61 60 62 61 counter: 63 62 type: object 63 + additionalProperties: false 64 64 65 65 properties: 66 66 compatible: ··· 72 70 73 71 timer: 74 72 type: object 73 + additionalProperties: false 75 74 76 75 properties: 77 76 compatible: ··· 84 81 patternProperties: 85 82 "^trigger@[0-9]+$": 86 83 type: object 84 + additionalProperties: false 87 85 88 86 properties: 89 87 compatible:
+3
Documentation/devicetree/bindings/mfd/st,stm32-timers.yaml
··· 69 69 70 70 pwm: 71 71 type: object 72 + additionalProperties: false 72 73 73 74 properties: 74 75 compatible: ··· 105 104 106 105 counter: 107 106 type: object 107 + additionalProperties: false 108 108 109 109 properties: 110 110 compatible: ··· 117 115 patternProperties: 118 116 "^timer@[0-9]+$": 119 117 type: object 118 + additionalProperties: false 120 119 121 120 properties: 122 121 compatible:
+1
Documentation/devicetree/bindings/mfd/st,stmfx.yaml
··· 57 57 patternProperties: 58 58 "^[a-zA-Z]*-pins$": 59 59 type: object 60 + additionalProperties: false 60 61 61 62 allOf: 62 63 - $ref: ../pinctrl/pinmux-node.yaml
+22
Documentation/devicetree/bindings/mfd/stericsson,ab8500.yaml
··· 51 51 provides the reference clock for the entire U8500 system and 52 52 the DB8500 counterpart. 53 53 type: object 54 + additionalProperties: false 54 55 55 56 properties: 56 57 compatible: ··· 64 63 description: Node describing the AB8500 GPIO controller. A few 65 64 GPIO pins available for misc usage. 66 65 type: object 66 + additionalProperties: false 67 67 68 68 properties: 69 69 compatible: ··· 80 78 rtc: 81 79 description: Node describing the AB8500 battery-backed RTC. 82 80 type: object 81 + additionalProperties: false 83 82 84 83 properties: 85 84 compatible: ··· 340 337 description: The voltage for the auxilary LDO regulator 1 341 338 type: object 342 339 $ref: ../regulator/regulator.yaml# 340 + unevaluatedProperties: false 343 341 344 342 ab8500_ldo_aux2: 345 343 description: The voltage for the auxilary LDO regulator 2 346 344 type: object 347 345 $ref: ../regulator/regulator.yaml# 346 + unevaluatedProperties: false 348 347 349 348 ab8500_ldo_aux3: 350 349 description: The voltage for the auxilary LDO regulator 3 351 350 type: object 352 351 $ref: ../regulator/regulator.yaml# 352 + unevaluatedProperties: false 353 353 354 354 ab8500_ldo_aux4: 355 355 description: The voltage for the auxilary LDO regulator 4 356 356 only present on AB8505 357 357 type: object 358 358 $ref: ../regulator/regulator.yaml# 359 + unevaluatedProperties: false 359 360 360 361 ab8500_ldo_aux5: 361 362 description: The voltage for the auxilary LDO regulator 5 362 363 only present on AB8505 363 364 type: object 364 365 $ref: ../regulator/regulator.yaml# 366 + unevaluatedProperties: false 365 367 366 368 ab8500_ldo_aux6: 367 369 description: The voltage for the auxilary LDO regulator 6 368 370 only present on AB8505 369 371 type: object 370 372 $ref: ../regulator/regulator.yaml# 373 + unevaluatedProperties: false 371 374 372 375 # There is never any AUX7 regulator which is confusing 373 376 ··· 382 373 only present on AB8505 383 374 type: object 384 375 $ref: ../regulator/regulator.yaml# 376 + unevaluatedProperties: false 385 377 386 378 ab8500_ldo_intcore: 387 379 description: The LDO regulator for the internal core voltage 388 380 of the AB8500 389 381 type: object 390 382 $ref: ../regulator/regulator.yaml# 383 + unevaluatedProperties: false 391 384 392 385 ab8500_ldo_adc: 393 386 description: Analog power regulator for the analog to digital converter 394 387 ADC, only present on AB8505 395 388 type: object 396 389 $ref: ../regulator/regulator.yaml# 390 + unevaluatedProperties: false 397 391 398 392 ab8500_ldo_tvout: 399 393 description: The voltage for the TV output regulator, incidentally ··· 405 393 Only present on AB8500. 406 394 type: object 407 395 $ref: ../regulator/regulator.yaml# 396 + unevaluatedProperties: false 408 397 409 398 ab8500_ldo_audio: 410 399 description: The LDO regulator for the audio codec output 411 400 type: object 412 401 $ref: ../regulator/regulator.yaml# 402 + unevaluatedProperties: false 413 403 414 404 ab8500_ldo_anamic1: 415 405 description: The LDO regulator for the analog microphone 1 416 406 type: object 417 407 $ref: ../regulator/regulator.yaml# 408 + unevaluatedProperties: false 418 409 419 410 ab8500_ldo_anamic2: 420 411 description: The LDO regulator for the analog microphone 2 421 412 type: object 422 413 $ref: ../regulator/regulator.yaml# 414 + unevaluatedProperties: false 423 415 424 416 ab8500_ldo_dmic: 425 417 description: The LDO regulator for the digital microphone 426 418 only present on AB8500 427 419 type: object 428 420 $ref: ../regulator/regulator.yaml# 421 + unevaluatedProperties: false 429 422 430 423 ab8500_ldo_ana: 431 424 description: Analog power regulator for CSI and DSI interfaces, 432 425 Camera Serial Interface CSI and Display Serial Interface DSI. 433 426 type: object 434 427 $ref: ../regulator/regulator.yaml# 428 + unevaluatedProperties: false 435 429 436 430 required: 437 431 - compatible ··· 460 442 description: The voltage for the VSMPS1 external regulator 461 443 type: object 462 444 $ref: ../regulator/regulator.yaml# 445 + unevaluatedProperties: false 463 446 464 447 ab8500_ext2: 465 448 description: The voltage for the VSMPS2 external regulator 466 449 type: object 467 450 $ref: ../regulator/regulator.yaml# 451 + unevaluatedProperties: false 468 452 469 453 ab8500_ext3: 470 454 description: The voltage for the VSMPS3 external regulator 471 455 type: object 472 456 $ref: ../regulator/regulator.yaml# 457 + unevaluatedProperties: false 473 458 474 459 required: 475 460 - compatible ··· 483 462 "^pwm@[1-9]+?$": 484 463 type: object 485 464 $ref: ../pwm/pwm.yaml# 465 + unevaluatedProperties: false 486 466 description: Represents each of the PWM blocks in the AB8500 487 467 488 468 properties:
+15 -2
Documentation/devicetree/bindings/mfd/syscon.yaml
··· 61 61 - rockchip,rk3368-qos 62 62 - rockchip,rk3399-qos 63 63 - rockchip,rk3568-qos 64 + - rockchip,rk3588-qos 65 + - rockchip,rv1126-qos 64 66 - samsung,exynos3-sysreg 65 67 - samsung,exynos4-sysreg 66 68 - samsung,exynos5-sysreg ··· 75 73 - contains: 76 74 const: syscon 77 75 minItems: 2 78 - maxItems: 4 # Should be enough 76 + maxItems: 5 # Should be enough 79 77 80 78 reg: 81 79 maxItems: 1 ··· 84 82 description: | 85 83 The size (in bytes) of the IO accesses that should be performed 86 84 on the device. 87 - $ref: /schemas/types.yaml#/definitions/uint32 88 85 enum: [1, 2, 4, 8] 89 86 90 87 hwlocks: ··· 94 93 required: 95 94 - compatible 96 95 - reg 96 + 97 + allOf: 98 + - if: 99 + properties: 100 + compatible: 101 + contains: 102 + const: simple-mfd 103 + then: 104 + properties: 105 + compatible: 106 + minItems: 3 107 + maxItems: 5 97 108 98 109 additionalProperties: true 99 110
+1
Documentation/devicetree/bindings/mfd/ti,tps65086.yaml
··· 38 38 39 39 regulators: 40 40 type: object 41 + additionalProperties: false 41 42 description: | 42 43 List of child nodes that specify the regulator initialization data. 43 44 Child nodes must be named after their hardware counterparts:
+4
Documentation/devicetree/bindings/mfd/x-powers,axp152.yaml
··· 93 93 - x-powers,axp809 94 94 - x-powers,axp813 95 95 - items: 96 + - const: x-powers,axp228 97 + - const: x-powers,axp221 98 + - items: 96 99 - const: x-powers,axp805 97 100 - const: x-powers,axp806 98 101 - items: ··· 263 260 "^(([a-f])?ldo[0-9]|dcdc[0-7a-e]|ldo(_|-)io(0|1)|(dc1)?sw|rtc(_|-)ldo|drivevbus|dc5ldo)$": 264 261 $ref: /schemas/regulator/regulator.yaml# 265 262 type: object 263 + unevaluatedProperties: false 266 264 267 265 properties: 268 266 regulator-ramp-delay:
+1 -1
Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
··· 135 135 #size-cells = <2>; 136 136 137 137 scpsys: syscon@10006000 { 138 - compatible = "syscon", "simple-mfd"; 138 + compatible = "mediatek,mt8173-scpsys", "syscon", "simple-mfd"; 139 139 reg = <0 0x10006000 0 0x1000>; 140 140 141 141 spm: power-controller {
-1
MAINTAINERS
··· 8475 8475 8476 8476 GATEWORKS SYSTEM CONTROLLER (GSC) DRIVER 8477 8477 M: Tim Harvey <tharvey@gateworks.com> 8478 - M: Robert Jones <rjones@gateworks.com> 8479 8478 S: Maintained 8480 8479 F: Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml 8481 8480 F: drivers/mfd/gateworks-gsc.c
+1 -1
arch/arm/boot/dts/tegra30-apalis-v1.1.dtsi
··· 993 993 touchscreen@41 { 994 994 compatible = "st,stmpe811"; 995 995 reg = <0x41>; 996 - irq-gpio = <&gpio TEGRA_GPIO(V, 0) IRQ_TYPE_LEVEL_LOW>; 996 + irq-gpio = <&gpio TEGRA_GPIO(V, 0) GPIO_ACTIVE_LOW>; 997 997 interrupt-controller; 998 998 id = <0>; 999 999 blocks = <0x5>;
+1 -1
arch/arm/boot/dts/tegra30-apalis.dtsi
··· 976 976 touchscreen@41 { 977 977 compatible = "st,stmpe811"; 978 978 reg = <0x41>; 979 - irq-gpio = <&gpio TEGRA_GPIO(V, 0) IRQ_TYPE_LEVEL_LOW>; 979 + irq-gpio = <&gpio TEGRA_GPIO(V, 0) GPIO_ACTIVE_LOW>; 980 980 interrupt-controller; 981 981 id = <0>; 982 982 blocks = <0x5>;
+1 -1
arch/arm/boot/dts/tegra30-colibri.dtsi
··· 849 849 touchscreen@41 { 850 850 compatible = "st,stmpe811"; 851 851 reg = <0x41>; 852 - irq-gpio = <&gpio TEGRA_GPIO(V, 0) IRQ_TYPE_LEVEL_LOW>; 852 + irq-gpio = <&gpio TEGRA_GPIO(V, 0) GPIO_ACTIVE_LOW>; 853 853 interrupt-controller; 854 854 id = <0>; 855 855 blocks = <0x5>;
-9
arch/arm/mach-omap1/board-htcherald.c
··· 141 141 #define HTCPLD_GPIO_DOWN_DPAD HTCPLD_BASE(7, 4) 142 142 #define HTCPLD_GPIO_ENTER_DPAD HTCPLD_BASE(7, 3) 143 143 144 - /* 145 - * The htcpld chip requires a gpio write to a specific line 146 - * to re-enable interrupts after one has occurred. 147 - */ 148 - #define HTCPLD_GPIO_INT_RESET_HI HTCPLD_BASE(2, 7) 149 - #define HTCPLD_GPIO_INT_RESET_LO HTCPLD_BASE(2, 0) 150 - 151 144 /* Chip 5 */ 152 145 #define HTCPLD_IRQ_RIGHT_KBD HTCPLD_IRQ(0, 7) 153 146 #define HTCPLD_IRQ_UP_KBD HTCPLD_IRQ(0, 6) ··· 341 348 }; 342 349 343 350 static struct htcpld_core_platform_data htcpld_pfdata = { 344 - .int_reset_gpio_hi = HTCPLD_GPIO_INT_RESET_HI, 345 - .int_reset_gpio_lo = HTCPLD_GPIO_INT_RESET_LO, 346 351 .i2c_adapter_id = 1, 347 352 348 353 .chip = htcpld_chips,
+1
drivers/hwmon/Kconfig
··· 1758 1758 1759 1759 config SENSORS_SY7636A 1760 1760 tristate "Silergy SY7636A" 1761 + depends on MFD_SY7636A 1761 1762 help 1762 1763 If you say yes here you get support for the thermistor readout of 1763 1764 the Silergy SY7636A PMIC.
+41 -3
drivers/mfd/Kconfig
··· 589 589 590 590 config INTEL_SOC_PMIC 591 591 bool "Support for Crystal Cove PMIC" 592 - depends on ACPI && HAS_IOMEM && I2C=y && GPIOLIB && COMMON_CLK 593 - depends on X86 || COMPILE_TEST 592 + depends on HAS_IOMEM && I2C=y && GPIOLIB && COMMON_CLK 593 + depends on (X86 && ACPI) || COMPILE_TEST 594 594 depends on I2C_DESIGNWARE_PLATFORM=y 595 595 select MFD_CORE 596 596 select REGMAP_I2C ··· 938 938 PMIC part includes 2-channel BUCKs and 2-channel LDOs 939 939 LDO part includes 4-channel LDOs 940 940 941 + config MFD_MT6370 942 + tristate "MediaTek MT6370 SubPMIC" 943 + select MFD_CORE 944 + select REGMAP_I2C 945 + select REGMAP_IRQ 946 + depends on I2C 947 + help 948 + Say Y here to enable MT6370 SubPMIC functional support. 949 + It consists of a single cell battery charger with ADC monitoring, RGB 950 + LEDs, dual channel flashlight, WLED backlight driver, display bias 951 + voltage supply, one general purpose LDO, and the USB Type-C & PD 952 + controller complies with the latest USB Type-C and PD standards. 953 + 954 + This driver can also be built as a module. If so, the module 955 + will be called "mt6370". 956 + 941 957 config MFD_MT6397 942 958 tristate "MediaTek MT6397 PMIC Support" 943 959 select MFD_CORE ··· 1133 1117 Say M here if you want to include support for the SPMI PMIC 1134 1118 series as a module. The module will be called "qcom-spmi-pmic". 1135 1119 1120 + config MFD_SY7636A 1121 + tristate "Silergy SY7636A voltage regulator" 1122 + depends on I2C 1123 + select MFD_SIMPLE_MFD_I2C 1124 + help 1125 + Enable support for Silergy SY7636A voltage regulator. 1126 + 1127 + To enable support for building sub-devices as modules, 1128 + choose M here. 1129 + 1136 1130 config MFD_RDC321X 1137 1131 tristate "RDC R-321x southbridge" 1138 1132 select MFD_CORE ··· 1174 1148 common support for accessing the device. The device supports multiple 1175 1149 sub-devices like charger, fuel gauge, flash LED, current source, 1176 1150 LDO and Buck. 1151 + 1152 + config MFD_RT5120 1153 + tristate "Richtek RT5120 Power Management IC" 1154 + depends on I2C 1155 + select MFD_CORE 1156 + select REGMAP_I2C 1157 + select REGMAP_IRQ 1158 + help 1159 + The enables support for Richtek RT5120 PMIC. It includes four high 1160 + efficiency buck converters and one LDO voltage regulator. The device 1161 + is targeted at providing the CPU voltage, memory, I/O and peripheral 1162 + power rails in home entertainment devices. 1177 1163 1178 1164 config MFD_RC5T583 1179 1165 bool "Ricoh RC5T583 Power Management system device" ··· 1262 1224 module will be called si476x-core. 1263 1225 1264 1226 config MFD_SIMPLE_MFD_I2C 1265 - tristate "Simple Multi-Functional Device support (I2C)" 1227 + tristate 1266 1228 depends on I2C 1267 1229 select MFD_CORE 1268 1230 select REGMAP_I2C
+7 -5
drivers/mfd/Makefile
··· 175 175 176 176 obj-$(CONFIG_MFD_MP2629) += mp2629.o 177 177 178 + obj-$(CONFIG_MFD_MT6360) += mt6360-core.o 179 + obj-$(CONFIG_MFD_MT6370) += mt6370.o 180 + mt6397-objs := mt6397-core.o mt6397-irq.o mt6358-irq.o 181 + obj-$(CONFIG_MFD_MT6397) += mt6397.o 182 + 178 183 pcf50633-objs := pcf50633-core.o pcf50633-irq.o 179 184 obj-$(CONFIG_MFD_PCF50633) += pcf50633.o 180 185 obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o ··· 242 237 obj-$(CONFIG_MFD_DLN2) += dln2.o 243 238 obj-$(CONFIG_MFD_RT4831) += rt4831.o 244 239 obj-$(CONFIG_MFD_RT5033) += rt5033.o 240 + obj-$(CONFIG_MFD_RT5120) += rt5120.o 245 241 obj-$(CONFIG_MFD_SKY81452) += sky81452.o 246 242 247 - intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o 248 - obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o 243 + obj-$(CONFIG_INTEL_SOC_PMIC) += intel_soc_pmic_crc.o 249 244 obj-$(CONFIG_INTEL_SOC_PMIC_BXTWC) += intel_soc_pmic_bxtwc.o 250 245 obj-$(CONFIG_INTEL_SOC_PMIC_CHTWC) += intel_soc_pmic_chtwc.o 251 246 obj-$(CONFIG_INTEL_SOC_PMIC_CHTDC_TI) += intel_soc_pmic_chtdc_ti.o 252 - obj-$(CONFIG_MFD_MT6360) += mt6360-core.o 253 - mt6397-objs := mt6397-core.o mt6397-irq.o mt6358-irq.o 254 - obj-$(CONFIG_MFD_MT6397) += mt6397.o 255 247 obj-$(CONFIG_INTEL_SOC_PMIC_MRFLD) += intel_soc_pmic_mrfld.o 256 248 257 249 obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
+1
drivers/mfd/da9062-core.c
··· 453 453 regmap_reg_range(DA9062AA_VBUCK1_B, DA9062AA_VBUCK4_B), 454 454 regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B), 455 455 regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B), 456 + regmap_reg_range(DA9062AA_CONFIG_J, DA9062AA_CONFIG_J), 456 457 regmap_reg_range(DA9062AA_GP_ID_0, DA9062AA_GP_ID_19), 457 458 }; 458 459
+25 -9
drivers/mfd/fsl-imx25-tsadc.c
··· 69 69 int irq; 70 70 71 71 irq = platform_get_irq(pdev, 0); 72 - if (irq <= 0) 72 + if (irq < 0) 73 73 return irq; 74 74 75 75 tsadc->domain = irq_domain_add_simple(np, 2, 0, &mx25_tsadc_domain_ops, ··· 80 80 } 81 81 82 82 irq_set_chained_handler_and_data(irq, mx25_tsadc_irq_handler, tsadc); 83 + 84 + return 0; 85 + } 86 + 87 + static int mx25_tsadc_unset_irq(struct platform_device *pdev) 88 + { 89 + struct mx25_tsadc *tsadc = platform_get_drvdata(pdev); 90 + int irq = platform_get_irq(pdev, 0); 91 + 92 + if (irq >= 0) { 93 + irq_set_chained_handler_and_data(irq, NULL, NULL); 94 + irq_domain_remove(tsadc->domain); 95 + } 83 96 84 97 return 0; 85 98 } ··· 184 171 185 172 platform_set_drvdata(pdev, tsadc); 186 173 187 - return devm_of_platform_populate(dev); 174 + ret = devm_of_platform_populate(dev); 175 + if (ret) 176 + goto err_irq; 177 + 178 + return 0; 179 + 180 + err_irq: 181 + mx25_tsadc_unset_irq(pdev); 182 + 183 + return ret; 188 184 } 189 185 190 186 static int mx25_tsadc_remove(struct platform_device *pdev) 191 187 { 192 - struct mx25_tsadc *tsadc = platform_get_drvdata(pdev); 193 - int irq = platform_get_irq(pdev, 0); 194 - 195 - if (irq) { 196 - irq_set_chained_handler_and_data(irq, NULL, NULL); 197 - irq_domain_remove(tsadc->domain); 198 - } 188 + mx25_tsadc_unset_irq(pdev); 199 189 200 190 return 0; 201 191 }
+28 -32
drivers/mfd/htc-i2cpld.c
··· 20 20 #include <linux/irq.h> 21 21 #include <linux/spinlock.h> 22 22 #include <linux/htcpld.h> 23 - #include <linux/gpio.h> 23 + #include <linux/gpio/driver.h> 24 + #include <linux/gpio/machine.h> 25 + #include <linux/gpio/consumer.h> 24 26 #include <linux/slab.h> 25 27 26 28 struct htcpld_chip { ··· 60 58 uint irq_start; 61 59 int nirqs; 62 60 uint chained_irq; 63 - unsigned int int_reset_gpio_hi; 64 - unsigned int int_reset_gpio_lo; 61 + struct gpio_desc *int_reset_gpio_hi; 62 + struct gpio_desc *int_reset_gpio_lo; 65 63 66 64 /* htcpld info */ 67 65 struct htcpld_chip *chip; ··· 198 196 * be asserted. 199 197 */ 200 198 if (htcpld->int_reset_gpio_hi) 201 - gpio_set_value(htcpld->int_reset_gpio_hi, 1); 199 + gpiod_set_value(htcpld->int_reset_gpio_hi, 1); 202 200 if (htcpld->int_reset_gpio_lo) 203 - gpio_set_value(htcpld->int_reset_gpio_lo, 0); 201 + gpiod_set_value(htcpld->int_reset_gpio_lo, 0); 204 202 205 203 return IRQ_HANDLED; 206 204 } ··· 354 352 355 353 memset(&info, 0, sizeof(struct i2c_board_info)); 356 354 info.addr = plat_chip_data->addr; 357 - strlcpy(info.type, "htcpld-chip", I2C_NAME_SIZE); 355 + strscpy(info.type, "htcpld-chip", I2C_NAME_SIZE); 358 356 info.platform_data = chip; 359 357 360 358 /* Add the I2C device. This calls the probe() function. */ ··· 564 562 return ret; 565 563 566 564 /* Request the GPIO(s) for the int reset and set them up */ 567 - if (pdata->int_reset_gpio_hi) { 568 - ret = gpio_request(pdata->int_reset_gpio_hi, "htcpld-core"); 569 - if (ret) { 570 - /* 571 - * If it failed, that sucks, but we can probably 572 - * continue on without it. 573 - */ 574 - dev_warn(dev, "Unable to request int_reset_gpio_hi -- interrupts may not work\n"); 575 - htcpld->int_reset_gpio_hi = 0; 576 - } else { 577 - htcpld->int_reset_gpio_hi = pdata->int_reset_gpio_hi; 578 - gpio_set_value(htcpld->int_reset_gpio_hi, 1); 579 - } 565 + htcpld->int_reset_gpio_hi = gpiochip_request_own_desc(&htcpld->chip[2].chip_out, 566 + 7, "htcpld-core", GPIO_ACTIVE_HIGH, 567 + GPIOD_OUT_HIGH); 568 + if (IS_ERR(htcpld->int_reset_gpio_hi)) { 569 + /* 570 + * If it failed, that sucks, but we can probably 571 + * continue on without it. 572 + */ 573 + htcpld->int_reset_gpio_hi = NULL; 574 + dev_warn(dev, "Unable to request int_reset_gpio_hi -- interrupts may not work\n"); 580 575 } 581 576 582 - if (pdata->int_reset_gpio_lo) { 583 - ret = gpio_request(pdata->int_reset_gpio_lo, "htcpld-core"); 584 - if (ret) { 585 - /* 586 - * If it failed, that sucks, but we can probably 587 - * continue on without it. 588 - */ 589 - dev_warn(dev, "Unable to request int_reset_gpio_lo -- interrupts may not work\n"); 590 - htcpld->int_reset_gpio_lo = 0; 591 - } else { 592 - htcpld->int_reset_gpio_lo = pdata->int_reset_gpio_lo; 593 - gpio_set_value(htcpld->int_reset_gpio_lo, 0); 594 - } 577 + htcpld->int_reset_gpio_lo = gpiochip_request_own_desc(&htcpld->chip[2].chip_out, 578 + 0, "htcpld-core", GPIO_ACTIVE_HIGH, 579 + GPIOD_OUT_LOW); 580 + if (IS_ERR(htcpld->int_reset_gpio_lo)) { 581 + /* 582 + * If it failed, that sucks, but we can probably 583 + * continue on without it. 584 + */ 585 + htcpld->int_reset_gpio_lo = NULL; 586 + dev_warn(dev, "Unable to request int_reset_gpio_lo -- interrupts may not work\n"); 595 587 } 596 588 597 589 dev_info(dev, "Initialized successfully\n");
+95 -46
drivers/mfd/intel-lpss-pci.c
··· 14 14 #include <linux/pci.h> 15 15 #include <linux/pm_runtime.h> 16 16 #include <linux/property.h> 17 + #include <linux/pxa2xx_ssp.h> 17 18 18 19 #include "intel-lpss.h" 19 20 ··· 74 73 75 74 static INTEL_LPSS_PM_OPS(intel_lpss_pci_pm_ops); 76 75 76 + static const struct property_entry spt_spi_properties[] = { 77 + PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_SPT_SSP), 78 + { } 79 + }; 80 + 81 + static const struct software_node spt_spi_node = { 82 + .properties = spt_spi_properties, 83 + }; 84 + 77 85 static const struct intel_lpss_platform_info spt_info = { 78 86 .clk_rate = 120000000, 87 + .swnode = &spt_spi_node, 79 88 }; 80 89 81 90 static const struct property_entry spt_i2c_properties[] = { ··· 119 108 .swnode = &uart_node, 120 109 }; 121 110 111 + static const struct property_entry bxt_spi_properties[] = { 112 + PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_BXT_SSP), 113 + { } 114 + }; 115 + 116 + static const struct software_node bxt_spi_node = { 117 + .properties = bxt_spi_properties, 118 + }; 119 + 122 120 static const struct intel_lpss_platform_info bxt_info = { 123 121 .clk_rate = 100000000, 122 + .swnode = &bxt_spi_node, 124 123 }; 125 124 126 125 static const struct intel_lpss_platform_info bxt_uart_info = { ··· 187 166 .swnode = &glk_i2c_node, 188 167 }; 189 168 169 + static const struct property_entry cnl_spi_properties[] = { 170 + PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_CNL_SSP), 171 + { } 172 + }; 173 + 174 + static const struct software_node cnl_spi_node = { 175 + .properties = cnl_spi_properties, 176 + }; 177 + 178 + static const struct intel_lpss_platform_info cnl_info = { 179 + .clk_rate = 120000000, 180 + .swnode = &cnl_spi_node, 181 + }; 182 + 190 183 static const struct intel_lpss_platform_info cnl_i2c_info = { 191 184 .clk_rate = 216000000, 192 185 .swnode = &spt_i2c_node, ··· 211 176 .swnode = &bxt_i2c_node, 212 177 }; 213 178 179 + static const struct property_entry tgl_spi_properties[] = { 180 + PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_CNL_SSP), 181 + { } 182 + }; 183 + 184 + static const struct software_node tgl_spi_node = { 185 + .properties = tgl_spi_properties, 186 + }; 187 + 188 + static const struct intel_lpss_platform_info tgl_info = { 189 + .clk_rate = 100000000, 190 + .swnode = &tgl_spi_node, 191 + }; 192 + 214 193 static const struct pci_device_id intel_lpss_pci_ids[] = { 215 194 /* CML-LP */ 216 195 { PCI_VDEVICE(INTEL, 0x02a8), (kernel_ulong_t)&spt_uart_info }, 217 196 { PCI_VDEVICE(INTEL, 0x02a9), (kernel_ulong_t)&spt_uart_info }, 218 - { PCI_VDEVICE(INTEL, 0x02aa), (kernel_ulong_t)&spt_info }, 219 - { PCI_VDEVICE(INTEL, 0x02ab), (kernel_ulong_t)&spt_info }, 197 + { PCI_VDEVICE(INTEL, 0x02aa), (kernel_ulong_t)&cnl_info }, 198 + { PCI_VDEVICE(INTEL, 0x02ab), (kernel_ulong_t)&cnl_info }, 220 199 { PCI_VDEVICE(INTEL, 0x02c5), (kernel_ulong_t)&cnl_i2c_info }, 221 200 { PCI_VDEVICE(INTEL, 0x02c6), (kernel_ulong_t)&cnl_i2c_info }, 222 201 { PCI_VDEVICE(INTEL, 0x02c7), (kernel_ulong_t)&spt_uart_info }, ··· 238 189 { PCI_VDEVICE(INTEL, 0x02e9), (kernel_ulong_t)&cnl_i2c_info }, 239 190 { PCI_VDEVICE(INTEL, 0x02ea), (kernel_ulong_t)&cnl_i2c_info }, 240 191 { PCI_VDEVICE(INTEL, 0x02eb), (kernel_ulong_t)&cnl_i2c_info }, 241 - { PCI_VDEVICE(INTEL, 0x02fb), (kernel_ulong_t)&spt_info }, 192 + { PCI_VDEVICE(INTEL, 0x02fb), (kernel_ulong_t)&cnl_info }, 242 193 /* CML-H */ 243 194 { PCI_VDEVICE(INTEL, 0x06a8), (kernel_ulong_t)&spt_uart_info }, 244 195 { PCI_VDEVICE(INTEL, 0x06a9), (kernel_ulong_t)&spt_uart_info }, 245 - { PCI_VDEVICE(INTEL, 0x06aa), (kernel_ulong_t)&spt_info }, 246 - { PCI_VDEVICE(INTEL, 0x06ab), (kernel_ulong_t)&spt_info }, 196 + { PCI_VDEVICE(INTEL, 0x06aa), (kernel_ulong_t)&cnl_info }, 197 + { PCI_VDEVICE(INTEL, 0x06ab), (kernel_ulong_t)&cnl_info }, 247 198 { PCI_VDEVICE(INTEL, 0x06c7), (kernel_ulong_t)&spt_uart_info }, 248 199 { PCI_VDEVICE(INTEL, 0x06e8), (kernel_ulong_t)&cnl_i2c_info }, 249 200 { PCI_VDEVICE(INTEL, 0x06e9), (kernel_ulong_t)&cnl_i2c_info }, 250 201 { PCI_VDEVICE(INTEL, 0x06ea), (kernel_ulong_t)&cnl_i2c_info }, 251 202 { PCI_VDEVICE(INTEL, 0x06eb), (kernel_ulong_t)&cnl_i2c_info }, 252 - { PCI_VDEVICE(INTEL, 0x06fb), (kernel_ulong_t)&spt_info }, 203 + { PCI_VDEVICE(INTEL, 0x06fb), (kernel_ulong_t)&cnl_info }, 253 204 /* BXT A-Step */ 254 205 { PCI_VDEVICE(INTEL, 0x0aac), (kernel_ulong_t)&bxt_i2c_info }, 255 206 { PCI_VDEVICE(INTEL, 0x0aae), (kernel_ulong_t)&bxt_i2c_info }, ··· 304 255 /* ICL-LP */ 305 256 { PCI_VDEVICE(INTEL, 0x34a8), (kernel_ulong_t)&spt_uart_info }, 306 257 { PCI_VDEVICE(INTEL, 0x34a9), (kernel_ulong_t)&spt_uart_info }, 307 - { PCI_VDEVICE(INTEL, 0x34aa), (kernel_ulong_t)&spt_info }, 308 - { PCI_VDEVICE(INTEL, 0x34ab), (kernel_ulong_t)&spt_info }, 258 + { PCI_VDEVICE(INTEL, 0x34aa), (kernel_ulong_t)&cnl_info }, 259 + { PCI_VDEVICE(INTEL, 0x34ab), (kernel_ulong_t)&cnl_info }, 309 260 { PCI_VDEVICE(INTEL, 0x34c5), (kernel_ulong_t)&bxt_i2c_info }, 310 261 { PCI_VDEVICE(INTEL, 0x34c6), (kernel_ulong_t)&bxt_i2c_info }, 311 262 { PCI_VDEVICE(INTEL, 0x34c7), (kernel_ulong_t)&spt_uart_info }, ··· 313 264 { PCI_VDEVICE(INTEL, 0x34e9), (kernel_ulong_t)&bxt_i2c_info }, 314 265 { PCI_VDEVICE(INTEL, 0x34ea), (kernel_ulong_t)&bxt_i2c_info }, 315 266 { PCI_VDEVICE(INTEL, 0x34eb), (kernel_ulong_t)&bxt_i2c_info }, 316 - { PCI_VDEVICE(INTEL, 0x34fb), (kernel_ulong_t)&spt_info }, 267 + { PCI_VDEVICE(INTEL, 0x34fb), (kernel_ulong_t)&cnl_info }, 317 268 /* ICL-N */ 318 269 { PCI_VDEVICE(INTEL, 0x38a8), (kernel_ulong_t)&spt_uart_info }, 319 270 /* TGL-H */ 320 271 { PCI_VDEVICE(INTEL, 0x43a7), (kernel_ulong_t)&bxt_uart_info }, 321 272 { PCI_VDEVICE(INTEL, 0x43a8), (kernel_ulong_t)&bxt_uart_info }, 322 273 { PCI_VDEVICE(INTEL, 0x43a9), (kernel_ulong_t)&bxt_uart_info }, 323 - { PCI_VDEVICE(INTEL, 0x43aa), (kernel_ulong_t)&bxt_info }, 324 - { PCI_VDEVICE(INTEL, 0x43ab), (kernel_ulong_t)&bxt_info }, 274 + { PCI_VDEVICE(INTEL, 0x43aa), (kernel_ulong_t)&tgl_info }, 275 + { PCI_VDEVICE(INTEL, 0x43ab), (kernel_ulong_t)&tgl_info }, 325 276 { PCI_VDEVICE(INTEL, 0x43ad), (kernel_ulong_t)&bxt_i2c_info }, 326 277 { PCI_VDEVICE(INTEL, 0x43ae), (kernel_ulong_t)&bxt_i2c_info }, 327 278 { PCI_VDEVICE(INTEL, 0x43d8), (kernel_ulong_t)&bxt_i2c_info }, ··· 330 281 { PCI_VDEVICE(INTEL, 0x43e9), (kernel_ulong_t)&bxt_i2c_info }, 331 282 { PCI_VDEVICE(INTEL, 0x43ea), (kernel_ulong_t)&bxt_i2c_info }, 332 283 { PCI_VDEVICE(INTEL, 0x43eb), (kernel_ulong_t)&bxt_i2c_info }, 333 - { PCI_VDEVICE(INTEL, 0x43fb), (kernel_ulong_t)&bxt_info }, 334 - { PCI_VDEVICE(INTEL, 0x43fd), (kernel_ulong_t)&bxt_info }, 284 + { PCI_VDEVICE(INTEL, 0x43fb), (kernel_ulong_t)&tgl_info }, 285 + { PCI_VDEVICE(INTEL, 0x43fd), (kernel_ulong_t)&tgl_info }, 335 286 /* EHL */ 336 287 { PCI_VDEVICE(INTEL, 0x4b28), (kernel_ulong_t)&bxt_uart_info }, 337 288 { PCI_VDEVICE(INTEL, 0x4b29), (kernel_ulong_t)&bxt_uart_info }, ··· 350 301 /* JSL */ 351 302 { PCI_VDEVICE(INTEL, 0x4da8), (kernel_ulong_t)&spt_uart_info }, 352 303 { PCI_VDEVICE(INTEL, 0x4da9), (kernel_ulong_t)&spt_uart_info }, 353 - { PCI_VDEVICE(INTEL, 0x4daa), (kernel_ulong_t)&spt_info }, 354 - { PCI_VDEVICE(INTEL, 0x4dab), (kernel_ulong_t)&spt_info }, 304 + { PCI_VDEVICE(INTEL, 0x4daa), (kernel_ulong_t)&cnl_info }, 305 + { PCI_VDEVICE(INTEL, 0x4dab), (kernel_ulong_t)&cnl_info }, 355 306 { PCI_VDEVICE(INTEL, 0x4dc5), (kernel_ulong_t)&bxt_i2c_info }, 356 307 { PCI_VDEVICE(INTEL, 0x4dc6), (kernel_ulong_t)&bxt_i2c_info }, 357 308 { PCI_VDEVICE(INTEL, 0x4dc7), (kernel_ulong_t)&spt_uart_info }, ··· 359 310 { PCI_VDEVICE(INTEL, 0x4de9), (kernel_ulong_t)&bxt_i2c_info }, 360 311 { PCI_VDEVICE(INTEL, 0x4dea), (kernel_ulong_t)&bxt_i2c_info }, 361 312 { PCI_VDEVICE(INTEL, 0x4deb), (kernel_ulong_t)&bxt_i2c_info }, 362 - { PCI_VDEVICE(INTEL, 0x4dfb), (kernel_ulong_t)&spt_info }, 313 + { PCI_VDEVICE(INTEL, 0x4dfb), (kernel_ulong_t)&cnl_info }, 363 314 /* ADL-P */ 364 315 { PCI_VDEVICE(INTEL, 0x51a8), (kernel_ulong_t)&bxt_uart_info }, 365 316 { PCI_VDEVICE(INTEL, 0x51a9), (kernel_ulong_t)&bxt_uart_info }, 366 - { PCI_VDEVICE(INTEL, 0x51aa), (kernel_ulong_t)&bxt_info }, 367 - { PCI_VDEVICE(INTEL, 0x51ab), (kernel_ulong_t)&bxt_info }, 317 + { PCI_VDEVICE(INTEL, 0x51aa), (kernel_ulong_t)&tgl_info }, 318 + { PCI_VDEVICE(INTEL, 0x51ab), (kernel_ulong_t)&tgl_info }, 368 319 { PCI_VDEVICE(INTEL, 0x51c5), (kernel_ulong_t)&bxt_i2c_info }, 369 320 { PCI_VDEVICE(INTEL, 0x51c6), (kernel_ulong_t)&bxt_i2c_info }, 370 321 { PCI_VDEVICE(INTEL, 0x51c7), (kernel_ulong_t)&bxt_uart_info }, ··· 374 325 { PCI_VDEVICE(INTEL, 0x51e9), (kernel_ulong_t)&bxt_i2c_info }, 375 326 { PCI_VDEVICE(INTEL, 0x51ea), (kernel_ulong_t)&bxt_i2c_info }, 376 327 { PCI_VDEVICE(INTEL, 0x51eb), (kernel_ulong_t)&bxt_i2c_info }, 377 - { PCI_VDEVICE(INTEL, 0x51fb), (kernel_ulong_t)&bxt_info }, 328 + { PCI_VDEVICE(INTEL, 0x51fb), (kernel_ulong_t)&tgl_info }, 378 329 /* ADL-M */ 379 330 { PCI_VDEVICE(INTEL, 0x54a8), (kernel_ulong_t)&bxt_uart_info }, 380 331 { PCI_VDEVICE(INTEL, 0x54a9), (kernel_ulong_t)&bxt_uart_info }, 381 - { PCI_VDEVICE(INTEL, 0x54aa), (kernel_ulong_t)&bxt_info }, 382 - { PCI_VDEVICE(INTEL, 0x54ab), (kernel_ulong_t)&bxt_info }, 332 + { PCI_VDEVICE(INTEL, 0x54aa), (kernel_ulong_t)&tgl_info }, 333 + { PCI_VDEVICE(INTEL, 0x54ab), (kernel_ulong_t)&tgl_info }, 383 334 { PCI_VDEVICE(INTEL, 0x54c5), (kernel_ulong_t)&bxt_i2c_info }, 384 335 { PCI_VDEVICE(INTEL, 0x54c6), (kernel_ulong_t)&bxt_i2c_info }, 385 336 { PCI_VDEVICE(INTEL, 0x54c7), (kernel_ulong_t)&bxt_uart_info }, ··· 387 338 { PCI_VDEVICE(INTEL, 0x54e9), (kernel_ulong_t)&bxt_i2c_info }, 388 339 { PCI_VDEVICE(INTEL, 0x54ea), (kernel_ulong_t)&bxt_i2c_info }, 389 340 { PCI_VDEVICE(INTEL, 0x54eb), (kernel_ulong_t)&bxt_i2c_info }, 390 - { PCI_VDEVICE(INTEL, 0x54fb), (kernel_ulong_t)&bxt_info }, 341 + { PCI_VDEVICE(INTEL, 0x54fb), (kernel_ulong_t)&tgl_info }, 391 342 /* APL */ 392 343 { PCI_VDEVICE(INTEL, 0x5aac), (kernel_ulong_t)&apl_i2c_info }, 393 344 { PCI_VDEVICE(INTEL, 0x5aae), (kernel_ulong_t)&apl_i2c_info }, ··· 407 358 /* RPL-S */ 408 359 { PCI_VDEVICE(INTEL, 0x7a28), (kernel_ulong_t)&bxt_uart_info }, 409 360 { PCI_VDEVICE(INTEL, 0x7a29), (kernel_ulong_t)&bxt_uart_info }, 410 - { PCI_VDEVICE(INTEL, 0x7a2a), (kernel_ulong_t)&bxt_info }, 411 - { PCI_VDEVICE(INTEL, 0x7a2b), (kernel_ulong_t)&bxt_info }, 361 + { PCI_VDEVICE(INTEL, 0x7a2a), (kernel_ulong_t)&tgl_info }, 362 + { PCI_VDEVICE(INTEL, 0x7a2b), (kernel_ulong_t)&tgl_info }, 412 363 { PCI_VDEVICE(INTEL, 0x7a4c), (kernel_ulong_t)&bxt_i2c_info }, 413 364 { PCI_VDEVICE(INTEL, 0x7a4d), (kernel_ulong_t)&bxt_i2c_info }, 414 365 { PCI_VDEVICE(INTEL, 0x7a4e), (kernel_ulong_t)&bxt_i2c_info }, 415 366 { PCI_VDEVICE(INTEL, 0x7a4f), (kernel_ulong_t)&bxt_i2c_info }, 416 367 { PCI_VDEVICE(INTEL, 0x7a5c), (kernel_ulong_t)&bxt_uart_info }, 417 - { PCI_VDEVICE(INTEL, 0x7a79), (kernel_ulong_t)&bxt_info }, 418 - { PCI_VDEVICE(INTEL, 0x7a7b), (kernel_ulong_t)&bxt_info }, 368 + { PCI_VDEVICE(INTEL, 0x7a79), (kernel_ulong_t)&tgl_info }, 369 + { PCI_VDEVICE(INTEL, 0x7a7b), (kernel_ulong_t)&tgl_info }, 419 370 { PCI_VDEVICE(INTEL, 0x7a7c), (kernel_ulong_t)&bxt_i2c_info }, 420 371 { PCI_VDEVICE(INTEL, 0x7a7d), (kernel_ulong_t)&bxt_i2c_info }, 421 372 { PCI_VDEVICE(INTEL, 0x7a7e), (kernel_ulong_t)&bxt_uart_info }, 422 373 /* ADL-S */ 423 374 { PCI_VDEVICE(INTEL, 0x7aa8), (kernel_ulong_t)&bxt_uart_info }, 424 375 { PCI_VDEVICE(INTEL, 0x7aa9), (kernel_ulong_t)&bxt_uart_info }, 425 - { PCI_VDEVICE(INTEL, 0x7aaa), (kernel_ulong_t)&bxt_info }, 426 - { PCI_VDEVICE(INTEL, 0x7aab), (kernel_ulong_t)&bxt_info }, 376 + { PCI_VDEVICE(INTEL, 0x7aaa), (kernel_ulong_t)&tgl_info }, 377 + { PCI_VDEVICE(INTEL, 0x7aab), (kernel_ulong_t)&tgl_info }, 427 378 { PCI_VDEVICE(INTEL, 0x7acc), (kernel_ulong_t)&bxt_i2c_info }, 428 379 { PCI_VDEVICE(INTEL, 0x7acd), (kernel_ulong_t)&bxt_i2c_info }, 429 380 { PCI_VDEVICE(INTEL, 0x7ace), (kernel_ulong_t)&bxt_i2c_info }, 430 381 { PCI_VDEVICE(INTEL, 0x7acf), (kernel_ulong_t)&bxt_i2c_info }, 431 382 { PCI_VDEVICE(INTEL, 0x7adc), (kernel_ulong_t)&bxt_uart_info }, 432 - { PCI_VDEVICE(INTEL, 0x7af9), (kernel_ulong_t)&bxt_info }, 433 - { PCI_VDEVICE(INTEL, 0x7afb), (kernel_ulong_t)&bxt_info }, 383 + { PCI_VDEVICE(INTEL, 0x7af9), (kernel_ulong_t)&tgl_info }, 384 + { PCI_VDEVICE(INTEL, 0x7afb), (kernel_ulong_t)&tgl_info }, 434 385 { PCI_VDEVICE(INTEL, 0x7afc), (kernel_ulong_t)&bxt_i2c_info }, 435 386 { PCI_VDEVICE(INTEL, 0x7afd), (kernel_ulong_t)&bxt_i2c_info }, 436 387 { PCI_VDEVICE(INTEL, 0x7afe), (kernel_ulong_t)&bxt_uart_info }, 437 388 /* MTL-P */ 438 389 { PCI_VDEVICE(INTEL, 0x7e25), (kernel_ulong_t)&bxt_uart_info }, 439 390 { PCI_VDEVICE(INTEL, 0x7e26), (kernel_ulong_t)&bxt_uart_info }, 440 - { PCI_VDEVICE(INTEL, 0x7e27), (kernel_ulong_t)&bxt_info }, 441 - { PCI_VDEVICE(INTEL, 0x7e30), (kernel_ulong_t)&bxt_info }, 442 - { PCI_VDEVICE(INTEL, 0x7e46), (kernel_ulong_t)&bxt_info }, 391 + { PCI_VDEVICE(INTEL, 0x7e27), (kernel_ulong_t)&tgl_info }, 392 + { PCI_VDEVICE(INTEL, 0x7e30), (kernel_ulong_t)&tgl_info }, 393 + { PCI_VDEVICE(INTEL, 0x7e46), (kernel_ulong_t)&tgl_info }, 443 394 { PCI_VDEVICE(INTEL, 0x7e50), (kernel_ulong_t)&bxt_i2c_info }, 444 395 { PCI_VDEVICE(INTEL, 0x7e51), (kernel_ulong_t)&bxt_i2c_info }, 445 396 { PCI_VDEVICE(INTEL, 0x7e52), (kernel_ulong_t)&bxt_uart_info }, ··· 473 424 /* CNL-LP */ 474 425 { PCI_VDEVICE(INTEL, 0x9da8), (kernel_ulong_t)&spt_uart_info }, 475 426 { PCI_VDEVICE(INTEL, 0x9da9), (kernel_ulong_t)&spt_uart_info }, 476 - { PCI_VDEVICE(INTEL, 0x9daa), (kernel_ulong_t)&spt_info }, 477 - { PCI_VDEVICE(INTEL, 0x9dab), (kernel_ulong_t)&spt_info }, 427 + { PCI_VDEVICE(INTEL, 0x9daa), (kernel_ulong_t)&cnl_info }, 428 + { PCI_VDEVICE(INTEL, 0x9dab), (kernel_ulong_t)&cnl_info }, 478 429 { PCI_VDEVICE(INTEL, 0x9dc5), (kernel_ulong_t)&cnl_i2c_info }, 479 430 { PCI_VDEVICE(INTEL, 0x9dc6), (kernel_ulong_t)&cnl_i2c_info }, 480 431 { PCI_VDEVICE(INTEL, 0x9dc7), (kernel_ulong_t)&spt_uart_info }, ··· 482 433 { PCI_VDEVICE(INTEL, 0x9de9), (kernel_ulong_t)&cnl_i2c_info }, 483 434 { PCI_VDEVICE(INTEL, 0x9dea), (kernel_ulong_t)&cnl_i2c_info }, 484 435 { PCI_VDEVICE(INTEL, 0x9deb), (kernel_ulong_t)&cnl_i2c_info }, 485 - { PCI_VDEVICE(INTEL, 0x9dfb), (kernel_ulong_t)&spt_info }, 436 + { PCI_VDEVICE(INTEL, 0x9dfb), (kernel_ulong_t)&cnl_info }, 486 437 /* TGL-LP */ 487 438 { PCI_VDEVICE(INTEL, 0xa0a8), (kernel_ulong_t)&bxt_uart_info }, 488 439 { PCI_VDEVICE(INTEL, 0xa0a9), (kernel_ulong_t)&bxt_uart_info }, 489 - { PCI_VDEVICE(INTEL, 0xa0aa), (kernel_ulong_t)&spt_info }, 490 - { PCI_VDEVICE(INTEL, 0xa0ab), (kernel_ulong_t)&spt_info }, 440 + { PCI_VDEVICE(INTEL, 0xa0aa), (kernel_ulong_t)&cnl_info }, 441 + { PCI_VDEVICE(INTEL, 0xa0ab), (kernel_ulong_t)&cnl_info }, 491 442 { PCI_VDEVICE(INTEL, 0xa0c5), (kernel_ulong_t)&spt_i2c_info }, 492 443 { PCI_VDEVICE(INTEL, 0xa0c6), (kernel_ulong_t)&spt_i2c_info }, 493 444 { PCI_VDEVICE(INTEL, 0xa0c7), (kernel_ulong_t)&bxt_uart_info }, ··· 497 448 { PCI_VDEVICE(INTEL, 0xa0db), (kernel_ulong_t)&bxt_uart_info }, 498 449 { PCI_VDEVICE(INTEL, 0xa0dc), (kernel_ulong_t)&bxt_uart_info }, 499 450 { PCI_VDEVICE(INTEL, 0xa0dd), (kernel_ulong_t)&bxt_uart_info }, 500 - { PCI_VDEVICE(INTEL, 0xa0de), (kernel_ulong_t)&spt_info }, 501 - { PCI_VDEVICE(INTEL, 0xa0df), (kernel_ulong_t)&spt_info }, 451 + { PCI_VDEVICE(INTEL, 0xa0de), (kernel_ulong_t)&cnl_info }, 452 + { PCI_VDEVICE(INTEL, 0xa0df), (kernel_ulong_t)&cnl_info }, 502 453 { PCI_VDEVICE(INTEL, 0xa0e8), (kernel_ulong_t)&spt_i2c_info }, 503 454 { PCI_VDEVICE(INTEL, 0xa0e9), (kernel_ulong_t)&spt_i2c_info }, 504 455 { PCI_VDEVICE(INTEL, 0xa0ea), (kernel_ulong_t)&spt_i2c_info }, 505 456 { PCI_VDEVICE(INTEL, 0xa0eb), (kernel_ulong_t)&spt_i2c_info }, 506 - { PCI_VDEVICE(INTEL, 0xa0fb), (kernel_ulong_t)&spt_info }, 507 - { PCI_VDEVICE(INTEL, 0xa0fd), (kernel_ulong_t)&spt_info }, 508 - { PCI_VDEVICE(INTEL, 0xa0fe), (kernel_ulong_t)&spt_info }, 457 + { PCI_VDEVICE(INTEL, 0xa0fb), (kernel_ulong_t)&cnl_info }, 458 + { PCI_VDEVICE(INTEL, 0xa0fd), (kernel_ulong_t)&cnl_info }, 459 + { PCI_VDEVICE(INTEL, 0xa0fe), (kernel_ulong_t)&cnl_info }, 509 460 /* SPT-H */ 510 461 { PCI_VDEVICE(INTEL, 0xa127), (kernel_ulong_t)&spt_uart_info }, 511 462 { PCI_VDEVICE(INTEL, 0xa128), (kernel_ulong_t)&spt_uart_info }, ··· 528 479 /* CNL-H */ 529 480 { PCI_VDEVICE(INTEL, 0xa328), (kernel_ulong_t)&spt_uart_info }, 530 481 { PCI_VDEVICE(INTEL, 0xa329), (kernel_ulong_t)&spt_uart_info }, 531 - { PCI_VDEVICE(INTEL, 0xa32a), (kernel_ulong_t)&spt_info }, 532 - { PCI_VDEVICE(INTEL, 0xa32b), (kernel_ulong_t)&spt_info }, 482 + { PCI_VDEVICE(INTEL, 0xa32a), (kernel_ulong_t)&cnl_info }, 483 + { PCI_VDEVICE(INTEL, 0xa32b), (kernel_ulong_t)&cnl_info }, 533 484 { PCI_VDEVICE(INTEL, 0xa347), (kernel_ulong_t)&spt_uart_info }, 534 485 { PCI_VDEVICE(INTEL, 0xa368), (kernel_ulong_t)&cnl_i2c_info }, 535 486 { PCI_VDEVICE(INTEL, 0xa369), (kernel_ulong_t)&cnl_i2c_info }, 536 487 { PCI_VDEVICE(INTEL, 0xa36a), (kernel_ulong_t)&cnl_i2c_info }, 537 488 { PCI_VDEVICE(INTEL, 0xa36b), (kernel_ulong_t)&cnl_i2c_info }, 538 - { PCI_VDEVICE(INTEL, 0xa37b), (kernel_ulong_t)&spt_info }, 489 + { PCI_VDEVICE(INTEL, 0xa37b), (kernel_ulong_t)&cnl_info }, 539 490 /* CML-V */ 540 491 { PCI_VDEVICE(INTEL, 0xa3a7), (kernel_ulong_t)&spt_uart_info }, 541 492 { PCI_VDEVICE(INTEL, 0xa3a8), (kernel_ulong_t)&spt_uart_info },
+1
drivers/mfd/intel-m10-bmc.c
··· 21 21 22 22 static struct mfd_cell m10bmc_d5005_subdevs[] = { 23 23 { .name = "d5005bmc-hwmon" }, 24 + { .name = "d5005bmc-sec-update" } 24 25 }; 25 26 26 27 static struct mfd_cell m10bmc_pacn3000_subdevs[] = {
+4 -4
drivers/mfd/intel_soc_pmic_chtdc_ti.c
··· 140 140 disable_irq(pmic->irq); 141 141 } 142 142 143 - static int __maybe_unused chtdc_ti_suspend(struct device *dev) 143 + static int chtdc_ti_suspend(struct device *dev) 144 144 { 145 145 struct intel_soc_pmic *pmic = dev_get_drvdata(dev); 146 146 ··· 149 149 return 0; 150 150 } 151 151 152 - static int __maybe_unused chtdc_ti_resume(struct device *dev) 152 + static int chtdc_ti_resume(struct device *dev) 153 153 { 154 154 struct intel_soc_pmic *pmic = dev_get_drvdata(dev); 155 155 ··· 158 158 return 0; 159 159 } 160 160 161 - static SIMPLE_DEV_PM_OPS(chtdc_ti_pm_ops, chtdc_ti_suspend, chtdc_ti_resume); 161 + static DEFINE_SIMPLE_DEV_PM_OPS(chtdc_ti_pm_ops, chtdc_ti_suspend, chtdc_ti_resume); 162 162 163 163 static const struct acpi_device_id chtdc_ti_acpi_ids[] = { 164 164 { "INT33F5" }, ··· 169 169 static struct i2c_driver chtdc_ti_i2c_driver = { 170 170 .driver = { 171 171 .name = "intel_soc_pmic_chtdc_ti", 172 - .pm = &chtdc_ti_pm_ops, 172 + .pm = pm_sleep_ptr(&chtdc_ti_pm_ops), 173 173 .acpi_match_table = chtdc_ti_acpi_ids, 174 174 }, 175 175 .probe_new = chtdc_ti_probe,
-158
drivers/mfd/intel_soc_pmic_core.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * Intel SoC PMIC MFD Driver 4 - * 5 - * Copyright (C) 2013, 2014 Intel Corporation. All rights reserved. 6 - * 7 - * Author: Yang, Bin <bin.yang@intel.com> 8 - * Author: Zhu, Lejun <lejun.zhu@linux.intel.com> 9 - */ 10 - 11 - #include <linux/acpi.h> 12 - #include <linux/i2c.h> 13 - #include <linux/interrupt.h> 14 - #include <linux/module.h> 15 - #include <linux/mfd/core.h> 16 - #include <linux/mfd/intel_soc_pmic.h> 17 - #include <linux/platform_data/x86/soc.h> 18 - #include <linux/pwm.h> 19 - #include <linux/regmap.h> 20 - 21 - #include "intel_soc_pmic_core.h" 22 - 23 - /* PWM consumed by the Intel GFX */ 24 - static struct pwm_lookup crc_pwm_lookup[] = { 25 - PWM_LOOKUP("crystal_cove_pwm", 0, "0000:00:02.0", "pwm_pmic_backlight", 0, PWM_POLARITY_NORMAL), 26 - }; 27 - 28 - static int intel_soc_pmic_i2c_probe(struct i2c_client *i2c, 29 - const struct i2c_device_id *i2c_id) 30 - { 31 - struct device *dev = &i2c->dev; 32 - struct intel_soc_pmic_config *config; 33 - struct intel_soc_pmic *pmic; 34 - int ret; 35 - 36 - if (soc_intel_is_byt()) 37 - config = &intel_soc_pmic_config_byt_crc; 38 - else 39 - config = &intel_soc_pmic_config_cht_crc; 40 - 41 - pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL); 42 - if (!pmic) 43 - return -ENOMEM; 44 - 45 - dev_set_drvdata(dev, pmic); 46 - 47 - pmic->regmap = devm_regmap_init_i2c(i2c, config->regmap_config); 48 - if (IS_ERR(pmic->regmap)) 49 - return PTR_ERR(pmic->regmap); 50 - 51 - pmic->irq = i2c->irq; 52 - 53 - ret = regmap_add_irq_chip(pmic->regmap, pmic->irq, 54 - config->irq_flags | IRQF_ONESHOT, 55 - 0, config->irq_chip, 56 - &pmic->irq_chip_data); 57 - if (ret) 58 - return ret; 59 - 60 - ret = enable_irq_wake(pmic->irq); 61 - if (ret) 62 - dev_warn(dev, "Can't enable IRQ as wake source: %d\n", ret); 63 - 64 - /* Add lookup table for crc-pwm */ 65 - pwm_add_table(crc_pwm_lookup, ARRAY_SIZE(crc_pwm_lookup)); 66 - 67 - /* To distuingish this domain from the GPIO/charger's irqchip domains */ 68 - irq_domain_update_bus_token(regmap_irq_get_domain(pmic->irq_chip_data), 69 - DOMAIN_BUS_NEXUS); 70 - 71 - ret = mfd_add_devices(dev, -1, config->cell_dev, 72 - config->n_cell_devs, NULL, 0, 73 - regmap_irq_get_domain(pmic->irq_chip_data)); 74 - if (ret) 75 - goto err_del_irq_chip; 76 - 77 - return 0; 78 - 79 - err_del_irq_chip: 80 - regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data); 81 - return ret; 82 - } 83 - 84 - static void intel_soc_pmic_i2c_remove(struct i2c_client *i2c) 85 - { 86 - struct intel_soc_pmic *pmic = dev_get_drvdata(&i2c->dev); 87 - 88 - regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data); 89 - 90 - /* remove crc-pwm lookup table */ 91 - pwm_remove_table(crc_pwm_lookup, ARRAY_SIZE(crc_pwm_lookup)); 92 - 93 - mfd_remove_devices(&i2c->dev); 94 - } 95 - 96 - static void intel_soc_pmic_shutdown(struct i2c_client *i2c) 97 - { 98 - struct intel_soc_pmic *pmic = dev_get_drvdata(&i2c->dev); 99 - 100 - disable_irq(pmic->irq); 101 - 102 - return; 103 - } 104 - 105 - #if defined(CONFIG_PM_SLEEP) 106 - static int intel_soc_pmic_suspend(struct device *dev) 107 - { 108 - struct intel_soc_pmic *pmic = dev_get_drvdata(dev); 109 - 110 - disable_irq(pmic->irq); 111 - 112 - return 0; 113 - } 114 - 115 - static int intel_soc_pmic_resume(struct device *dev) 116 - { 117 - struct intel_soc_pmic *pmic = dev_get_drvdata(dev); 118 - 119 - enable_irq(pmic->irq); 120 - 121 - return 0; 122 - } 123 - #endif 124 - 125 - static SIMPLE_DEV_PM_OPS(intel_soc_pmic_pm_ops, intel_soc_pmic_suspend, 126 - intel_soc_pmic_resume); 127 - 128 - static const struct i2c_device_id intel_soc_pmic_i2c_id[] = { 129 - { } 130 - }; 131 - MODULE_DEVICE_TABLE(i2c, intel_soc_pmic_i2c_id); 132 - 133 - #if defined(CONFIG_ACPI) 134 - static const struct acpi_device_id intel_soc_pmic_acpi_match[] = { 135 - { "INT33FD" }, 136 - { }, 137 - }; 138 - MODULE_DEVICE_TABLE(acpi, intel_soc_pmic_acpi_match); 139 - #endif 140 - 141 - static struct i2c_driver intel_soc_pmic_i2c_driver = { 142 - .driver = { 143 - .name = "intel_soc_pmic_i2c", 144 - .pm = &intel_soc_pmic_pm_ops, 145 - .acpi_match_table = ACPI_PTR(intel_soc_pmic_acpi_match), 146 - }, 147 - .probe = intel_soc_pmic_i2c_probe, 148 - .remove = intel_soc_pmic_i2c_remove, 149 - .id_table = intel_soc_pmic_i2c_id, 150 - .shutdown = intel_soc_pmic_shutdown, 151 - }; 152 - 153 - module_i2c_driver(intel_soc_pmic_i2c_driver); 154 - 155 - MODULE_DESCRIPTION("I2C driver for Intel SoC PMIC"); 156 - MODULE_LICENSE("GPL v2"); 157 - MODULE_AUTHOR("Yang, Bin <bin.yang@intel.com>"); 158 - MODULE_AUTHOR("Zhu, Lejun <lejun.zhu@linux.intel.com>");
-25
drivers/mfd/intel_soc_pmic_core.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - /* 3 - * Intel SoC PMIC MFD Driver 4 - * 5 - * Copyright (C) 2012-2014 Intel Corporation. All rights reserved. 6 - * 7 - * Author: Yang, Bin <bin.yang@intel.com> 8 - * Author: Zhu, Lejun <lejun.zhu@linux.intel.com> 9 - */ 10 - 11 - #ifndef __INTEL_SOC_PMIC_CORE_H__ 12 - #define __INTEL_SOC_PMIC_CORE_H__ 13 - 14 - struct intel_soc_pmic_config { 15 - unsigned long irq_flags; 16 - struct mfd_cell *cell_dev; 17 - int n_cell_devs; 18 - const struct regmap_config *regmap_config; 19 - const struct regmap_irq_chip *irq_chip; 20 - }; 21 - 22 - extern struct intel_soc_pmic_config intel_soc_pmic_config_byt_crc; 23 - extern struct intel_soc_pmic_config intel_soc_pmic_config_cht_crc; 24 - 25 - #endif /* __INTEL_SOC_PMIC_CORE_H__ */
+133 -6
drivers/mfd/intel_soc_pmic_crc.c
··· 2 2 /* 3 3 * Device access for Crystal Cove PMIC 4 4 * 5 - * Copyright (C) 2013, 2014 Intel Corporation. All rights reserved. 5 + * Copyright (C) 2012-2014, 2022 Intel Corporation. All rights reserved. 6 6 * 7 7 * Author: Yang, Bin <bin.yang@intel.com> 8 8 * Author: Zhu, Lejun <lejun.zhu@linux.intel.com> 9 9 */ 10 10 11 + #include <linux/i2c.h> 11 12 #include <linux/interrupt.h> 12 - #include <linux/regmap.h> 13 + #include <linux/mod_devicetable.h> 14 + #include <linux/module.h> 13 15 #include <linux/mfd/core.h> 14 16 #include <linux/mfd/intel_soc_pmic.h> 15 - 16 - #include "intel_soc_pmic_core.h" 17 + #include <linux/platform_data/x86/soc.h> 18 + #include <linux/pwm.h> 19 + #include <linux/regmap.h> 17 20 18 21 #define CRYSTAL_COVE_MAX_REGISTER 0xC6 19 22 ··· 135 132 .mask_base = CRYSTAL_COVE_REG_MIRQLVL1, 136 133 }; 137 134 138 - struct intel_soc_pmic_config intel_soc_pmic_config_byt_crc = { 135 + /* PWM consumed by the Intel GFX */ 136 + static struct pwm_lookup crc_pwm_lookup[] = { 137 + PWM_LOOKUP("crystal_cove_pwm", 0, "0000:00:02.0", "pwm_pmic_backlight", 0, PWM_POLARITY_NORMAL), 138 + }; 139 + 140 + struct crystal_cove_config { 141 + unsigned long irq_flags; 142 + struct mfd_cell *cell_dev; 143 + int n_cell_devs; 144 + const struct regmap_config *regmap_config; 145 + const struct regmap_irq_chip *irq_chip; 146 + }; 147 + 148 + static const struct crystal_cove_config crystal_cove_config_byt_crc = { 139 149 .irq_flags = IRQF_TRIGGER_RISING, 140 150 .cell_dev = crystal_cove_byt_dev, 141 151 .n_cell_devs = ARRAY_SIZE(crystal_cove_byt_dev), ··· 156 140 .irq_chip = &crystal_cove_irq_chip, 157 141 }; 158 142 159 - struct intel_soc_pmic_config intel_soc_pmic_config_cht_crc = { 143 + static const struct crystal_cove_config crystal_cove_config_cht_crc = { 160 144 .irq_flags = IRQF_TRIGGER_RISING, 161 145 .cell_dev = crystal_cove_cht_dev, 162 146 .n_cell_devs = ARRAY_SIZE(crystal_cove_cht_dev), 163 147 .regmap_config = &crystal_cove_regmap_config, 164 148 .irq_chip = &crystal_cove_irq_chip, 165 149 }; 150 + 151 + static int crystal_cove_i2c_probe(struct i2c_client *i2c) 152 + { 153 + const struct crystal_cove_config *config; 154 + struct device *dev = &i2c->dev; 155 + struct intel_soc_pmic *pmic; 156 + int ret; 157 + 158 + if (soc_intel_is_byt()) 159 + config = &crystal_cove_config_byt_crc; 160 + else 161 + config = &crystal_cove_config_cht_crc; 162 + 163 + pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL); 164 + if (!pmic) 165 + return -ENOMEM; 166 + 167 + i2c_set_clientdata(i2c, pmic); 168 + 169 + pmic->regmap = devm_regmap_init_i2c(i2c, config->regmap_config); 170 + if (IS_ERR(pmic->regmap)) 171 + return PTR_ERR(pmic->regmap); 172 + 173 + pmic->irq = i2c->irq; 174 + 175 + ret = devm_regmap_add_irq_chip(dev, pmic->regmap, pmic->irq, 176 + config->irq_flags | IRQF_ONESHOT, 177 + 0, config->irq_chip, &pmic->irq_chip_data); 178 + if (ret) 179 + return ret; 180 + 181 + ret = enable_irq_wake(pmic->irq); 182 + if (ret) 183 + dev_warn(dev, "Can't enable IRQ as wake source: %d\n", ret); 184 + 185 + /* Add lookup table for crc-pwm */ 186 + pwm_add_table(crc_pwm_lookup, ARRAY_SIZE(crc_pwm_lookup)); 187 + 188 + /* To distuingish this domain from the GPIO/charger's irqchip domains */ 189 + irq_domain_update_bus_token(regmap_irq_get_domain(pmic->irq_chip_data), 190 + DOMAIN_BUS_NEXUS); 191 + 192 + ret = mfd_add_devices(dev, PLATFORM_DEVID_NONE, config->cell_dev, 193 + config->n_cell_devs, NULL, 0, 194 + regmap_irq_get_domain(pmic->irq_chip_data)); 195 + if (ret) 196 + pwm_remove_table(crc_pwm_lookup, ARRAY_SIZE(crc_pwm_lookup)); 197 + 198 + return ret; 199 + } 200 + 201 + static void crystal_cove_i2c_remove(struct i2c_client *i2c) 202 + { 203 + /* remove crc-pwm lookup table */ 204 + pwm_remove_table(crc_pwm_lookup, ARRAY_SIZE(crc_pwm_lookup)); 205 + 206 + mfd_remove_devices(&i2c->dev); 207 + } 208 + 209 + static void crystal_cove_shutdown(struct i2c_client *i2c) 210 + { 211 + struct intel_soc_pmic *pmic = i2c_get_clientdata(i2c); 212 + 213 + disable_irq(pmic->irq); 214 + 215 + return; 216 + } 217 + 218 + static int crystal_cove_suspend(struct device *dev) 219 + { 220 + struct intel_soc_pmic *pmic = dev_get_drvdata(dev); 221 + 222 + disable_irq(pmic->irq); 223 + 224 + return 0; 225 + } 226 + 227 + static int crystal_cove_resume(struct device *dev) 228 + { 229 + struct intel_soc_pmic *pmic = dev_get_drvdata(dev); 230 + 231 + enable_irq(pmic->irq); 232 + 233 + return 0; 234 + } 235 + 236 + static DEFINE_SIMPLE_DEV_PM_OPS(crystal_cove_pm_ops, crystal_cove_suspend, crystal_cove_resume); 237 + 238 + static const struct acpi_device_id crystal_cove_acpi_match[] = { 239 + { "INT33FD" }, 240 + { }, 241 + }; 242 + MODULE_DEVICE_TABLE(acpi, crystal_cove_acpi_match); 243 + 244 + static struct i2c_driver crystal_cove_i2c_driver = { 245 + .driver = { 246 + .name = "crystal_cove_i2c", 247 + .pm = pm_sleep_ptr(&crystal_cove_pm_ops), 248 + .acpi_match_table = crystal_cove_acpi_match, 249 + }, 250 + .probe_new = crystal_cove_i2c_probe, 251 + .remove = crystal_cove_i2c_remove, 252 + .shutdown = crystal_cove_shutdown, 253 + }; 254 + 255 + module_i2c_driver(crystal_cove_i2c_driver); 256 + 257 + MODULE_DESCRIPTION("I2C driver for Intel SoC PMIC"); 258 + MODULE_LICENSE("GPL v2"); 259 + MODULE_AUTHOR("Yang, Bin <bin.yang@intel.com>"); 260 + MODULE_AUTHOR("Zhu, Lejun <lejun.zhu@linux.intel.com>");
+3
drivers/mfd/lp8788-irq.c
··· 175 175 IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 176 176 "lp8788-irq", irqd); 177 177 if (ret) { 178 + irq_domain_remove(lp->irqdm); 178 179 dev_err(lp->dev, "failed to create a thread for IRQ_N\n"); 179 180 return ret; 180 181 } ··· 189 188 { 190 189 if (lp->irq) 191 190 free_irq(lp->irq, lp->irqdm); 191 + if (lp->irqdm) 192 + irq_domain_remove(lp->irqdm); 192 193 }
+10 -2
drivers/mfd/lp8788.c
··· 195 195 if (ret) 196 196 return ret; 197 197 198 - return mfd_add_devices(lp->dev, -1, lp8788_devs, 199 - ARRAY_SIZE(lp8788_devs), NULL, 0, NULL); 198 + ret = mfd_add_devices(lp->dev, -1, lp8788_devs, 199 + ARRAY_SIZE(lp8788_devs), NULL, 0, NULL); 200 + if (ret) 201 + goto err_exit_irq; 202 + 203 + return 0; 204 + 205 + err_exit_irq: 206 + lp8788_irq_exit(lp); 207 + return ret; 200 208 } 201 209 202 210 static void lp8788_remove(struct i2c_client *cl)
+1 -1
drivers/mfd/lpc_ich.c
··· 959 959 info = &lpc_chipset_info[priv->chipset]; 960 960 961 961 pdata->version = info->iTCO_version; 962 - strlcpy(pdata->name, info->name, sizeof(pdata->name)); 962 + strscpy(pdata->name, info->name, sizeof(pdata->name)); 963 963 964 964 cell->platform_data = pdata; 965 965 cell->pdata_size = sizeof(*pdata);
+8 -1
drivers/mfd/mfd-core.c
··· 105 105 .ids = ids, 106 106 }; 107 107 108 - strlcpy(ids[0].id, match->pnpid, sizeof(ids[0].id)); 108 + strscpy(ids[0].id, match->pnpid, sizeof(ids[0].id)); 109 109 acpi_dev_for_each_child(parent, match_device_ids, &wd); 110 110 adev = wd.adev; 111 111 } else { ··· 368 368 { 369 369 struct platform_device *pdev; 370 370 const struct mfd_cell *cell; 371 + struct mfd_of_node_entry *of_entry, *tmp; 371 372 int *level = data; 372 373 373 374 if (dev->type != &mfd_dev_type) ··· 382 381 383 382 if (cell->swnode) 384 383 device_remove_software_node(&pdev->dev); 384 + 385 + list_for_each_entry_safe(of_entry, tmp, &mfd_of_node_list, list) 386 + if (of_entry->dev == &pdev->dev) { 387 + list_del(&of_entry->list); 388 + kfree(of_entry); 389 + } 385 390 386 391 regulator_bulk_unregister_supply_alias(dev, cell->parent_supplies, 387 392 cell->num_parent_supplies);
+312
drivers/mfd/mt6370.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (C) 2022 Richtek Technology Corp. 4 + * 5 + * Author: ChiYuan Huang <cy_huang@richtek.com> 6 + */ 7 + 8 + #include <linux/bits.h> 9 + #include <linux/bitfield.h> 10 + #include <linux/i2c.h> 11 + #include <linux/interrupt.h> 12 + #include <linux/kernel.h> 13 + #include <linux/mfd/core.h> 14 + #include <linux/module.h> 15 + #include <linux/regmap.h> 16 + 17 + #include "mt6370.h" 18 + 19 + #define MT6370_REG_DEV_INFO 0x100 20 + #define MT6370_REG_CHG_IRQ1 0x1C0 21 + #define MT6370_REG_CHG_MASK1 0x1E0 22 + #define MT6370_REG_MAXADDR 0x1FF 23 + 24 + #define MT6370_VENID_MASK GENMASK(7, 4) 25 + 26 + #define MT6370_NUM_IRQREGS 16 27 + #define MT6370_USBC_I2CADDR 0x4E 28 + #define MT6370_MAX_ADDRLEN 2 29 + 30 + #define MT6370_VENID_RT5081 0x8 31 + #define MT6370_VENID_RT5081A 0xA 32 + #define MT6370_VENID_MT6370 0xE 33 + #define MT6370_VENID_MT6371 0xF 34 + #define MT6370_VENID_MT6372P 0x9 35 + #define MT6370_VENID_MT6372CP 0xB 36 + 37 + static const struct regmap_irq mt6370_irqs[] = { 38 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_DIRCHGON, 8), 39 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_CHG_TREG, 8), 40 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_CHG_AICR, 8), 41 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_CHG_MIVR, 8), 42 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_PWR_RDY, 8), 43 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_FL_CHG_VINOVP, 8), 44 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_CHG_VSYSUV, 8), 45 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_CHG_VSYSOV, 8), 46 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_CHG_VBATOV, 8), 47 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_CHG_VINOVPCHG, 8), 48 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_TS_BAT_COLD, 8), 49 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_TS_BAT_COOL, 8), 50 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_TS_BAT_WARM, 8), 51 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_TS_BAT_HOT, 8), 52 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_TS_STATC, 8), 53 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_CHG_FAULT, 8), 54 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_CHG_STATC, 8), 55 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_CHG_TMR, 8), 56 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_CHG_BATABS, 8), 57 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_CHG_ADPBAD, 8), 58 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_CHG_RVP, 8), 59 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_TSHUTDOWN, 8), 60 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_CHG_IINMEAS, 8), 61 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_CHG_ICCMEAS, 8), 62 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_CHGDET_DONE, 8), 63 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_WDTMR, 8), 64 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_SSFINISH, 8), 65 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_CHG_RECHG, 8), 66 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_CHG_TERM, 8), 67 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_CHG_IEOC, 8), 68 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_ADC_DONE, 8), 69 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_PUMPX_DONE, 8), 70 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_BST_BATUV, 8), 71 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_BST_MIDOV, 8), 72 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_BST_OLP, 8), 73 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_ATTACH, 8), 74 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_DETACH, 8), 75 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_HVDCP_STPDONE, 8), 76 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_HVDCP_VBUSDET_DONE, 8), 77 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_HVDCP_DET, 8), 78 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_CHGDET, 8), 79 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_DCDT, 8), 80 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_DIRCHG_VGOK, 8), 81 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_DIRCHG_WDTMR, 8), 82 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_DIRCHG_UC, 8), 83 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_DIRCHG_OC, 8), 84 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_DIRCHG_OV, 8), 85 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_OVPCTRL_SWON, 8), 86 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_OVPCTRL_UVP_D, 8), 87 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_OVPCTRL_UVP, 8), 88 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_OVPCTRL_OVP_D, 8), 89 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_OVPCTRL_OVP, 8), 90 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_FLED_STRBPIN, 8), 91 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_FLED_TORPIN, 8), 92 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_FLED_TX, 8), 93 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_FLED_LVF, 8), 94 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_FLED2_SHORT, 8), 95 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_FLED1_SHORT, 8), 96 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_FLED2_STRB, 8), 97 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_FLED1_STRB, 8), 98 + REGMAP_IRQ_REG_LINE(mT6370_IRQ_FLED2_STRB_TO, 8), 99 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_FLED1_STRB_TO, 8), 100 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_FLED2_TOR, 8), 101 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_FLED1_TOR, 8), 102 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_OTP, 8), 103 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_VDDA_OVP, 8), 104 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_VDDA_UV, 8), 105 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_LDO_OC, 8), 106 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_BLED_OCP, 8), 107 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_BLED_OVP, 8), 108 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_DSV_VNEG_OCP, 8), 109 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_DSV_VPOS_OCP, 8), 110 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_DSV_BST_OCP, 8), 111 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_DSV_VNEG_SCP, 8), 112 + REGMAP_IRQ_REG_LINE(MT6370_IRQ_DSV_VPOS_SCP, 8), 113 + }; 114 + 115 + static const struct regmap_irq_chip mt6370_irq_chip = { 116 + .name = "mt6370-irqs", 117 + .status_base = MT6370_REG_CHG_IRQ1, 118 + .mask_base = MT6370_REG_CHG_MASK1, 119 + .num_regs = MT6370_NUM_IRQREGS, 120 + .irqs = mt6370_irqs, 121 + .num_irqs = ARRAY_SIZE(mt6370_irqs), 122 + }; 123 + 124 + static const struct resource mt6370_regulator_irqs[] = { 125 + DEFINE_RES_IRQ_NAMED(MT6370_IRQ_DSV_VPOS_SCP, "db_vpos_scp"), 126 + DEFINE_RES_IRQ_NAMED(MT6370_IRQ_DSV_VNEG_SCP, "db_vneg_scp"), 127 + DEFINE_RES_IRQ_NAMED(MT6370_IRQ_DSV_BST_OCP, "db_vbst_ocp"), 128 + DEFINE_RES_IRQ_NAMED(MT6370_IRQ_DSV_VPOS_OCP, "db_vpos_ocp"), 129 + DEFINE_RES_IRQ_NAMED(MT6370_IRQ_DSV_VNEG_OCP, "db_vneg_ocp"), 130 + DEFINE_RES_IRQ_NAMED(MT6370_IRQ_LDO_OC, "ldo_oc"), 131 + }; 132 + 133 + static const struct mfd_cell mt6370_devices[] = { 134 + MFD_CELL_OF("mt6370-adc", 135 + NULL, NULL, 0, 0, "mediatek,mt6370-adc"), 136 + MFD_CELL_OF("mt6370-charger", 137 + NULL, NULL, 0, 0, "mediatek,mt6370-charger"), 138 + MFD_CELL_OF("mt6370-flashlight", 139 + NULL, NULL, 0, 0, "mediatek,mt6370-flashlight"), 140 + MFD_CELL_OF("mt6370-indicator", 141 + NULL, NULL, 0, 0, "mediatek,mt6370-indicator"), 142 + MFD_CELL_OF("mt6370-tcpc", 143 + NULL, NULL, 0, 0, "mediatek,mt6370-tcpc"), 144 + MFD_CELL_RES("mt6370-regulator", mt6370_regulator_irqs), 145 + }; 146 + 147 + static const struct mfd_cell mt6370_exclusive_devices[] = { 148 + MFD_CELL_OF("mt6370-backlight", 149 + NULL, NULL, 0, 0, "mediatek,mt6370-backlight"), 150 + }; 151 + 152 + static const struct mfd_cell mt6372_exclusive_devices[] = { 153 + MFD_CELL_OF("mt6370-backlight", 154 + NULL, NULL, 0, 0, "mediatek,mt6372-backlight"), 155 + }; 156 + 157 + static int mt6370_check_vendor_info(struct device *dev, struct regmap *rmap, 158 + int *vid) 159 + { 160 + unsigned int devinfo; 161 + int ret; 162 + 163 + ret = regmap_read(rmap, MT6370_REG_DEV_INFO, &devinfo); 164 + if (ret) 165 + return ret; 166 + 167 + *vid = FIELD_GET(MT6370_VENID_MASK, devinfo); 168 + switch (*vid) { 169 + case MT6370_VENID_RT5081: 170 + case MT6370_VENID_RT5081A: 171 + case MT6370_VENID_MT6370: 172 + case MT6370_VENID_MT6371: 173 + case MT6370_VENID_MT6372P: 174 + case MT6370_VENID_MT6372CP: 175 + return 0; 176 + default: 177 + dev_err(dev, "Unknown Vendor ID 0x%02x\n", devinfo); 178 + return -ENODEV; 179 + } 180 + } 181 + 182 + static int mt6370_regmap_read(void *context, const void *reg_buf, 183 + size_t reg_size, void *val_buf, size_t val_size) 184 + { 185 + struct mt6370_info *info = context; 186 + const u8 *u8_buf = reg_buf; 187 + u8 bank_idx, bank_addr; 188 + int ret; 189 + 190 + bank_idx = u8_buf[0]; 191 + bank_addr = u8_buf[1]; 192 + 193 + ret = i2c_smbus_read_i2c_block_data(info->i2c[bank_idx], bank_addr, 194 + val_size, val_buf); 195 + if (ret < 0) 196 + return ret; 197 + 198 + if (ret != val_size) 199 + return -EIO; 200 + 201 + return 0; 202 + } 203 + 204 + static int mt6370_regmap_write(void *context, const void *data, size_t count) 205 + { 206 + struct mt6370_info *info = context; 207 + const u8 *u8_buf = data; 208 + u8 bank_idx, bank_addr; 209 + int len = count - MT6370_MAX_ADDRLEN; 210 + 211 + bank_idx = u8_buf[0]; 212 + bank_addr = u8_buf[1]; 213 + 214 + return i2c_smbus_write_i2c_block_data(info->i2c[bank_idx], bank_addr, 215 + len, data + MT6370_MAX_ADDRLEN); 216 + } 217 + 218 + static const struct regmap_bus mt6370_regmap_bus = { 219 + .read = mt6370_regmap_read, 220 + .write = mt6370_regmap_write, 221 + }; 222 + 223 + static const struct regmap_config mt6370_regmap_config = { 224 + .reg_bits = 16, 225 + .val_bits = 8, 226 + .reg_format_endian = REGMAP_ENDIAN_BIG, 227 + .max_register = MT6370_REG_MAXADDR, 228 + }; 229 + 230 + static int mt6370_probe(struct i2c_client *i2c) 231 + { 232 + struct mt6370_info *info; 233 + struct i2c_client *usbc_i2c; 234 + struct regmap *regmap; 235 + struct device *dev = &i2c->dev; 236 + int ret, vid; 237 + 238 + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); 239 + if (!info) 240 + return -ENOMEM; 241 + 242 + usbc_i2c = devm_i2c_new_dummy_device(dev, i2c->adapter, 243 + MT6370_USBC_I2CADDR); 244 + if (IS_ERR(usbc_i2c)) 245 + return dev_err_probe(dev, PTR_ERR(usbc_i2c), 246 + "Failed to register USBC I2C client\n"); 247 + 248 + /* Assign I2C client for PMU and TypeC */ 249 + info->i2c[MT6370_PMU_I2C] = i2c; 250 + info->i2c[MT6370_USBC_I2C] = usbc_i2c; 251 + 252 + regmap = devm_regmap_init(dev, &mt6370_regmap_bus, 253 + info, &mt6370_regmap_config); 254 + if (IS_ERR(regmap)) 255 + return dev_err_probe(dev, PTR_ERR(regmap), 256 + "Failed to init regmap\n"); 257 + 258 + ret = mt6370_check_vendor_info(dev, regmap, &vid); 259 + if (ret) 260 + return dev_err_probe(dev, ret, "Failed to check vendor info\n"); 261 + 262 + ret = devm_regmap_add_irq_chip(dev, regmap, i2c->irq, 263 + IRQF_ONESHOT, -1, &mt6370_irq_chip, 264 + &info->irq_data); 265 + if (ret) 266 + return dev_err_probe(dev, ret, "Failed to add irq chip\n"); 267 + 268 + switch (vid) { 269 + case MT6370_VENID_MT6372P: 270 + case MT6370_VENID_MT6372CP: 271 + ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, 272 + mt6372_exclusive_devices, 273 + ARRAY_SIZE(mt6372_exclusive_devices), 274 + NULL, 0, 275 + regmap_irq_get_domain(info->irq_data)); 276 + break; 277 + default: 278 + ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, 279 + mt6370_exclusive_devices, 280 + ARRAY_SIZE(mt6370_exclusive_devices), 281 + NULL, 0, 282 + regmap_irq_get_domain(info->irq_data)); 283 + break; 284 + } 285 + 286 + if (ret) 287 + return dev_err_probe(dev, ret, "Failed to add the exclusive devices\n"); 288 + 289 + return devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, 290 + mt6370_devices, ARRAY_SIZE(mt6370_devices), 291 + NULL, 0, 292 + regmap_irq_get_domain(info->irq_data)); 293 + } 294 + 295 + static const struct of_device_id mt6370_match_table[] = { 296 + { .compatible = "mediatek,mt6370" }, 297 + {} 298 + }; 299 + MODULE_DEVICE_TABLE(of, mt6370_match_table); 300 + 301 + static struct i2c_driver mt6370_driver = { 302 + .driver = { 303 + .name = "mt6370", 304 + .of_match_table = mt6370_match_table, 305 + }, 306 + .probe_new = mt6370_probe, 307 + }; 308 + module_i2c_driver(mt6370_driver); 309 + 310 + MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>"); 311 + MODULE_DESCRIPTION("MediaTek MT6370 SubPMIC Driver"); 312 + MODULE_LICENSE("GPL v2");
+99
drivers/mfd/mt6370.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright (C) 2022 Richtek Technology Corp. 4 + * 5 + * Author: ChiYuan Huang <cy_huang@richtek.com> 6 + */ 7 + 8 + #ifndef __MFD_MT6370_H__ 9 + #define __MFD_MT6370_H__ 10 + 11 + /* IRQ definitions */ 12 + #define MT6370_IRQ_DIRCHGON 0 13 + #define MT6370_IRQ_CHG_TREG 4 14 + #define MT6370_IRQ_CHG_AICR 5 15 + #define MT6370_IRQ_CHG_MIVR 6 16 + #define MT6370_IRQ_PWR_RDY 7 17 + #define MT6370_IRQ_FL_CHG_VINOVP 11 18 + #define MT6370_IRQ_CHG_VSYSUV 12 19 + #define MT6370_IRQ_CHG_VSYSOV 13 20 + #define MT6370_IRQ_CHG_VBATOV 14 21 + #define MT6370_IRQ_CHG_VINOVPCHG 15 22 + #define MT6370_IRQ_TS_BAT_COLD 20 23 + #define MT6370_IRQ_TS_BAT_COOL 21 24 + #define MT6370_IRQ_TS_BAT_WARM 22 25 + #define MT6370_IRQ_TS_BAT_HOT 23 26 + #define MT6370_IRQ_TS_STATC 24 27 + #define MT6370_IRQ_CHG_FAULT 25 28 + #define MT6370_IRQ_CHG_STATC 26 29 + #define MT6370_IRQ_CHG_TMR 27 30 + #define MT6370_IRQ_CHG_BATABS 28 31 + #define MT6370_IRQ_CHG_ADPBAD 29 32 + #define MT6370_IRQ_CHG_RVP 30 33 + #define MT6370_IRQ_TSHUTDOWN 31 34 + #define MT6370_IRQ_CHG_IINMEAS 32 35 + #define MT6370_IRQ_CHG_ICCMEAS 33 36 + #define MT6370_IRQ_CHGDET_DONE 34 37 + #define MT6370_IRQ_WDTMR 35 38 + #define MT6370_IRQ_SSFINISH 36 39 + #define MT6370_IRQ_CHG_RECHG 37 40 + #define MT6370_IRQ_CHG_TERM 38 41 + #define MT6370_IRQ_CHG_IEOC 39 42 + #define MT6370_IRQ_ADC_DONE 40 43 + #define MT6370_IRQ_PUMPX_DONE 41 44 + #define MT6370_IRQ_BST_BATUV 45 45 + #define MT6370_IRQ_BST_MIDOV 46 46 + #define MT6370_IRQ_BST_OLP 47 47 + #define MT6370_IRQ_ATTACH 48 48 + #define MT6370_IRQ_DETACH 49 49 + #define MT6370_IRQ_HVDCP_STPDONE 51 50 + #define MT6370_IRQ_HVDCP_VBUSDET_DONE 52 51 + #define MT6370_IRQ_HVDCP_DET 53 52 + #define MT6370_IRQ_CHGDET 54 53 + #define MT6370_IRQ_DCDT 55 54 + #define MT6370_IRQ_DIRCHG_VGOK 59 55 + #define MT6370_IRQ_DIRCHG_WDTMR 60 56 + #define MT6370_IRQ_DIRCHG_UC 61 57 + #define MT6370_IRQ_DIRCHG_OC 62 58 + #define MT6370_IRQ_DIRCHG_OV 63 59 + #define MT6370_IRQ_OVPCTRL_SWON 67 60 + #define MT6370_IRQ_OVPCTRL_UVP_D 68 61 + #define MT6370_IRQ_OVPCTRL_UVP 69 62 + #define MT6370_IRQ_OVPCTRL_OVP_D 70 63 + #define MT6370_IRQ_OVPCTRL_OVP 71 64 + #define MT6370_IRQ_FLED_STRBPIN 72 65 + #define MT6370_IRQ_FLED_TORPIN 73 66 + #define MT6370_IRQ_FLED_TX 74 67 + #define MT6370_IRQ_FLED_LVF 75 68 + #define MT6370_IRQ_FLED2_SHORT 78 69 + #define MT6370_IRQ_FLED1_SHORT 79 70 + #define MT6370_IRQ_FLED2_STRB 80 71 + #define MT6370_IRQ_FLED1_STRB 81 72 + #define mT6370_IRQ_FLED2_STRB_TO 82 73 + #define MT6370_IRQ_FLED1_STRB_TO 83 74 + #define MT6370_IRQ_FLED2_TOR 84 75 + #define MT6370_IRQ_FLED1_TOR 85 76 + #define MT6370_IRQ_OTP 93 77 + #define MT6370_IRQ_VDDA_OVP 94 78 + #define MT6370_IRQ_VDDA_UV 95 79 + #define MT6370_IRQ_LDO_OC 103 80 + #define MT6370_IRQ_BLED_OCP 118 81 + #define MT6370_IRQ_BLED_OVP 119 82 + #define MT6370_IRQ_DSV_VNEG_OCP 123 83 + #define MT6370_IRQ_DSV_VPOS_OCP 124 84 + #define MT6370_IRQ_DSV_BST_OCP 125 85 + #define MT6370_IRQ_DSV_VNEG_SCP 126 86 + #define MT6370_IRQ_DSV_VPOS_SCP 127 87 + 88 + enum { 89 + MT6370_USBC_I2C = 0, 90 + MT6370_PMU_I2C, 91 + MT6370_MAX_I2C 92 + }; 93 + 94 + struct mt6370_info { 95 + struct i2c_client *i2c[MT6370_MAX_I2C]; 96 + struct regmap_irq_chip_data *irq_data; 97 + }; 98 + 99 + #endif /* __MFD_MT6375_H__ */
+1
drivers/mfd/ocelot-spi.c
··· 276 276 { "vsc7512", 0 }, 277 277 { } 278 278 }; 279 + MODULE_DEVICE_TABLE(spi, ocelot_spi_ids); 279 280 280 281 static const struct of_device_id ocelot_spi_of_match[] = { 281 282 { .compatible = "mscc,vsc7512" },
+1
drivers/mfd/qcom-spmi-pmic.c
··· 60 60 { .compatible = "qcom,pmi8994", .data = N_USIDS(2) }, 61 61 { .compatible = "qcom,pmi8998", .data = N_USIDS(2) }, 62 62 { .compatible = "qcom,pmk8002", .data = N_USIDS(2) }, 63 + { .compatible = "qcom,pmp8074", .data = N_USIDS(2) }, 63 64 { .compatible = "qcom,smb2351", .data = N_USIDS(2) }, 64 65 { .compatible = "qcom,spmi-pmic", .data = N_USIDS(1) }, 65 66 { }
+15 -1
drivers/mfd/rk808.c
··· 67 67 case RK817_SECONDS_REG ... RK817_WEEKS_REG: 68 68 case RK817_RTC_STATUS_REG: 69 69 case RK817_CODEC_DTOP_LPT_SRST: 70 + case RK817_GAS_GAUGE_ADC_CONFIG0 ... RK817_GAS_GAUGE_CUR_ADC_K0: 71 + case RK817_PMIC_CHRG_STS: 72 + case RK817_PMIC_CHRG_OUT: 73 + case RK817_PMIC_CHRG_IN: 70 74 case RK817_INT_STS_REG0: 71 75 case RK817_INT_STS_REG1: 72 76 case RK817_INT_STS_REG2: ··· 78 74 return true; 79 75 } 80 76 81 - return true; 77 + return false; 82 78 } 83 79 84 80 static const struct regmap_config rk818_regmap_config = { ··· 131 127 DEFINE_RES_IRQ(RK817_IRQ_PWRON_FALL), 132 128 }; 133 129 130 + static const struct resource rk817_charger_resources[] = { 131 + DEFINE_RES_IRQ(RK817_IRQ_PLUG_IN), 132 + DEFINE_RES_IRQ(RK817_IRQ_PLUG_OUT), 133 + }; 134 + 134 135 static const struct mfd_cell rk805s[] = { 135 136 { .name = "rk808-clkout", }, 136 137 { .name = "rk808-regulator", }, ··· 175 166 .resources = &rk817_rtc_resources[0], 176 167 }, 177 168 { .name = "rk817-codec",}, 169 + { 170 + .name = "rk817-charger", 171 + .num_resources = ARRAY_SIZE(rk817_charger_resources), 172 + .resources = &rk817_charger_resources[0], 173 + }, 178 174 }; 179 175 180 176 static const struct mfd_cell rk818s[] = {
+124
drivers/mfd/rt5120.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (C) 2022 Richtek Technology Corp. 4 + * Author: ChiYuan Huang <cy_huang@richtek.com> 5 + */ 6 + 7 + #include <linux/i2c.h> 8 + #include <linux/kernel.h> 9 + #include <linux/mfd/core.h> 10 + #include <linux/module.h> 11 + #include <linux/mod_devicetable.h> 12 + #include <linux/regmap.h> 13 + 14 + #define RT5120_REG_INTENABLE 0x1D 15 + #define RT5120_REG_INTSTAT 0x1E 16 + #define RT5120_REG_FZCMODE 0x44 17 + 18 + #define RT5120_INT_HOTDIE 0 19 + #define RT5120_INT_PWRKEY_REL 5 20 + #define RT5120_INT_PWRKEY_PRESS 6 21 + 22 + static const struct regmap_range rt5120_rd_yes_ranges[] = { 23 + regmap_reg_range(0x03, 0x13), 24 + regmap_reg_range(0x1c, 0x20), 25 + regmap_reg_range(0x44, 0x44), 26 + }; 27 + 28 + static const struct regmap_range rt5120_wr_yes_ranges[] = { 29 + regmap_reg_range(0x06, 0x13), 30 + regmap_reg_range(0x1c, 0x20), 31 + regmap_reg_range(0x44, 0x44), 32 + }; 33 + 34 + static const struct regmap_access_table rt5120_rd_table = { 35 + .yes_ranges = rt5120_rd_yes_ranges, 36 + .n_yes_ranges = ARRAY_SIZE(rt5120_rd_yes_ranges), 37 + }; 38 + 39 + static const struct regmap_access_table rt5120_wr_table = { 40 + .yes_ranges = rt5120_wr_yes_ranges, 41 + .n_yes_ranges = ARRAY_SIZE(rt5120_wr_yes_ranges), 42 + }; 43 + 44 + static const struct regmap_config rt5120_regmap_config = { 45 + .reg_bits = 8, 46 + .val_bits = 8, 47 + .max_register = RT5120_REG_FZCMODE, 48 + 49 + .wr_table = &rt5120_wr_table, 50 + .rd_table = &rt5120_rd_table, 51 + }; 52 + 53 + static const struct regmap_irq rt5120_irqs[] = { 54 + REGMAP_IRQ_REG_LINE(RT5120_INT_HOTDIE, 8), 55 + REGMAP_IRQ_REG_LINE(RT5120_INT_PWRKEY_REL, 8), 56 + REGMAP_IRQ_REG_LINE(RT5120_INT_PWRKEY_PRESS, 8), 57 + }; 58 + 59 + static const struct regmap_irq_chip rt5120_irq_chip = { 60 + .name = "rt5120-pmic", 61 + .status_base = RT5120_REG_INTSTAT, 62 + .mask_base = RT5120_REG_INTENABLE, 63 + .ack_base = RT5120_REG_INTSTAT, 64 + .mask_invert = true, 65 + .use_ack = true, 66 + .num_regs = 1, 67 + .irqs = rt5120_irqs, 68 + .num_irqs = ARRAY_SIZE(rt5120_irqs), 69 + }; 70 + 71 + static const struct resource rt5120_regulator_resources[] = { 72 + DEFINE_RES_IRQ(RT5120_INT_HOTDIE), 73 + }; 74 + 75 + static const struct resource rt5120_pwrkey_resources[] = { 76 + DEFINE_RES_IRQ_NAMED(RT5120_INT_PWRKEY_PRESS, "pwrkey-press"), 77 + DEFINE_RES_IRQ_NAMED(RT5120_INT_PWRKEY_REL, "pwrkey-release"), 78 + }; 79 + 80 + static const struct mfd_cell rt5120_devs[] = { 81 + MFD_CELL_RES("rt5120-regulator", rt5120_regulator_resources), 82 + MFD_CELL_OF("rt5120-pwrkey", rt5120_pwrkey_resources, NULL, 0, 0, "richtek,rt5120-pwrkey"), 83 + }; 84 + 85 + static int rt5120_probe(struct i2c_client *i2c) 86 + { 87 + struct device *dev = &i2c->dev; 88 + struct regmap *regmap; 89 + struct regmap_irq_chip_data *irq_data; 90 + int ret; 91 + 92 + regmap = devm_regmap_init_i2c(i2c, &rt5120_regmap_config); 93 + if (IS_ERR(regmap)) 94 + return dev_err_probe(dev, PTR_ERR(regmap), 95 + "Failed to init regmap\n"); 96 + 97 + ret = devm_regmap_add_irq_chip(dev, regmap, i2c->irq, IRQF_ONESHOT, 0, 98 + &rt5120_irq_chip, &irq_data); 99 + if (ret) 100 + return dev_err_probe(dev, ret, "Failed to add IRQ chip\n"); 101 + 102 + return devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, rt5120_devs, 103 + ARRAY_SIZE(rt5120_devs), NULL, 0, 104 + regmap_irq_get_domain(irq_data)); 105 + } 106 + 107 + static const struct of_device_id rt5120_device_match_table[] = { 108 + { .compatible = "richtek,rt5120" }, 109 + {} 110 + }; 111 + MODULE_DEVICE_TABLE(of, rt5120_device_match_table); 112 + 113 + static struct i2c_driver rt5120_driver = { 114 + .driver = { 115 + .name = "rt5120", 116 + .of_match_table = rt5120_device_match_table, 117 + }, 118 + .probe_new = rt5120_probe, 119 + }; 120 + module_i2c_driver(rt5120_driver); 121 + 122 + MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>"); 123 + MODULE_DESCRIPTION("Richtek RT5120 I2C driver"); 124 + MODULE_LICENSE("GPL v2");
+6 -1
drivers/mfd/sm501.c
··· 1720 1720 1721 1721 static int __init sm501_base_init(void) 1722 1722 { 1723 - platform_driver_register(&sm501_plat_driver); 1723 + int ret; 1724 + 1725 + ret = platform_driver_register(&sm501_plat_driver); 1726 + if (ret < 0) 1727 + return ret; 1728 + 1724 1729 return pci_register_driver(&sm501_pci_driver); 1725 1730 } 1726 1731
+18 -31
drivers/mfd/stmpe.c
··· 8 8 */ 9 9 10 10 #include <linux/err.h> 11 - #include <linux/gpio.h> 11 + #include <linux/gpio/consumer.h> 12 12 #include <linux/export.h> 13 13 #include <linux/kernel.h> 14 14 #include <linux/interrupt.h> 15 15 #include <linux/irq.h> 16 16 #include <linux/irqdomain.h> 17 17 #include <linux/of.h> 18 - #include <linux/of_gpio.h> 19 18 #include <linux/pm.h> 20 19 #include <linux/slab.h> 21 20 #include <linux/mfd/core.h> ··· 29 30 * @irq_trigger: IRQ trigger to use for the interrupt to the host 30 31 * @autosleep: bool to enable/disable stmpe autosleep 31 32 * @autosleep_timeout: inactivity timeout in milliseconds for autosleep 32 - * @irq_over_gpio: true if gpio is used to get irq 33 - * @irq_gpio: gpio number over which irq will be requested (significant only if 34 - * irq_over_gpio is true) 35 33 */ 36 34 struct stmpe_platform_data { 37 35 int id; 38 36 unsigned int blocks; 39 37 unsigned int irq_trigger; 40 38 bool autosleep; 41 - bool irq_over_gpio; 42 - int irq_gpio; 43 39 int autosleep_timeout; 44 40 }; 45 41 ··· 1343 1349 if (pdata->id < 0) 1344 1350 pdata->id = -1; 1345 1351 1346 - pdata->irq_gpio = of_get_named_gpio_flags(np, "irq-gpio", 0, 1347 - &pdata->irq_trigger); 1348 - if (gpio_is_valid(pdata->irq_gpio)) 1349 - pdata->irq_over_gpio = 1; 1350 - else 1351 - pdata->irq_trigger = IRQF_TRIGGER_NONE; 1352 - 1353 1352 of_property_read_u32(np, "st,autosleep-timeout", 1354 1353 &pdata->autosleep_timeout); 1355 1354 1356 1355 pdata->autosleep = (pdata->autosleep_timeout) ? true : false; 1357 1356 1358 1357 for_each_available_child_of_node(np, child) { 1359 - if (of_node_name_eq(child, "stmpe_gpio")) { 1358 + if (of_device_is_compatible(child, stmpe_gpio_cell.of_compatible)) 1360 1359 pdata->blocks |= STMPE_BLOCK_GPIO; 1361 - } else if (of_node_name_eq(child, "stmpe_keypad")) { 1360 + else if (of_device_is_compatible(child, stmpe_keypad_cell.of_compatible)) 1362 1361 pdata->blocks |= STMPE_BLOCK_KEYPAD; 1363 - } else if (of_node_name_eq(child, "stmpe_touchscreen")) { 1362 + else if (of_device_is_compatible(child, stmpe_ts_cell.of_compatible)) 1364 1363 pdata->blocks |= STMPE_BLOCK_TOUCHSCREEN; 1365 - } else if (of_node_name_eq(child, "stmpe_adc")) { 1364 + else if (of_device_is_compatible(child, stmpe_adc_cell.of_compatible)) 1366 1365 pdata->blocks |= STMPE_BLOCK_ADC; 1367 - } else if (of_node_name_eq(child, "stmpe_pwm")) { 1366 + else if (of_device_is_compatible(child, stmpe_pwm_cell.of_compatible)) 1368 1367 pdata->blocks |= STMPE_BLOCK_PWM; 1369 - } else if (of_node_name_eq(child, "stmpe_rotator")) { 1370 - pdata->blocks |= STMPE_BLOCK_ROTATOR; 1371 - } 1372 1368 } 1373 1369 } 1374 1370 ··· 1368 1384 struct stmpe_platform_data *pdata; 1369 1385 struct device_node *np = ci->dev->of_node; 1370 1386 struct stmpe *stmpe; 1387 + struct gpio_desc *irq_gpio; 1371 1388 int ret; 1372 1389 u32 val; 1373 1390 ··· 1422 1437 if (ci->init) 1423 1438 ci->init(stmpe); 1424 1439 1425 - if (pdata->irq_over_gpio) { 1426 - ret = devm_gpio_request_one(ci->dev, pdata->irq_gpio, 1427 - GPIOF_DIR_IN, "stmpe"); 1428 - if (ret) { 1429 - dev_err(stmpe->dev, "failed to request IRQ GPIO: %d\n", 1430 - ret); 1431 - return ret; 1432 - } 1440 + irq_gpio = devm_gpiod_get_optional(ci->dev, "irq", GPIOD_ASIS); 1441 + ret = PTR_ERR_OR_ZERO(irq_gpio); 1442 + if (ret) { 1443 + dev_err(stmpe->dev, "failed to request IRQ GPIO: %d\n", ret); 1444 + return ret; 1445 + } 1433 1446 1434 - stmpe->irq = gpio_to_irq(pdata->irq_gpio); 1447 + if (irq_gpio) { 1448 + stmpe->irq = gpiod_to_irq(irq_gpio); 1449 + pdata->irq_trigger = gpiod_is_active_low(irq_gpio) ? 1450 + IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH; 1435 1451 } else { 1436 1452 stmpe->irq = ci->irq; 1453 + pdata->irq_trigger = IRQF_TRIGGER_NONE; 1437 1454 } 1438 1455 1439 1456 if (stmpe->irq < 0) {
-8
drivers/mfd/syscon.c
··· 66 66 goto err_map; 67 67 } 68 68 69 - /* Parse the device's DT node for an endianness specification */ 70 - if (of_property_read_bool(np, "big-endian")) 71 - syscon_config.val_format_endian = REGMAP_ENDIAN_BIG; 72 - else if (of_property_read_bool(np, "little-endian")) 73 - syscon_config.val_format_endian = REGMAP_ENDIAN_LITTLE; 74 - else if (of_property_read_bool(np, "native-endian")) 75 - syscon_config.val_format_endian = REGMAP_ENDIAN_NATIVE; 76 - 77 69 /* 78 70 * search for reg-io-width property in DT. If it is not provided, 79 71 * default to 4 bytes. regmap_init_mmio will return an error if values
+1 -1
drivers/mfd/twl-core.c
··· 882 882 * SR_I2C_SCL_CTRL_PU(bit 4)=0 and SR_I2C_SDA_CTRL_PU(bit 6)=0. 883 883 * 884 884 * Also, always enable SmartReflex bit as that's needed for omaps to 885 - * to do anything over I2C4 for voltage scaling even if SmartReflex 885 + * do anything over I2C4 for voltage scaling even if SmartReflex 886 886 * is disabled. Without the SmartReflex bit omap sys_clkreq idle 887 887 * signal will never trigger for retention idle. 888 888 */
+1
drivers/mfd/twl4030-irq.c
··· 14 14 * by syed khasim <x0khasim@ti.com> 15 15 */ 16 16 17 + #include <linux/device.h> 17 18 #include <linux/export.h> 18 19 #include <linux/interrupt.h> 19 20 #include <linux/irq.h>
+6
drivers/power/supply/Kconfig
··· 708 708 charge management and system power path management devices for single 709 709 cell Li-ion and Li-polymer batteries. 710 710 711 + config CHARGER_RK817 712 + tristate "Rockchip RK817 PMIC Battery Charger" 713 + depends on MFD_RK808 714 + help 715 + Say Y to include support for Rockchip RK817 Battery Charger. 716 + 711 717 config CHARGER_SMB347 712 718 tristate "Summit Microelectronics SMB3XX Battery Charger" 713 719 depends on I2C
+1
drivers/power/supply/Makefile
··· 91 91 obj-$(CONFIG_CHARGER_BQ25890) += bq25890_charger.o 92 92 obj-$(CONFIG_CHARGER_BQ25980) += bq25980_charger.o 93 93 obj-$(CONFIG_CHARGER_BQ256XX) += bq256xx_charger.o 94 + obj-$(CONFIG_CHARGER_RK817) += rk817_charger.o 94 95 obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o 95 96 obj-$(CONFIG_CHARGER_TPS65090) += tps65090-charger.o 96 97 obj-$(CONFIG_CHARGER_TPS65217) += tps65217_charger.o
+1211
drivers/power/supply/rk817_charger.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Charger Driver for Rockchip rk817 4 + * 5 + * Copyright (c) 2021 Maya Matuszczyk <maccraft123mc@gmail.com> 6 + * 7 + * Authors: Maya Matuszczyk <maccraft123mc@gmail.com> 8 + * Chris Morgan <macromorgan@hotmail.com> 9 + */ 10 + 11 + #include <asm/unaligned.h> 12 + #include <linux/devm-helpers.h> 13 + #include <linux/mfd/rk808.h> 14 + #include <linux/irq.h> 15 + #include <linux/of.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/power_supply.h> 18 + #include <linux/regmap.h> 19 + 20 + /* Charging statuses reported by hardware register */ 21 + enum rk817_charge_status { 22 + CHRG_OFF, 23 + DEAD_CHRG, 24 + TRICKLE_CHRG, 25 + CC_OR_CV_CHRG, 26 + CHARGE_FINISH, 27 + USB_OVER_VOL, 28 + BAT_TMP_ERR, 29 + BAT_TIM_ERR, 30 + }; 31 + 32 + /* 33 + * Max charging current read to/written from hardware register. 34 + * Note how highest value corresponding to 0x7 is the lowest 35 + * current, this is per the datasheet. 36 + */ 37 + enum rk817_chg_cur { 38 + CHG_1A, 39 + CHG_1_5A, 40 + CHG_2A, 41 + CHG_2_5A, 42 + CHG_2_75A, 43 + CHG_3A, 44 + CHG_3_5A, 45 + CHG_0_5A, 46 + }; 47 + 48 + struct rk817_charger { 49 + struct device *dev; 50 + struct rk808 *rk808; 51 + 52 + struct power_supply *bat_ps; 53 + struct power_supply *chg_ps; 54 + bool plugged_in; 55 + bool battery_present; 56 + 57 + /* 58 + * voltage_k and voltage_b values are used to calibrate the ADC 59 + * voltage readings. While they are documented in the BSP kernel and 60 + * datasheet as voltage_k and voltage_b, there is no further 61 + * information explaining them in more detail. 62 + */ 63 + 64 + uint32_t voltage_k; 65 + uint32_t voltage_b; 66 + 67 + /* 68 + * soc - state of charge - like the BSP this is stored as a percentage, 69 + * to the thousandth. BSP has a display state of charge (dsoc) and a 70 + * remaining state of charge (rsoc). This value will be used for both 71 + * purposes here so we don't do any fancy math to try and "smooth" the 72 + * charge and just report it as it is. Note for example an soc of 100 73 + * is stored as 100000, an soc of 50 is stored as 50000, etc. 74 + */ 75 + int soc; 76 + 77 + /* 78 + * Capacity of battery when fully charged, equal or less than design 79 + * capacity depending upon wear. BSP kernel saves to nvram in mAh, 80 + * so this value is in mAh not the standard uAh. 81 + */ 82 + int fcc_mah; 83 + 84 + /* 85 + * Calibrate the SOC on a fully charged battery, this way we can use 86 + * the calibrated SOC value to correct for columb counter drift. 87 + */ 88 + bool soc_cal; 89 + 90 + /* Implementation specific immutable properties from device tree */ 91 + int res_div; 92 + int sleep_enter_current_ua; 93 + int sleep_filter_current_ua; 94 + int bat_charge_full_design_uah; 95 + int bat_voltage_min_design_uv; 96 + int bat_voltage_max_design_uv; 97 + 98 + /* Values updated periodically by driver for display. */ 99 + int charge_now_uah; 100 + int volt_avg_uv; 101 + int cur_avg_ua; 102 + int max_chg_cur_ua; 103 + int max_chg_volt_uv; 104 + int charge_status; 105 + int charger_input_volt_avg_uv; 106 + 107 + /* Work queue to periodically update values. */ 108 + struct delayed_work work; 109 + }; 110 + 111 + /* ADC coefficients extracted from BSP kernel */ 112 + #define ADC_TO_CURRENT(adc_value, res_div) \ 113 + (adc_value * 172 / res_div) 114 + 115 + #define CURRENT_TO_ADC(current, samp_res) \ 116 + (current * samp_res / 172) 117 + 118 + #define CHARGE_TO_ADC(capacity, res_div) \ 119 + (capacity * res_div * 3600 / 172 * 1000) 120 + 121 + #define ADC_TO_CHARGE_UAH(adc_value, res_div) \ 122 + (adc_value / 3600 * 172 / res_div) 123 + 124 + static u8 rk817_chg_cur_to_reg(u32 chg_cur_ma) 125 + { 126 + if (chg_cur_ma >= 3500) 127 + return CHG_3_5A; 128 + else if (chg_cur_ma >= 3000) 129 + return CHG_3A; 130 + else if (chg_cur_ma >= 2750) 131 + return CHG_2_75A; 132 + else if (chg_cur_ma >= 2500) 133 + return CHG_2_5A; 134 + else if (chg_cur_ma >= 2000) 135 + return CHG_2A; 136 + else if (chg_cur_ma >= 1500) 137 + return CHG_1_5A; 138 + else if (chg_cur_ma >= 1000) 139 + return CHG_1A; 140 + else if (chg_cur_ma >= 500) 141 + return CHG_0_5A; 142 + else 143 + return -EINVAL; 144 + } 145 + 146 + static int rk817_chg_cur_from_reg(u8 reg) 147 + { 148 + switch (reg) { 149 + case CHG_0_5A: 150 + return 500000; 151 + case CHG_1A: 152 + return 1000000; 153 + case CHG_1_5A: 154 + return 1500000; 155 + case CHG_2A: 156 + return 2000000; 157 + case CHG_2_5A: 158 + return 2500000; 159 + case CHG_2_75A: 160 + return 2750000; 161 + case CHG_3A: 162 + return 3000000; 163 + case CHG_3_5A: 164 + return 3500000; 165 + default: 166 + return -EINVAL; 167 + } 168 + } 169 + 170 + static void rk817_bat_calib_vol(struct rk817_charger *charger) 171 + { 172 + uint32_t vcalib0 = 0; 173 + uint32_t vcalib1 = 0; 174 + u8 bulk_reg[2]; 175 + 176 + /* calibrate voltage */ 177 + regmap_bulk_read(charger->rk808->regmap, RK817_GAS_GAUGE_VCALIB0_H, 178 + bulk_reg, 2); 179 + vcalib0 = get_unaligned_be16(bulk_reg); 180 + 181 + regmap_bulk_read(charger->rk808->regmap, RK817_GAS_GAUGE_VCALIB1_H, 182 + bulk_reg, 2); 183 + vcalib1 = get_unaligned_be16(bulk_reg); 184 + 185 + /* values were taken from BSP kernel */ 186 + charger->voltage_k = (4025 - 2300) * 1000 / 187 + ((vcalib1 - vcalib0) ? (vcalib1 - vcalib0) : 1); 188 + charger->voltage_b = 4025 - (charger->voltage_k * vcalib1) / 1000; 189 + } 190 + 191 + static void rk817_bat_calib_cur(struct rk817_charger *charger) 192 + { 193 + u8 bulk_reg[2]; 194 + 195 + /* calibrate current */ 196 + regmap_bulk_read(charger->rk808->regmap, RK817_GAS_GAUGE_IOFFSET_H, 197 + bulk_reg, 2); 198 + regmap_bulk_write(charger->rk808->regmap, RK817_GAS_GAUGE_CAL_OFFSET_H, 199 + bulk_reg, 2); 200 + } 201 + 202 + /* 203 + * note that only the fcc_mah is really used by this driver, the other values 204 + * are to ensure we can remain backwards compatible with the BSP kernel. 205 + */ 206 + static int rk817_record_battery_nvram_values(struct rk817_charger *charger) 207 + { 208 + u8 bulk_reg[3]; 209 + int ret, rsoc; 210 + 211 + /* 212 + * write the soc value to the nvram location used by the BSP kernel 213 + * for the dsoc value. 214 + */ 215 + put_unaligned_le24(charger->soc, bulk_reg); 216 + ret = regmap_bulk_write(charger->rk808->regmap, RK817_GAS_GAUGE_BAT_R1, 217 + bulk_reg, 3); 218 + if (ret < 0) 219 + return ret; 220 + /* 221 + * write the remaining capacity in mah to the nvram location used by 222 + * the BSP kernel for the rsoc value. 223 + */ 224 + rsoc = (charger->soc * charger->fcc_mah) / 100000; 225 + put_unaligned_le24(rsoc, bulk_reg); 226 + ret = regmap_bulk_write(charger->rk808->regmap, RK817_GAS_GAUGE_DATA0, 227 + bulk_reg, 3); 228 + if (ret < 0) 229 + return ret; 230 + /* write the fcc_mah in mAh, just as the BSP kernel does. */ 231 + put_unaligned_le24(charger->fcc_mah, bulk_reg); 232 + ret = regmap_bulk_write(charger->rk808->regmap, RK817_GAS_GAUGE_DATA3, 233 + bulk_reg, 3); 234 + if (ret < 0) 235 + return ret; 236 + 237 + return 0; 238 + } 239 + 240 + static int rk817_bat_calib_cap(struct rk817_charger *charger) 241 + { 242 + struct rk808 *rk808 = charger->rk808; 243 + int tmp, charge_now, charge_now_adc, volt_avg; 244 + u8 bulk_reg[4]; 245 + 246 + /* Calibrate the soc and fcc on a fully charged battery */ 247 + 248 + if (charger->charge_status == CHARGE_FINISH && (!charger->soc_cal)) { 249 + /* 250 + * soc should be 100000 and columb counter should show the full 251 + * charge capacity. Note that if the device is unplugged for a 252 + * period of several days the columb counter will have a large 253 + * margin of error, so setting it back to the full charge on 254 + * a completed charge cycle should correct this (my device was 255 + * showing 33% battery after 3 days unplugged when it should 256 + * have been closer to 95% based on voltage and charge 257 + * current). 258 + */ 259 + 260 + charger->soc = 100000; 261 + charge_now_adc = CHARGE_TO_ADC(charger->fcc_mah, 262 + charger->res_div); 263 + put_unaligned_be32(charge_now_adc, bulk_reg); 264 + regmap_bulk_write(rk808->regmap, RK817_GAS_GAUGE_Q_INIT_H3, 265 + bulk_reg, 4); 266 + 267 + charger->soc_cal = 1; 268 + dev_dbg(charger->dev, 269 + "Fully charged. SOC is %d, full capacity is %d\n", 270 + charger->soc, charger->fcc_mah * 1000); 271 + } 272 + 273 + /* 274 + * The columb counter can drift up slightly, so we should correct for 275 + * it. But don't correct it until we're at 100% soc. 276 + */ 277 + if (charger->charge_status == CHARGE_FINISH && charger->soc_cal) { 278 + regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_Q_PRES_H3, 279 + bulk_reg, 4); 280 + charge_now_adc = get_unaligned_be32(bulk_reg); 281 + if (charge_now_adc < 0) 282 + return charge_now_adc; 283 + charge_now = ADC_TO_CHARGE_UAH(charge_now_adc, 284 + charger->res_div); 285 + 286 + /* 287 + * Re-init columb counter with updated values to correct drift. 288 + */ 289 + if (charge_now / 1000 > charger->fcc_mah) { 290 + dev_dbg(charger->dev, 291 + "Recalibrating columb counter to %d uah\n", 292 + charge_now); 293 + /* 294 + * Order of operations matters here to ensure we keep 295 + * enough precision until the last step to keep from 296 + * making needless updates to columb counter. 297 + */ 298 + charge_now_adc = CHARGE_TO_ADC(charger->fcc_mah, 299 + charger->res_div); 300 + put_unaligned_be32(charge_now_adc, bulk_reg); 301 + regmap_bulk_write(rk808->regmap, 302 + RK817_GAS_GAUGE_Q_INIT_H3, 303 + bulk_reg, 4); 304 + } 305 + } 306 + 307 + /* 308 + * Calibrate the fully charged capacity when we previously had a full 309 + * battery (soc_cal = 1) and are now empty (at or below minimum design 310 + * voltage). If our columb counter is still positive, subtract that 311 + * from our fcc value to get a calibrated fcc, and if our columb 312 + * counter is negative add that to our fcc (but not to exceed our 313 + * design capacity). 314 + */ 315 + regmap_bulk_read(charger->rk808->regmap, RK817_GAS_GAUGE_BAT_VOL_H, 316 + bulk_reg, 2); 317 + tmp = get_unaligned_be16(bulk_reg); 318 + volt_avg = (charger->voltage_k * tmp) + 1000 * charger->voltage_b; 319 + if (volt_avg <= charger->bat_voltage_min_design_uv && 320 + charger->soc_cal) { 321 + regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_Q_PRES_H3, 322 + bulk_reg, 4); 323 + charge_now_adc = get_unaligned_be32(bulk_reg); 324 + charge_now = ADC_TO_CHARGE_UAH(charge_now_adc, 325 + charger->res_div); 326 + /* 327 + * Note, if charge_now is negative this will add it (what we 328 + * want) and if it's positive this will subtract (also what 329 + * we want). 330 + */ 331 + charger->fcc_mah = charger->fcc_mah - (charge_now / 1000); 332 + 333 + dev_dbg(charger->dev, 334 + "Recalibrating full charge capacity to %d uah\n", 335 + charger->fcc_mah * 1000); 336 + } 337 + 338 + rk817_record_battery_nvram_values(charger); 339 + 340 + return 0; 341 + } 342 + 343 + static void rk817_read_props(struct rk817_charger *charger) 344 + { 345 + int tmp, reg; 346 + u8 bulk_reg[4]; 347 + 348 + /* 349 + * Recalibrate voltage and current readings if we need to BSP does both 350 + * on CUR_CALIB_UPD, ignoring VOL_CALIB_UPD. Curiously enough, both 351 + * documentation and the BSP show that you perform an update if bit 7 352 + * is 1, but you clear the status by writing a 1 to bit 7. 353 + */ 354 + regmap_read(charger->rk808->regmap, RK817_GAS_GAUGE_ADC_CONFIG1, &reg); 355 + if (reg & RK817_VOL_CUR_CALIB_UPD) { 356 + rk817_bat_calib_cur(charger); 357 + rk817_bat_calib_vol(charger); 358 + regmap_write_bits(charger->rk808->regmap, 359 + RK817_GAS_GAUGE_ADC_CONFIG1, 360 + RK817_VOL_CUR_CALIB_UPD, 361 + RK817_VOL_CUR_CALIB_UPD); 362 + } 363 + 364 + /* Update reported charge. */ 365 + regmap_bulk_read(charger->rk808->regmap, RK817_GAS_GAUGE_Q_PRES_H3, 366 + bulk_reg, 4); 367 + tmp = get_unaligned_be32(bulk_reg); 368 + charger->charge_now_uah = ADC_TO_CHARGE_UAH(tmp, charger->res_div); 369 + if (charger->charge_now_uah < 0) 370 + charger->charge_now_uah = 0; 371 + if (charger->charge_now_uah > charger->fcc_mah * 1000) 372 + charger->charge_now_uah = charger->fcc_mah * 1000; 373 + 374 + /* Update soc based on reported charge. */ 375 + charger->soc = charger->charge_now_uah * 100 / charger->fcc_mah; 376 + 377 + /* Update reported voltage. */ 378 + regmap_bulk_read(charger->rk808->regmap, RK817_GAS_GAUGE_BAT_VOL_H, 379 + bulk_reg, 2); 380 + tmp = get_unaligned_be16(bulk_reg); 381 + charger->volt_avg_uv = (charger->voltage_k * tmp) + 1000 * 382 + charger->voltage_b; 383 + 384 + /* 385 + * Update reported current. Note value from registers is a signed 16 386 + * bit int. 387 + */ 388 + regmap_bulk_read(charger->rk808->regmap, RK817_GAS_GAUGE_BAT_CUR_H, 389 + bulk_reg, 2); 390 + tmp = (short int)get_unaligned_be16(bulk_reg); 391 + charger->cur_avg_ua = ADC_TO_CURRENT(tmp, charger->res_div); 392 + 393 + /* 394 + * Update the max charge current. This value shouldn't change, but we 395 + * can read it to report what the PMIC says it is instead of simply 396 + * returning the default value. 397 + */ 398 + regmap_read(charger->rk808->regmap, RK817_PMIC_CHRG_OUT, &reg); 399 + charger->max_chg_cur_ua = 400 + rk817_chg_cur_from_reg(reg & RK817_CHRG_CUR_SEL); 401 + 402 + /* 403 + * Update max charge voltage. Like the max charge current this value 404 + * shouldn't change, but we can report what the PMIC says. 405 + */ 406 + regmap_read(charger->rk808->regmap, RK817_PMIC_CHRG_OUT, &reg); 407 + charger->max_chg_volt_uv = ((((reg & RK817_CHRG_VOL_SEL) >> 4) * 408 + 50000) + 4100000); 409 + 410 + /* Check if battery still present. */ 411 + regmap_read(charger->rk808->regmap, RK817_PMIC_CHRG_STS, &reg); 412 + charger->battery_present = (reg & RK817_BAT_EXS); 413 + 414 + /* Get which type of charge we are using (if any). */ 415 + regmap_read(charger->rk808->regmap, RK817_PMIC_CHRG_STS, &reg); 416 + charger->charge_status = (reg >> 4) & 0x07; 417 + 418 + /* 419 + * Get charger input voltage. Note that on my example hardware (an 420 + * Odroid Go Advance) the voltage of the power connector is measured 421 + * on the register labelled USB in the datasheet; I don't know if this 422 + * is how it is designed or just a quirk of the implementation. I 423 + * believe this will also measure the voltage of the USB output when in 424 + * OTG mode, if that is the case we may need to change this in the 425 + * future to return 0 if the power supply status is offline (I can't 426 + * test this with my current implementation. Also, when the voltage 427 + * should be zero sometimes the ADC still shows a single bit (which 428 + * would register as 20000uv). When this happens set it to 0. 429 + */ 430 + regmap_bulk_read(charger->rk808->regmap, RK817_GAS_GAUGE_USB_VOL_H, 431 + bulk_reg, 2); 432 + reg = get_unaligned_be16(bulk_reg); 433 + if (reg > 1) { 434 + tmp = ((charger->voltage_k * reg / 1000 + charger->voltage_b) * 435 + 60 / 46); 436 + charger->charger_input_volt_avg_uv = tmp * 1000; 437 + } else { 438 + charger->charger_input_volt_avg_uv = 0; 439 + } 440 + 441 + /* Calibrate battery capacity and soc. */ 442 + rk817_bat_calib_cap(charger); 443 + } 444 + 445 + static int rk817_bat_get_prop(struct power_supply *ps, 446 + enum power_supply_property prop, 447 + union power_supply_propval *val) 448 + { 449 + struct rk817_charger *charger = power_supply_get_drvdata(ps); 450 + 451 + switch (prop) { 452 + case POWER_SUPPLY_PROP_PRESENT: 453 + val->intval = charger->battery_present; 454 + break; 455 + case POWER_SUPPLY_PROP_STATUS: 456 + if (charger->cur_avg_ua < 0) { 457 + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 458 + break; 459 + } 460 + switch (charger->charge_status) { 461 + case CHRG_OFF: 462 + val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 463 + break; 464 + /* 465 + * Dead charge is documented, but not explained. I never 466 + * observed it but assume it's a pre-charge for a dead 467 + * battery. 468 + */ 469 + case DEAD_CHRG: 470 + case TRICKLE_CHRG: 471 + case CC_OR_CV_CHRG: 472 + val->intval = POWER_SUPPLY_STATUS_CHARGING; 473 + break; 474 + case CHARGE_FINISH: 475 + val->intval = POWER_SUPPLY_STATUS_FULL; 476 + break; 477 + default: 478 + val->intval = POWER_SUPPLY_STATUS_UNKNOWN; 479 + return -EINVAL; 480 + 481 + } 482 + break; 483 + case POWER_SUPPLY_PROP_CHARGE_TYPE: 484 + switch (charger->charge_status) { 485 + case CHRG_OFF: 486 + case CHARGE_FINISH: 487 + val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE; 488 + break; 489 + case TRICKLE_CHRG: 490 + val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; 491 + break; 492 + case DEAD_CHRG: 493 + case CC_OR_CV_CHRG: 494 + val->intval = POWER_SUPPLY_CHARGE_TYPE_STANDARD; 495 + break; 496 + default: 497 + val->intval = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN; 498 + break; 499 + } 500 + break; 501 + case POWER_SUPPLY_PROP_CHARGE_FULL: 502 + val->intval = charger->fcc_mah * 1000; 503 + break; 504 + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 505 + val->intval = charger->bat_charge_full_design_uah; 506 + break; 507 + case POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN: 508 + val->intval = 0; 509 + break; 510 + case POWER_SUPPLY_PROP_CHARGE_NOW: 511 + val->intval = charger->charge_now_uah; 512 + break; 513 + case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 514 + val->intval = charger->bat_voltage_min_design_uv; 515 + break; 516 + case POWER_SUPPLY_PROP_CAPACITY: 517 + /* Add 500 so that values like 99999 are 100% not 99%. */ 518 + val->intval = (charger->soc + 500) / 1000; 519 + if (val->intval > 100) 520 + val->intval = 100; 521 + if (val->intval < 0) 522 + val->intval = 0; 523 + break; 524 + case POWER_SUPPLY_PROP_VOLTAGE_AVG: 525 + val->intval = charger->volt_avg_uv; 526 + break; 527 + case POWER_SUPPLY_PROP_CURRENT_AVG: 528 + val->intval = charger->cur_avg_ua; 529 + break; 530 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 531 + val->intval = charger->max_chg_cur_ua; 532 + break; 533 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: 534 + val->intval = charger->max_chg_volt_uv; 535 + break; 536 + case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 537 + val->intval = charger->bat_voltage_max_design_uv; 538 + break; 539 + default: 540 + return -EINVAL; 541 + } 542 + return 0; 543 + } 544 + 545 + static int rk817_chg_get_prop(struct power_supply *ps, 546 + enum power_supply_property prop, 547 + union power_supply_propval *val) 548 + { 549 + struct rk817_charger *charger = power_supply_get_drvdata(ps); 550 + 551 + switch (prop) { 552 + case POWER_SUPPLY_PROP_ONLINE: 553 + val->intval = charger->plugged_in; 554 + break; 555 + case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 556 + /* max voltage from datasheet at 5.5v (default 5.0v) */ 557 + val->intval = 5500000; 558 + break; 559 + case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 560 + /* min voltage from datasheet at 3.8v (default 5.0v) */ 561 + val->intval = 3800000; 562 + break; 563 + case POWER_SUPPLY_PROP_VOLTAGE_AVG: 564 + val->intval = charger->charger_input_volt_avg_uv; 565 + break; 566 + /* 567 + * While it's possible that other implementations could use different 568 + * USB types, the current implementation for this PMIC (the Odroid Go 569 + * Advance) only uses a dedicated charging port with no rx/tx lines. 570 + */ 571 + case POWER_SUPPLY_PROP_USB_TYPE: 572 + val->intval = POWER_SUPPLY_USB_TYPE_DCP; 573 + break; 574 + default: 575 + return -EINVAL; 576 + } 577 + return 0; 578 + 579 + } 580 + 581 + static irqreturn_t rk817_plug_in_isr(int irq, void *cg) 582 + { 583 + struct rk817_charger *charger; 584 + 585 + charger = (struct rk817_charger *)cg; 586 + charger->plugged_in = 1; 587 + power_supply_changed(charger->chg_ps); 588 + power_supply_changed(charger->bat_ps); 589 + /* try to recalibrate capacity if we hit full charge. */ 590 + charger->soc_cal = 0; 591 + 592 + rk817_read_props(charger); 593 + 594 + dev_dbg(charger->dev, "Power Cord Inserted\n"); 595 + 596 + return IRQ_HANDLED; 597 + } 598 + 599 + static irqreturn_t rk817_plug_out_isr(int irq, void *cg) 600 + { 601 + struct rk817_charger *charger; 602 + struct rk808 *rk808; 603 + 604 + charger = (struct rk817_charger *)cg; 605 + rk808 = charger->rk808; 606 + charger->plugged_in = 0; 607 + power_supply_changed(charger->bat_ps); 608 + power_supply_changed(charger->chg_ps); 609 + 610 + /* 611 + * For some reason the bits of RK817_PMIC_CHRG_IN reset whenever the 612 + * power cord is unplugged. This was not documented in the BSP kernel 613 + * or the datasheet and only discovered by trial and error. Set minimum 614 + * USB input voltage to 4.5v and enable USB voltage input limit. 615 + */ 616 + regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, 617 + RK817_USB_VLIM_SEL, (0x05 << 4)); 618 + regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_VLIM_EN, 619 + (0x01 << 7)); 620 + 621 + /* 622 + * Set average USB input current limit to 1.5A and enable USB current 623 + * input limit. 624 + */ 625 + regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, 626 + RK817_USB_ILIM_SEL, 0x03); 627 + regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_ILIM_EN, 628 + (0x01 << 3)); 629 + 630 + rk817_read_props(charger); 631 + 632 + dev_dbg(charger->dev, "Power Cord Removed\n"); 633 + 634 + return IRQ_HANDLED; 635 + } 636 + 637 + static enum power_supply_property rk817_bat_props[] = { 638 + POWER_SUPPLY_PROP_PRESENT, 639 + POWER_SUPPLY_PROP_STATUS, 640 + POWER_SUPPLY_PROP_CHARGE_TYPE, 641 + POWER_SUPPLY_PROP_CHARGE_FULL, 642 + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 643 + POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN, 644 + POWER_SUPPLY_PROP_CHARGE_NOW, 645 + POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, 646 + POWER_SUPPLY_PROP_VOLTAGE_AVG, 647 + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, 648 + POWER_SUPPLY_PROP_CURRENT_AVG, 649 + POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 650 + POWER_SUPPLY_PROP_CAPACITY, 651 + POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 652 + }; 653 + 654 + static enum power_supply_property rk817_chg_props[] = { 655 + POWER_SUPPLY_PROP_ONLINE, 656 + POWER_SUPPLY_PROP_USB_TYPE, 657 + POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 658 + POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 659 + POWER_SUPPLY_PROP_VOLTAGE_AVG, 660 + }; 661 + 662 + static enum power_supply_usb_type rk817_usb_type[] = { 663 + POWER_SUPPLY_USB_TYPE_DCP, 664 + POWER_SUPPLY_USB_TYPE_UNKNOWN, 665 + }; 666 + 667 + static const struct power_supply_desc rk817_bat_desc = { 668 + .name = "rk817-battery", 669 + .type = POWER_SUPPLY_TYPE_BATTERY, 670 + .properties = rk817_bat_props, 671 + .num_properties = ARRAY_SIZE(rk817_bat_props), 672 + .get_property = rk817_bat_get_prop, 673 + }; 674 + 675 + static const struct power_supply_desc rk817_chg_desc = { 676 + .name = "rk817-charger", 677 + .type = POWER_SUPPLY_TYPE_USB, 678 + .usb_types = rk817_usb_type, 679 + .num_usb_types = ARRAY_SIZE(rk817_usb_type), 680 + .properties = rk817_chg_props, 681 + .num_properties = ARRAY_SIZE(rk817_chg_props), 682 + .get_property = rk817_chg_get_prop, 683 + }; 684 + 685 + static int rk817_read_battery_nvram_values(struct rk817_charger *charger) 686 + { 687 + u8 bulk_reg[3]; 688 + int ret; 689 + 690 + /* Read the nvram data for full charge capacity. */ 691 + ret = regmap_bulk_read(charger->rk808->regmap, 692 + RK817_GAS_GAUGE_DATA3, bulk_reg, 3); 693 + if (ret < 0) 694 + return ret; 695 + charger->fcc_mah = get_unaligned_le24(bulk_reg); 696 + 697 + /* 698 + * Sanity checking for values equal to zero or less than would be 699 + * practical for this device (BSP Kernel assumes 500mAH or less) for 700 + * practicality purposes. Also check if the value is too large and 701 + * correct it. 702 + */ 703 + if ((charger->fcc_mah < 500) || 704 + ((charger->fcc_mah * 1000) > charger->bat_charge_full_design_uah)) { 705 + dev_info(charger->dev, 706 + "Invalid NVRAM max charge, setting to %u uAH\n", 707 + charger->bat_charge_full_design_uah); 708 + charger->fcc_mah = charger->bat_charge_full_design_uah / 1000; 709 + } 710 + 711 + /* 712 + * Read the nvram for state of charge. Sanity check for values greater 713 + * than 100 (10000). If the value is off it should get corrected 714 + * automatically when the voltage drops to the min (soc is 0) or when 715 + * the battery is full (soc is 100). 716 + */ 717 + ret = regmap_bulk_read(charger->rk808->regmap, 718 + RK817_GAS_GAUGE_BAT_R1, bulk_reg, 3); 719 + if (ret < 0) 720 + return ret; 721 + charger->soc = get_unaligned_le24(bulk_reg); 722 + if (charger->soc > 10000) 723 + charger->soc = 10000; 724 + 725 + return 0; 726 + } 727 + 728 + static int 729 + rk817_read_or_set_full_charge_on_boot(struct rk817_charger *charger, 730 + struct power_supply_battery_info *bat_info) 731 + { 732 + struct rk808 *rk808 = charger->rk808; 733 + u8 bulk_reg[4]; 734 + u32 boot_voltage, boot_charge_mah, tmp; 735 + int ret, reg, off_time; 736 + bool first_boot; 737 + 738 + /* 739 + * Check if the battery is uninitalized. If it is, the columb counter 740 + * needs to be set up. 741 + */ 742 + ret = regmap_read(rk808->regmap, RK817_GAS_GAUGE_GG_STS, &reg); 743 + if (ret < 0) 744 + return ret; 745 + first_boot = reg & RK817_BAT_CON; 746 + /* 747 + * If the battery is uninitialized, use the poweron voltage and an ocv 748 + * lookup to guess our charge. The number won't be very accurate until 749 + * we hit either our minimum voltage (0%) or full charge (100%). 750 + */ 751 + if (first_boot) { 752 + regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_PWRON_VOL_H, 753 + bulk_reg, 2); 754 + tmp = get_unaligned_be16(bulk_reg); 755 + boot_voltage = (charger->voltage_k * tmp) + 756 + 1000 * charger->voltage_b; 757 + /* 758 + * Since only implementation has no working thermistor, assume 759 + * 20C for OCV lookup. If lookup fails, report error with OCV 760 + * table. 761 + */ 762 + charger->soc = power_supply_batinfo_ocv2cap(bat_info, 763 + boot_voltage, 764 + 20) * 1000; 765 + if (charger->soc < 0) 766 + charger->soc = 0; 767 + 768 + /* Guess that full charge capacity is the design capacity */ 769 + charger->fcc_mah = charger->bat_charge_full_design_uah / 1000; 770 + /* 771 + * Set battery as "set up". BSP driver uses this value even 772 + * though datasheet claims it's a read-only value. 773 + */ 774 + regmap_write_bits(rk808->regmap, RK817_GAS_GAUGE_GG_STS, 775 + RK817_BAT_CON, 0); 776 + /* Save nvram values */ 777 + ret = rk817_record_battery_nvram_values(charger); 778 + if (ret < 0) 779 + return ret; 780 + } else { 781 + ret = rk817_read_battery_nvram_values(charger); 782 + if (ret < 0) 783 + return ret; 784 + 785 + regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_Q_PRES_H3, 786 + bulk_reg, 4); 787 + tmp = get_unaligned_be32(bulk_reg); 788 + if (tmp < 0) 789 + tmp = 0; 790 + boot_charge_mah = ADC_TO_CHARGE_UAH(tmp, 791 + charger->res_div) / 1000; 792 + /* 793 + * Check if the columb counter has been off for more than 300 794 + * minutes as it tends to drift downward. If so, re-init soc 795 + * with the boot voltage instead. Note the unit values for the 796 + * OFF_CNT register appear to be in decaminutes and stops 797 + * counting at 2550 (0xFF) minutes. BSP kernel used OCV, but 798 + * for me occasionally that would show invalid values. Boot 799 + * voltage is only accurate for me on first poweron (not 800 + * reboots), but we shouldn't ever encounter an OFF_CNT more 801 + * than 0 on a reboot anyway. 802 + */ 803 + regmap_read(rk808->regmap, RK817_GAS_GAUGE_OFF_CNT, &off_time); 804 + if (off_time >= 30) { 805 + regmap_bulk_read(rk808->regmap, 806 + RK817_GAS_GAUGE_PWRON_VOL_H, 807 + bulk_reg, 2); 808 + tmp = get_unaligned_be16(bulk_reg); 809 + boot_voltage = (charger->voltage_k * tmp) + 810 + 1000 * charger->voltage_b; 811 + charger->soc = 812 + power_supply_batinfo_ocv2cap(bat_info, 813 + boot_voltage, 814 + 20) * 1000; 815 + } else { 816 + charger->soc = (boot_charge_mah * 1000 * 100 / 817 + charger->fcc_mah); 818 + } 819 + } 820 + 821 + regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_PWRON_VOL_H, 822 + bulk_reg, 2); 823 + tmp = get_unaligned_be16(bulk_reg); 824 + boot_voltage = (charger->voltage_k * tmp) + 1000 * charger->voltage_b; 825 + regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_Q_PRES_H3, 826 + bulk_reg, 4); 827 + tmp = get_unaligned_be32(bulk_reg); 828 + if (tmp < 0) 829 + tmp = 0; 830 + boot_charge_mah = ADC_TO_CHARGE_UAH(tmp, charger->res_div) / 1000; 831 + regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_OCV_VOL_H, 832 + bulk_reg, 2); 833 + tmp = get_unaligned_be16(bulk_reg); 834 + boot_voltage = (charger->voltage_k * tmp) + 1000 * charger->voltage_b; 835 + 836 + /* 837 + * Now we have our full charge capacity and soc, init the columb 838 + * counter. 839 + */ 840 + boot_charge_mah = charger->soc * charger->fcc_mah / 100 / 1000; 841 + if (boot_charge_mah > charger->fcc_mah) 842 + boot_charge_mah = charger->fcc_mah; 843 + tmp = CHARGE_TO_ADC(boot_charge_mah, charger->res_div); 844 + put_unaligned_be32(tmp, bulk_reg); 845 + ret = regmap_bulk_write(rk808->regmap, RK817_GAS_GAUGE_Q_INIT_H3, 846 + bulk_reg, 4); 847 + if (ret < 0) 848 + return ret; 849 + 850 + /* Set QMAX value to max design capacity. */ 851 + tmp = CHARGE_TO_ADC((charger->bat_charge_full_design_uah / 1000), 852 + charger->res_div); 853 + put_unaligned_be32(tmp, bulk_reg); 854 + ret = regmap_bulk_write(rk808->regmap, RK817_GAS_GAUGE_Q_MAX_H3, 855 + bulk_reg, 4); 856 + if (ret < 0) 857 + return ret; 858 + 859 + return 0; 860 + } 861 + 862 + static int rk817_battery_init(struct rk817_charger *charger, 863 + struct power_supply_battery_info *bat_info) 864 + { 865 + struct rk808 *rk808 = charger->rk808; 866 + u32 tmp, max_chg_vol_mv, max_chg_cur_ma; 867 + u8 max_chg_vol_reg, chg_term_i_reg, max_chg_cur_reg; 868 + int ret, chg_term_ma; 869 + u8 bulk_reg[2]; 870 + 871 + /* Get initial plug state */ 872 + regmap_read(rk808->regmap, RK817_SYS_STS, &tmp); 873 + charger->plugged_in = (tmp & RK817_PLUG_IN_STS); 874 + 875 + /* 876 + * Turn on all ADC functions to measure battery, USB, and sys voltage, 877 + * as well as batt temp. Note only tested implementation so far does 878 + * not use a battery with a thermistor. 879 + */ 880 + regmap_write(rk808->regmap, RK817_GAS_GAUGE_ADC_CONFIG0, 0xfc); 881 + 882 + /* 883 + * Set relax mode voltage sampling interval and ADC offset calibration 884 + * interval to 8 minutes to mirror BSP kernel. Set voltage and current 885 + * modes to average to mirror BSP kernel. 886 + */ 887 + regmap_write(rk808->regmap, RK817_GAS_GAUGE_GG_CON, 0x04); 888 + 889 + /* Calibrate voltage like the BSP does here. */ 890 + rk817_bat_calib_vol(charger); 891 + 892 + /* Write relax threshold, derived from sleep enter current. */ 893 + tmp = CURRENT_TO_ADC(charger->sleep_enter_current_ua, 894 + charger->res_div); 895 + put_unaligned_be16(tmp, bulk_reg); 896 + regmap_bulk_write(rk808->regmap, RK817_GAS_GAUGE_RELAX_THRE_H, 897 + bulk_reg, 2); 898 + 899 + /* Write sleep sample current, derived from sleep filter current. */ 900 + tmp = CURRENT_TO_ADC(charger->sleep_filter_current_ua, 901 + charger->res_div); 902 + put_unaligned_be16(tmp, bulk_reg); 903 + regmap_bulk_write(rk808->regmap, RK817_GAS_GAUGE_SLEEP_CON_SAMP_CUR_H, 904 + bulk_reg, 2); 905 + 906 + /* Restart battery relax voltage */ 907 + regmap_write_bits(rk808->regmap, RK817_GAS_GAUGE_GG_STS, 908 + RK817_RELAX_VOL_UPD, (0x0 << 2)); 909 + 910 + /* 911 + * Set OCV Threshold Voltage to 127.5mV. This was hard coded like this 912 + * in the BSP. 913 + */ 914 + regmap_write(rk808->regmap, RK817_GAS_GAUGE_OCV_THRE_VOL, 0xff); 915 + 916 + /* 917 + * Set maximum charging voltage to battery max voltage. Trying to be 918 + * incredibly safe with these value, as setting them wrong could 919 + * overcharge the battery, which would be very bad. 920 + */ 921 + max_chg_vol_mv = bat_info->constant_charge_voltage_max_uv / 1000; 922 + max_chg_cur_ma = bat_info->constant_charge_current_max_ua / 1000; 923 + 924 + if (max_chg_vol_mv < 4100) { 925 + return dev_err_probe(charger->dev, -EINVAL, 926 + "invalid max charger voltage, value %u unsupported\n", 927 + max_chg_vol_mv * 1000); 928 + } 929 + if (max_chg_vol_mv > 4450) { 930 + dev_info(charger->dev, 931 + "Setting max charge voltage to 4450000uv\n"); 932 + max_chg_vol_mv = 4450; 933 + } 934 + 935 + if (max_chg_cur_ma < 500) { 936 + return dev_err_probe(charger->dev, -EINVAL, 937 + "invalid max charger current, value %u unsupported\n", 938 + max_chg_cur_ma * 1000); 939 + } 940 + if (max_chg_cur_ma > 3500) 941 + dev_info(charger->dev, 942 + "Setting max charge current to 3500000ua\n"); 943 + 944 + /* 945 + * Now that the values are sanity checked, if we subtract 4100 from the 946 + * max voltage and divide by 50, we conviently get the exact value for 947 + * the registers, which are 4.1v, 4.15v, 4.2v, 4.25v, 4.3v, 4.35v, 948 + * 4.4v, and 4.45v; these correspond to values 0x00 through 0x07. 949 + */ 950 + max_chg_vol_reg = (max_chg_vol_mv - 4100) / 50; 951 + 952 + max_chg_cur_reg = rk817_chg_cur_to_reg(max_chg_cur_ma); 953 + 954 + if (max_chg_vol_reg < 0 || max_chg_vol_reg > 7) { 955 + return dev_err_probe(charger->dev, -EINVAL, 956 + "invalid max charger voltage, value %u unsupported\n", 957 + max_chg_vol_mv * 1000); 958 + } 959 + if (max_chg_cur_reg < 0 || max_chg_cur_reg > 7) { 960 + return dev_err_probe(charger->dev, -EINVAL, 961 + "invalid max charger current, value %u unsupported\n", 962 + max_chg_cur_ma * 1000); 963 + } 964 + 965 + /* 966 + * Write the values to the registers, and deliver an emergency warning 967 + * in the event they are not written correctly. 968 + */ 969 + ret = regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_OUT, 970 + RK817_CHRG_VOL_SEL, (max_chg_vol_reg << 4)); 971 + if (ret) { 972 + dev_emerg(charger->dev, 973 + "Danger, unable to set max charger voltage: %u\n", 974 + ret); 975 + } 976 + 977 + ret = regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_OUT, 978 + RK817_CHRG_CUR_SEL, max_chg_cur_reg); 979 + if (ret) { 980 + dev_emerg(charger->dev, 981 + "Danger, unable to set max charger current: %u\n", 982 + ret); 983 + } 984 + 985 + /* Set charge finishing mode to analog */ 986 + regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_TERM, 987 + RK817_CHRG_TERM_ANA_DIG, (0x0 << 2)); 988 + 989 + /* 990 + * Set charge finish current, warn if value not in range and keep 991 + * default. 992 + */ 993 + chg_term_ma = bat_info->charge_term_current_ua / 1000; 994 + if (chg_term_ma < 150 || chg_term_ma > 400) { 995 + dev_warn(charger->dev, 996 + "Invalid charge termination %u, keeping default\n", 997 + chg_term_ma * 1000); 998 + chg_term_ma = 200; 999 + } 1000 + 1001 + /* 1002 + * Values of 150ma, 200ma, 300ma, and 400ma correspond to 00, 01, 10, 1003 + * and 11. 1004 + */ 1005 + chg_term_i_reg = (chg_term_ma - 100) / 100; 1006 + regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_TERM, 1007 + RK817_CHRG_TERM_ANA_SEL, chg_term_i_reg); 1008 + 1009 + ret = rk817_read_or_set_full_charge_on_boot(charger, bat_info); 1010 + if (ret < 0) 1011 + return ret; 1012 + 1013 + /* 1014 + * Set minimum USB input voltage to 4.5v and enable USB voltage input 1015 + * limit. 1016 + */ 1017 + regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, 1018 + RK817_USB_VLIM_SEL, (0x05 << 4)); 1019 + regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_VLIM_EN, 1020 + (0x01 << 7)); 1021 + 1022 + /* 1023 + * Set average USB input current limit to 1.5A and enable USB current 1024 + * input limit. 1025 + */ 1026 + regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, 1027 + RK817_USB_ILIM_SEL, 0x03); 1028 + regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_ILIM_EN, 1029 + (0x01 << 3)); 1030 + 1031 + return 0; 1032 + } 1033 + 1034 + static void rk817_charging_monitor(struct work_struct *work) 1035 + { 1036 + struct rk817_charger *charger; 1037 + 1038 + charger = container_of(work, struct rk817_charger, work.work); 1039 + 1040 + rk817_read_props(charger); 1041 + 1042 + /* Run every 8 seconds like the BSP driver did. */ 1043 + queue_delayed_work(system_wq, &charger->work, msecs_to_jiffies(8000)); 1044 + } 1045 + 1046 + static int rk817_charger_probe(struct platform_device *pdev) 1047 + { 1048 + struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); 1049 + struct rk817_charger *charger; 1050 + struct device_node *node; 1051 + struct power_supply_battery_info *bat_info; 1052 + struct device *dev = &pdev->dev; 1053 + struct power_supply_config pscfg = {}; 1054 + int plugin_irq, plugout_irq; 1055 + int of_value; 1056 + int ret; 1057 + 1058 + node = of_get_child_by_name(dev->parent->of_node, "charger"); 1059 + if (!node) 1060 + return -ENODEV; 1061 + 1062 + charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL); 1063 + if (!charger) 1064 + return -ENOMEM; 1065 + 1066 + charger->rk808 = rk808; 1067 + 1068 + charger->dev = &pdev->dev; 1069 + platform_set_drvdata(pdev, charger); 1070 + 1071 + rk817_bat_calib_vol(charger); 1072 + 1073 + pscfg.drv_data = charger; 1074 + pscfg.of_node = node; 1075 + 1076 + /* 1077 + * Get sample resistor value. Note only values of 10000 or 20000 1078 + * microohms are allowed. Schematic for my test implementation (an 1079 + * Odroid Go Advance) shows a 10 milliohm resistor for reference. 1080 + */ 1081 + ret = of_property_read_u32(node, "rockchip,resistor-sense-micro-ohms", 1082 + &of_value); 1083 + if (ret < 0) { 1084 + return dev_err_probe(dev, ret, 1085 + "Error reading sample resistor value\n"); 1086 + } 1087 + /* 1088 + * Store as a 1 or a 2, since all we really use the value for is as a 1089 + * divisor in some calculations. 1090 + */ 1091 + charger->res_div = (of_value == 20000) ? 2 : 1; 1092 + 1093 + /* 1094 + * Get sleep enter current value. Not sure what this value is for 1095 + * other than to help calibrate the relax threshold. 1096 + */ 1097 + ret = of_property_read_u32(node, 1098 + "rockchip,sleep-enter-current-microamp", 1099 + &of_value); 1100 + if (ret < 0) { 1101 + return dev_err_probe(dev, ret, 1102 + "Error reading sleep enter cur value\n"); 1103 + } 1104 + charger->sleep_enter_current_ua = of_value; 1105 + 1106 + /* Get sleep filter current value */ 1107 + ret = of_property_read_u32(node, 1108 + "rockchip,sleep-filter-current-microamp", 1109 + &of_value); 1110 + if (ret < 0) { 1111 + return dev_err_probe(dev, ret, 1112 + "Error reading sleep filter cur value\n"); 1113 + } 1114 + 1115 + charger->sleep_filter_current_ua = of_value; 1116 + 1117 + charger->bat_ps = devm_power_supply_register(&pdev->dev, 1118 + &rk817_bat_desc, &pscfg); 1119 + 1120 + charger->chg_ps = devm_power_supply_register(&pdev->dev, 1121 + &rk817_chg_desc, &pscfg); 1122 + 1123 + if (IS_ERR(charger->chg_ps)) 1124 + return dev_err_probe(dev, -EINVAL, 1125 + "Battery failed to probe\n"); 1126 + 1127 + if (IS_ERR(charger->chg_ps)) 1128 + return dev_err_probe(dev, -EINVAL, 1129 + "Charger failed to probe\n"); 1130 + 1131 + ret = power_supply_get_battery_info(charger->bat_ps, 1132 + &bat_info); 1133 + if (ret) { 1134 + return dev_err_probe(dev, ret, 1135 + "Unable to get battery info: %d\n", ret); 1136 + } 1137 + 1138 + if ((bat_info->charge_full_design_uah <= 0) || 1139 + (bat_info->voltage_min_design_uv <= 0) || 1140 + (bat_info->voltage_max_design_uv <= 0) || 1141 + (bat_info->constant_charge_voltage_max_uv <= 0) || 1142 + (bat_info->constant_charge_current_max_ua <= 0) || 1143 + (bat_info->charge_term_current_ua <= 0)) { 1144 + return dev_err_probe(dev, -EINVAL, 1145 + "Required bat info missing or invalid\n"); 1146 + } 1147 + 1148 + charger->bat_charge_full_design_uah = bat_info->charge_full_design_uah; 1149 + charger->bat_voltage_min_design_uv = bat_info->voltage_min_design_uv; 1150 + charger->bat_voltage_max_design_uv = bat_info->voltage_max_design_uv; 1151 + 1152 + /* 1153 + * Has to run after power_supply_get_battery_info as it depends on some 1154 + * values discovered from that routine. 1155 + */ 1156 + ret = rk817_battery_init(charger, bat_info); 1157 + if (ret) 1158 + return ret; 1159 + 1160 + power_supply_put_battery_info(charger->bat_ps, bat_info); 1161 + 1162 + plugin_irq = platform_get_irq(pdev, 0); 1163 + if (plugin_irq < 0) 1164 + return plugin_irq; 1165 + 1166 + plugout_irq = platform_get_irq(pdev, 1); 1167 + if (plugout_irq < 0) 1168 + return plugout_irq; 1169 + 1170 + ret = devm_request_threaded_irq(charger->dev, plugin_irq, NULL, 1171 + rk817_plug_in_isr, 1172 + IRQF_TRIGGER_RISING | IRQF_ONESHOT, 1173 + "rk817_plug_in", charger); 1174 + if (ret) { 1175 + return dev_err_probe(&pdev->dev, ret, 1176 + "plug_in_irq request failed!\n"); 1177 + } 1178 + 1179 + ret = devm_request_threaded_irq(charger->dev, plugout_irq, NULL, 1180 + rk817_plug_out_isr, 1181 + IRQF_TRIGGER_RISING | IRQF_ONESHOT, 1182 + "rk817_plug_out", charger); 1183 + if (ret) { 1184 + return dev_err_probe(&pdev->dev, ret, 1185 + "plug_out_irq request failed!\n"); 1186 + } 1187 + 1188 + ret = devm_delayed_work_autocancel(&pdev->dev, &charger->work, 1189 + rk817_charging_monitor); 1190 + if (ret) 1191 + return ret; 1192 + 1193 + /* Force the first update immediately. */ 1194 + mod_delayed_work(system_wq, &charger->work, 0); 1195 + 1196 + return 0; 1197 + } 1198 + 1199 + 1200 + static struct platform_driver rk817_charger_driver = { 1201 + .probe = rk817_charger_probe, 1202 + .driver = { 1203 + .name = "rk817-charger", 1204 + }, 1205 + }; 1206 + module_platform_driver(rk817_charger_driver); 1207 + 1208 + MODULE_DESCRIPTION("Battery power supply driver for RK817 PMIC"); 1209 + MODULE_AUTHOR("Maya Matuszczyk <maccraft123mc@gmail.com>"); 1210 + MODULE_AUTHOR("Chris Morgan <macromorgan@hotmail.com>"); 1211 + MODULE_LICENSE("GPL");
+1
drivers/regulator/Kconfig
··· 1282 1282 1283 1283 config REGULATOR_SY7636A 1284 1284 tristate "Silergy SY7636A voltage regulator" 1285 + depends on MFD_SY7636A 1285 1286 help 1286 1287 This driver supports Silergy SY3686A voltage regulator. 1287 1288
+18
include/dt-bindings/iio/adc/mediatek,mt6370_adc.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ 2 + 3 + #ifndef __DT_BINDINGS_MEDIATEK_MT6370_ADC_H__ 4 + #define __DT_BINDINGS_MEDIATEK_MT6370_ADC_H__ 5 + 6 + /* ADC Channel Index */ 7 + #define MT6370_CHAN_VBUSDIV5 0 8 + #define MT6370_CHAN_VBUSDIV2 1 9 + #define MT6370_CHAN_VSYS 2 10 + #define MT6370_CHAN_VBAT 3 11 + #define MT6370_CHAN_TS_BAT 4 12 + #define MT6370_CHAN_IBUS 5 13 + #define MT6370_CHAN_IBAT 6 14 + #define MT6370_CHAN_CHG_VDDP 7 15 + #define MT6370_CHAN_TEMP_JC 8 16 + #define MT6370_CHAN_MAX 9 17 + 18 + #endif
-2
include/linux/htcpld.h
··· 13 13 }; 14 14 15 15 struct htcpld_core_platform_data { 16 - unsigned int int_reset_gpio_hi; 17 - unsigned int int_reset_gpio_lo; 18 16 unsigned int i2c_adapter_id; 19 17 20 18 struct htcpld_chip_platform_data *chip;
+91
include/linux/mfd/rk808.h
··· 519 519 #define MIC_DIFF_DIS (0x0 << 7) 520 520 #define MIC_DIFF_EN (0x1 << 7) 521 521 522 + /* RK817 Battery Registers */ 523 + #define RK817_GAS_GAUGE_ADC_CONFIG0 0x50 524 + #define RK817_GG_EN (0x1 << 7) 525 + #define RK817_SYS_VOL_ADC_EN (0x1 << 6) 526 + #define RK817_TS_ADC_EN (0x1 << 5) 527 + #define RK817_USB_VOL_ADC_EN (0x1 << 4) 528 + #define RK817_BAT_VOL_ADC_EN (0x1 << 3) 529 + #define RK817_BAT_CUR_ADC_EN (0x1 << 2) 530 + 531 + #define RK817_GAS_GAUGE_ADC_CONFIG1 0x55 532 + 533 + #define RK817_VOL_CUR_CALIB_UPD BIT(7) 534 + 535 + #define RK817_GAS_GAUGE_GG_CON 0x56 536 + #define RK817_GAS_GAUGE_GG_STS 0x57 537 + 538 + #define RK817_BAT_CON (0x1 << 4) 539 + #define RK817_RELAX_VOL_UPD (0x3 << 2) 540 + #define RK817_RELAX_STS (0x1 << 1) 541 + 542 + #define RK817_GAS_GAUGE_RELAX_THRE_H 0x58 543 + #define RK817_GAS_GAUGE_RELAX_THRE_L 0x59 544 + #define RK817_GAS_GAUGE_OCV_THRE_VOL 0x62 545 + #define RK817_GAS_GAUGE_OCV_VOL_H 0x63 546 + #define RK817_GAS_GAUGE_OCV_VOL_L 0x64 547 + #define RK817_GAS_GAUGE_PWRON_VOL_H 0x6b 548 + #define RK817_GAS_GAUGE_PWRON_VOL_L 0x6c 549 + #define RK817_GAS_GAUGE_PWRON_CUR_H 0x6d 550 + #define RK817_GAS_GAUGE_PWRON_CUR_L 0x6e 551 + #define RK817_GAS_GAUGE_OFF_CNT 0x6f 552 + #define RK817_GAS_GAUGE_Q_INIT_H3 0x70 553 + #define RK817_GAS_GAUGE_Q_INIT_H2 0x71 554 + #define RK817_GAS_GAUGE_Q_INIT_L1 0x72 555 + #define RK817_GAS_GAUGE_Q_INIT_L0 0x73 556 + #define RK817_GAS_GAUGE_Q_PRES_H3 0x74 557 + #define RK817_GAS_GAUGE_Q_PRES_H2 0x75 558 + #define RK817_GAS_GAUGE_Q_PRES_L1 0x76 559 + #define RK817_GAS_GAUGE_Q_PRES_L0 0x77 560 + #define RK817_GAS_GAUGE_BAT_VOL_H 0x78 561 + #define RK817_GAS_GAUGE_BAT_VOL_L 0x79 562 + #define RK817_GAS_GAUGE_BAT_CUR_H 0x7a 563 + #define RK817_GAS_GAUGE_BAT_CUR_L 0x7b 564 + #define RK817_GAS_GAUGE_USB_VOL_H 0x7e 565 + #define RK817_GAS_GAUGE_USB_VOL_L 0x7f 566 + #define RK817_GAS_GAUGE_SYS_VOL_H 0x80 567 + #define RK817_GAS_GAUGE_SYS_VOL_L 0x81 568 + #define RK817_GAS_GAUGE_Q_MAX_H3 0x82 569 + #define RK817_GAS_GAUGE_Q_MAX_H2 0x83 570 + #define RK817_GAS_GAUGE_Q_MAX_L1 0x84 571 + #define RK817_GAS_GAUGE_Q_MAX_L0 0x85 572 + #define RK817_GAS_GAUGE_SLEEP_CON_SAMP_CUR_H 0x8f 573 + #define RK817_GAS_GAUGE_SLEEP_CON_SAMP_CUR_L 0x90 574 + #define RK817_GAS_GAUGE_CAL_OFFSET_H 0x91 575 + #define RK817_GAS_GAUGE_CAL_OFFSET_L 0x92 576 + #define RK817_GAS_GAUGE_VCALIB0_H 0x93 577 + #define RK817_GAS_GAUGE_VCALIB0_L 0x94 578 + #define RK817_GAS_GAUGE_VCALIB1_H 0x95 579 + #define RK817_GAS_GAUGE_VCALIB1_L 0x96 580 + #define RK817_GAS_GAUGE_IOFFSET_H 0x97 581 + #define RK817_GAS_GAUGE_IOFFSET_L 0x98 582 + #define RK817_GAS_GAUGE_BAT_R1 0x9a 583 + #define RK817_GAS_GAUGE_BAT_R2 0x9b 584 + #define RK817_GAS_GAUGE_BAT_R3 0x9c 585 + #define RK817_GAS_GAUGE_DATA0 0x9d 586 + #define RK817_GAS_GAUGE_DATA1 0x9e 587 + #define RK817_GAS_GAUGE_DATA2 0x9f 588 + #define RK817_GAS_GAUGE_DATA3 0xa0 589 + #define RK817_GAS_GAUGE_DATA4 0xa1 590 + #define RK817_GAS_GAUGE_DATA5 0xa2 591 + #define RK817_GAS_GAUGE_CUR_ADC_K0 0xb0 592 + 522 593 #define RK817_POWER_EN_REG(i) (0xb1 + (i)) 523 594 #define RK817_POWER_SLP_EN_REG(i) (0xb5 + (i)) 524 595 ··· 615 544 #define RK817_LDO_ON_VSEL_REG(idx) (0xcc + (idx) * 2) 616 545 #define RK817_BOOST_OTG_CFG (0xde) 617 546 547 + #define RK817_PMIC_CHRG_OUT 0xe4 548 + #define RK817_CHRG_VOL_SEL (0x07 << 4) 549 + #define RK817_CHRG_CUR_SEL (0x07 << 0) 550 + 551 + #define RK817_PMIC_CHRG_IN 0xe5 552 + #define RK817_USB_VLIM_EN (0x01 << 7) 553 + #define RK817_USB_VLIM_SEL (0x07 << 4) 554 + #define RK817_USB_ILIM_EN (0x01 << 3) 555 + #define RK817_USB_ILIM_SEL (0x07 << 0) 556 + #define RK817_PMIC_CHRG_TERM 0xe6 557 + #define RK817_CHRG_TERM_ANA_DIG (0x01 << 2) 558 + #define RK817_CHRG_TERM_ANA_SEL (0x03 << 0) 559 + #define RK817_CHRG_EN (0x01 << 6) 560 + 561 + #define RK817_PMIC_CHRG_STS 0xeb 562 + #define RK817_BAT_EXS BIT(7) 563 + #define RK817_CHG_STS (0x07 << 4) 564 + 618 565 #define RK817_ID_MSB 0xed 619 566 #define RK817_ID_LSB 0xee 620 567 621 568 #define RK817_SYS_STS 0xf0 569 + #define RK817_PLUG_IN_STS (0x1 << 6) 570 + 622 571 #define RK817_SYS_CFG(i) (0xf1 + (i)) 623 572 624 573 #define RK817_ON_SOURCE_REG 0xf5