diff --git a/Documentation/devicetree/bindings/input/cpcap-pwrbutton.txt b/Documentation/devicetree/bindings/input/cpcap-pwrbutton.txt deleted file mode 100644 index 0dd0076daf71..000000000000 --- a/Documentation/devicetree/bindings/input/cpcap-pwrbutton.txt +++ /dev/null @@ -1,20 +0,0 @@ -Motorola CPCAP on key - -This module is part of the CPCAP. For more details about the whole -chip see Documentation/devicetree/bindings/mfd/motorola-cpcap.txt. - -This module provides a simple power button event via an Interrupt. - -Required properties: -- compatible: should be one of the following - - "motorola,cpcap-pwrbutton" -- interrupts: irq specifier for CPCAP's ON IRQ - -Example: - -&cpcap { - cpcap_pwrbutton: pwrbutton { - compatible = "motorola,cpcap-pwrbutton"; - interrupts = <23 IRQ_TYPE_NONE>; - }; -}; diff --git a/Documentation/devicetree/bindings/input/motorola,cpcap-pwrbutton.yaml b/Documentation/devicetree/bindings/input/motorola,cpcap-pwrbutton.yaml new file mode 100644 index 000000000000..77a3e5a47d1a --- /dev/null +++ b/Documentation/devicetree/bindings/input/motorola,cpcap-pwrbutton.yaml @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/motorola,cpcap-pwrbutton.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Motorola CPCAP PMIC power key + +maintainers: + - Svyatoslav Ryhel + +description: + This module is part of the Motorola CPCAP MFD device. For more details + see Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml. The + power key is represented as a sub-node of the PMIC node on the device + tree. + +properties: + compatible: + const: motorola,cpcap-pwrbutton + + interrupts: + items: + - description: CPCAP's ON interrupt + +required: + - compatible + - interrupts + +additionalProperties: false + +... diff --git a/Documentation/devicetree/bindings/leds/backlight/ti,lm3533-backlight.yaml b/Documentation/devicetree/bindings/leds/backlight/ti,lm3533-backlight.yaml new file mode 100644 index 000000000000..a25846e9b375 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/backlight/ti,lm3533-backlight.yaml @@ -0,0 +1,69 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/backlight/ti,lm3533-backlight.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI LM3533 high voltage series LED strings + +description: + This is part of the TI LM3533 MFD device. It represents two high voltage series + LED strings for display backlight controlled by the TI LM3533. + +maintainers: + - Svyatoslav Ryhel + +allOf: + - $ref: /schemas/leds/backlight/common.yaml# + +properties: + compatible: + const: ti,lm3533-backlight + + reg: + description: Control bank selection (0 = bank A, 1 = bank B). + maximum: 1 + + led-max-microamp: + description: maximum current in uA with a 800 uA step. + minimum: 5000 + maximum: 29800 + default: 5000 + + led-sources: + description: | + HVLED strings associated with this control bank: + 0 - HVLED1 + 1 - HVLED2 + minItems: 1 + maxItems: 2 + items: + maximum: 1 + + ti,pwm-config-mask: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + Control Bank PWM Configuration Register mask that allows to configure + PWM input in Zones 0-4 + BIT(0) - PWM Input is enabled + BIT(1) - PWM Input is enabled in Zone 0 + BIT(2) - PWM Input is enabled in Zone 1 + BIT(3) - PWM Input is enabled in Zone 2 + BIT(4) - PWM Input is enabled in Zone 3 + BIT(5) - PWM Input is enabled in Zone 4 + default: 0 + + ti,linear-mapping-mode: + description: + Enable linear mapping mode. If disabled, then it will use exponential + mapping mode in which the ramp up/down appears to have a more uniform + transition to the human eye. + type: boolean + +required: + - compatible + - reg + +unevaluatedProperties: false + +# see ti,lm3533.yaml for an example diff --git a/Documentation/devicetree/bindings/leds/ti,lm3533-leds.yaml b/Documentation/devicetree/bindings/leds/ti,lm3533-leds.yaml new file mode 100644 index 000000000000..d8dbefef3323 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/ti,lm3533-leds.yaml @@ -0,0 +1,67 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/ti,lm3533-leds.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI LM3533 low voltage control banks for individual LEDs + +description: + This is part of the TI LM3533 MFD device. It represents four low voltage + control banks for individual LEDs provided by the TI LM3533. + +maintainers: + - Svyatoslav Ryhel + +allOf: + - $ref: /schemas/leds/common.yaml# + +properties: + compatible: + const: ti,lm3533-leds + + reg: + description: + Control bank selection (2 = bank C, 3 = bank D, 4 = bank E, 5 = bank F). + minimum: 2 + maximum: 5 + + led-max-microamp: + description: maximum current in uA with a 800 uA step. + minimum: 5000 + maximum: 29800 + default: 5000 + + led-sources: + description: | + LVLED associated with this control bank. May be more than 1 source per bank. + 0 - LVLED1 + 1 - LVLED2 + 2 - LVLED3 + 3 - LVLED4 + 4 - LVLED5 + minItems: 1 + maxItems: 5 + items: + maximum: 4 + + ti,pwm-config-mask: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + Control Bank PWM Configuration Register mask that allows to configure + PWM input in Zones 0-4 + BIT(0) - PWM Input is enabled + BIT(1) - PWM Input is enabled in Zone 0 + BIT(2) - PWM Input is enabled in Zone 1 + BIT(3) - PWM Input is enabled in Zone 2 + BIT(4) - PWM Input is enabled in Zone 3 + BIT(5) - PWM Input is enabled in Zone 4 + default: 0 + +required: + - compatible + - reg + +unevaluatedProperties: false + +# see ti,lm3533.yaml for an example diff --git a/Documentation/devicetree/bindings/leds/ti,lm3533.yaml b/Documentation/devicetree/bindings/leds/ti,lm3533.yaml new file mode 100644 index 000000000000..bdc05a9f3d66 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/ti,lm3533.yaml @@ -0,0 +1,169 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/ti,lm3533.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI LM3533 Complete Lighting Power Solution + +description: > + The LM3533 is a complete power source for backlight, keypad, and indicator LEDs + in smartphone handsets. The high-voltage inductive boost converter provides the + power for two high voltage series LED strings for display backlight and four low + voltage control banks for individual LEDs. Additionally, LM3533 features an + interface for an external light sensor. + + https://www.ti.com/product/LM3533 + +maintainers: + - Svyatoslav Ryhel + +properties: + compatible: + const: ti,lm3533 + + reg: + maxItems: 1 + + enable-gpios: + description: GPIO connected to the HWEN pin. + maxItems: 1 + + vin-supply: + description: Supply connected to the IN line (2.7 V to 5.5 V). + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + ti,boost-ovp-microvolt: + description: boost OVP select (16V, 24V, 32V, 40V) + enum: [ 16000000, 24000000, 32000000, 40000000 ] + default: 16000000 + + ti,boost-freq-hz: + description: boost frequency select (500KHz or 1MHz) + enum: [ 500000, 1000000 ] + default: 500000 + + light-sensor: + type: object + additionalProperties: false + + properties: + compatible: + const: ti,lm3533-als + + interrupts: + maxItems: 1 + + ti,resistor-ohms: + description: + Internal configuration resistor value when light sensor is in + Analog Sensor mode and PWM mode is disabled. The expectation is + the input is a current from the external analog light sensor and + this is used to convert it to a voltage within the target range. + minimum: 1575 + maximum: 200000 + + ti,pwm-mode: + type: boolean + description: + Switch for mode in which light sensor interface is running. If + this property is set then the light sensor interface is running + in PWM mode, internal resistor value is set to high-impedance (0) + and ti,resistor-ohms property is ignored. + + required: + - compatible + + oneOf: + - required: + - ti,resistor-ohms + - required: + - ti,pwm-mode + +patternProperties: + "^backlight@[01]$": + $ref: /schemas/leds/backlight/ti,lm3533-backlight.yaml# + + "^led@[2-5]$": + $ref: /schemas/leds/ti,lm3533-leds.yaml# + +required: + - compatible + - reg + - '#address-cells' + - '#size-cells' + +additionalProperties: false + +examples: + - | + #include + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + led-controller@36 { + compatible = "ti,lm3533"; + reg = <0x36>; + + enable-gpios = <&gpio 110 GPIO_ACTIVE_HIGH>; + vin-supply = <&vdd_3v3_bat>; + + ti,boost-ovp-microvolt = <24000000>; + ti,boost-freq-hz = <500000>; + + #address-cells = <1>; + #size-cells = <0>; + + backlight@0 { + compatible = "ti,lm3533-backlight"; + reg = <0>; + + default-brightness = <113>; + + led-max-microamp = <23400>; + led-sources = <0 1>; + }; + + led@2 { + compatible = "ti,lm3533-leds"; + reg = <2>; + + led-max-microamp = <23400>; + led-sources = <0 1>; + }; + + led@4 { + compatible = "ti,lm3533-leds"; + reg = <4>; + + led-max-microamp = <23400>; + led-sources = <2>; + }; + + led@5 { + compatible = "ti,lm3533-leds"; + reg = <5>; + + led-max-microamp = <23400>; + led-sources = <3 4>; + }; + + light-sensor { + compatible = "ti,lm3533-als"; + + interrupt-parent = <&gpio>; + interrupts = <80 IRQ_TYPE_LEVEL_LOW>; + + ti,pwm-mode; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml index 6a824351834e..0dd37c40eeff 100644 --- a/Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml +++ b/Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml @@ -24,7 +24,7 @@ properties: pattern: "pmic@[0-9a-f]" compatible: - const: hisilicon,hi6421v600-spmi + const: hisilicon,hi6421-spmi reg: maxItems: 1 @@ -66,7 +66,7 @@ examples: #size-cells = <0>; pmic@0 { - compatible = "hisilicon,hi6421v600-spmi"; + compatible = "hisilicon,hi6421-spmi"; reg = <0 SPMI_USID>; #interrupt-cells = <2>; diff --git a/Documentation/devicetree/bindings/mfd/lp3943.txt b/Documentation/devicetree/bindings/mfd/lp3943.txt deleted file mode 100644 index ca5324ed0df4..000000000000 --- a/Documentation/devicetree/bindings/mfd/lp3943.txt +++ /dev/null @@ -1,33 +0,0 @@ -TI/National Semiconductor LP3943 MFD driver - -Required properties: - - compatible: "ti,lp3943" - - reg: I2C slave address. From 0x60 to 0x67. - -LP3943 consists of two sub-devices, lp3943-gpio and lp3943-pwm. - -For the LP3943 GPIO properties please refer to: -Documentation/devicetree/bindings/gpio/trivial-gpio.yaml - -For the LP3943 PWM properties please refer to: -Documentation/devicetree/bindings/pwm/pwm-lp3943.txt - -Example: - -lp3943@60 { - compatible = "ti,lp3943"; - reg = <0x60>; - - gpioex: gpio { - compatible = "ti,lp3943-gpio"; - gpio-controller; - #gpio-cells = <2>; - }; - - pwm3943: pwm { - compatible = "ti,lp3943-pwm"; - #pwm-cells = <2>; - ti,pwm0 = <8 9 10>; - ti,pwm1 = <15>; - }; -}; diff --git a/Documentation/devicetree/bindings/mfd/mediatek,mt6357.yaml b/Documentation/devicetree/bindings/mfd/mediatek,mt6357.yaml index b67fbe0e7a63..dbb48e380e77 100644 --- a/Documentation/devicetree/bindings/mfd/mediatek,mt6357.yaml +++ b/Documentation/devicetree/bindings/mfd/mediatek,mt6357.yaml @@ -62,6 +62,13 @@ properties: description: List of MT6357 BUCKs and LDOs regulators. + adc: + type: object + $ref: /schemas/iio/adc/mediatek,mt6359-auxadc.yaml# + unevaluatedProperties: false + description: + MT6357 auxiliary ADC. + rtc: type: object $ref: /schemas/rtc/rtc.yaml# diff --git a/Documentation/devicetree/bindings/mfd/mediatek,mt6360.yaml b/Documentation/devicetree/bindings/mfd/mediatek,mt6360.yaml index fb65abf30d57..828ed7f558f6 100644 --- a/Documentation/devicetree/bindings/mfd/mediatek,mt6360.yaml +++ b/Documentation/devicetree/bindings/mfd/mediatek,mt6360.yaml @@ -33,9 +33,10 @@ properties: interrupt-controller: true "#interrupt-cells": - const: 1 + enum: [1, 2] description: - The first cell is the IRQ number. + The first cell is the IRQ number. The optional second cell is the IRQ + trigger type. regulators: $ref: /schemas/regulator/mt6360-regulator.yaml# diff --git a/Documentation/devicetree/bindings/mfd/mediatek,mt6397.yaml b/Documentation/devicetree/bindings/mfd/mediatek,mt6397.yaml index d2de227ae7a6..055625362951 100644 --- a/Documentation/devicetree/bindings/mfd/mediatek,mt6397.yaml +++ b/Documentation/devicetree/bindings/mfd/mediatek,mt6397.yaml @@ -57,6 +57,9 @@ properties: "#interrupt-cells": const: 2 + "#sound-dai-cells": + const: 1 + rtc: type: object $ref: /schemas/rtc/rtc.yaml# @@ -81,6 +84,15 @@ properties: start-year: true + nvmem-layout: + $ref: /schemas/nvmem/layouts/nvmem-layout.yaml + description: + The RTC carries four bytes of storage that neither the clock nor the + alarm uses, in the high half of four of the alarm registers, and + offers them as a battery-backed nvmem provider. MediaTek's + documentation names them RTC_NEW_SPARE0 to RTC_NEW_SPARE3 and gives + the first to a fuel gauge. + required: - compatible diff --git a/Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml b/Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml new file mode 100644 index 000000000000..da7abe2ec912 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml @@ -0,0 +1,408 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/motorola,cpcap.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Motorola CPCAP PMIC MFD + +maintainers: + - Svyatoslav Ryhel + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +properties: + compatible: + oneOf: + - enum: + - motorola,mapphone-cpcap + - motorola,mot-cpcap + + - items: + - const: motorola,cpcap + - const: st,6556002 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + interrupt-controller: true + + "#interrupt-cells": + const: 2 + + spi-max-frequency: + maximum: 9600000 + + spi-cs-high: true + spi-cpol: true + spi-cpha: true + + adc: + $ref: /schemas/iio/adc/motorola,cpcap-adc.yaml# + + audio-codec: + type: object + additionalProperties: false + + properties: + interrupts: + items: + - description: headset detect interrupt + - description: microphone bias 2 detect interrupt + + interrupt-names: + items: + - const: hs + - const: mb2 + + "#sound-dai-cells": + const: 1 + + VAUDIO-supply: + description: + Codec power supply, usually VAUDIO regulator of CPCAP. + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + properties: + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: port connected to the Stereo HiFi DAC + + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: port connected to the Voice DAC + + required: + - port@0 + - port@1 + + required: + - interrupts + - interrupt-names + - "#sound-dai-cells" + + battery: + $ref: /schemas/power/supply/cpcap-battery.yaml# + + charger: + $ref: /schemas/power/supply/cpcap-charger.yaml# + + key-power: + $ref: /schemas/input/motorola,cpcap-pwrbutton.yaml# + + phy: + $ref: /schemas/phy/motorola,cpcap-usb-phy.yaml# + + regulator: + $ref: /schemas/regulator/motorola,cpcap-regulator.yaml# + + rtc: + $ref: /schemas/rtc/motorola,cpcap-rtc.yaml# + +patternProperties: + "^led(-[a-z]+)?$": + $ref: /schemas/leds/motorola,cpcap-leds.yaml# + +required: + - compatible + - reg + - interrupts + - interrupt-controller + - "#interrupt-cells" + - spi-max-frequency + +additionalProperties: false + +examples: + - | + #include + #include + #include + + spi { + #address-cells = <1>; + #size-cells = <0>; + + cpcap: pmic@0 { + compatible = "motorola,cpcap", "st,6556002"; + reg = <0>; /* cs0 */ + + interrupt-parent = <&gpio1>; + interrupts = <7 IRQ_TYPE_EDGE_RISING>; + + interrupt-controller; + #interrupt-cells = <2>; + + spi-max-frequency = <3000000>; + spi-cs-high; + + spi-cpol; + spi-cpha; + + cpcap_adc: adc { + compatible = "motorola,cpcap-adc"; + + interrupt-parent = <&cpcap>; + interrupts = <8 IRQ_TYPE_NONE>; + interrupt-names = "adcdone"; + + #io-channel-cells = <1>; + }; + + cpcap_audio: audio-codec { + interrupt-parent = <&cpcap>; + interrupts = <9 IRQ_TYPE_NONE>, <10 IRQ_TYPE_NONE>; + interrupt-names = "hs", "mb2"; + + VAUDIO-supply = <&vdd_audio>; + + #sound-dai-cells = <1>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + /* HiFi */ + port@0 { + reg = <0>; + + cpcap_audio_codec0: endpoint { + }; + }; + + /* Voice */ + port@1 { + reg = <1>; + + cpcap_audio_codec1: endpoint { + }; + }; + }; + }; + + cpcap_battery: battery { + compatible = "motorola,cpcap-battery"; + + interrupt-parent = <&cpcap>; + interrupts = <6 IRQ_TYPE_NONE>, <5 IRQ_TYPE_NONE>, + <3 IRQ_TYPE_NONE>, <20 IRQ_TYPE_NONE>, + <54 IRQ_TYPE_NONE>, <57 IRQ_TYPE_NONE>; + interrupt-names = "eol", "lowbph", "lowbpl", + "chrgcurr1", "battdetb", "cccal"; + + io-channels = <&cpcap_adc 0>, <&cpcap_adc 1>, + <&cpcap_adc 5>, <&cpcap_adc 6>; + io-channel-names = "battdetb", "battp", + "chg_isense", "batti"; + power-supplies = <&cpcap_charger>; + }; + + cpcap_charger: charger { + compatible = "motorola,mapphone-cpcap-charger"; + + interrupt-parent = <&cpcap>; + interrupts = <13 IRQ_TYPE_NONE>, <12 IRQ_TYPE_NONE>, + <29 IRQ_TYPE_NONE>, <28 IRQ_TYPE_NONE>, + <22 IRQ_TYPE_NONE>, <21 IRQ_TYPE_NONE>, + <20 IRQ_TYPE_NONE>, <19 IRQ_TYPE_NONE>, + <54 IRQ_TYPE_NONE>; + interrupt-names = "chrg_det", "rvrs_chrg", "chrg_se1b", + "se0conn", "rvrs_mode", "chrgcurr2", + "chrgcurr1", "vbusvld", "battdetb"; + + mode-gpios = <&gpio3 29 GPIO_ACTIVE_LOW>, + <&gpio3 23 GPIO_ACTIVE_LOW>; + + io-channels = <&cpcap_adc 0>, <&cpcap_adc 1>, + <&cpcap_adc 2>, <&cpcap_adc 5>, + <&cpcap_adc 6>; + io-channel-names = "battdetb", "battp", + "vbus", "chg_isense", + "batti"; + }; + + key-power { + compatible = "motorola,cpcap-pwrbutton"; + + interrupt-parent = <&cpcap>; + interrupts = <23 IRQ_TYPE_NONE>; + }; + + led-red { + compatible = "motorola,cpcap-led-red"; + vdd-supply = <&vdd_led>; + label = "status-led::red"; + }; + + led-green { + compatible = "motorola,cpcap-led-green"; + vdd-supply = <&vdd_led>; + label = "status-led::green"; + }; + + led-blue { + compatible = "motorola,cpcap-led-blue"; + vdd-supply = <&vdd_led>; + label = "status-led::blue"; + }; + + cpcap_usb2_phy: phy { + compatible = "motorola,cpcap-usb-phy"; + + pinctrl-0 = <&usb_gpio_mux_sel1>, <&usb_gpio_mux_sel2>; + pinctrl-1 = <&usb_ulpi_pins>; + pinctrl-2 = <&usb_utmi_pins>; + pinctrl-3 = <&uart3_pins>; + pinctrl-names = "default", "ulpi", "utmi", "uart"; + #phy-cells = <0>; + + interrupts-extended = + <&cpcap 15 IRQ_TYPE_NONE>, <&cpcap 14 IRQ_TYPE_NONE>, + <&cpcap 28 IRQ_TYPE_NONE>, <&cpcap 19 IRQ_TYPE_NONE>, + <&cpcap 18 IRQ_TYPE_NONE>, <&cpcap 17 IRQ_TYPE_NONE>, + <&cpcap 16 IRQ_TYPE_NONE>, <&cpcap 49 IRQ_TYPE_NONE>, + <&cpcap 48 IRQ_TYPE_NONE>; + interrupt-names = "id_ground", "id_float", "se0conn", + "vbusvld", "sessvld", "sessend", + "se1", "dm", "dp"; + + mode-gpios = <&gpio2 28 GPIO_ACTIVE_HIGH>, + <&gpio1 0 GPIO_ACTIVE_HIGH>; + + io-channels = <&cpcap_adc 2>, <&cpcap_adc 7>; + io-channel-names = "vbus", "id"; + + vusb-supply = <&avdd_usb>; + }; + + regulator { + compatible = "motorola,cpcap-regulator"; + + regulators { + vdd_cpu: SW1 { + regulator-name = "vdd_cpu"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1125000>; + regulator-enable-ramp-delay = <1500>; + regulator-always-on; + regulator-boot-on; + }; + + vdd_core: SW2 { + regulator-name = "vdd_core"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1300000>; + regulator-enable-ramp-delay = <1500>; + regulator-always-on; + regulator-boot-on; + }; + + vdd_1v8_vio: SW3 { + regulator-name = "vdd_1v8_vio"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-enable-ramp-delay = <0>; + regulator-always-on; + regulator-boot-on; + }; + + vdd_aon: SW4 { + regulator-name = "vdd_aon"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1300000>; + regulator-enable-ramp-delay = <1500>; + regulator-always-on; + regulator-boot-on; + }; + + vdd_led: SW5 { + regulator-name = "vdd_led"; + regulator-min-microvolt = <5050000>; + regulator-max-microvolt = <5050000>; + regulator-enable-ramp-delay = <1500>; + regulator-boot-on; + }; + + vdd_hvio: VHVIO { + regulator-name = "vdd_hvio"; + regulator-min-microvolt = <2775000>; + regulator-max-microvolt = <2775000>; + regulator-enable-ramp-delay = <1000>; + }; + + vcore_emmc: VSDIO { + regulator-name = "vcore_emmc"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <3000000>; + regulator-enable-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; + }; + + avdd_dsi_csi: VCSI { + regulator-name = "avdd_dsi_csi"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-enable-ramp-delay = <1000>; + regulator-boot-on; + }; + + avdd_3v3_periph: VWLAN2 { + regulator-name = "avdd_3v3_periph"; + regulator-min-microvolt = <2775000>; + regulator-max-microvolt = <3300000>; + regulator-enable-ramp-delay = <1000>; + regulator-boot-on; + }; + + vddio_usd: VSIMCARD { + regulator-name = "vddio_usd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2900000>; + regulator-enable-ramp-delay = <1000>; + regulator-boot-on; + }; + + vdd_haptic: VVIB { + regulator-name = "vdd_haptic"; + regulator-min-microvolt = <1300000>; + regulator-max-microvolt = <3000000>; + regulator-enable-ramp-delay = <1000>; + }; + + avdd_usb: VUSB { + regulator-name = "avdd_usb"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-enable-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; + }; + + vdd_audio: VAUDIO { + regulator-name = "vdd_audio"; + regulator-min-microvolt = <2775000>; + regulator-max-microvolt = <2775000>; + regulator-enable-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; + }; + }; + }; + + cpcap_rtc: rtc { + compatible = "motorola,cpcap-rtc"; + + interrupt-parent = <&cpcap>; + interrupts = <39 IRQ_TYPE_NONE>, <26 IRQ_TYPE_NONE>; + }; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/mfd/motorola-cpcap.txt b/Documentation/devicetree/bindings/mfd/motorola-cpcap.txt deleted file mode 100644 index 18c3fc26ca93..000000000000 --- a/Documentation/devicetree/bindings/mfd/motorola-cpcap.txt +++ /dev/null @@ -1,78 +0,0 @@ -Motorola CPCAP PMIC device tree binding - -Required properties: -- compatible : One or both of "motorola,cpcap" or "ste,6556002" -- reg : SPI chip select -- interrupts : The interrupt line the device is connected to -- interrupt-controller : Marks the device node as an interrupt controller -- #interrupt-cells : The number of cells to describe an IRQ, should be 2 -- #address-cells : Child device offset number of cells, should be 1 -- #size-cells : Child device size number of cells, should be 0 -- spi-max-frequency : Typically set to 3000000 -- spi-cs-high : SPI chip select direction - -Optional subnodes: - -The sub-functions of CPCAP get their own node with their own compatible values, -which are described in the following files: - -- Documentation/devicetree/bindings/power/supply/cpcap-battery.yaml -- Documentation/devicetree/bindings/power/supply/cpcap-charger.yaml -- Documentation/devicetree/bindings/regulator/cpcap-regulator.txt -- Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml -- Documentation/devicetree/bindings/input/cpcap-pwrbutton.txt -- Documentation/devicetree/bindings/rtc/cpcap-rtc.txt -- Documentation/devicetree/bindings/leds/leds-cpcap.txt -- Documentation/devicetree/bindings/iio/adc/motorola,cpcap-adc.yaml - -The only exception is the audio codec. Instead of a compatible value its -node must be named "audio-codec". - -Required properties for the audio-codec subnode: - -- #sound-dai-cells = <1>; -- interrupts : should contain jack detection interrupts, with headset - detect interrupt matching "hs" and microphone bias 2 - detect interrupt matching "mb2" in interrupt-names. -- interrupt-names : Contains "hs", "mb2" - -The audio-codec provides two DAIs. The first one is connected to the -Stereo HiFi DAC and the second one is connected to the Voice DAC. - -Example: - -&mcspi1 { - cpcap: pmic@0 { - compatible = "motorola,cpcap", "ste,6556002"; - reg = <0>; /* cs0 */ - interrupt-parent = <&gpio1>; - interrupts = <7 IRQ_TYPE_EDGE_RISING>; - interrupt-controller; - #interrupt-cells = <2>; - #address-cells = <1>; - #size-cells = <0>; - spi-max-frequency = <3000000>; - spi-cs-high; - - audio-codec { - #sound-dai-cells = <1>; - interrupts-extended = <&cpcap 9 0>, <&cpcap 10 0>; - interrupt-names = "hs", "mb2"; - - /* HiFi */ - port@0 { - endpoint { - remote-endpoint = <&cpu_dai1>; - }; - }; - - /* Voice */ - port@1 { - endpoint { - remote-endpoint = <&cpu_dai2>; - }; - }; - }; - }; -}; - diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml index 5e0ed30a9a46..7a889d888383 100644 --- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml +++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml @@ -74,6 +74,7 @@ properties: - qcom,pm8994 - qcom,pm8998 - qcom,pma8084 + - qcom,pmau0102 - qcom,pmc8180 - qcom,pmc8180c - qcom,pmc8380 @@ -147,7 +148,9 @@ patternProperties: "^audio-codec@[0-9a-f]+$": type: object - $ref: /schemas/sound/qcom,pm8916-wcd-analog-codec.yaml# + oneOf: + - $ref: /schemas/sound/qcom,pm4125-codec.yaml# + - $ref: /schemas/sound/qcom,pm8916-wcd-analog-codec.yaml# "^battery@[0-9a-f]+$": type: object diff --git a/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml b/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml index c3889f974ed3..a021e4dea486 100644 --- a/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml +++ b/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml @@ -60,6 +60,7 @@ properties: - qcom,tcsr-msm8916 - qcom,tcsr-msm8917 - qcom,tcsr-msm8937 + - qcom,tcsr-msm8952 - qcom,tcsr-msm8953 - qcom,tcsr-msm8960 - qcom,tcsr-msm8974 diff --git a/Documentation/devicetree/bindings/mfd/rockchip,rk805.yaml b/Documentation/devicetree/bindings/mfd/rockchip,rk805.yaml index da2391530c16..ecd9846dffec 100644 --- a/Documentation/devicetree/bindings/mfd/rockchip,rk805.yaml +++ b/Documentation/devicetree/bindings/mfd/rockchip,rk805.yaml @@ -77,6 +77,16 @@ properties: description: The input supply for LDO_REG3. + # pinctrl-bindings.txt allows the pin configuration nodes to be grandchildren + # of the pin controller, and the text binding this replaces used that layout: + # a "pinmux" node holding the nodes that carry "pins". The driver reaches both + # layouts, because pinconf_generic_dt_node_to_map() parses the referenced node + # and then walks its children. + pinmux: + type: object + additionalProperties: + $ref: '#/$defs/rk805-pin-config' + regulators: type: object patternProperties: @@ -86,6 +96,38 @@ properties: unevaluatedProperties: false unevaluatedProperties: false +$defs: + rk805-pin-config: + type: object + description: + The RK805 has two output-only GPIOs which can be muxed to the GPIO + function and driven low or high at boot. + additionalProperties: false + + properties: + pins: + description: + List of GPIO pins to configure. + items: + enum: [gpio0, gpio1] + minItems: 1 + maxItems: 2 + + function: + description: + The RK805 only supports the GPIO function. + enum: [gpio] + + output-low: true + output-high: true + + required: + - pins + +patternProperties: + '-pins$': + $ref: '#/$defs/rk805-pin-config' + allOf: - if: properties: @@ -125,9 +167,11 @@ examples: interrupt-parent = <&gpio2>; interrupts = ; pinctrl-names = "default"; - pinctrl-0 = <&pmic_int_l>; + pinctrl-0 = <&pmic_int_l>, <&rk805_default>, <&rk805_grouped>; rockchip,system-power-controller; wakeup-source; + gpio-controller; + #gpio-cells = <2>; #clock-cells = <0>; vcc1-supply = <&vcc_sys>; @@ -137,6 +181,20 @@ examples: vcc5-supply = <&vcc_io>; vcc6-supply = <&vcc_io>; + rk805_default: rk805-default-pins { + pins = "gpio0"; + function = "gpio"; + output-high; + }; + + rk805_grouped: pinmux { + gpio01 { + pins = "gpio1"; + function = "gpio"; + output-low; + }; + }; + regulators { vdd_logic: DCDC_REG1 { regulator-name = "vdd_logic"; diff --git a/Documentation/devicetree/bindings/mfd/stericsson,ab8500.yaml b/Documentation/devicetree/bindings/mfd/stericsson,ab8500.yaml index 0fdfbfdfe88a..d819954ee731 100644 --- a/Documentation/devicetree/bindings/mfd/stericsson,ab8500.yaml +++ b/Documentation/devicetree/bindings/mfd/stericsson,ab8500.yaml @@ -312,6 +312,33 @@ properties: items: - const: audioclk + '#sound-dai-cells': + description: Selects one of the two digital audio interfaces + const: 1 + + ports: + $ref: /schemas/sound/audio-graph-port.yaml#/definitions/ports + + stericsson,amic1-type-single-ended: + description: Configure analog microphone 1 as single-ended + type: boolean + + stericsson,amic2-type-single-ended: + description: Configure analog microphone 2 as single-ended + type: boolean + + stericsson,amic1a-bias-vamic2: + description: Supply analog microphone 1A from VAMIC2 instead of VAMIC1 + type: boolean + + stericsson,amic1b-bias-vamic2: + description: Supply analog microphone 1B from VAMIC2 instead of VAMIC1 + type: boolean + + stericsson,amic2-bias-vamic1: + description: Supply analog microphone 2 from VAMIC1 instead of VAMIC2 + type: boolean + stericsson,earpeice-cmv: description: Earpiece voltage $ref: /schemas/types.yaml#/definitions/uint32 @@ -319,11 +346,14 @@ properties: required: - compatible + - '#sound-dai-cells' additionalProperties: false regulator: description: Node describing the AB8500 internal regulators. + LDO means low-dropout regulator. SMPS means switched-mode power + supply; the SMPS regulators described here are buck converters. type: object properties: @@ -439,16 +469,117 @@ properties: $ref: /schemas/regulator/regulator.yaml# unevaluatedProperties: false + allOf: + - if: + properties: + compatible: + const: stericsson,ab8500-regulator + then: + properties: + ab8500_buck_smps1: + description: Analog buck converter for the VSMPS1 1.2V I/O + and memory supply. + type: object + $ref: /schemas/regulator/regulator.yaml# + unevaluatedProperties: false + + ab8500_buck_smps2: + description: Analog buck converter for the VSMPS2 1.8V I/O + and memory supply. + type: object + $ref: /schemas/regulator/regulator.yaml# + unevaluatedProperties: false + + ab8500_buck_smps3: + description: Analog buck converter for VSMPS3, which supplies + the VSAFE power domain. + type: object + $ref: /schemas/regulator/regulator.yaml# + unevaluatedProperties: false + + ab8500_buck_arm: + description: Analog buck converter for the VARM processor + supply. + type: object + $ref: /schemas/regulator/regulator.yaml# + unevaluatedProperties: false + + ab8500_buck_ape: + description: Analog buck converter for the VAPE application + processor supply. + type: object + $ref: /schemas/regulator/regulator.yaml# + unevaluatedProperties: false + + ab8500_buck_mod: + description: Analog buck converter for the VMOD modem supply. + type: object + $ref: /schemas/regulator/regulator.yaml# + unevaluatedProperties: false + + - if: + properties: + compatible: + const: stericsson,ab8505-regulator + then: + properties: + ab8505_buck_smpsa: + description: Analog buck converter for the VSMPSA 1.2V I/O + and memory supply. The selector range depends on OTP + configuration. + type: object + $ref: /schemas/regulator/regulator.yaml# + unevaluatedProperties: false + + ab8505_buck_smpsb: + description: Analog buck converter for the VSMPSB 1.8V I/O + and memory supply. The selector range depends on OTP + configuration. + type: object + $ref: /schemas/regulator/regulator.yaml# + unevaluatedProperties: false + + ab8505_buck_safe: + description: Analog buck converter for the VSAFE permanent + logic and DDR supply. The selector range depends on OTP + configuration. + type: object + $ref: /schemas/regulator/regulator.yaml# + unevaluatedProperties: false + + ab8505_buck_arm: + description: Analog buck converter for the VARM processor + supply, with a 0.6V to 1.39375V selector range. + type: object + $ref: /schemas/regulator/regulator.yaml# + unevaluatedProperties: false + + ab8505_buck_smpsc: + description: Analog buck converter for the VSMPSC multimedia + and graphics supply. The selector range depends on OTP + configuration. + type: object + $ref: /schemas/regulator/regulator.yaml# + unevaluatedProperties: false + + ab8505_buck_smpsm: + description: Analog buck converter for the VSMPSM modem + supply. The selector range depends on OTP configuration. + type: object + $ref: /schemas/regulator/regulator.yaml# + unevaluatedProperties: false + required: - compatible - additionalProperties: false + unevaluatedProperties: false regulator-external: - description: Node describing the AB8500 external regulators. This - concerns the autonomous regulators VSMPS1, VSMPS2 and VSMPS3 - that are normally controlled by external electronics but also - sometimes need to be explicitly controlled by software. + description: Node describing AB8500 control interfaces for external + regulators. AB8500 controls these external devices through the + ExtSupply1Ena, ExtSupply2Ena and ExtSupply3Ena signals and associated + low-power-mode signals. They are distinct from the VSMPS1, VSMPS2 and + VSMPS3 buck converters integrated into AB8500. type: object properties: @@ -456,19 +587,22 @@ properties: const: stericsson,ab8500-ext-regulator ab8500_ext1: - description: The voltage for the VSMPS1 external regulator + description: External regulator controlled through ExtSupply1Ena and + ExtSupply12LPn type: object $ref: /schemas/regulator/regulator.yaml# unevaluatedProperties: false ab8500_ext2: - description: The voltage for the VSMPS2 external regulator + description: External regulator controlled through ExtSupply2Ena and + ExtSupply12LPn type: object $ref: /schemas/regulator/regulator.yaml# unevaluatedProperties: false ab8500_ext3: - description: The voltage for the VSMPS3 external regulator + description: External regulator controlled through ExtSupply3Ena and + ExtSupply3LPn type: object $ref: /schemas/regulator/regulator.yaml# unevaluatedProperties: false diff --git a/Documentation/devicetree/bindings/mfd/stericsson,db8500-prcmu.yaml b/Documentation/devicetree/bindings/mfd/stericsson,db8500-prcmu.yaml index 4edd4a3bab88..ce9060340e0c 100644 --- a/Documentation/devicetree/bindings/mfd/stericsson,db8500-prcmu.yaml +++ b/Documentation/devicetree/bindings/mfd/stericsson,db8500-prcmu.yaml @@ -58,6 +58,7 @@ properties: const: 2 db8500-prcmu-regulators: + deprecated: true description: Node describing the DB8500 regulators. These are mainly power rails inside the silicon but some of those are also routed out to external pins. @@ -207,26 +208,6 @@ properties: required: - compatible - - db8500_vape - - db8500_varm - - db8500_vmodem - - db8500_vpll - - db8500_vsmps1 - - db8500_vsmps2 - - db8500_vsmps3 - - db8500_vrf1 - - db8500_sva_mmdsp - - db8500_sva_mmdsp_ret - - db8500_sva_pipe - - db8500_sia_mmdsp - - db8500_sia_mmdsp_ret - - db8500_sia_pipe - - db8500_sga - - db8500_b2r2_mcde - - db8500_esram12 - - db8500_esram12_ret - - db8500_esram34 - - db8500_esram34_ret additionalProperties: false @@ -294,6 +275,5 @@ required: - interrupts - interrupt-controller - '#interrupt-cells' - - db8500-prcmu-regulators additionalProperties: false diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml index 33e0b1bad5ab..80ff0e1caca2 100644 --- a/Documentation/devicetree/bindings/mfd/syscon.yaml +++ b/Documentation/devicetree/bindings/mfd/syscon.yaml @@ -32,6 +32,7 @@ properties: - allwinner,sun50i-a64-system-controller - altr,l3regs - altr,sdr-ctl + - ambarella,cv75-sec-scratchpad - amd,pensando-elba-syscon - amlogic,meson-mx-assist - amlogic,meson-mx-bootrom diff --git a/Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml b/Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml index cdce83f05804..3bc07f25d063 100644 --- a/Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml +++ b/Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml @@ -11,9 +11,14 @@ maintainers: properties: compatible: - enum: - - ti,bq25703a - - ti,bq25792 + oneOf: + - enum: + - ti,bq25703a + - ti,bq25792 + - items: + - enum: + - ti,bq25798 + - const: ti,bq25792 reg: const: 0x6b @@ -103,7 +108,8 @@ allOf: - if: properties: compatible: - const: ti,bq25792 + contains: + const: ti,bq25792 then: properties: input-current-limit-microamp: diff --git a/Documentation/devicetree/bindings/mfd/ti,keystone-devctrl.yaml b/Documentation/devicetree/bindings/mfd/ti,keystone-devctrl.yaml new file mode 100644 index 000000000000..564dfc8a731f --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/ti,keystone-devctrl.yaml @@ -0,0 +1,90 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/ti,keystone-devctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments Keystone Device State Control + +maintainers: + - Ivan Khoronzhuk + +description: + The Keystone II devices have a set of registers that are used to control the + status of its peripherals. This node is intended to allow access to this + functionality. + +properties: + compatible: + items: + - const: ti,keystone-devctrl + - const: syscon + - const: simple-mfd + + reg: + maxItems: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 1 + + ranges: true + +patternProperties: + "^gpio@[0-9a-f]+$": + type: object + description: Keystone DSP GPIO controller + required: + - compatible + + "^interrupt-controller@[0-9a-f]+$": + type: object + description: Keystone DSP to ARM interrupt controller + required: + - compatible + + "^reset-controller@[0-9a-f]+$": + type: object + description: Keystone reset controller + required: + - compatible + +required: + - compatible + - reg + - "#address-cells" + - "#size-cells" + - ranges + +additionalProperties: false + +examples: + - | + #include + + device-state-control@2620000 { + compatible = "ti,keystone-devctrl", "syscon", "simple-mfd"; + reg = <0x02620000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x02620000 0x1000>; + + interrupt-controller@2a0 { + compatible = "ti,keystone-irq"; + reg = <0x2a0 0x4>; + interrupts = ; + interrupt-controller; + #interrupt-cells = <1>; + ti,syscon-dev = <&devctrl 0x2a0>; + }; + + reset-controller@328 { + compatible = "ti,keystone-reset"; + reg = <0x328 0x10>; + ti,syscon-pll = <&pllctrl 0xe4>; + ti,syscon-dev = <&devctrl 0x328>; + ti,wdt-list = <0>; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/ti,lp3943.yaml b/Documentation/devicetree/bindings/mfd/ti,lp3943.yaml new file mode 100644 index 000000000000..eff32b05c21c --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/ti,lp3943.yaml @@ -0,0 +1,64 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/ti,lp3943.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI/National Semiconductor LP3943 MFD driver + +maintainers: + - Chaosheng Qu + +description: + LP3943 is an integrated device capable of driving LEDs. It contains two + sub-devices, lp3943-gpio and lp3943-pwm, which are instantiated by the MFD + core from the child nodes described below. + +properties: + compatible: + const: ti,lp3943 + + reg: + maxItems: 1 + description: I2C slave address, from 0x60 to 0x67 + +patternProperties: + "^gpio": + type: object + $ref: /schemas/gpio/trivial-gpio.yaml# + + "^pwm": + type: object + $ref: /schemas/pwm/pwm-lp3943.yaml# + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + lp3943: gpio@60 { + compatible = "ti,lp3943"; + reg = <0x60>; + + gpio { + compatible = "ti,lp3943-gpio"; + gpio-controller; + #gpio-cells = <2>; + }; + + pwm { + compatible = "ti,lp3943-pwm"; + #pwm-cells = <2>; + ti,pwm0 = <8 9 10>; + ti,pwm1 = <15>; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/mfd/ti,tps61050.yaml b/Documentation/devicetree/bindings/mfd/ti,tps61050.yaml new file mode 100644 index 000000000000..974ef78d6e26 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/ti,tps61050.yaml @@ -0,0 +1,92 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/ti,tps61050.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments TPS61050/TPS61052 Boost Converter + +maintainers: + - Eduard Bostina + +description: + The TP61050/TPS61052 is a high-power "white LED driver". The device + provides LED, GPIO and regulator functionalities. + +properties: + compatible: + enum: + - ti,tps61050 + - ti,tps61052 + + reg: + maxItems: 1 + + regulator: + type: object + $ref: /schemas/regulator/regulator.yaml# + description: Puts the chip in regulator mode. + unevaluatedProperties: false + + led: + type: object + $ref: /schemas/leds/common.yaml# + description: Puts the chip in LED mode. + unevaluatedProperties: false + +required: + - compatible + - reg + +allOf: + - not: + required: + - regulator + - led + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + tps61052@33 { + compatible = "ti,tps61052"; + reg = <0x33>; + }; + }; + + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + tps61052@33 { + compatible = "ti,tps61052"; + reg = <0x33>; + + regulator { + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + }; + }; + + - | + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + tps61052@33 { + compatible = "ti,tps61052"; + reg = <0x33>; + + led { + color = ; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/ti,tps65086.yaml b/Documentation/devicetree/bindings/mfd/ti,tps65086.yaml index a8eed9065d96..64f02d1e1e4d 100644 --- a/Documentation/devicetree/bindings/mfd/ti,tps65086.yaml +++ b/Documentation/devicetree/bindings/mfd/ti,tps65086.yaml @@ -90,7 +90,6 @@ required: - reg - gpio-controller - '#gpio-cells' - - regulators examples: - | diff --git a/Documentation/devicetree/bindings/mfd/ti,tps65910.yaml b/Documentation/devicetree/bindings/mfd/ti,tps65910.yaml index 31a2f77a463b..29f1901db6c9 100644 --- a/Documentation/devicetree/bindings/mfd/ti,tps65910.yaml +++ b/Documentation/devicetree/bindings/mfd/ti,tps65910.yaml @@ -37,6 +37,8 @@ properties: interrupt-controller: true + wakeup-source: true + '#interrupt-cells': description: Specifies the IRQ number and flags const: 2 @@ -169,6 +171,12 @@ patternProperties: vcc7-supply: VRTC input. vccio-supply: VIO input. + "^.+-hog$": + type: object + + required: + - gpio-hog + required: - compatible - reg diff --git a/Documentation/devicetree/bindings/mfd/ti,twl6040.yaml b/Documentation/devicetree/bindings/mfd/ti,twl6040.yaml new file mode 100644 index 000000000000..5efcd79b527c --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/ti,twl6040.yaml @@ -0,0 +1,156 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/ti,twl6040.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments TWL6040 family audio codec + +maintainers: + - Eduard Bostina + +description: + The TWL6040s are 8-channel high quality low-power audio codecs providing + audio, vibra and GPO functionality on OMAP4+ platforms. They are connected + to the host processor via i2c for commands, McPDM for audio data and + commands. + +properties: + compatible: + enum: + - ti,twl6040 + - ti,twl6041 + + reg: + const: 0x4b + + interrupts: + maxItems: 1 + + gpio-controller: true + + "#gpio-cells": + const: 1 + + "#clock-cells": + const: 0 + + ti,audpwron-gpio: + maxItems: 1 + description: Power on GPIO line for the twl6040 + + vio-supply: + description: Regulator for the twl6040 VIO supply + + v2v1-supply: + description: Regulator for the twl6040 V2V1 supply + + enable-active-high: + type: boolean + description: To power on the twl6040 during boot. + + clocks: + minItems: 1 + maxItems: 2 + + clock-names: + minItems: 1 + maxItems: 2 + items: + enum: + - clk32k + - mclk + + vddvibl-supply: + description: Regulator for the left vibra motor + + vddvibr-supply: + description: Regulator for the right vibra motor + + vibra: + type: object + additionalProperties: false + properties: + ti,vibldrv-res: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Resistance parameter for left driver + + ti,vibrdrv-res: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Resistance parameter for right driver + + ti,viblmotor-res: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Resistance parameter for left motor + + ti,vibrmotor-res: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Resistance parameter for right motor + + ti,vddvibl-uV: + $ref: /schemas/types.yaml#/definitions/uint32 + description: vddvibl default voltage if it needs to be changed + + ti,vddvibr-uV: + $ref: /schemas/types.yaml#/definitions/uint32 + description: vddvibr default voltage if it needs to be changed + + required: + - ti,vibldrv-res + - ti,vibrdrv-res + - ti,viblmotor-res + - ti,vibrmotor-res + +required: + - compatible + - reg + - interrupts + - "#clock-cells" + - vio-supply + - v2v1-supply + +allOf: + - if: + required: + - vibra + then: + required: + - vddvibl-supply + - vddvibr-supply + +additionalProperties: false + +examples: + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + audio-codec@4b { + compatible = "ti,twl6040"; + reg = <0x4b>; + interrupts = <0 119 IRQ_TYPE_LEVEL_HIGH>; + interrupt-parent = <&gic>; + gpio-controller; + #gpio-cells = <1>; + #clock-cells = <0>; + ti,audpwron-gpio = <&gpio4 31 0>; + + vio-supply = <&v1v8>; + v2v1-supply = <&v2v1>; + enable-active-high; + + /* regulators for vibra motor */ + vddvibl-supply = <&vbat>; + vddvibr-supply = <&vbat>; + + vibra { + ti,vibldrv-res = <8>; + ti,vibrdrv-res = <3>; + ti,viblmotor-res = <10>; + ti,vibrmotor-res = <10>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/ti-keystone-devctrl.txt b/Documentation/devicetree/bindings/mfd/ti-keystone-devctrl.txt deleted file mode 100644 index 71a1f5963936..000000000000 --- a/Documentation/devicetree/bindings/mfd/ti-keystone-devctrl.txt +++ /dev/null @@ -1,19 +0,0 @@ -* Device tree bindings for Texas Instruments keystone device state control - -The Keystone II devices have a set of registers that are used to control -the status of its peripherals. This node is intended to allow access to -this functionality. - -Required properties: - -- compatible: "ti,keystone-devctrl", "syscon" - -- reg: contains offset/length value for device state control - registers space. - -Example: - -devctrl: device-state-control@02620000 { - compatible = "ti,keystone-devctrl", "syscon"; - reg = <0x02620000 0x1000>; -}; diff --git a/Documentation/devicetree/bindings/mfd/tps6105x.txt b/Documentation/devicetree/bindings/mfd/tps6105x.txt deleted file mode 100644 index dc448a9d5b4d..000000000000 --- a/Documentation/devicetree/bindings/mfd/tps6105x.txt +++ /dev/null @@ -1,62 +0,0 @@ -* Device tree bindings for TI TPS61050/61052 Boost Converters - -The TP61050/TPS61052 is a high-power "white LED driver". The -device provides LED, GPIO and regulator functionalities. - -Required properties: -- compatible: "ti,tps61050" or "ti,tps61052" -- reg: Specifies the I2C slave address - -Optional sub-node: - -This subnode selects the chip's operational mode. -There can be at most one single available subnode. - -- regulator: presence of this sub-node puts the chip in regulator mode. - see ../regulator/regulator.yaml - -- led: presence of this sub-node puts the chip in led mode. - Optional properties: - - function : see ../leds/common.txt - - color : see ../leds/common.txt - - label : see ../leds/common.txt - (deprecated) - -Example (GPIO operation only): - -i2c0 { - tps61052@33 { - compatible = "ti,tps61052"; - reg = <0x33>; - }; -}; - -Example (GPIO + regulator operation): - -i2c0 { - tps61052@33 { - compatible = "ti,tps61052"; - reg = <0x33>; - - regulator { - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - regulator-always-on; - }; - }; -}; - -Example (GPIO + led operation): - -#include - -i2c0 { - tps61052@33 { - compatible = "ti,tps61052"; - reg = <0x33>; - - led { - color = ; - }; - }; -}; diff --git a/Documentation/devicetree/bindings/mfd/twl6040.txt b/Documentation/devicetree/bindings/mfd/twl6040.txt deleted file mode 100644 index dfd8683ede0c..000000000000 --- a/Documentation/devicetree/bindings/mfd/twl6040.txt +++ /dev/null @@ -1,67 +0,0 @@ -Texas Instruments TWL6040 family - -The TWL6040s are 8-channel high quality low-power audio codecs providing audio, -vibra and GPO functionality on OMAP4+ platforms. -They are connected to the host processor via i2c for commands, McPDM for audio -data and commands. - -Required properties: -- compatible : "ti,twl6040" for twl6040, "ti,twl6041" for twl6041 -- reg: must be 0x4b for i2c address -- interrupts: twl6040 has one interrupt line connecteded to the main SoC -- gpio-controller: -- #gpio-cells = <1>: twl6040 provides GPO lines. -- #clock-cells = <0>; twl6040 is a provider of pdmclk which is used by McPDM -- twl6040,audpwron-gpio: Power on GPIO line for the twl6040 - -- vio-supply: Regulator for the twl6040 VIO supply -- v2v1-supply: Regulator for the twl6040 V2V1 supply - -Optional properties, nodes: -- enable-active-high: To power on the twl6040 during boot. -- clocks: phandle to the clk32k and/or to mclk clock provider -- clock-names: Must be "clk32k" for the 32K clock and "mclk" for the MCLK. - -Vibra functionality -Required properties: -- vddvibl-supply: Regulator for the left vibra motor -- vddvibr-supply: Regulator for the right vibra motor -- vibra { }: Configuration section for vibra parameters containing the following - properties: -- ti,vibldrv-res: Resistance parameter for left driver -- ti,vibrdrv-res: Resistance parameter for right driver -- ti,viblmotor-res: Resistance parameter for left motor -- ti,viblmotor-res: Resistance parameter for right motor - -Optional properties within vibra { } section: -- vddvibl_uV: If the vddvibl default voltage need to be changed -- vddvibr_uV: If the vddvibr default voltage need to be changed - -Example: -&i2c1 { - twl6040: twl@4b { - compatible = "ti,twl6040"; - - interrupts = <0 119 4>; - interrupt-parent = <&gic>; - twl6040,audpwron-gpio = <&gpio4 31 0>; - - vio-supply = <&v1v8>; - v2v1-supply = <&v2v1>; - enable-active-high; - - /* regulators for vibra motor */ - vddvibl-supply = <&vbat>; - vddvibr-supply = <&vbat>; - - vibra { - /* Vibra driver, motor resistance parameters */ - ti,vibldrv-res = <8>; - ti,vibrdrv-res = <3>; - ti,viblmotor-res = <10>; - ti,vibrmotor-res = <10>; - }; - }; -}; - -/include/ "twl6040.dtsi" diff --git a/Documentation/devicetree/bindings/mfd/x-powers,ac200.yaml b/Documentation/devicetree/bindings/mfd/x-powers,ac200.yaml new file mode 100644 index 000000000000..75dafa7c1071 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/x-powers,ac200.yaml @@ -0,0 +1,168 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/x-powers,ac200.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: X-Powers AC200 mixed-signal IC + +maintainers: + - James Hilliard + - Jernej Skrabec + +description: + The AC200 is a mixed-signal companion IC containing audio, video, RTC and + Fast Ethernet PHY functions. Its control registers are accessed over I2C. + The audio codec and TV encoder are described by properties of this node. + The Ethernet PHY is described separately on its MDIO bus. + +allOf: + - $ref: /schemas/sound/dai-common.yaml# + +properties: + compatible: + const: x-powers,ac200 + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + description: + AC200 input clock. When using the Ethernet PHY, its configured rate must + be 24 or 27 MHz, matching the rates encoded by the documented EPHY clock + selector. + + interrupts: + maxItems: 1 + description: + The shared, level-triggered, open-drain INTB output for the TV encoder, + Ethernet PHY and RTC interrupts. Omit when INTB is not connected. TV + encoder cable detection status can also be read over I2C without an + interrupt. + + '#sound-dai-cells': + const: 0 + + ac-ldoin-supply: + description: + The 3.3 V supply connected to the AC_LDOIN pin for the audio codec LDO + input. This may be the same regulator as tv-vcc-supply. + + tv-vcc-supply: + description: + The 3.3 V supply connected to the TV_VCC pin for the composite-video + DAC. This may be the same regulator as ac-ldoin-supply. + + nvmem-cells: + maxItems: 1 + description: TV encoder bandgap calibration. + + nvmem-cell-names: + items: + - const: bandgap + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + properties: + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: Input to the TV encoder, carrying CCIR656. + + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: Output to the composite-video connector. + + required: + - port@0 + - port@1 + +required: + - compatible + - reg + - clocks + +dependencies: + '#sound-dai-cells': [ ac-ldoin-supply ] + ports: [ tv-vcc-supply ] + nvmem-cells: [ nvmem-cell-names ] + nvmem-cell-names: [ nvmem-cells ] + +unevaluatedProperties: false + +examples: + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + mixed-signal@10 { + compatible = "x-powers,ac200"; + reg = <0x10>; + clocks = <&pwm 5>; + interrupt-parent = <&pio>; + interrupts = <1 20 IRQ_TYPE_LEVEL_LOW>; + #sound-dai-cells = <0>; + ac-ldoin-supply = <®_aldo2>; + tv-vcc-supply = <®_aldo2>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + tve_in: endpoint { + remote-endpoint = <&tcon_out_tve>; + }; + }; + + port@1 { + reg = <1>; + + tve_out: endpoint { + remote-endpoint = <&composite_in>; + }; + }; + }; + }; + }; + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + mixed-signal@10 { + compatible = "x-powers,ac200"; + reg = <0x10>; + clocks = <&pwm 5>; + /* INTB is not connected. */ + tv-vcc-supply = <®_aldo2>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + endpoint { + remote-endpoint = <&tcon_out_tve>; + }; + }; + + port@1 { + reg = <1>; + + endpoint { + remote-endpoint = <&composite_in>; + }; + }; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-rk805.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-rk805.txt deleted file mode 100644 index 6ad49e51c72e..000000000000 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-rk805.txt +++ /dev/null @@ -1,63 +0,0 @@ -Pincontrol driver for RK805 Power management IC. - -RK805 has 2 pins which can be configured as GPIO output only. - -Please refer file -for details of the common pinctrl bindings used by client devices, -including the meaning of the phrase "pin configuration node". - -Optional Pinmux properties: --------------------------- -Following properties are required if default setting of pins are required -at boot. -- pinctrl-names: A pinctrl state named per . -- pinctrl[0...n]: Properties to contain the phandle for pinctrl states per - . - -The pin configurations are defined as child of the pinctrl states node. Each -sub-node have following properties: - -Required properties: ------------------- -- #gpio-cells: Should be two. The first cell is the pin number and the - second is the GPIO flags. - -- gpio-controller: Marks the device node as a GPIO controller. - -- pins: List of pins. Valid values of pins properties are: gpio0, gpio1. - -First 2 properties must be added in the RK805 PMIC node, documented in -Documentation/devicetree/bindings/mfd/rockchip,rk808.yaml - -Optional properties: -------------------- -Following are optional properties defined as pinmux DT binding document -. Absence of properties will leave the configuration -on default. - function, - output-low, - output-high. - -Valid values for function properties are: gpio. - -There are also not customised properties for any GPIO. - -Example: --------- -rk805: rk805@18 { - compatible = "rockchip,rk805"; - ... - gpio-controller; - #gpio-cells = <2>; - - pinctrl-names = "default"; - pinctrl-0 = <&pmic_int_l>, <&rk805_default>; - - rk805_default: pinmux { - gpio01 { - pins = "gpio0", "gpio1"; - function = "gpio"; - output-high; - }; - }; -}; diff --git a/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt b/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt deleted file mode 100644 index f214305a8f5e..000000000000 --- a/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt +++ /dev/null @@ -1,58 +0,0 @@ -TI/National Semiconductor LP3943 PWM controller - -Required properties: - - compatible: "ti,lp3943-pwm" - - #pwm-cells: Should be 2. See pwm.yaml in this directory for a - description of the cells format. - Note that this hardware limits the period length to the - range 6250~1600000. - - ti,pwm0 or ti,pwm1: Output pin number(s) for PWM channel 0 or 1. - 0 = output 0 - 1 = output 1 - . - . - 15 = output 15 - -Example: -PWM 0 is for RGB LED brightness control -PWM 1 is for brightness control of LP8557 backlight device - -&i2c3 { - lp3943@60 { - compatible = "ti,lp3943"; - reg = <0x60>; - - /* - * PWM 0 : output 8, 9 and 10 - * PWM 1 : output 15 - */ - pwm3943: pwm { - compatible = "ti,lp3943-pwm"; - #pwm-cells = <2>; - ti,pwm0 = <8 9 10>; - ti,pwm1 = <15>; - }; - }; - -}; - -/* LEDs control with PWM 0 of LP3943 */ -pwmleds { - compatible = "pwm-leds"; - rgb { - label = "indi::rgb"; - pwms = <&pwm3943 0 10000>; - max-brightness = <255>; - }; -}; - -&i2c4 { - /* Backlight control with PWM 1 of LP3943 */ - backlight@2c { - compatible = "ti,lp8557"; - reg = <0x2c>; - - pwms = <&pwm3943 1 10000>; - pwm-names = "lp8557"; - }; -}; diff --git a/Documentation/devicetree/bindings/pwm/pwm-lp3943.yaml b/Documentation/devicetree/bindings/pwm/pwm-lp3943.yaml new file mode 100644 index 000000000000..3da5cd4b2ada --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/pwm-lp3943.yaml @@ -0,0 +1,80 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pwm/pwm-lp3943.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI/National Semiconductor LP3943 PWM controller + +maintainers: + - Chaosheng Qu + +description: + LP3943 has two internal PWM channels. Each channel can be routed to one or + more of the 16 outputs of the device. + + Note that the hardware limits the period length to the range 6250~1600000. + +allOf: + - $ref: pwm.yaml# + +properties: + compatible: + const: ti,lp3943-pwm + + "#pwm-cells": + const: 2 + + ti,pwm0: + description: Output pin number(s) for PWM channel 0. + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 1 + maxItems: 16 + items: + minimum: 0 + maximum: 15 + + ti,pwm1: + description: Output pin number(s) for PWM channel 1. + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 1 + maxItems: 16 + items: + minimum: 0 + maximum: 15 + +anyOf: + - required: + - ti,pwm0 + - required: + - ti,pwm1 + +required: + - compatible + - "#pwm-cells" + +unevaluatedProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + gpio@60 { + compatible = "ti,lp3943"; + reg = <0x60>; + + /* + * PWM 0 : output 8, 9 and 10 + * PWM 1 : output 15 + */ + pwm { + compatible = "ti,lp3943-pwm"; + #pwm-cells = <2>; + ti,pwm0 = <8 9 10>; + ti,pwm1 = <15>; + }; + }; + }; +... diff --git a/MAINTAINERS b/MAINTAINERS index e39af4e16095..ec0cc5e755ab 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19007,7 +19007,7 @@ MULTIFUNCTION DEVICES (MFD) M: Lee Jones L: mfd@lists.linux.dev S: Maintained -T: git git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next F: Documentation/devicetree/bindings/mfd/ F: drivers/mfd/ F: include/dt-bindings/mfd/ @@ -27145,7 +27145,7 @@ SYSTEM CONFIGURATION (SYSCON) M: Lee Jones M: Arnd Bergmann S: Supported -T: git git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next F: drivers/mfd/syscon.c SYSTEM CONTROL & POWER/MANAGEMENT INTERFACE (SCPI/SCMI) Message Protocol drivers @@ -30133,6 +30133,14 @@ F: drivers/net/wwan/ F: include/linux/wwan.h F: include/uapi/linux/wwan.h +X-POWERS AC200 DRIVERS +M: Jernej Skrabec +M: James Hilliard +L: linux-sunxi@lists.linux.dev +S: Maintained +F: Documentation/devicetree/bindings/mfd/x-powers,ac200.yaml +F: drivers/mfd/ac200.c + X-POWERS AXP288 PMIC DRIVERS M: Hans de Goede S: Maintained diff --git a/drivers/iio/light/lm3533-als.c b/drivers/iio/light/lm3533-als.c index 5db9591a85b9..218cb93b4cf9 100644 --- a/drivers/iio/light/lm3533-als.c +++ b/drivers/iio/light/lm3533-als.c @@ -18,14 +18,17 @@ #include #include #include +#include +#include #include #include +#include #include -#define LM3533_ALS_RESISTOR_MIN 1 -#define LM3533_ALS_RESISTOR_MAX 127 +#define LM3533_ALS_RESISTOR_MIN_OHMS 1575 +#define LM3533_ALS_RESISTOR_MAX_OHMS 200000 #define LM3533_ALS_CHANNEL_CURRENT_MAX 2 #define LM3533_ALS_THRESH_MAX 3 #define LM3533_ALS_ZONE_MAX 4 @@ -49,7 +52,7 @@ struct lm3533_als { - struct lm3533 *lm3533; + struct regmap *regmap; struct platform_device *pdev; unsigned long flags; @@ -57,6 +60,9 @@ struct lm3533_als { atomic_t zone; struct mutex thresh_mutex; + + u32 r_select; + bool pwm_mode; }; @@ -65,7 +71,7 @@ static int lm3533_als_get_adc(struct iio_dev *indio_dev, bool average, { struct lm3533_als *als = iio_priv(indio_dev); u8 reg; - u8 val; + u32 val; int ret; if (average) @@ -73,7 +79,7 @@ static int lm3533_als_get_adc(struct iio_dev *indio_dev, bool average, else reg = LM3533_REG_ALS_READ_ADC_RAW; - ret = lm3533_read(als->lm3533, reg, &val); + ret = regmap_read(als->regmap, reg, &val); if (ret) { dev_err(&indio_dev->dev, "failed to read adc\n"); return ret; @@ -87,10 +93,10 @@ static int lm3533_als_get_adc(struct iio_dev *indio_dev, bool average, static int _lm3533_als_get_zone(struct iio_dev *indio_dev, u8 *zone) { struct lm3533_als *als = iio_priv(indio_dev); - u8 val; + u32 val; int ret; - ret = lm3533_read(als->lm3533, LM3533_REG_ALS_ZONE_INFO, &val); + ret = regmap_read(als->regmap, LM3533_REG_ALS_ZONE_INFO, &val); if (ret) { dev_err(&indio_dev->dev, "failed to read zone\n"); return ret; @@ -128,7 +134,7 @@ static inline u8 lm3533_als_get_target_reg(unsigned channel, unsigned zone) } static int lm3533_als_get_target(struct iio_dev *indio_dev, unsigned channel, - unsigned zone, u8 *val) + unsigned zone, u32 *val) { struct lm3533_als *als = iio_priv(indio_dev); u8 reg; @@ -141,7 +147,7 @@ static int lm3533_als_get_target(struct iio_dev *indio_dev, unsigned channel, return -EINVAL; reg = lm3533_als_get_target_reg(channel, zone); - ret = lm3533_read(als->lm3533, reg, val); + ret = regmap_read(als->regmap, reg, val); if (ret) dev_err(&indio_dev->dev, "failed to get target current\n"); @@ -162,7 +168,7 @@ static int lm3533_als_set_target(struct iio_dev *indio_dev, unsigned channel, return -EINVAL; reg = lm3533_als_get_target_reg(channel, zone); - ret = lm3533_write(als->lm3533, reg, val); + ret = regmap_write(als->regmap, reg, val); if (ret) dev_err(&indio_dev->dev, "failed to set target current\n"); @@ -172,8 +178,8 @@ static int lm3533_als_set_target(struct iio_dev *indio_dev, unsigned channel, static int lm3533_als_get_current(struct iio_dev *indio_dev, unsigned channel, int *val) { + u32 target; u8 zone; - u8 target; int ret; ret = lm3533_als_get_zone(indio_dev, &zone); @@ -272,16 +278,10 @@ static irqreturn_t lm3533_als_isr(int irq, void *dev_id) static int lm3533_als_set_int_mode(struct iio_dev *indio_dev, int enable) { struct lm3533_als *als = iio_priv(indio_dev); - u8 mask = LM3533_ALS_INT_ENABLE_MASK; - u8 val; int ret; - if (enable) - val = mask; - else - val = 0; - - ret = lm3533_update(als->lm3533, LM3533_REG_ALS_ZONE_INFO, val, mask); + ret = regmap_assign_bits(als->regmap, LM3533_REG_ALS_ZONE_INFO, + LM3533_ALS_INT_ENABLE_MASK, enable); if (ret) { dev_err(&indio_dev->dev, "failed to set int mode %d\n", enable); @@ -294,17 +294,16 @@ static int lm3533_als_set_int_mode(struct iio_dev *indio_dev, int enable) static int lm3533_als_get_int_mode(struct iio_dev *indio_dev, int *enable) { struct lm3533_als *als = iio_priv(indio_dev); - u8 mask = LM3533_ALS_INT_ENABLE_MASK; - u8 val; int ret; - ret = lm3533_read(als->lm3533, LM3533_REG_ALS_ZONE_INFO, &val); - if (ret) { + ret = regmap_test_bits(als->regmap, LM3533_REG_ALS_ZONE_INFO, + LM3533_ALS_INT_ENABLE_MASK); + if (ret < 0) { dev_err(&indio_dev->dev, "failed to get int mode\n"); return ret; } - *enable = !!(val & mask); + *enable = ret; return 0; } @@ -317,7 +316,7 @@ static inline u8 lm3533_als_get_threshold_reg(unsigned nr, bool raising) } static int lm3533_als_get_threshold(struct iio_dev *indio_dev, unsigned nr, - bool raising, u8 *val) + bool raising, u32 *val) { struct lm3533_als *als = iio_priv(indio_dev); u8 reg; @@ -327,7 +326,7 @@ static int lm3533_als_get_threshold(struct iio_dev *indio_dev, unsigned nr, return -EINVAL; reg = lm3533_als_get_threshold_reg(nr, raising); - ret = lm3533_read(als->lm3533, reg, val); + ret = regmap_read(als->regmap, reg, val); if (ret) dev_err(&indio_dev->dev, "failed to get threshold\n"); @@ -338,8 +337,8 @@ static int lm3533_als_set_threshold(struct iio_dev *indio_dev, unsigned nr, bool raising, u8 val) { struct lm3533_als *als = iio_priv(indio_dev); - u8 val2; u8 reg, reg2; + u32 val2; int ret; if (nr > LM3533_ALS_THRESH_MAX) @@ -349,7 +348,7 @@ static int lm3533_als_set_threshold(struct iio_dev *indio_dev, unsigned nr, reg2 = lm3533_als_get_threshold_reg(nr, !raising); mutex_lock(&als->thresh_mutex); - ret = lm3533_read(als->lm3533, reg2, &val2); + ret = regmap_read(als->regmap, reg2, &val2); if (ret) { dev_err(&indio_dev->dev, "failed to get threshold\n"); goto out; @@ -364,7 +363,7 @@ static int lm3533_als_set_threshold(struct iio_dev *indio_dev, unsigned nr, goto out; } - ret = lm3533_write(als->lm3533, reg, val); + ret = regmap_write(als->regmap, reg, val); if (ret) { dev_err(&indio_dev->dev, "failed to set threshold\n"); goto out; @@ -376,11 +375,11 @@ static int lm3533_als_set_threshold(struct iio_dev *indio_dev, unsigned nr, } static int lm3533_als_get_hysteresis(struct iio_dev *indio_dev, unsigned nr, - u8 *val) + u32 *val) { struct lm3533_als *als = iio_priv(indio_dev); - u8 falling; - u8 raising; + u32 falling; + u32 raising; int ret; if (nr > LM3533_ALS_THRESH_MAX) @@ -410,7 +409,7 @@ static ssize_t show_thresh_either_en(struct device *dev, int enable; int ret; - if (als->irq) { + if (als->irq > 0) { ret = lm3533_als_get_int_mode(indio_dev, &enable); if (ret) return ret; @@ -432,7 +431,7 @@ static ssize_t store_thresh_either_en(struct device *dev, u8 zone; int ret; - if (!als->irq) + if (als->irq <= 0) return -EBUSY; ret = kstrtoul(buf, 0, &enable); @@ -505,7 +504,7 @@ static ssize_t show_als_attr(struct device *dev, { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct lm3533_als_attribute *als_attr = to_lm3533_als_attr(attr); - u8 val; + u32 val; int ret; switch (als_attr->type) { @@ -717,71 +716,51 @@ static const struct attribute_group lm3533_als_attribute_group = { .attrs = lm3533_als_attributes }; -static int lm3533_als_set_input_mode(struct lm3533_als *als, bool pwm_mode) +static int lm3533_als_setup(struct lm3533_als *als) { - u8 mask = LM3533_ALS_INPUT_MODE_MASK; - u8 val; + struct device *dev = &als->pdev->dev; int ret; - if (pwm_mode) - val = mask; /* pwm input */ - else - val = 0; /* analog input */ + als->pwm_mode = device_property_read_bool(dev, "ti,pwm-mode"); - ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, val, mask); - if (ret) { - dev_err(&als->pdev->dev, "failed to set input mode %d\n", - pwm_mode); - return ret; - } - - return 0; -} - -static int lm3533_als_set_resistor(struct lm3533_als *als, u8 val) -{ - int ret; - - if (val < LM3533_ALS_RESISTOR_MIN || val > LM3533_ALS_RESISTOR_MAX) { - dev_err(&als->pdev->dev, "invalid resistor value\n"); - return -EINVAL; - } - - ret = lm3533_write(als->lm3533, LM3533_REG_ALS_RESISTOR_SELECT, val); - if (ret) { - dev_err(&als->pdev->dev, "failed to set resistor\n"); - return ret; - } - - return 0; -} - -static int lm3533_als_setup(struct lm3533_als *als, - const struct lm3533_als_platform_data *pdata) -{ - int ret; - - ret = lm3533_als_set_input_mode(als, pdata->pwm_mode); + ret = regmap_assign_bits(als->regmap, LM3533_REG_ALS_CONF, + LM3533_ALS_INPUT_MODE_MASK, als->pwm_mode); if (ret) - return ret; + return dev_err_probe(dev, ret, "failed to set input mode %d\n", + als->pwm_mode); /* ALS input is always high impedance in PWM-mode. */ - if (!pdata->pwm_mode) { - ret = lm3533_als_set_resistor(als, pdata->r_select); - if (ret) - return ret; - } + if (als->pwm_mode) + return 0; + + ret = device_property_read_u32(dev, "ti,resistor-ohms", + &als->r_select); + if (ret) + return dev_err_probe(dev, ret, + "failed to ger resistor value\n"); + + if (als->r_select < LM3533_ALS_RESISTOR_MIN_OHMS || + als->r_select > LM3533_ALS_RESISTOR_MAX_OHMS) + return dev_err_probe(dev, -EINVAL, + "invalid resistor value\n"); + + als->r_select = DIV_ROUND_UP(2 * MICRO, 10 * als->r_select); + + ret = regmap_write(als->regmap, LM3533_REG_ALS_RESISTOR_SELECT, + als->r_select); + if (ret) + return dev_err_probe(dev, ret, "failed to set resistor\n"); return 0; } static int lm3533_als_setup_irq(struct lm3533_als *als, void *dev) { - u8 mask = LM3533_ALS_INT_ENABLE_MASK; int ret; /* Make sure interrupts are disabled. */ - ret = lm3533_update(als->lm3533, LM3533_REG_ALS_ZONE_INFO, 0, mask); + ret = regmap_clear_bits(als->regmap, LM3533_REG_ALS_ZONE_INFO, + LM3533_ALS_INT_ENABLE_MASK); if (ret) { dev_err(&als->pdev->dev, "failed to disable interrupts\n"); return ret; @@ -801,10 +780,10 @@ static int lm3533_als_setup_irq(struct lm3533_als *als, void *dev) static int lm3533_als_enable(struct lm3533_als *als) { - u8 mask = LM3533_ALS_ENABLE_MASK; int ret; - ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, mask, mask); + ret = regmap_set_bits(als->regmap, LM3533_REG_ALS_CONF, + LM3533_ALS_ENABLE_MASK); if (ret) dev_err(&als->pdev->dev, "failed to enable ALS\n"); @@ -813,10 +792,10 @@ static int lm3533_als_enable(struct lm3533_als *als) static int lm3533_als_disable(struct lm3533_als *als) { - u8 mask = LM3533_ALS_ENABLE_MASK; int ret; - ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, 0, mask); + ret = regmap_clear_bits(als->regmap, LM3533_REG_ALS_CONF, + LM3533_ALS_ENABLE_MASK); if (ret) dev_err(&als->pdev->dev, "failed to disable ALS\n"); @@ -831,7 +810,6 @@ static const struct iio_info lm3533_als_info = { static int lm3533_als_probe(struct platform_device *pdev) { - const struct lm3533_als_platform_data *pdata; struct lm3533 *lm3533; struct lm3533_als *als; struct iio_dev *indio_dev; @@ -841,12 +819,6 @@ static int lm3533_als_probe(struct platform_device *pdev) if (!lm3533) return -EINVAL; - pdata = dev_get_platdata(&pdev->dev); - if (!pdata) { - dev_err(&pdev->dev, "no platform data\n"); - return -EINVAL; - } - indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*als)); if (!indio_dev) return -ENOMEM; @@ -855,25 +827,27 @@ static int lm3533_als_probe(struct platform_device *pdev) indio_dev->channels = lm3533_als_channels; indio_dev->num_channels = ARRAY_SIZE(lm3533_als_channels); indio_dev->name = dev_name(&pdev->dev); - iio_device_set_parent(indio_dev, pdev->dev.parent); indio_dev->modes = INDIO_DIRECT_MODE; als = iio_priv(indio_dev); - als->lm3533 = lm3533; + als->regmap = lm3533->regmap; als->pdev = pdev; - als->irq = lm3533->irq; + als->irq = platform_get_irq_optional(pdev, 0); + if (als->irq == -EPROBE_DEFER) + return -EPROBE_DEFER; + atomic_set(&als->zone, 0); mutex_init(&als->thresh_mutex); platform_set_drvdata(pdev, indio_dev); - if (als->irq) { + if (als->irq > 0) { ret = lm3533_als_setup_irq(als, indio_dev); if (ret) return ret; } - ret = lm3533_als_setup(als, pdata); + ret = lm3533_als_setup(als); if (ret) goto err_free_irq; @@ -892,7 +866,7 @@ static int lm3533_als_probe(struct platform_device *pdev) err_disable: lm3533_als_disable(als); err_free_irq: - if (als->irq) + if (als->irq > 0) free_irq(als->irq, indio_dev); return ret; @@ -906,13 +880,20 @@ static void lm3533_als_remove(struct platform_device *pdev) lm3533_als_set_int_mode(indio_dev, false); iio_device_unregister(indio_dev); lm3533_als_disable(als); - if (als->irq) + if (als->irq > 0) free_irq(als->irq, indio_dev); } +static const struct of_device_id lm3533_als_match_table[] = { + { .compatible = "ti,lm3533-als" }, + { } +}; +MODULE_DEVICE_TABLE(of, lm3533_als_match_table); + static struct platform_driver lm3533_als_driver = { .driver = { .name = "lm3533-als", + .of_match_table = lm3533_als_match_table, }, .probe = lm3533_als_probe, .remove = lm3533_als_remove, diff --git a/drivers/leds/leds-lm3533.c b/drivers/leds/leds-lm3533.c index 45795f2a1042..7259097bd6a7 100644 --- a/drivers/leds/leds-lm3533.c +++ b/drivers/leds/leds-lm3533.c @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include #include @@ -41,13 +43,18 @@ struct lm3533_led { - struct lm3533 *lm3533; + struct regmap *regmap; struct lm3533_ctrlbank cb; struct led_classdev cdev; int id; struct mutex mutex; unsigned long flags; + + u32 max_current; + u32 pwm; + + bool have_als; }; @@ -80,7 +87,6 @@ static inline u8 lm3533_led_get_pattern_reg(struct lm3533_led *led, static int lm3533_led_pattern_enable(struct lm3533_led *led, int enable) { u8 mask; - u8 val; int pattern; int state; int ret = 0; @@ -96,12 +102,8 @@ static int lm3533_led_pattern_enable(struct lm3533_led *led, int enable) pattern = lm3533_led_get_pattern(led); mask = 1 << (2 * pattern); - if (enable) - val = mask; - else - val = 0; - - ret = lm3533_update(led->lm3533, LM3533_REG_PATTERN_ENABLE, val, mask); + ret = regmap_assign_bits(led->regmap, + LM3533_REG_PATTERN_ENABLE, mask, enable); if (ret) { dev_err(led->cdev.dev, "failed to enable pattern %d (%d)\n", pattern, enable); @@ -131,7 +133,7 @@ static int lm3533_led_set(struct led_classdev *cdev, static enum led_brightness lm3533_led_get(struct led_classdev *cdev) { struct lm3533_led *led = to_lm3533_led(cdev); - u8 val; + u32 val; int ret; ret = lm3533_ctrlbank_get_brightness(&led->cb, &val); @@ -259,7 +261,7 @@ static u8 lm3533_led_delay_set(struct lm3533_led *led, u8 base, dev_dbg(led->cdev.dev, "%s - %lu: %u (0x%02x)\n", __func__, *delay, t, val); reg = lm3533_led_get_pattern_reg(led, base); - ret = lm3533_write(led->lm3533, reg, val); + ret = regmap_write(led->regmap, reg, val); if (ret) dev_err(led->cdev.dev, "failed to set delay (%02x)\n", reg); @@ -337,10 +339,10 @@ static ssize_t show_risefalltime(struct device *dev, struct lm3533_led *led = to_lm3533_led(led_cdev); ssize_t ret; u8 reg; - u8 val; + u32 val; reg = lm3533_led_get_pattern_reg(led, base); - ret = lm3533_read(led->lm3533, reg, &val); + ret = regmap_read(led->regmap, reg, &val); if (ret) return ret; @@ -375,7 +377,7 @@ static ssize_t store_risefalltime(struct device *dev, return -EINVAL; reg = lm3533_led_get_pattern_reg(led, base); - ret = lm3533_write(led->lm3533, reg, val); + ret = regmap_write(led->regmap, reg, val); if (ret) return ret; @@ -405,11 +407,11 @@ static ssize_t show_als_channel(struct device *dev, struct lm3533_led *led = to_lm3533_led(led_cdev); unsigned channel; u8 reg; - u8 val; + u32 val; int ret; reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE); - ret = lm3533_read(led->lm3533, reg, &val); + ret = regmap_read(led->regmap, reg, &val); if (ret) return ret; @@ -441,7 +443,7 @@ static ssize_t store_als_channel(struct device *dev, mask = LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK; val = channel - 1; - ret = lm3533_update(led->lm3533, reg, val, mask); + ret = regmap_update_bits(led->regmap, reg, mask, val); if (ret) return ret; @@ -455,11 +457,11 @@ static ssize_t show_als_en(struct device *dev, struct lm3533_led *led = to_lm3533_led(led_cdev); bool enable; u8 reg; - u8 val; + u32 val; int ret; reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE); - ret = lm3533_read(led->lm3533, reg, &val); + ret = regmap_read(led->regmap, reg, &val); if (ret) return ret; @@ -476,22 +478,15 @@ static ssize_t store_als_en(struct device *dev, struct lm3533_led *led = to_lm3533_led(led_cdev); unsigned enable; u8 reg; - u8 mask; - u8 val; int ret; if (kstrtouint(buf, 0, &enable)) return -EINVAL; reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE); - mask = LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK; - if (enable) - val = mask; - else - val = 0; - - ret = lm3533_update(led->lm3533, reg, val, mask); + ret = regmap_assign_bits(led->regmap, reg, + LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK, enable); if (ret) return ret; @@ -504,12 +499,12 @@ static ssize_t show_linear(struct device *dev, struct led_classdev *led_cdev = dev_get_drvdata(dev); struct lm3533_led *led = to_lm3533_led(led_cdev); u8 reg; - u8 val; + u32 val; int linear; int ret; reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE); - ret = lm3533_read(led->lm3533, reg, &val); + ret = regmap_read(led->regmap, reg, &val); if (ret) return ret; @@ -529,22 +524,15 @@ static ssize_t store_linear(struct device *dev, struct lm3533_led *led = to_lm3533_led(led_cdev); unsigned long linear; u8 reg; - u8 mask; - u8 val; int ret; if (kstrtoul(buf, 0, &linear)) return -EINVAL; reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE); - mask = LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK; - if (linear) - val = mask; - else - val = 0; - - ret = lm3533_update(led->lm3533, reg, val, mask); + ret = regmap_assign_bits(led->regmap, reg, + LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK, linear); if (ret) return ret; @@ -557,7 +545,7 @@ static ssize_t show_pwm(struct device *dev, { struct led_classdev *led_cdev = dev_get_drvdata(dev); struct lm3533_led *led = to_lm3533_led(led_cdev); - u8 val; + u32 val; int ret; ret = lm3533_ctrlbank_get_pwm(&led->cb, &val); @@ -573,10 +561,10 @@ static ssize_t store_pwm(struct device *dev, { struct led_classdev *led_cdev = dev_get_drvdata(dev); struct lm3533_led *led = to_lm3533_led(led_cdev); - u8 val; + u32 val; int ret; - if (kstrtou8(buf, 0, &val)) + if (kstrtou32(buf, 0, &val)) return -EINVAL; ret = lm3533_ctrlbank_set_pwm(&led->cb, val); @@ -615,7 +603,7 @@ static umode_t lm3533_led_attr_is_visible(struct kobject *kobj, if (attr == &dev_attr_als_channel.attr || attr == &dev_attr_als_en.attr) { - if (!led->lm3533->have_als) + if (!led->have_als) mode = 0; } @@ -632,22 +620,20 @@ static const struct attribute_group *lm3533_led_attribute_groups[] = { NULL }; -static int lm3533_led_setup(struct lm3533_led *led, - struct lm3533_led_platform_data *pdata) +static int lm3533_led_setup(struct lm3533_led *led) { int ret; - ret = lm3533_ctrlbank_set_max_current(&led->cb, pdata->max_current); + ret = lm3533_ctrlbank_set_max_current(&led->cb, led->max_current); if (ret) return ret; - return lm3533_ctrlbank_set_pwm(&led->cb, pdata->pwm); + return lm3533_ctrlbank_set_pwm(&led->cb, led->pwm); } static int lm3533_led_probe(struct platform_device *pdev) { struct lm3533 *lm3533; - struct lm3533_led_platform_data *pdata; struct lm3533_led *led; int ret; @@ -657,12 +643,6 @@ static int lm3533_led_probe(struct platform_device *pdev) if (!lm3533) return -EINVAL; - pdata = dev_get_platdata(&pdev->dev); - if (!pdata) { - dev_err(&pdev->dev, "no platform data\n"); - return -EINVAL; - } - if (pdev->id < 0 || pdev->id >= LM3533_LVCTRLBANK_COUNT) { dev_err(&pdev->dev, "illegal LED id %d\n", pdev->id); return -EINVAL; @@ -672,9 +652,9 @@ static int lm3533_led_probe(struct platform_device *pdev) if (!led) return -ENOMEM; - led->lm3533 = lm3533; - led->cdev.name = pdata->name; - led->cdev.default_trigger = pdata->default_trigger; + led->regmap = lm3533->regmap; + led->have_als = lm3533->have_als; + led->cdev.brightness_set_blocking = lm3533_led_set; led->cdev.brightness_get = lm3533_led_get; led->cdev.blink_set = lm3533_led_blink_set; @@ -682,19 +662,28 @@ static int lm3533_led_probe(struct platform_device *pdev) led->cdev.groups = lm3533_led_attribute_groups; led->id = pdev->id; + led->cdev.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s-%d", + pdev->name, led->id); + if (!led->cdev.name) + return -ENOMEM; + + led->cdev.default_trigger = "none"; + device_property_read_string(&pdev->dev, "linux,default-trigger", + &led->cdev.default_trigger); + mutex_init(&led->mutex); /* The class framework makes a callback to get brightness during * registration so use parent device (for error reporting) until * registered. */ - led->cb.lm3533 = lm3533; + led->cb.regmap = lm3533->regmap; led->cb.id = lm3533_led_get_ctrlbank_id(led); led->cb.dev = lm3533->dev; platform_set_drvdata(pdev, led); - ret = led_classdev_register(pdev->dev.parent, &led->cdev); + ret = led_classdev_register(&pdev->dev, &led->cdev); if (ret) { dev_err(&pdev->dev, "failed to register LED %d\n", pdev->id); return ret; @@ -702,7 +691,14 @@ static int lm3533_led_probe(struct platform_device *pdev) led->cb.dev = led->cdev.dev; - ret = lm3533_led_setup(led, pdata); + device_property_read_u32(&pdev->dev, "led-max-microamp", + &led->max_current); + led->max_current = clamp(led->max_current, LM3533_MAX_CURRENT_MIN, + LM3533_MAX_CURRENT_MAX); + + device_property_read_u32(&pdev->dev, "ti,pwm-config-mask", &led->pwm); + + ret = lm3533_led_setup(led); if (ret) goto err_deregister; @@ -739,9 +735,16 @@ static void lm3533_led_shutdown(struct platform_device *pdev) lm3533_led_set(&led->cdev, LED_OFF); /* disable blink */ } +static const struct of_device_id lm3533_led_match_table[] = { + { .compatible = "ti,lm3533-leds" }, + { } +}; +MODULE_DEVICE_TABLE(of, lm3533_led_match_table); + static struct platform_driver lm3533_led_driver = { .driver = { .name = "lm3533-leds", + .of_match_table = lm3533_led_match_table, }, .probe = lm3533_led_probe, .remove = lm3533_led_remove, diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c index e9941da58b18..7f3e312b8f73 100644 --- a/drivers/mfd/88pm800.c +++ b/drivers/mfd/88pm800.c @@ -275,10 +275,10 @@ static int device_gpadc_init(struct pm80x_chip *chip, goto out; /* - * the defult of PM800 is GPADC operates at 100Ks/s rate + * the default of PM800 is GPADC operates at 100Ks/s rate * and Number of GPADC slots with active current bias prior * to GPADC sampling = 1 slot for all GPADCs set for - * Temprature mesurmants + * Temperature measurements */ mask = (PM800_GPADC_GP_BIAS_EN0 | PM800_GPADC_GP_BIAS_EN1 | PM800_GPADC_GP_BIAS_EN2 | PM800_GPADC_GP_BIAS_EN3); diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 439dbf5ee110..87ed55c155f0 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -205,6 +205,20 @@ config MFD_AC100 This driver include only the core APIs. You have to select individual components like codecs or RTC under the corresponding menus. +config MFD_AC200 + tristate "X-Powers AC200" + depends on COMMON_CLK + depends on I2C + depends on OF + select MFD_CORE + select REGMAP_I2C + help + Support for the X-Powers AC200 mixed-signal companion IC. The AC200 + contains audio, video, RTC and Fast Ethernet PHY functions and is + co-packaged with some Allwinner H6 and H616 SoCs. This driver provides + the shared register access and instantiates the individual function + devices. + config MFD_AXP20X tristate select MFD_CORE @@ -1006,6 +1020,8 @@ config MFD_MAX77705 depends on I2C select MFD_CORE select MFD_SIMPLE_MFD_I2C + select REGMAP_I2C + select REGMAP_IRQ help Say yes here to add support for Maxim Integrated MAX77705 PMIC. This is a Power Management IC with Charger, safe LDOs, Flash, Haptic diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 72d3944b0ad8..f8101d2a9ce9 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -150,6 +150,7 @@ obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o obj-$(CONFIG_MFD_AC100) += ac100.o +obj-$(CONFIG_MFD_AC200) += ac200.o obj-$(CONFIG_MFD_AXP20X) += axp20x.o obj-$(CONFIG_MFD_AXP20X_I2C) += axp20x-i2c.o obj-$(CONFIG_MFD_AXP20X_RSB) += axp20x-rsb.o diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 86fa99022cb3..d5602b2f4a0e 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -125,7 +125,7 @@ static u8 turn_on_stat_set; /* * Map interrupt numbers to the LATCH and MASK register offsets, Interrupt - * numbers are indexed into this array with (num / 8). The interupts are + * numbers are indexed into this array with (num / 8). The interrupts are * defined in linux/mfd/ab8500.h * * This is one off from the register names, i.e. AB8500_IT_MASK1_REG is at @@ -1194,39 +1194,41 @@ static int ab8500_probe(struct platform_device *pdev) return ret; if (is_ab9540(ab8500)) - ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs, - ARRAY_SIZE(ab9540_devs), NULL, - 0, ab8500->domain); + ret = devm_mfd_add_devices(ab8500->dev, 0, ab9540_devs, + ARRAY_SIZE(ab9540_devs), NULL, + 0, ab8500->domain); else if (is_ab8540(ab8500)) { - ret = mfd_add_devices(ab8500->dev, 0, ab8540_devs, - ARRAY_SIZE(ab8540_devs), NULL, - 0, ab8500->domain); + ret = devm_mfd_add_devices(ab8500->dev, 0, ab8540_devs, + ARRAY_SIZE(ab8540_devs), NULL, + 0, ab8500->domain); if (ret) return ret; if (is_ab8540_1p2_or_earlier(ab8500)) - ret = mfd_add_devices(ab8500->dev, 0, ab8540_cut1_devs, - ARRAY_SIZE(ab8540_cut1_devs), NULL, - 0, ab8500->domain); + ret = devm_mfd_add_devices(ab8500->dev, 0, + ab8540_cut1_devs, + ARRAY_SIZE(ab8540_cut1_devs), + NULL, 0, ab8500->domain); else /* ab8540 >= cut2 */ - ret = mfd_add_devices(ab8500->dev, 0, ab8540_cut2_devs, - ARRAY_SIZE(ab8540_cut2_devs), NULL, - 0, ab8500->domain); + ret = devm_mfd_add_devices(ab8500->dev, 0, + ab8540_cut2_devs, + ARRAY_SIZE(ab8540_cut2_devs), + NULL, 0, ab8500->domain); } else if (is_ab8505(ab8500)) - ret = mfd_add_devices(ab8500->dev, 0, ab8505_devs, - ARRAY_SIZE(ab8505_devs), NULL, - 0, ab8500->domain); + ret = devm_mfd_add_devices(ab8500->dev, 0, ab8505_devs, + ARRAY_SIZE(ab8505_devs), NULL, + 0, ab8500->domain); else - ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs, - ARRAY_SIZE(ab8500_devs), NULL, - 0, ab8500->domain); + ret = devm_mfd_add_devices(ab8500->dev, 0, ab8500_devs, + ARRAY_SIZE(ab8500_devs), NULL, + 0, ab8500->domain); if (ret) return ret; /* Add battery management devices */ - ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs, - ARRAY_SIZE(ab8500_bm_devs), NULL, - 0, ab8500->domain); + ret = devm_mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs, + ARRAY_SIZE(ab8500_bm_devs), NULL, + 0, ab8500->domain); if (ret) dev_err(ab8500->dev, "error adding bm devices\n"); diff --git a/drivers/mfd/ac200.c b/drivers/mfd/ac200.c new file mode 100644 index 000000000000..3c6543a1688c --- /dev/null +++ b/drivers/mfd/ac200.c @@ -0,0 +1,222 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * X-Powers AC200 Core driver + * + * Copyright (C) 2019 Jernej Skrabec + * Copyright (C) 2026 James Hilliard + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define AC200_SYS_CONTROL_REG 0x0002 +#define AC200_SYS_CONTROL_CHIP_RESET_DEASSERT BIT(0) +#define AC200_SYS_IRQ_ENABLE_REG 0x0004 +#define AC200_SYS_IRQ_INTB_ENABLE BIT(15) +#define AC200_SYS_IRQ_INTB_ACTIVE_HIGH BIT(14) +#define AC200_SYS_IRQ_RTC BIT(12) +#define AC200_SYS_IRQ_EPHY BIT(8) +#define AC200_SYS_IRQ_TVE BIT(4) + +/* Interface register accessible from every register page. */ +#define AC200_TWI_REG_ADDR_H 0x00fe +#define AC200_MAX_REG 0xa1f2 + +static const struct regmap_range_cfg ac200_range_cfg[] = { + { + .range_max = AC200_MAX_REG, + .selector_reg = AC200_TWI_REG_ADDR_H, + .selector_mask = 0xff, + .window_len = 256, + }, +}; + +/* + * Each AC200 sub-block can reset independently, invalidating its register + * contents without regmap's knowledge. Cache only the common page selector; + * this avoids a selector read-modify-write for every access on the same page + * without ever returning stale functional-register values. + */ +static bool ac200_volatile_reg(struct device *dev, unsigned int reg) +{ + return reg != AC200_TWI_REG_ADDR_H; +} + +static const struct regmap_config ac200_regmap_config = { + .name = "ac200", + .reg_bits = 8, + .reg_stride = 2, + .val_bits = 16, + .ranges = ac200_range_cfg, + .num_ranges = ARRAY_SIZE(ac200_range_cfg), + .max_register = AC200_MAX_REG, + .volatile_reg = ac200_volatile_reg, + .cache_type = REGCACHE_MAPLE, +}; + +static const char * const ac200_codec_supplies[] = { + "ac-ldoin", +}; + +static const char * const ac200_tve_supplies[] = { + "tv-vcc", +}; + +static const struct resource ac200_tve_resources[] = { + DEFINE_RES_IRQ_NAMED(0, "intb"), +}; + +#define AC200_CELL(_name, _supplies, _resources) \ + { \ + .name = (_name), \ + .parent_supplies = (_supplies), \ + .num_parent_supplies = ARRAY_SIZE(_supplies), \ + .resources = (_resources), \ + .num_resources = MFD_RES_SIZE(_resources), \ + } + +static const struct mfd_cell ac200_cells[] = { + AC200_CELL("ac200-codec", ac200_codec_supplies, NULL), + AC200_CELL("ac200-tve", ac200_tve_supplies, ac200_tve_resources), +}; + +static const struct mfd_cell ac200_noirq_cells[] = { + AC200_CELL("ac200-codec", ac200_codec_supplies, NULL), + AC200_CELL("ac200-tve", ac200_tve_supplies, NULL), +}; + +static void ac200_disable_intb(void *data) +{ + struct regmap *regmap = data; + int ret; + + ret = regmap_clear_bits(regmap, AC200_SYS_IRQ_ENABLE_REG, AC200_SYS_IRQ_INTB_ENABLE); + if (ret) + dev_err(regmap_get_device(regmap), "failed to disable INTB: %d\n", ret); +} + +static int ac200_init_irq(struct device *dev, struct regmap *regmap, int irq) +{ + unsigned int trigger; + u16 value = 0; + int ret; + + trigger = irq_get_trigger_type(irq); + switch (trigger) { + case IRQ_TYPE_LEVEL_HIGH: + value |= AC200_SYS_IRQ_INTB_ACTIVE_HIGH; + break; + case IRQ_TYPE_NONE: + case IRQ_TYPE_LEVEL_LOW: + break; + default: + return dev_err_probe(dev, -EINVAL, + "INTB is level triggered, not type %u\n", trigger); + } + + /* Mask every source before enabling the shared output. */ + ret = regmap_update_bits(regmap, AC200_SYS_IRQ_ENABLE_REG, + AC200_SYS_IRQ_INTB_ENABLE | AC200_SYS_IRQ_INTB_ACTIVE_HIGH | + AC200_SYS_IRQ_RTC | AC200_SYS_IRQ_EPHY | AC200_SYS_IRQ_TVE, value); + if (ret) + return ret; + + /* Children are removed before INTB is disabled and the regmap released. */ + ret = devm_add_action_or_reset(dev, ac200_disable_intb, regmap); + if (ret) + return ret; + + if (trigger == IRQ_TYPE_NONE) { + ret = irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW); + if (ret) + return dev_err_probe(dev, ret, "failed to set INTB trigger\n"); + } + + /* + * Function drivers request INTB with IRQF_SHARED | IRQF_ONESHOT before + * enabling their own source. They check and clear their own status and + * mask their source before freeing the IRQ. No IRQ domain is needed. + */ + return regmap_set_bits(regmap, AC200_SYS_IRQ_ENABLE_REG, AC200_SYS_IRQ_INTB_ENABLE); +} + +static int ac200_probe(struct i2c_client *client) +{ + const struct mfd_cell *cells = ac200_noirq_cells; + unsigned int num_cells = ARRAY_SIZE(ac200_noirq_cells); + struct device *dev = &client->dev; + struct regmap *regmap; + struct clk *clk; + int ret; + + clk = devm_clk_get_enabled(dev, NULL); + if (IS_ERR(clk)) + return dev_err_probe(dev, PTR_ERR(clk), "failed to enable input clock\n"); + + ret = devm_clk_rate_exclusive_get(dev, clk); + if (ret) + return dev_err_probe(dev, ret, "failed to lock clock rate\n"); + + /* + * No minimum delay is documented. Retain the vendor resume path's 40 ms + * wait after enabling the input clock and before register access. + */ + msleep(40); + + regmap = devm_regmap_init_i2c(client, &ac200_regmap_config); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), "failed to initialize regmap\n"); + + ret = regmap_set_bits(regmap, AC200_SYS_CONTROL_REG, AC200_SYS_CONTROL_CHIP_RESET_DEASSERT); + if (ret) + return ret; + + if (client->irq > 0) { + ret = ac200_init_irq(dev, regmap, client->irq); + if (ret) + return ret; + cells = ac200_cells; + num_cells = ARRAY_SIZE(ac200_cells); + } + + /* Function drivers read their firmware properties from the parent. */ + ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, cells, num_cells, + NULL, client->irq, NULL); + if (ret) + return dev_err_probe(dev, ret, "failed to add function devices\n"); + + return 0; +} + +static const struct of_device_id ac200_of_match[] = { + { .compatible = "x-powers,ac200" }, + { } +}; +MODULE_DEVICE_TABLE(of, ac200_of_match); + +static const struct i2c_device_id ac200_i2c_ids[] = { + { .name = "ac200" }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ac200_i2c_ids); + +static struct i2c_driver ac200_driver = { + .driver = { + .name = "ac200", + .of_match_table = ac200_of_match, + }, + .probe = ac200_probe, + .id_table = ac200_i2c_ids, +}; +module_i2c_driver(ac200_driver); + +MODULE_AUTHOR("Jernej Skrabec "); +MODULE_AUTHOR("James Hilliard "); +MODULE_DESCRIPTION("X-Powers AC200 Core driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/bq257xx.c b/drivers/mfd/bq257xx.c index 054342c60b73..01f5fc97f538 100644 --- a/drivers/mfd/bq257xx.c +++ b/drivers/mfd/bq257xx.c @@ -52,8 +52,18 @@ static const struct regmap_access_table bq25792_writeable_regs = { }; static const struct regmap_range bq25792_volatile_reg_ranges[] = { + regmap_reg_range(BQ25792_REG05_INPUT_VOLTAGE_LIMIT, + BQ25792_REG06_INPUT_CURRENT_LIMIT + 1), + regmap_reg_range(BQ25792_REG0F_CHARGER_CONTROL_0, + BQ25792_REG0F_CHARGER_CONTROL_0), + regmap_reg_range(BQ25792_REG11_CHARGER_CONTROL_2, + BQ25792_REG11_CHARGER_CONTROL_2), + regmap_reg_range(BQ25792_REG13_CHARGER_CONTROL_4, + BQ25792_REG13_CHARGER_CONTROL_4), regmap_reg_range(BQ25792_REG19_ICO_CURRENT_LIMIT, BQ25792_REG27_FAULT_FLAG_1), + regmap_reg_range(BQ25792_REG2E_ADC_CONTROL, + BQ25792_REG2E_ADC_CONTROL), regmap_reg_range(BQ25792_REG31_IBUS_ADC, BQ25792_REG47_DPDM_DRIVER), }; diff --git a/drivers/mfd/cs42l43-i2c.c b/drivers/mfd/cs42l43-i2c.c index cbe05c3ea910..2f1862199618 100644 --- a/drivers/mfd/cs42l43-i2c.c +++ b/drivers/mfd/cs42l43-i2c.c @@ -54,10 +54,18 @@ static int cs42l43_i2c_probe(struct i2c_client *i2c) return cs42l43_dev_probe(cs42l43); } +static void cs42l43_i2c_remove(struct i2c_client *i2c) +{ + struct cs42l43 *cs42l43 = dev_get_drvdata(&i2c->dev); + + cs42l43_dev_remove(cs42l43); +} + #if IS_ENABLED(CONFIG_OF) static const struct of_device_id cs42l43_of_match[] = { { .compatible = "cirrus,cs42l43", .data = (void *)CS42L43_DEVID_VAL }, { .compatible = "cirrus,cs42l43b", .data = (void *)CS42L43B_DEVID_VAL }, + { .compatible = "cirrus,cs42l44", .data = (void *)CS42L43B_DEVID_VAL }, {} }; MODULE_DEVICE_TABLE(of, cs42l43_of_match); @@ -67,6 +75,7 @@ MODULE_DEVICE_TABLE(of, cs42l43_of_match); static const struct acpi_device_id cs42l43_acpi_match[] = { { "CSC4243", CS42L43_DEVID_VAL }, { "CSC2A3B", CS42L43B_DEVID_VAL }, + { "CSC4244", CS42L43B_DEVID_VAL }, {} }; MODULE_DEVICE_TABLE(acpi, cs42l43_acpi_match); @@ -81,6 +90,7 @@ static struct i2c_driver cs42l43_i2c_driver = { }, .probe = cs42l43_i2c_probe, + .remove = cs42l43_i2c_remove, }; module_i2c_driver(cs42l43_i2c_driver); diff --git a/drivers/mfd/cs42l43-sdw.c b/drivers/mfd/cs42l43-sdw.c index 0a6999453f32..22e4c1fe9298 100644 --- a/drivers/mfd/cs42l43-sdw.c +++ b/drivers/mfd/cs42l43-sdw.c @@ -180,9 +180,17 @@ static int cs42l43_sdw_probe(struct sdw_slave *sdw, const struct sdw_device_id * return cs42l43_dev_probe(cs42l43); } +static void cs42l43_sdw_remove(struct sdw_slave *sdw) +{ + struct cs42l43 *cs42l43 = dev_get_drvdata(&sdw->dev); + + cs42l43_dev_remove(cs42l43); +} + static const struct sdw_device_id cs42l43_sdw_id[] = { SDW_SLAVE_ENTRY(0x01FA, 0x4243, (void *)CS42L43_DEVID_VAL), SDW_SLAVE_ENTRY(0x01FA, 0x2A3B, (void *)CS42L43B_DEVID_VAL), + SDW_SLAVE_ENTRY(0x01FA, 0x4244, (void *)CS42L43B_DEVID_VAL), { } }; MODULE_DEVICE_TABLE(sdw, cs42l43_sdw_id); @@ -194,6 +202,7 @@ static struct sdw_driver cs42l43_sdw_driver = { }, .probe = cs42l43_sdw_probe, + .remove = cs42l43_sdw_remove, .id_table = cs42l43_sdw_id, .ops = &cs42l43_sdw_ops, }; diff --git a/drivers/mfd/cs42l43.c b/drivers/mfd/cs42l43.c index 4212ebcca60b..a83b62064dae 100644 --- a/drivers/mfd/cs42l43.c +++ b/drivers/mfd/cs42l43.c @@ -959,6 +959,7 @@ static void cs42l43_boot_work(struct work_struct *work) { struct cs42l43 *cs42l43 = container_of(work, struct cs42l43, boot_work); unsigned int devid, revid, otp; + bool valid_id; int ret; ret = cs42l43_wait_for_attach(cs42l43); @@ -973,19 +974,24 @@ static void cs42l43_boot_work(struct work_struct *work) switch (devid) { case CS42L43_DEVID_VAL: + valid_id = (cs42l43->variant_id == CS42L43_DEVID_VAL); + break; case CS42L43B_DEVID_VAL: - if (devid != cs42l43->variant_id) { - dev_err(cs42l43->dev, - "Device ID (0x%06x) does not match variant ID (0x%06lx)\n", - devid, cs42l43->variant_id); - goto err; - } + case CS42L44_DEVID_VAL: + valid_id = (cs42l43->variant_id == CS42L43B_DEVID_VAL); break; default: dev_err(cs42l43->dev, "Unrecognised devid: 0x%06x\n", devid); goto err; } + if (!valid_id) { + dev_err(cs42l43->dev, + "Device ID (0x%06x) does not match variant ID (0x%06lx)\n", + devid, cs42l43->variant_id); + goto err; + } + ret = regmap_read(cs42l43->regmap, CS42L43_REVID, &revid); if (ret) { dev_err(cs42l43->dev, "Failed to read rev: %d\n", ret); @@ -1099,15 +1105,19 @@ static int cs42l43_power_down(struct cs42l43 *cs42l43) return 0; } -static void cs42l43_dev_remove(void *data) +static void cs42l43_dev_power_down(void *data) { struct cs42l43 *cs42l43 = data; - cancel_work_sync(&cs42l43->boot_work); - cs42l43_power_down(cs42l43); } +void cs42l43_dev_remove(struct cs42l43 *cs42l43) +{ + flush_work(&cs42l43->boot_work); +} +EXPORT_SYMBOL_NS_GPL(cs42l43_dev_remove, "MFD_CS42L43"); + int cs42l43_dev_probe(struct cs42l43 *cs42l43) { int i, ret; @@ -1153,7 +1163,7 @@ int cs42l43_dev_probe(struct cs42l43 *cs42l43) if (ret) return ret; - ret = devm_add_action_or_reset(cs42l43->dev, cs42l43_dev_remove, cs42l43); + ret = devm_add_action_or_reset(cs42l43->dev, cs42l43_dev_power_down, cs42l43); if (ret) return ret; diff --git a/drivers/mfd/cs42l43.h b/drivers/mfd/cs42l43.h index a0068f6572e2..862bc6fb68cb 100644 --- a/drivers/mfd/cs42l43.h +++ b/drivers/mfd/cs42l43.h @@ -25,5 +25,6 @@ bool cs42l43_precious_register(struct device *dev, unsigned int reg); bool cs42l43_volatile_register(struct device *dev, unsigned int reg); int cs42l43_dev_probe(struct cs42l43 *cs42l43); +void cs42l43_dev_remove(struct cs42l43 *cs42l43); #endif /* CS42L43_CORE_INT_H */ diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c index e86b39de3303..e4ad48e1f139 100644 --- a/drivers/mfd/da903x.c +++ b/drivers/mfd/da903x.c @@ -421,6 +421,14 @@ static irqreturn_t da903x_irq_handler(int irq, void *data) return IRQ_HANDLED; } +static void da903x_cancel_irq_work(void *data) +{ + struct da903x_chip *chip = data; + + disable_irq(chip->client->irq); + cancel_work_sync(&chip->irq_work); +} + static const struct da903x_chip_ops da903x_ops[] = { [0] = { .init_chip = da9030_init_chip, @@ -456,6 +464,13 @@ static int da903x_remove_subdevs(struct da903x_chip *chip) return device_for_each_child(chip->dev, NULL, __remove_subdev); } +static void da903x_remove_subdevs_action(void *data) +{ + struct da903x_chip *chip = data; + + da903x_remove_subdevs(chip); +} + static int da903x_add_subdevs(struct da903x_chip *chip, struct da903x_platform_data *pdata) { @@ -484,7 +499,6 @@ static int da903x_add_subdevs(struct da903x_chip *chip, return 0; failed: - da903x_remove_subdevs(chip); return ret; } @@ -520,6 +534,11 @@ static int da903x_probe(struct i2c_client *client) chip->ops->mask_events(chip, chip->events_mask); chip->ops->read_events(chip, &tmp); + ret = devm_add_action_or_reset(&client->dev, + da903x_remove_subdevs_action, chip); + if (ret) + return ret; + ret = devm_request_irq(&client->dev, client->irq, da903x_irq_handler, IRQF_TRIGGER_FALLING, "da903x", chip); @@ -529,22 +548,19 @@ static int da903x_probe(struct i2c_client *client) return ret; } + ret = devm_add_action_or_reset(&client->dev, da903x_cancel_irq_work, + chip); + if (ret) + return ret; + return da903x_add_subdevs(chip, pdata); } -static void da903x_remove(struct i2c_client *client) -{ - struct da903x_chip *chip = i2c_get_clientdata(client); - - da903x_remove_subdevs(chip); -} - static struct i2c_driver da903x_driver = { .driver = { .name = "da903x", }, .probe = da903x_probe, - .remove = da903x_remove, .id_table = da903x_id_table, }; diff --git a/drivers/mfd/da9062-core.c b/drivers/mfd/da9062-core.c index 637c5f47a4b0..ad198183aff7 100644 --- a/drivers/mfd/da9062-core.c +++ b/drivers/mfd/da9062-core.c @@ -203,36 +203,36 @@ static const struct mfd_cell da9061_devs_noirq[] = { }; static const struct resource da9062_core_resources[] = { - DEFINE_RES_NAMED(DA9062_IRQ_VDD_WARN, 1, "VDD_WARN", IORESOURCE_IRQ), + DEFINE_RES_IRQ_NAMED(DA9062_IRQ_VDD_WARN, "VDD_WARN"), }; static const struct resource da9062_regulators_resources[] = { - DEFINE_RES_NAMED(DA9062_IRQ_LDO_LIM, 1, "LDO_LIM", IORESOURCE_IRQ), + DEFINE_RES_IRQ_NAMED(DA9062_IRQ_LDO_LIM, "LDO_LIM"), }; static const struct resource da9062_thermal_resources[] = { - DEFINE_RES_NAMED(DA9062_IRQ_TEMP, 1, "THERMAL", IORESOURCE_IRQ), + DEFINE_RES_IRQ_NAMED(DA9062_IRQ_TEMP, "THERMAL"), }; static const struct resource da9062_wdt_resources[] = { - DEFINE_RES_NAMED(DA9062_IRQ_WDG_WARN, 1, "WD_WARN", IORESOURCE_IRQ), + DEFINE_RES_IRQ_NAMED(DA9062_IRQ_WDG_WARN, "WD_WARN"), }; static const struct resource da9062_rtc_resources[] = { - DEFINE_RES_NAMED(DA9062_IRQ_ALARM, 1, "ALARM", IORESOURCE_IRQ), - DEFINE_RES_NAMED(DA9062_IRQ_TICK, 1, "TICK", IORESOURCE_IRQ), + DEFINE_RES_IRQ_NAMED(DA9062_IRQ_ALARM, "ALARM"), + DEFINE_RES_IRQ_NAMED(DA9062_IRQ_TICK, "TICK"), }; static const struct resource da9062_onkey_resources[] = { - DEFINE_RES_NAMED(DA9062_IRQ_ONKEY, 1, "ONKEY", IORESOURCE_IRQ), + DEFINE_RES_IRQ_NAMED(DA9062_IRQ_ONKEY, "ONKEY"), }; static const struct resource da9062_gpio_resources[] = { - DEFINE_RES_NAMED(DA9062_IRQ_GPI0, 1, "GPI0", IORESOURCE_IRQ), - DEFINE_RES_NAMED(DA9062_IRQ_GPI1, 1, "GPI1", IORESOURCE_IRQ), - DEFINE_RES_NAMED(DA9062_IRQ_GPI2, 1, "GPI2", IORESOURCE_IRQ), - DEFINE_RES_NAMED(DA9062_IRQ_GPI3, 1, "GPI3", IORESOURCE_IRQ), - DEFINE_RES_NAMED(DA9062_IRQ_GPI4, 1, "GPI4", IORESOURCE_IRQ), + DEFINE_RES_IRQ_NAMED(DA9062_IRQ_GPI0, "GPI0"), + DEFINE_RES_IRQ_NAMED(DA9062_IRQ_GPI1, "GPI1"), + DEFINE_RES_IRQ_NAMED(DA9062_IRQ_GPI2, "GPI2"), + DEFINE_RES_IRQ_NAMED(DA9062_IRQ_GPI3, "GPI3"), + DEFINE_RES_IRQ_NAMED(DA9062_IRQ_GPI4, "GPI4"), }; static const struct mfd_cell da9062_devs_irq[] = { diff --git a/drivers/mfd/da9150-core.c b/drivers/mfd/da9150-core.c index 5c59cc869fb3..19325d72a27e 100644 --- a/drivers/mfd/da9150-core.c +++ b/drivers/mfd/da9150-core.c @@ -450,7 +450,7 @@ static int da9150_probe(struct i2c_client *client) da9150->irq_base = regmap_irq_chip_get_base(da9150->regmap_irq_data); - enable_irq_wake(da9150->irq); + da9150->irq_wake_enabled = !enable_irq_wake(da9150->irq); ret = mfd_add_devices(da9150->dev, -1, da9150_devs, ARRAY_SIZE(da9150_devs), NULL, @@ -463,6 +463,8 @@ static int da9150_probe(struct i2c_client *client) return 0; mfd_fail: + if (da9150->irq_wake_enabled) + disable_irq_wake(da9150->irq); regmap_del_irq_chip(da9150->irq, da9150->regmap_irq_data); regmap_irq_fail: i2c_unregister_device(da9150->core_qif); @@ -474,8 +476,10 @@ static void da9150_remove(struct i2c_client *client) { struct da9150 *da9150 = i2c_get_clientdata(client); - regmap_del_irq_chip(da9150->irq, da9150->regmap_irq_data); mfd_remove_devices(da9150->dev); + if (da9150->irq_wake_enabled) + disable_irq_wake(da9150->irq); + regmap_del_irq_chip(da9150->irq, da9150->regmap_irq_data); i2c_unregister_device(da9150->core_qif); } diff --git a/drivers/mfd/intel-lpss-acpi.c b/drivers/mfd/intel-lpss-acpi.c index d4b24a717848..720adb0ee21f 100644 --- a/drivers/mfd/intel-lpss-acpi.c +++ b/drivers/mfd/intel-lpss-acpi.c @@ -8,7 +8,9 @@ * Mika Westerberg */ +#include #include +#include #include #include #include @@ -171,6 +173,33 @@ static const struct acpi_device_id intel_lpss_acpi_ids[] = { }; MODULE_DEVICE_TABLE(acpi, intel_lpss_acpi_ids); +/* + * Devices that need a quirk applied only on the machines matched by + * intel_lpss_quirk_dmi[] below. The quirk to apply is carried in the + * matching entry's driver_data. + */ +static const struct acpi_device_id intel_lpss_acpi_quirk_ids[] = { + /* Dell Latitude 5285: ACPI GEXP device conflicts with I2C4 (INT3446) */ + { .id = "INT3446", .driver_data = QUIRK_IGNORE_RESOURCE_CONFLICTS }, + { } +}; + +static const struct dmi_system_id intel_lpss_quirk_dmi[] = { + { + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Latitude 5285"), + }, + }, + { + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Latitude 7275"), + }, + }, + { } +}; + static int intel_lpss_acpi_probe(struct platform_device *pdev) { const struct intel_lpss_platform_info *data; @@ -185,6 +214,15 @@ static int intel_lpss_acpi_probe(struct platform_device *pdev) if (!info) return -ENOMEM; + /* Apply per-device quirks that are only needed on certain machines */ + if (dmi_check_system(intel_lpss_quirk_dmi)) { + const struct acpi_device_id *id; + + id = acpi_match_device(intel_lpss_acpi_quirk_ids, &pdev->dev); + if (id) + info->quirks |= id->driver_data; + } + /* No need to check mem and irq here as intel_lpss_probe() does it for us */ info->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); info->irq = platform_get_irq(pdev, 0); diff --git a/drivers/mfd/intel-lpss.c b/drivers/mfd/intel-lpss.c index 63d6694f7145..29f30ef0da99 100644 --- a/drivers/mfd/intel-lpss.c +++ b/drivers/mfd/intel-lpss.c @@ -142,28 +142,21 @@ static void intel_lpss_cache_ltr(struct intel_lpss *lpss) lpss->idle_ltr = readl(lpss->priv + LPSS_PRIV_IDLELTR); } -static int intel_lpss_debugfs_add(struct intel_lpss *lpss) +static void intel_lpss_debugfs_add(struct intel_lpss *lpss) { - struct dentry *dir; - - dir = debugfs_create_dir(dev_name(lpss->dev), intel_lpss_debugfs); - if (IS_ERR(dir)) - return PTR_ERR(dir); + lpss->debugfs = debugfs_create_dir(dev_name(lpss->dev), intel_lpss_debugfs); /* Cache the values into lpss structure */ intel_lpss_cache_ltr(lpss); - debugfs_create_x32("capabilities", S_IRUGO, dir, &lpss->caps); - debugfs_create_x32("active_ltr", S_IRUGO, dir, &lpss->active_ltr); - debugfs_create_x32("idle_ltr", S_IRUGO, dir, &lpss->idle_ltr); - - lpss->debugfs = dir; - return 0; + debugfs_create_x32("capabilities", 0444, lpss->debugfs, &lpss->caps); + debugfs_create_x32("active_ltr", 0444, lpss->debugfs, &lpss->active_ltr); + debugfs_create_x32("idle_ltr", 0444, lpss->debugfs, &lpss->idle_ltr); } static void intel_lpss_debugfs_remove(struct intel_lpss *lpss) { - debugfs_remove_recursive(lpss->debugfs); + debugfs_remove(lpss->debugfs); } static void intel_lpss_ltr_set(struct device *dev, s32 val) @@ -432,10 +425,7 @@ int intel_lpss_probe(struct device *dev, goto err_clk_register; intel_lpss_ltr_expose(lpss); - - ret = intel_lpss_debugfs_add(lpss); - if (ret) - dev_warn(dev, "Failed to create debugfs entries\n"); + intel_lpss_debugfs_add(lpss); if (intel_lpss_has_idma(lpss)) { ret = mfd_add_devices(dev, lpss->devid, &intel_lpss_idma64_cell, diff --git a/drivers/mfd/intel_quark_i2c_gpio.c b/drivers/mfd/intel_quark_i2c_gpio.c index 9b9c76bd067b..443a1a0cf777 100644 --- a/drivers/mfd/intel_quark_i2c_gpio.c +++ b/drivers/mfd/intel_quark_i2c_gpio.c @@ -35,11 +35,6 @@ /* The Quark I2C controller source clock */ #define INTEL_QUARK_I2C_CLK_HZ 33000000 -struct intel_quark_mfd { - struct clk *i2c_clk; - struct clk_lookup *i2c_clk_lookup; -}; - static const struct property_entry intel_quark_i2c_controller_standard_properties[] = { PROPERTY_ENTRY_U32("clock-frequency", I2C_MAX_STANDARD_MODE_FREQ), { } @@ -160,37 +155,12 @@ MODULE_DEVICE_TABLE(pci, intel_quark_mfd_ids); static int intel_quark_register_i2c_clk(struct device *dev) { - struct intel_quark_mfd *quark_mfd = dev_get_drvdata(dev); - struct clk *i2c_clk; + struct clk_hw *hw; - i2c_clk = clk_register_fixed_rate(dev, - INTEL_QUARK_I2C_CONTROLLER_CLK, NULL, - 0, INTEL_QUARK_I2C_CLK_HZ); - if (IS_ERR(i2c_clk)) - return PTR_ERR(i2c_clk); - - quark_mfd->i2c_clk = i2c_clk; - quark_mfd->i2c_clk_lookup = clkdev_create(i2c_clk, NULL, - INTEL_QUARK_I2C_CONTROLLER_CLK); - - if (!quark_mfd->i2c_clk_lookup) { - clk_unregister(quark_mfd->i2c_clk); - dev_err(dev, "Fixed clk register failed\n"); - return -ENOMEM; - } - - return 0; -} - -static void intel_quark_unregister_i2c_clk(struct device *dev) -{ - struct intel_quark_mfd *quark_mfd = dev_get_drvdata(dev); - - if (!quark_mfd->i2c_clk_lookup) - return; - - clkdev_drop(quark_mfd->i2c_clk_lookup); - clk_unregister(quark_mfd->i2c_clk); + hw = devm_clk_hw_register_fixed_rate(dev, INTEL_QUARK_I2C_CONTROLLER_CLK, + NULL, 0, INTEL_QUARK_I2C_CLK_HZ); + return devm_clk_hw_register_clkdev(dev, hw, NULL, + INTEL_QUARK_I2C_CONTROLLER_CLK); } static int intel_quark_i2c_setup(struct pci_dev *pdev) @@ -238,19 +208,12 @@ static int intel_quark_gpio_setup(struct pci_dev *pdev) static int intel_quark_mfd_probe(struct pci_dev *pdev, const struct pci_device_id *id) { - struct intel_quark_mfd *quark_mfd; int ret; ret = pcim_enable_device(pdev); if (ret) return ret; - quark_mfd = devm_kzalloc(&pdev->dev, sizeof(*quark_mfd), GFP_KERNEL); - if (!quark_mfd) - return -ENOMEM; - - dev_set_drvdata(&pdev->dev, quark_mfd); - ret = intel_quark_register_i2c_clk(&pdev->dev); if (ret) return ret; @@ -260,7 +223,7 @@ static int intel_quark_mfd_probe(struct pci_dev *pdev, /* This driver only requires 1 IRQ vector */ ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); if (ret < 0) - goto err_unregister_i2c_clk; + return ret; ret = intel_quark_i2c_setup(pdev); if (ret) @@ -282,8 +245,6 @@ static int intel_quark_mfd_probe(struct pci_dev *pdev, software_node_unregister_node_group(intel_quark_gpio_node_group); err_free_irq_vectors: pci_free_irq_vectors(pdev); -err_unregister_i2c_clk: - intel_quark_unregister_i2c_clk(&pdev->dev); return ret; } @@ -292,7 +253,6 @@ static void intel_quark_mfd_remove(struct pci_dev *pdev) mfd_remove_devices(&pdev->dev); software_node_unregister_node_group(intel_quark_gpio_node_group); pci_free_irq_vectors(pdev); - intel_quark_unregister_i2c_clk(&pdev->dev); } static struct pci_driver intel_quark_mfd_driver = { diff --git a/drivers/mfd/iqs62x.c b/drivers/mfd/iqs62x.c index 412ae7777f72..ef747a7b3845 100644 --- a/drivers/mfd/iqs62x.c +++ b/drivers/mfd/iqs62x.c @@ -1015,7 +1015,7 @@ static void iqs62x_remove(struct i2c_client *client) wait_for_completion(&iqs62x->fw_done); } -static int __maybe_unused iqs62x_suspend(struct device *dev) +static int iqs62x_suspend(struct device *dev) { struct iqs62x_core *iqs62x = dev_get_drvdata(dev); int ret; @@ -1036,7 +1036,7 @@ static int __maybe_unused iqs62x_suspend(struct device *dev) IQS62X_PWR_SETTINGS_PWR_MODE_HALT); } -static int __maybe_unused iqs62x_resume(struct device *dev) +static int iqs62x_resume(struct device *dev) { struct iqs62x_core *iqs62x = dev_get_drvdata(dev); int ret; @@ -1051,7 +1051,7 @@ static int __maybe_unused iqs62x_resume(struct device *dev) IQS62X_PWR_SETTINGS_DIS_AUTO, 0); } -static SIMPLE_DEV_PM_OPS(iqs62x_pm, iqs62x_suspend, iqs62x_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(iqs62x_pm, iqs62x_suspend, iqs62x_resume); static const struct of_device_id iqs62x_of_match[] = { { .compatible = "azoteq,iqs620a" }, @@ -1067,7 +1067,7 @@ static struct i2c_driver iqs62x_i2c_driver = { .driver = { .name = "iqs62x", .of_match_table = iqs62x_of_match, - .pm = &iqs62x_pm, + .pm = pm_sleep_ptr(&iqs62x_pm), }, .probe = iqs62x_probe, .remove = iqs62x_remove, diff --git a/drivers/mfd/kempld-core.c b/drivers/mfd/kempld-core.c index b64729918dfd..47062f876e5d 100644 --- a/drivers/mfd/kempld-core.c +++ b/drivers/mfd/kempld-core.c @@ -37,7 +37,7 @@ static void kempld_get_hardware_mutex(struct kempld_device_data *pld) static void kempld_release_hardware_mutex(struct kempld_device_data *pld) { - /* The harware mutex is released when 1 is written to the mutex bit. */ + /* The hardware mutex is released when 1 is written to the mutex bit. */ iowrite8(KEMPLD_MUTEX_KEY, pld->io_index); } diff --git a/drivers/mfd/khadas-mcu.c b/drivers/mfd/khadas-mcu.c index ba981a788692..4b37e74e2b04 100644 --- a/drivers/mfd/khadas-mcu.c +++ b/drivers/mfd/khadas-mcu.c @@ -75,47 +75,116 @@ static const struct regmap_config khadas_mcu_regmap_config = { .cache_type = REGCACHE_MAPLE, }; -static struct mfd_cell khadas_mcu_fan_cells[] = { +static const struct mfd_cell khadas_mcu_fan_cells[] = { /* VIM1/2 Rev13+ and VIM3 only */ - { .name = "khadas-mcu-fan-ctrl", }, + MFD_CELL_NAME("khadas-mcu-fan-ctrl"), }; -static struct mfd_cell khadas_mcu_cells[] = { - { .name = "khadas-mcu-user-mem", }, +static const struct mfd_cell khadas_mcu_cells[] = { + MFD_CELL_NAME("khadas-mcu-user-mem"), +}; + +static bool khadas_mcu_vim4_reg_volatile(struct device *dev, unsigned int reg) +{ + switch (reg) { + case KHADAS_MCU_PWR_OFF_CMD_REG: + case KHADAS_MCU_VIM4_REST_CONF_REG: + case KHADAS_MCU_WOL_INIT_START_REG: + case KHADAS_MCU_VIM4_LED_ON_RAM_REG: + case KHADAS_MCU_VIM4_FAN_CTRL_REG: + case KHADAS_MCU_VIM4_WDT_EN_REG: + case KHADAS_MCU_VIM4_SYS_RST_REG: + return true; + default: + return false; + } +} + +static bool khadas_mcu_vim4_reg_writeable(struct device *dev, unsigned int reg) +{ + switch (reg) { + case KHADAS_MCU_VERSION_0_REG: + case KHADAS_MCU_VERSION_1_REG: + case KHADAS_MCU_SHUTDOWN_NORMAL_STATUS_REG: + return false; + default: + return true; + } +} + +static const struct regmap_config khadas_mcu_vim4_regmap_config = { + .reg_bits = 8, + .reg_stride = 1, + .val_bits = 8, + .max_register = KHADAS_MCU_VIM4_SYS_RST_REG, + .volatile_reg = khadas_mcu_vim4_reg_volatile, + .writeable_reg = khadas_mcu_vim4_reg_writeable, + .cache_type = REGCACHE_MAPLE, +}; + +static const struct mfd_cell khadas_mcu_vim4_fan_cells[] = { + MFD_CELL_NAME("khadas-mcu-vim4-fan"), }; static int khadas_mcu_probe(struct i2c_client *client) { + const struct mfd_cell *cells, *fan_cells; + const struct regmap_config *regmap_cfg; struct device *dev = &client->dev; + int ncells, nfan_cells, ret; struct khadas_mcu *ddata; - int ret; + const void *mcu_variant; ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL); if (!ddata) return -ENOMEM; + mcu_variant = i2c_get_match_data(client); + if (!mcu_variant) + return -ENODEV; + + switch ((uintptr_t)mcu_variant) { + case KHADAS_MCU_GENERIC: + regmap_cfg = &khadas_mcu_regmap_config; + cells = khadas_mcu_cells; + ncells = ARRAY_SIZE(khadas_mcu_cells); + fan_cells = khadas_mcu_fan_cells; + nfan_cells = ARRAY_SIZE(khadas_mcu_fan_cells); + break; + case KHADAS_MCU_VIM4: + regmap_cfg = &khadas_mcu_vim4_regmap_config; + cells = NULL; + ncells = 0; + fan_cells = khadas_mcu_vim4_fan_cells; + nfan_cells = ARRAY_SIZE(khadas_mcu_vim4_fan_cells); + break; + default: + return -ENODEV; + } + i2c_set_clientdata(client, ddata); ddata->dev = dev; - ddata->regmap = devm_regmap_init_i2c(client, &khadas_mcu_regmap_config); + ddata->regmap = devm_regmap_init_i2c(client, regmap_cfg); if (IS_ERR(ddata->regmap)) { ret = PTR_ERR(ddata->regmap); - dev_err(dev, "Failed to allocate register map: %d\n", ret); - return ret; + return dev_err_probe(dev, ret, "Failed to allocate register map\n"); } - ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, - khadas_mcu_cells, - ARRAY_SIZE(khadas_mcu_cells), - NULL, 0, NULL); - if (ret) - return ret; + if (cells && ncells) { + ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, + cells, + ncells, + NULL, 0, NULL); + if (ret) + return ret; + } if (of_property_present(dev->of_node, "#cooling-cells")) return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, - khadas_mcu_fan_cells, - ARRAY_SIZE(khadas_mcu_fan_cells), + fan_cells, + nfan_cells, NULL, 0, NULL); return 0; @@ -123,7 +192,8 @@ static int khadas_mcu_probe(struct i2c_client *client) #ifdef CONFIG_OF static const struct of_device_id khadas_mcu_of_match[] = { - { .compatible = "khadas,mcu", }, + { .compatible = "khadas,mcu", .data = (void *)KHADAS_MCU_GENERIC }, + { .compatible = "khadas,vim4-mcu", .data = (void *)KHADAS_MCU_VIM4 }, {}, }; MODULE_DEVICE_TABLE(of, khadas_mcu_of_match); diff --git a/drivers/mfd/lm3533-core.c b/drivers/mfd/lm3533-core.c index 0a2409d00b2e..9233da7ce099 100644 --- a/drivers/mfd/lm3533-core.c +++ b/drivers/mfd/lm3533-core.c @@ -7,6 +7,7 @@ * Author: Johan Hovold */ +#include #include #include #include @@ -14,19 +15,24 @@ #include #include #include +#include #include +#include #include #include #include +#include #include #define LM3533_BOOST_OVP_MASK 0x06 -#define LM3533_BOOST_OVP_SHIFT 1 +#define LM3533_BOOST_OVP_MIN (16 * MICRO) +#define LM3533_BOOST_OVP_MAX (40 * MICRO) #define LM3533_BOOST_FREQ_MASK 0x01 -#define LM3533_BOOST_FREQ_SHIFT 0 +#define LM3533_BOOST_FREQ_MIN (500 * HZ_PER_KHZ) +#define LM3533_BOOST_FREQ_MAX (1000 * HZ_PER_KHZ) #define LM3533_BL_ID_MASK 1 #define LM3533_LED_ID_MASK 3 @@ -35,6 +41,7 @@ #define LM3533_HVLED_ID_MAX 2 #define LM3533_LVLED_ID_MAX 5 +#define LM3533_CELLS_MAX 7 #define LM3533_REG_OUTPUT_CONF1 0x10 #define LM3533_REG_OUTPUT_CONF2 0x11 @@ -42,125 +49,6 @@ #define LM3533_REG_MAX 0xb2 - -static struct mfd_cell lm3533_als_devs[] = { - { - .name = "lm3533-als", - .id = -1, - }, -}; - -static struct mfd_cell lm3533_bl_devs[] = { - { - .name = "lm3533-backlight", - .id = 0, - }, - { - .name = "lm3533-backlight", - .id = 1, - }, -}; - -static struct mfd_cell lm3533_led_devs[] = { - { - .name = "lm3533-leds", - .id = 0, - }, - { - .name = "lm3533-leds", - .id = 1, - }, - { - .name = "lm3533-leds", - .id = 2, - }, - { - .name = "lm3533-leds", - .id = 3, - }, -}; - -int lm3533_read(struct lm3533 *lm3533, u8 reg, u8 *val) -{ - int tmp; - int ret; - - ret = regmap_read(lm3533->regmap, reg, &tmp); - if (ret < 0) { - dev_err(lm3533->dev, "failed to read register %02x: %d\n", - reg, ret); - return ret; - } - - *val = tmp; - - dev_dbg(lm3533->dev, "read [%02x]: %02x\n", reg, *val); - - return ret; -} -EXPORT_SYMBOL_GPL(lm3533_read); - -int lm3533_write(struct lm3533 *lm3533, u8 reg, u8 val) -{ - int ret; - - dev_dbg(lm3533->dev, "write [%02x]: %02x\n", reg, val); - - ret = regmap_write(lm3533->regmap, reg, val); - if (ret < 0) { - dev_err(lm3533->dev, "failed to write register %02x: %d\n", - reg, ret); - } - - return ret; -} -EXPORT_SYMBOL_GPL(lm3533_write); - -int lm3533_update(struct lm3533 *lm3533, u8 reg, u8 val, u8 mask) -{ - int ret; - - dev_dbg(lm3533->dev, "update [%02x]: %02x/%02x\n", reg, val, mask); - - ret = regmap_update_bits(lm3533->regmap, reg, mask, val); - if (ret < 0) { - dev_err(lm3533->dev, "failed to update register %02x: %d\n", - reg, ret); - } - - return ret; -} -EXPORT_SYMBOL_GPL(lm3533_update); - -static int lm3533_set_boost_freq(struct lm3533 *lm3533, - enum lm3533_boost_freq freq) -{ - int ret; - - ret = lm3533_update(lm3533, LM3533_REG_BOOST_PWM, - freq << LM3533_BOOST_FREQ_SHIFT, - LM3533_BOOST_FREQ_MASK); - if (ret) - dev_err(lm3533->dev, "failed to set boost frequency\n"); - - return ret; -} - - -static int lm3533_set_boost_ovp(struct lm3533 *lm3533, - enum lm3533_boost_ovp ovp) -{ - int ret; - - ret = lm3533_update(lm3533, LM3533_REG_BOOST_PWM, - ovp << LM3533_BOOST_OVP_SHIFT, - LM3533_BOOST_OVP_MASK); - if (ret) - dev_err(lm3533->dev, "failed to set boost ovp\n"); - - return ret; -} - /* * HVLED output config -- output hvled controlled by backlight bl */ @@ -181,7 +69,8 @@ static int lm3533_set_hvled_config(struct lm3533 *lm3533, u8 hvled, u8 bl) mask = LM3533_BL_ID_MASK << shift; val = bl << shift; - ret = lm3533_update(lm3533, LM3533_REG_OUTPUT_CONF1, val, mask); + ret = regmap_update_bits(lm3533->regmap, LM3533_REG_OUTPUT_CONF1, + mask, val); if (ret) dev_err(lm3533->dev, "failed to set hvled config\n"); @@ -216,21 +105,32 @@ static int lm3533_set_lvled_config(struct lm3533 *lm3533, u8 lvled, u8 led) mask = LM3533_LED_ID_MASK << shift; val = led << shift; - ret = lm3533_update(lm3533, reg, val, mask); + ret = regmap_update_bits(lm3533->regmap, reg, mask, val); if (ret) dev_err(lm3533->dev, "failed to set lvled config\n"); return ret; } -static void lm3533_enable(struct lm3533 *lm3533) +static int lm3533_enable(struct lm3533 *lm3533) { + int ret; + + ret = regulator_enable(lm3533->vin_supply); + if (ret) { + dev_err(lm3533->dev, "failed to enable vin power supply\n"); + return ret; + } + gpiod_set_value(lm3533->hwen, 1); + + return 0; } static void lm3533_disable(struct lm3533 *lm3533) { gpiod_set_value(lm3533->hwen, 0); + regulator_disable(lm3533->vin_supply); } enum lm3533_attribute_type { @@ -258,7 +158,7 @@ static ssize_t show_output(struct device *dev, struct lm3533_device_attribute *lattr = to_lm3533_dev_attr(attr); int id = lattr->u.output.id; u8 reg; - u8 val; + u32 val; u8 mask; int shift; int ret; @@ -278,7 +178,7 @@ static ssize_t show_output(struct device *dev, mask = LM3533_LED_ID_MASK << shift; } - ret = lm3533_read(lm3533, reg, &val); + ret = regmap_read(lm3533->regmap, reg, &val); if (ret) return ret; @@ -376,136 +276,102 @@ static struct attribute_group lm3533_attribute_group = { .attrs = lm3533_attributes }; -static int lm3533_device_als_init(struct lm3533 *lm3533) -{ - struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev); - int ret; - - if (!pdata->als) - return 0; - - lm3533_als_devs[0].platform_data = pdata->als; - lm3533_als_devs[0].pdata_size = sizeof(*pdata->als); - - ret = mfd_add_devices(lm3533->dev, 0, lm3533_als_devs, 1, NULL, - 0, NULL); - if (ret) { - dev_err(lm3533->dev, "failed to add ALS device\n"); - return ret; - } - - lm3533->have_als = 1; - - return 0; -} - -static int lm3533_device_bl_init(struct lm3533 *lm3533) -{ - struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev); - int i; - int ret; - - if (!pdata->backlights || pdata->num_backlights == 0) - return 0; - - if (pdata->num_backlights > ARRAY_SIZE(lm3533_bl_devs)) - pdata->num_backlights = ARRAY_SIZE(lm3533_bl_devs); - - for (i = 0; i < pdata->num_backlights; ++i) { - lm3533_bl_devs[i].platform_data = &pdata->backlights[i]; - lm3533_bl_devs[i].pdata_size = sizeof(pdata->backlights[i]); - } - - ret = mfd_add_devices(lm3533->dev, 0, lm3533_bl_devs, - pdata->num_backlights, NULL, 0, NULL); - if (ret) { - dev_err(lm3533->dev, "failed to add backlight devices\n"); - return ret; - } - - lm3533->have_backlights = 1; - - return 0; -} - -static int lm3533_device_led_init(struct lm3533 *lm3533) -{ - struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev); - int i; - int ret; - - if (!pdata->leds || pdata->num_leds == 0) - return 0; - - if (pdata->num_leds > ARRAY_SIZE(lm3533_led_devs)) - pdata->num_leds = ARRAY_SIZE(lm3533_led_devs); - - for (i = 0; i < pdata->num_leds; ++i) { - lm3533_led_devs[i].platform_data = &pdata->leds[i]; - lm3533_led_devs[i].pdata_size = sizeof(pdata->leds[i]); - } - - ret = mfd_add_devices(lm3533->dev, 0, lm3533_led_devs, - pdata->num_leds, NULL, 0, NULL); - if (ret) { - dev_err(lm3533->dev, "failed to add LED devices\n"); - return ret; - } - - lm3533->have_leds = 1; - - return 0; -} - -static int lm3533_device_setup(struct lm3533 *lm3533, - struct lm3533_platform_data *pdata) -{ - int ret; - - ret = lm3533_set_boost_freq(lm3533, pdata->boost_freq); - if (ret) - return ret; - - return lm3533_set_boost_ovp(lm3533, pdata->boost_ovp); -} +static const struct attribute_group *lm3533_attribute_groups[] = { + &lm3533_attribute_group, + NULL, +}; static int lm3533_device_init(struct lm3533 *lm3533) { - struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev); + struct device *dev = lm3533->dev; + struct mfd_cell *lm3533_devices; + u32 reg, nchilds; + u32 count = 0; int ret; - dev_dbg(lm3533->dev, "%s\n", __func__); + nchilds = device_get_child_node_count(dev); + if (!nchilds || nchilds > LM3533_CELLS_MAX) + return dev_err_probe(dev, -ENODEV, + "num of child nodes is not supported\n"); - if (!pdata) { - dev_err(lm3533->dev, "no platform data\n"); - return -EINVAL; + lm3533_devices = devm_kcalloc(dev, nchilds, sizeof(*lm3533_devices), + GFP_KERNEL); + if (!lm3533_devices) + return -ENOMEM; + + device_for_each_child_node_scoped(dev, child) { + if (count >= nchilds) + break; + + if (fwnode_device_is_compatible(child, "ti,lm3533-als")) { + lm3533_devices[count].name = "lm3533-als"; + lm3533_devices[count].of_compatible = "ti,lm3533-als"; + lm3533_devices[count].id = PLATFORM_DEVID_NONE; + + lm3533->have_als = true; + count++; + } else if (fwnode_device_is_compatible(child, "ti,lm3533-backlight")) { + ret = fwnode_property_read_u32(child, "reg", ®); + if (ret || reg >= LM3533_HVLED_ID_MAX) { + dev_err(dev, "invalid backlight node %pfw\n", child); + continue; + } + + lm3533_devices[count].name = "lm3533-backlight"; + lm3533_devices[count].of_compatible = "ti,lm3533-backlight"; + lm3533_devices[count].id = reg; + lm3533_devices[count].of_reg = reg; + lm3533_devices[count].use_of_reg = true; + + lm3533->have_backlights = true; + count++; + } else if (fwnode_device_is_compatible(child, "ti,lm3533-leds")) { + ret = fwnode_property_read_u32(child, "reg", ®); + if (ret || reg < LM3533_HVLED_ID_MAX || + reg > LM3533_LVLED_ID_MAX) { + dev_err(dev, "invalid LED node %pfw\n", child); + continue; + } + + lm3533_devices[count].name = "lm3533-leds"; + lm3533_devices[count].of_compatible = "ti,lm3533-leds"; + lm3533_devices[count].id = reg - LM3533_HVLED_ID_MAX; + lm3533_devices[count].of_reg = reg; + lm3533_devices[count].use_of_reg = true; + + lm3533->have_leds = true; + count++; + } } - lm3533->hwen = devm_gpiod_get(lm3533->dev, NULL, GPIOD_OUT_LOW); - if (IS_ERR(lm3533->hwen)) - return dev_err_probe(lm3533->dev, PTR_ERR(lm3533->hwen), "failed to request HWEN GPIO\n"); - gpiod_set_consumer_name(lm3533->hwen, "lm3533-hwen"); - - lm3533_enable(lm3533); - - ret = lm3533_device_setup(lm3533, pdata); + ret = lm3533_enable(lm3533); if (ret) + return ret; + + ret = regmap_update_bits(lm3533->regmap, LM3533_REG_BOOST_PWM, + LM3533_BOOST_FREQ_MASK, + FIELD_PREP(LM3533_BOOST_FREQ_MASK, lm3533->boost_freq)); + if (ret) { + dev_err(dev, "failed to set boost frequency\n"); goto err_disable; + } - lm3533_device_als_init(lm3533); - lm3533_device_bl_init(lm3533); - lm3533_device_led_init(lm3533); + ret = regmap_update_bits(lm3533->regmap, LM3533_REG_BOOST_PWM, + LM3533_BOOST_OVP_MASK, + FIELD_PREP(LM3533_BOOST_OVP_MASK, lm3533->boost_ovp)); + if (ret) { + dev_err(dev, "failed to set boost ovp\n"); + goto err_disable; + } - ret = sysfs_create_group(&lm3533->dev->kobj, &lm3533_attribute_group); - if (ret < 0) { - dev_err(lm3533->dev, "failed to create sysfs attributes\n"); - goto err_unregister; + ret = mfd_add_devices(dev, 0, lm3533_devices, count, NULL, 0, NULL); + if (ret) { + dev_err(dev, "failed to add MFD devices: %d\n", ret); + goto err_disable; } return 0; -err_unregister: - mfd_remove_devices(lm3533->dev); err_disable: lm3533_disable(lm3533); @@ -516,8 +382,6 @@ static void lm3533_device_exit(struct lm3533 *lm3533) { dev_dbg(lm3533->dev, "%s\n", __func__); - sysfs_remove_group(&lm3533->dev->kobj, &lm3533_attribute_group); - mfd_remove_devices(lm3533->dev); lm3533_disable(lm3533); } @@ -589,7 +453,35 @@ static int lm3533_i2c_probe(struct i2c_client *i2c) return PTR_ERR(lm3533->regmap); lm3533->dev = &i2c->dev; - lm3533->irq = i2c->irq; + + lm3533->hwen = devm_gpiod_get_optional(lm3533->dev, "enable", + GPIOD_OUT_LOW); + if (IS_ERR(lm3533->hwen)) + return dev_err_probe(lm3533->dev, PTR_ERR(lm3533->hwen), + "failed to get HWEN GPIO\n"); + + lm3533->vin_supply = devm_regulator_get(lm3533->dev, "vin"); + if (IS_ERR(lm3533->vin_supply)) + return dev_err_probe(lm3533->dev, PTR_ERR(lm3533->vin_supply), + "failed to get vin-supply\n"); + + device_property_read_u32(lm3533->dev, "ti,boost-ovp-microvolt", + &lm3533->boost_ovp); + + lm3533->boost_ovp = clamp(lm3533->boost_ovp, LM3533_BOOST_OVP_MIN, + LM3533_BOOST_OVP_MAX); + lm3533->boost_ovp = lm3533->boost_ovp / (8 * MICRO) - 2; + + device_property_read_u32(lm3533->dev, "ti,boost-freq-hz", + &lm3533->boost_freq); + + lm3533->boost_freq = clamp(lm3533->boost_freq, LM3533_BOOST_FREQ_MIN, + LM3533_BOOST_FREQ_MAX); + lm3533->boost_freq = lm3533->boost_freq / (500 * KILO) - 1; + + /* LM3533 and child devices do not use DMA */ + i2c->dev.coherent_dma_mask = 0; + i2c->dev.dma_mask = &i2c->dev.coherent_dma_mask; return lm3533_device_init(lm3533); } @@ -603,6 +495,12 @@ static void lm3533_i2c_remove(struct i2c_client *i2c) lm3533_device_exit(lm3533); } +static const struct of_device_id lm3533_match_table[] = { + { .compatible = "ti,lm3533" }, + { } +}; +MODULE_DEVICE_TABLE(of, lm3533_match_table); + static const struct i2c_device_id lm3533_i2c_ids[] = { { "lm3533" }, { } @@ -612,6 +510,8 @@ MODULE_DEVICE_TABLE(i2c, lm3533_i2c_ids); static struct i2c_driver lm3533_i2c_driver = { .driver = { .name = "lm3533", + .dev_groups = lm3533_attribute_groups, + .of_match_table = lm3533_match_table, }, .id_table = lm3533_i2c_ids, .probe = lm3533_i2c_probe, diff --git a/drivers/mfd/lm3533-ctrlbank.c b/drivers/mfd/lm3533-ctrlbank.c index 2537dfade51c..3aab8ece4e8c 100644 --- a/drivers/mfd/lm3533-ctrlbank.c +++ b/drivers/mfd/lm3533-ctrlbank.c @@ -9,14 +9,10 @@ #include #include +#include #include - -#define LM3533_MAX_CURRENT_MIN 5000 -#define LM3533_MAX_CURRENT_MAX 29800 -#define LM3533_MAX_CURRENT_STEP 800 - #define LM3533_PWM_MAX 0x3f #define LM3533_REG_PWM_BASE 0x14 @@ -38,8 +34,8 @@ int lm3533_ctrlbank_enable(struct lm3533_ctrlbank *cb) dev_dbg(cb->dev, "%s - %d\n", __func__, cb->id); mask = 1 << cb->id; - ret = lm3533_update(cb->lm3533, LM3533_REG_CTRLBANK_ENABLE, - mask, mask); + ret = regmap_set_bits(cb->regmap, LM3533_REG_CTRLBANK_ENABLE, + mask); if (ret) dev_err(cb->dev, "failed to enable ctrlbank %d\n", cb->id); @@ -55,7 +51,8 @@ int lm3533_ctrlbank_disable(struct lm3533_ctrlbank *cb) dev_dbg(cb->dev, "%s - %d\n", __func__, cb->id); mask = 1 << cb->id; - ret = lm3533_update(cb->lm3533, LM3533_REG_CTRLBANK_ENABLE, 0, mask); + ret = regmap_clear_bits(cb->regmap, LM3533_REG_CTRLBANK_ENABLE, + mask); if (ret) dev_err(cb->dev, "failed to disable ctrlbank %d\n", cb->id); @@ -68,7 +65,7 @@ EXPORT_SYMBOL_GPL(lm3533_ctrlbank_disable); * * imax 5000 - 29800 uA (800 uA step) */ -int lm3533_ctrlbank_set_max_current(struct lm3533_ctrlbank *cb, u16 imax) +int lm3533_ctrlbank_set_max_current(struct lm3533_ctrlbank *cb, u32 imax) { u8 reg; u8 val; @@ -80,7 +77,7 @@ int lm3533_ctrlbank_set_max_current(struct lm3533_ctrlbank *cb, u16 imax) val = (imax - LM3533_MAX_CURRENT_MIN) / LM3533_MAX_CURRENT_STEP; reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_MAX_CURRENT_BASE); - ret = lm3533_write(cb->lm3533, reg, val); + ret = regmap_write(cb->regmap, reg, val); if (ret) dev_err(cb->dev, "failed to set max current\n"); @@ -88,13 +85,13 @@ int lm3533_ctrlbank_set_max_current(struct lm3533_ctrlbank *cb, u16 imax) } EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_max_current); -int lm3533_ctrlbank_set_brightness(struct lm3533_ctrlbank *cb, u8 val) +int lm3533_ctrlbank_set_brightness(struct lm3533_ctrlbank *cb, u32 val) { u8 reg; int ret; reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_BRIGHTNESS_BASE); - ret = lm3533_write(cb->lm3533, reg, val); + ret = regmap_write(cb->regmap, reg, val); if (ret) dev_err(cb->dev, "failed to set brightness\n"); @@ -102,13 +99,13 @@ int lm3533_ctrlbank_set_brightness(struct lm3533_ctrlbank *cb, u8 val) } EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_brightness); -int lm3533_ctrlbank_get_brightness(struct lm3533_ctrlbank *cb, u8 *val) +int lm3533_ctrlbank_get_brightness(struct lm3533_ctrlbank *cb, u32 *val) { u8 reg; int ret; reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_BRIGHTNESS_BASE); - ret = lm3533_read(cb->lm3533, reg, val); + ret = regmap_read(cb->regmap, reg, val); if (ret) dev_err(cb->dev, "failed to get brightness\n"); @@ -126,7 +123,7 @@ EXPORT_SYMBOL_GPL(lm3533_ctrlbank_get_brightness); * bit 1 - PWM-input enabled in Zone 0 * bit 0 - PWM-input enabled */ -int lm3533_ctrlbank_set_pwm(struct lm3533_ctrlbank *cb, u8 val) +int lm3533_ctrlbank_set_pwm(struct lm3533_ctrlbank *cb, u32 val) { u8 reg; int ret; @@ -135,7 +132,7 @@ int lm3533_ctrlbank_set_pwm(struct lm3533_ctrlbank *cb, u8 val) return -EINVAL; reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_PWM_BASE); - ret = lm3533_write(cb->lm3533, reg, val); + ret = regmap_write(cb->regmap, reg, val); if (ret) dev_err(cb->dev, "failed to set PWM mask\n"); @@ -143,13 +140,13 @@ int lm3533_ctrlbank_set_pwm(struct lm3533_ctrlbank *cb, u8 val) } EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_pwm); -int lm3533_ctrlbank_get_pwm(struct lm3533_ctrlbank *cb, u8 *val) +int lm3533_ctrlbank_get_pwm(struct lm3533_ctrlbank *cb, u32 *val) { u8 reg; int ret; reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_PWM_BASE); - ret = lm3533_read(cb->lm3533, reg, val); + ret = regmap_read(cb->regmap, reg, val); if (ret) dev_err(cb->dev, "failed to get PWM mask\n"); diff --git a/drivers/mfd/max77705.c b/drivers/mfd/max77705.c index e98c76d6b699..2e9b81f26414 100644 --- a/drivers/mfd/max77705.c +++ b/drivers/mfd/max77705.c @@ -105,7 +105,7 @@ static int max77705_i2c_probe(struct i2c_client *i2c) return -ENODEV; pmic_rev = pmic_rev_value & MAX77705_REVISION_MASK; - if (pmic_rev != MAX77705_PASS3) + if (pmic_rev != MAX77705_PASS2 && pmic_rev != MAX77705_PASS3) return dev_err_probe(dev, -ENODEV, "Rev.0x%x is not tested\n", pmic_rev); /* Active Discharge Enable */ diff --git a/drivers/mfd/max77843.c b/drivers/mfd/max77843.c index 2a48577b1a79..9ae6715642ae 100644 --- a/drivers/mfd/max77843.c +++ b/drivers/mfd/max77843.c @@ -173,7 +173,7 @@ static const struct i2c_device_id max77843_id[] = { { }, }; -static int __maybe_unused max77843_suspend(struct device *dev) +static int max77843_suspend(struct device *dev) { struct i2c_client *i2c = to_i2c_client(dev); struct max77693_dev *max77843 = i2c_get_clientdata(i2c); @@ -185,7 +185,7 @@ static int __maybe_unused max77843_suspend(struct device *dev) return 0; } -static int __maybe_unused max77843_resume(struct device *dev) +static int max77843_resume(struct device *dev) { struct i2c_client *i2c = to_i2c_client(dev); struct max77693_dev *max77843 = i2c_get_clientdata(i2c); @@ -197,12 +197,12 @@ static int __maybe_unused max77843_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(max77843_pm, max77843_suspend, max77843_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(max77843_pm, max77843_suspend, max77843_resume); static struct i2c_driver max77843_i2c_driver = { .driver = { .name = "max77843", - .pm = &max77843_pm, + .pm = pm_sleep_ptr(&max77843_pm), .of_match_table = max77843_dt_match, .suppress_bind_attrs = true, }, diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c index eb13bbaeda55..5032eab05bb4 100644 --- a/drivers/mfd/max8998.c +++ b/drivers/mfd/max8998.c @@ -146,7 +146,7 @@ static struct max8998_platform_data *max8998_i2c_parse_dt_pdata( /* * ToDo: the 'wakeup' member in the platform data is more of a linux - * specfic information. Hence, there is no binding for that yet and + * specific information. Hence, there is no binding for that yet and * not parsed here. */ return pd; diff --git a/drivers/mfd/motorola-cpcap.c b/drivers/mfd/motorola-cpcap.c index 4ed8704c985a..65d5eb18aa00 100644 --- a/drivers/mfd/motorola-cpcap.c +++ b/drivers/mfd/motorola-cpcap.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -29,6 +30,7 @@ struct cpcap_ddata { struct regmap_irq_chip_data *irqdata[CPCAP_NR_IRQ_CHIPS]; const struct regmap_config *regmap_conf; struct regmap *regmap; + enum cpcap_variant variant; }; static int cpcap_sense_irq(struct regmap *regmap, int irq) @@ -194,20 +196,6 @@ static int cpcap_init_irq(struct cpcap_ddata *cpcap) return 0; } -static const struct of_device_id cpcap_of_match[] = { - { .compatible = "motorola,cpcap", }, - { .compatible = "st,6556002", }, - {}, -}; -MODULE_DEVICE_TABLE(of, cpcap_of_match); - -static const struct spi_device_id cpcap_spi_ids[] = { - { .name = "cpcap" }, - { .name = "6556002" }, - { } -}; -MODULE_DEVICE_TABLE(spi, cpcap_spi_ids); - static const struct regmap_config cpcap_regmap_config = { .reg_bits = 16, .reg_stride = 4, @@ -240,62 +228,74 @@ static int cpcap_resume(struct device *dev) static DEFINE_SIMPLE_DEV_PM_OPS(cpcap_pm, cpcap_suspend, cpcap_resume); -static const struct mfd_cell cpcap_mfd_devices[] = { - { - .name = "cpcap_adc", - .of_compatible = "motorola,mapphone-cpcap-adc", - }, { - .name = "cpcap_battery", - .of_compatible = "motorola,cpcap-battery", - }, { - .name = "cpcap-charger", - .of_compatible = "motorola,mapphone-cpcap-charger", - }, { - .name = "cpcap-regulator", - .of_compatible = "motorola,mapphone-cpcap-regulator", - }, { - .name = "cpcap-rtc", - .of_compatible = "motorola,cpcap-rtc", - }, { - .name = "cpcap-pwrbutton", - .of_compatible = "motorola,cpcap-pwrbutton", - }, { - .name = "cpcap-usb-phy", - .of_compatible = "motorola,mapphone-cpcap-usb-phy", - }, { - .name = "cpcap-led", - .id = 0, - .of_compatible = "motorola,cpcap-led-red", - }, { - .name = "cpcap-led", - .id = 1, - .of_compatible = "motorola,cpcap-led-green", - }, { - .name = "cpcap-led", - .id = 2, - .of_compatible = "motorola,cpcap-led-blue", - }, { - .name = "cpcap-led", - .id = 3, - .of_compatible = "motorola,cpcap-led-adl", - }, { - .name = "cpcap-led", - .id = 4, - .of_compatible = "motorola,cpcap-led-cp", - }, { - .name = "cpcap-codec", - } +static const struct mfd_cell cpcap_common_devices[] = { + MFD_CELL_OF("cpcap_battery", NULL, NULL, 0, 0, "motorola,cpcap-battery"), + MFD_CELL_OF("cpcap-rtc", NULL, NULL, 0, 0, "motorola,cpcap-rtc"), + MFD_CELL_OF("cpcap-pwrbutton", NULL, NULL, 0, 0, "motorola,cpcap-pwrbutton"), + MFD_CELL_OF("cpcap-led", NULL, NULL, 0, 0, "motorola,cpcap-led-red"), + MFD_CELL_OF("cpcap-led", NULL, NULL, 0, 1, "motorola,cpcap-led-green"), + MFD_CELL_OF("cpcap-led", NULL, NULL, 0, 2, "motorola,cpcap-led-blue"), + MFD_CELL_OF("cpcap-led", NULL, NULL, 0, 3, "motorola,cpcap-led-adl"), + MFD_CELL_NAME("cpcap-codec"), +}; + +static const struct mfd_cell cpcap_default_devices[] = { + MFD_CELL_OF("cpcap_adc", NULL, NULL, 0, 0, "motorola,cpcap-adc"), + MFD_CELL_OF("cpcap-regulator", NULL, NULL, 0, 0, "motorola,cpcap-regulator"), + MFD_CELL_OF("cpcap-usb-phy", NULL, NULL, 0, 0, "motorola,cpcap-usb-phy"), + MFD_CELL_OF("cpcap-led", NULL, NULL, 0, 4, "motorola,cpcap-led-cp"), +}; + +static const struct mfd_cell cpcap_mapphone_devices[] = { + MFD_CELL_OF("cpcap_adc", NULL, NULL, 0, 0, "motorola,mapphone-cpcap-adc"), + MFD_CELL_OF("cpcap-charger", NULL, NULL, 0, 0, "motorola,mapphone-cpcap-charger"), + MFD_CELL_OF("cpcap-regulator", NULL, NULL, 0, 0, "motorola,mapphone-cpcap-regulator"), + MFD_CELL_OF("cpcap-usb-phy", NULL, NULL, 0, 0, "motorola,mapphone-cpcap-usb-phy"), + MFD_CELL_OF("cpcap-led", NULL, NULL, 0, 4, "motorola,cpcap-led-cp"), +}; + +/* + * The Mot board features a USB-PHY and charger similar to the ones in + * Mapphone; however, because Mot is based on Tegra20, it is incompatible + * with the existing implementation, which is tightly interconnected with + * the OMAP USB PHY. + */ +static const struct mfd_cell cpcap_mot_devices[] = { + MFD_CELL_OF("cpcap_adc", NULL, NULL, 0, 0, "motorola,mot-cpcap-adc"), + MFD_CELL_OF("cpcap-regulator", NULL, NULL, 0, 0, "motorola,mot-cpcap-regulator"), }; static int cpcap_probe(struct spi_device *spi) { struct cpcap_ddata *cpcap; + const struct mfd_cell *cells; + unsigned int num_cells; int ret; cpcap = devm_kzalloc(&spi->dev, sizeof(*cpcap), GFP_KERNEL); if (!cpcap) return -ENOMEM; + cpcap->variant = (enum cpcap_variant)spi_get_device_match_data(spi); + + switch (cpcap->variant) { + case CPCAP_DEFAULT: + cells = cpcap_default_devices; + num_cells = ARRAY_SIZE(cpcap_default_devices); + break; + case CPCAP_MAPPHONE: + cells = cpcap_mapphone_devices; + num_cells = ARRAY_SIZE(cpcap_mapphone_devices); + break; + case CPCAP_MOT: + cells = cpcap_mot_devices; + num_cells = ARRAY_SIZE(cpcap_mot_devices); + break; + default: + return dev_err_probe(&spi->dev, -ENODEV, + "Unknown device %d\n", cpcap->variant); + } + cpcap->spi = spi; spi_set_drvdata(spi, cpcap); @@ -330,10 +330,31 @@ static int cpcap_probe(struct spi_device *spi) spi->dev.coherent_dma_mask = 0; spi->dev.dma_mask = &spi->dev.coherent_dma_mask; - return devm_mfd_add_devices(&spi->dev, 0, cpcap_mfd_devices, - ARRAY_SIZE(cpcap_mfd_devices), NULL, 0, NULL); + ret = devm_mfd_add_devices(&spi->dev, 0, cpcap_common_devices, + ARRAY_SIZE(cpcap_common_devices), NULL, 0, NULL); + if (ret) + return dev_err_probe(&spi->dev, ret, + "Failed to add common child devices\n"); + + return devm_mfd_add_devices(&spi->dev, 0, cells, num_cells, NULL, 0, NULL); } +static const struct of_device_id cpcap_of_match[] = { + { .compatible = "motorola,cpcap", .data = (void *)CPCAP_DEFAULT }, + { .compatible = "motorola,mapphone-cpcap", .data = (void *)CPCAP_MAPPHONE }, + { .compatible = "motorola,mot-cpcap", .data = (void *)CPCAP_MOT }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, cpcap_of_match); + +static const struct spi_device_id cpcap_spi_ids[] = { + { .name = "cpcap", .driver_data = CPCAP_DEFAULT }, + { .name = "mapphone-cpcap", .driver_data = CPCAP_MAPPHONE }, + { .name = "mot-cpcap", .driver_data = CPCAP_MOT }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(spi, cpcap_spi_ids); + static struct spi_driver cpcap_driver = { .driver = { .name = "cpcap-core", diff --git a/drivers/mfd/mt6360-core.c b/drivers/mfd/mt6360-core.c index b9b1036c8ff4..8a97c30cad3f 100644 --- a/drivers/mfd/mt6360-core.c +++ b/drivers/mfd/mt6360-core.c @@ -583,7 +583,7 @@ static int mt6360_probe(struct i2c_client *client) return 0; } -static int __maybe_unused mt6360_suspend(struct device *dev) +static int mt6360_suspend(struct device *dev) { struct i2c_client *i2c = to_i2c_client(dev); @@ -593,7 +593,7 @@ static int __maybe_unused mt6360_suspend(struct device *dev) return 0; } -static int __maybe_unused mt6360_resume(struct device *dev) +static int mt6360_resume(struct device *dev) { struct i2c_client *i2c = to_i2c_client(dev); @@ -604,7 +604,7 @@ static int __maybe_unused mt6360_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(mt6360_pm_ops, mt6360_suspend, mt6360_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(mt6360_pm_ops, mt6360_suspend, mt6360_resume); static const struct of_device_id __maybe_unused mt6360_of_id[] = { { .compatible = "mediatek,mt6360", }, @@ -615,7 +615,7 @@ MODULE_DEVICE_TABLE(of, mt6360_of_id); static struct i2c_driver mt6360_driver = { .driver = { .name = "mt6360", - .pm = &mt6360_pm_ops, + .pm = pm_sleep_ptr(&mt6360_pm_ops), .of_match_table = of_match_ptr(mt6360_of_id), }, .probe = mt6360_probe, diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c index 9ec951996588..5d5f816492aa 100644 --- a/drivers/mfd/mt6397-core.c +++ b/drivers/mfd/mt6397-core.c @@ -261,6 +261,9 @@ static const struct mfd_cell mt6359_devs[] = { static const struct mfd_cell mt6397_devs[] = { { + .name = "mt6397-auxadc", + .of_compatible = "mediatek,mt6397-auxadc", + }, { .name = "mt6397-rtc", .num_resources = ARRAY_SIZE(mt6397_rtc_resources), .resources = mt6397_rtc_resources, diff --git a/drivers/mfd/rave-sp.c b/drivers/mfd/rave-sp.c index 05d26d92df03..53c57bafea8f 100644 --- a/drivers/mfd/rave-sp.c +++ b/drivers/mfd/rave-sp.c @@ -331,7 +331,7 @@ static u8 rave_sp_reply_code(u8 command) return command + 0x20; case 0xE0 ... 0xEF: /* - * Events emitted by all versions of the firmare use + * Events emitted by all versions of the firmware use * least significant bit to get an ACK code */ return command | 0x01; @@ -544,7 +544,7 @@ static size_t rave_sp_receive_buf(struct serdev_device *serdev, * NOTE: The above means that only the * frame started by third SOF, sent * after this one will have a chance - * to get throught. + * to get through. */ goto reset_framer; case RAVE_SP_DLE: @@ -595,7 +595,7 @@ static size_t rave_sp_receive_buf(struct serdev_device *serdev, /* * The only way to get out of the above loop and end up here - * is throught consuming all of the supplied data, so here we + * is through consuming all of the supplied data, so here we * report that we processed it all. */ return size; diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c index 3dcf6abfda74..21182df45d1b 100644 --- a/drivers/mfd/rk8xx-core.c +++ b/drivers/mfd/rk8xx-core.c @@ -875,7 +875,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap if (device_property_read_bool(dev, "system-power-controller") || device_property_read_bool(dev, "rockchip,system-power-controller")) { ret = devm_register_sys_off_handler(dev, - SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_PRIO_HIGH, + SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_HIGH, &rk808_power_off, rk808); if (ret) return dev_err_probe(dev, ret, diff --git a/drivers/mfd/rk8xx-i2c.c b/drivers/mfd/rk8xx-i2c.c index 2951b2911a37..161b25fbe146 100644 --- a/drivers/mfd/rk8xx-i2c.c +++ b/drivers/mfd/rk8xx-i2c.c @@ -251,7 +251,7 @@ static void rk8xx_i2c_shutdown(struct i2c_client *client) rk8xx_shutdown(&client->dev); } -static SIMPLE_DEV_PM_OPS(rk8xx_i2c_pm_ops, rk8xx_suspend, rk8xx_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(rk8xx_i2c_pm_ops, rk8xx_suspend, rk8xx_resume); static const struct of_device_id rk8xx_i2c_of_match[] = { { .compatible = "rockchip,rk801", .data = &rk801_data }, @@ -270,7 +270,7 @@ static struct i2c_driver rk8xx_i2c_driver = { .driver = { .name = "rk8xx-i2c", .of_match_table = rk8xx_i2c_of_match, - .pm = &rk8xx_i2c_pm_ops, + .pm = pm_sleep_ptr(&rk8xx_i2c_pm_ops), }, .probe = rk8xx_i2c_probe, .shutdown = rk8xx_i2c_shutdown, diff --git a/drivers/mfd/rn5t618.c b/drivers/mfd/rn5t618.c index 23ca00d2c624..8c68dd16bb9e 100644 --- a/drivers/mfd/rn5t618.c +++ b/drivers/mfd/rn5t618.c @@ -243,7 +243,7 @@ static void rn5t618_i2c_remove(struct i2c_client *i2c) unregister_restart_handler(&rn5t618_restart_handler); } -static int __maybe_unused rn5t618_i2c_suspend(struct device *dev) +static int rn5t618_i2c_suspend(struct device *dev) { struct rn5t618 *priv = dev_get_drvdata(dev); @@ -253,7 +253,7 @@ static int __maybe_unused rn5t618_i2c_suspend(struct device *dev) return 0; } -static int __maybe_unused rn5t618_i2c_resume(struct device *dev) +static int rn5t618_i2c_resume(struct device *dev) { struct rn5t618 *priv = dev_get_drvdata(dev); @@ -263,7 +263,7 @@ static int __maybe_unused rn5t618_i2c_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(rn5t618_i2c_dev_pm_ops, +static DEFINE_SIMPLE_DEV_PM_OPS(rn5t618_i2c_dev_pm_ops, rn5t618_i2c_suspend, rn5t618_i2c_resume); @@ -271,7 +271,7 @@ static struct i2c_driver rn5t618_i2c_driver = { .driver = { .name = "rn5t618", .of_match_table = rn5t618_of_match, - .pm = &rn5t618_i2c_dev_pm_ops, + .pm = pm_sleep_ptr(&rn5t618_i2c_dev_pm_ops), }, .probe = rn5t618_i2c_probe, .remove = rn5t618_i2c_remove, diff --git a/drivers/mfd/si476x-i2c.c b/drivers/mfd/si476x-i2c.c index 9bce720a0a08..6351aef2d3bb 100644 --- a/drivers/mfd/si476x-i2c.c +++ b/drivers/mfd/si476x-i2c.c @@ -222,7 +222,7 @@ int si476x_core_stop(struct si476x_core *core, bool soft) atomic_set(&core->is_alive, 0); if (soft) { - /* TODO: This probably shoud be a configurable option, + /* TODO: This probably should be a configurable option, * so it is possible to have the chips keep their * oscillators running */ diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c index 068c25401c6c..81f07a1d780c 100644 --- a/drivers/mfd/ti_am335x_tscadc.c +++ b/drivers/mfd/ti_am335x_tscadc.c @@ -313,7 +313,7 @@ static int __maybe_unused ti_tscadc_can_wakeup(struct device *dev, void *data) return device_may_wakeup(dev); } -static int __maybe_unused tscadc_suspend(struct device *dev) +static int tscadc_suspend(struct device *dev) { struct ti_tscadc_dev *tscadc = dev_get_drvdata(dev); @@ -331,7 +331,7 @@ static int __maybe_unused tscadc_suspend(struct device *dev) return 0; } -static int __maybe_unused tscadc_resume(struct device *dev) +static int tscadc_resume(struct device *dev) { struct ti_tscadc_dev *tscadc = dev_get_drvdata(dev); @@ -345,7 +345,7 @@ static int __maybe_unused tscadc_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(tscadc_pm_ops, tscadc_suspend, tscadc_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(tscadc_pm_ops, tscadc_suspend, tscadc_resume); static const struct ti_tscadc_data tscdata = { .adc_feature_name = "TI-am335x-adc", @@ -373,7 +373,7 @@ MODULE_DEVICE_TABLE(of, ti_tscadc_dt_ids); static struct platform_driver ti_tscadc_driver = { .driver = { .name = "ti_am3359-tscadc", - .pm = &tscadc_pm_ops, + .pm = pm_sleep_ptr(&tscadc_pm_ops), .of_match_table = ti_tscadc_dt_ids, }, .probe = ti_tscadc_probe, diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c index c240fac0ede7..569c28c8b20f 100644 --- a/drivers/mfd/tps65217.c +++ b/drivers/mfd/tps65217.c @@ -146,6 +146,31 @@ static const struct irq_domain_ops tps65217_irq_domain_ops = { .map = tps65217_irq_map, }; +static void tps65217_irq_cleanup(void *data) +{ + struct tps65217 *tps = data; + unsigned int virq; + + if (!tps->irq_domain) + return; + + for (int i = 0; i < TPS65217_NUM_IRQ; i++) { + virq = irq_find_mapping(tps->irq_domain, i); + if (virq) + irq_dispose_mapping(virq); + } + + irq_domain_remove(tps->irq_domain); + tps->irq_domain = NULL; +} + +static void tps65217_irq_wake_disable(void *data) +{ + unsigned long irq = (unsigned long)data; + + disable_irq_wake(irq); +} + static int tps65217_irq_init(struct tps65217 *tps, int irq) { int ret; @@ -155,8 +180,12 @@ static int tps65217_irq_init(struct tps65217 *tps, int irq) /* Mask all interrupt sources */ tps->irq_mask = TPS65217_INT_MASK; - tps65217_set_bits(tps, TPS65217_REG_INT, TPS65217_INT_MASK, - TPS65217_INT_MASK, TPS65217_PROTECT_NONE); + ret = tps65217_set_bits(tps, TPS65217_REG_INT, TPS65217_INT_MASK, + TPS65217_INT_MASK, TPS65217_PROTECT_NONE); + if (ret) { + dev_err(tps->dev, "Failed to mask interrupt sources: %d\n", ret); + return ret; + } tps->irq_domain = irq_domain_create_linear(dev_fwnode(tps->dev), TPS65217_NUM_IRQ, &tps65217_irq_domain_ops, tps); @@ -165,6 +194,10 @@ static int tps65217_irq_init(struct tps65217 *tps, int irq) return -ENOMEM; } + ret = devm_add_action_or_reset(tps->dev, tps65217_irq_cleanup, tps); + if (ret) + return ret; + ret = devm_request_threaded_irq(tps->dev, irq, NULL, tps65217_irq_thread, IRQF_ONESHOT, "tps65217-irq", tps); @@ -174,7 +207,16 @@ static int tps65217_irq_init(struct tps65217 *tps, int irq) return ret; } - enable_irq_wake(irq); + ret = enable_irq_wake(irq); + if (ret) { + dev_warn(tps->dev, "failed to enable IRQ wake: %d\n", ret); + return 0; + } + + ret = devm_add_action_or_reset(tps->dev, tps65217_irq_wake_disable, + (void *)(unsigned long)irq); + if (ret) + return ret; return 0; } @@ -333,7 +375,9 @@ static int tps65217_probe(struct i2c_client *client) } if (client->irq) { - tps65217_irq_init(tps, client->irq); + ret = tps65217_irq_init(tps, client->irq); + if (ret) + return ret; } else { int i; @@ -373,22 +417,6 @@ static int tps65217_probe(struct i2c_client *client) return 0; } -static void tps65217_remove(struct i2c_client *client) -{ - struct tps65217 *tps = i2c_get_clientdata(client); - unsigned int virq; - int i; - - for (i = 0; i < TPS65217_NUM_IRQ; i++) { - virq = irq_find_mapping(tps->irq_domain, i); - if (virq) - irq_dispose_mapping(virq); - } - - irq_domain_remove(tps->irq_domain); - tps->irq_domain = NULL; -} - static const struct i2c_device_id tps65217_id_table[] = { {"tps65217", TPS65217}, { /* sentinel */ } @@ -402,7 +430,6 @@ static struct i2c_driver tps65217_driver = { }, .id_table = tps65217_id_table, .probe = tps65217_probe, - .remove = tps65217_remove, }; static int __init tps65217_init(void) diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index 3cfd2f02b62f..600186b1e8cb 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c @@ -618,7 +618,7 @@ static void tps6586x_i2c_remove(struct i2c_client *client) free_irq(client->irq, tps6586x); } -static int __maybe_unused tps6586x_i2c_suspend(struct device *dev) +static int tps6586x_i2c_suspend(struct device *dev) { struct tps6586x *tps6586x = dev_get_drvdata(dev); @@ -628,7 +628,7 @@ static int __maybe_unused tps6586x_i2c_suspend(struct device *dev) return 0; } -static int __maybe_unused tps6586x_i2c_resume(struct device *dev) +static int tps6586x_i2c_resume(struct device *dev) { struct tps6586x *tps6586x = dev_get_drvdata(dev); @@ -638,7 +638,7 @@ static int __maybe_unused tps6586x_i2c_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(tps6586x_pm_ops, tps6586x_i2c_suspend, +static DEFINE_SIMPLE_DEV_PM_OPS(tps6586x_pm_ops, tps6586x_i2c_suspend, tps6586x_i2c_resume); static const struct i2c_device_id tps6586x_id_table[] = { @@ -651,7 +651,7 @@ static struct i2c_driver tps6586x_driver = { .driver = { .name = "tps6586x", .of_match_table = of_match_ptr(tps6586x_of_match), - .pm = &tps6586x_pm_ops, + .pm = pm_sleep_ptr(&tps6586x_pm_ops), }, .probe = tps6586x_i2c_probe, .remove = tps6586x_i2c_remove, diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index c024a28b057e..7fbce76efd30 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -719,6 +719,11 @@ static const struct mfd_cell twl6032_cells[] = { { .name = "twl6032-clk" }, }; +static void twl_unregister_device(void *data) +{ + platform_device_unregister(data); +} + /* NOTE: This driver only handles a single twl4030/tps659x0 chip */ static int twl_probe(struct i2c_client *client) @@ -754,17 +759,22 @@ twl_probe(struct i2c_client *client) return status; } + status = devm_add_action_or_reset(&client->dev, twl_unregister_device, + pdev); + if (status) + return status; + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_dbg(&client->dev, "can't talk I2C?\n"); status = -EIO; - goto free; + goto out; } twl_priv = devm_kzalloc(&client->dev, sizeof(struct twl_private), GFP_KERNEL); if (!twl_priv) { status = -ENOMEM; - goto free; + goto out; } if ((id->driver_data) & TWL6030_CLASS) { @@ -784,7 +794,7 @@ twl_probe(struct i2c_client *client) GFP_KERNEL); if (!twl_priv->twl_modules) { status = -ENOMEM; - goto free; + goto out; } for (i = 0; i < num_slaves; i++) { @@ -880,7 +890,7 @@ twl_probe(struct i2c_client *client) status = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE, cells, num_cells, NULL, 0, NULL); if (status < 0) - goto free; + goto out; if (of_device_is_system_power_controller(node)) { if (!pm_power_off) @@ -896,14 +906,11 @@ twl_probe(struct i2c_client *client) fail: if (status < 0) twl_remove(client); -free: - if (status < 0) - platform_device_unregister(pdev); - +out: return status; } -static int __maybe_unused twl_suspend(struct device *dev) +static int twl_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -913,7 +920,7 @@ static int __maybe_unused twl_suspend(struct device *dev) return 0; } -static int __maybe_unused twl_resume(struct device *dev) +static int twl_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -923,7 +930,7 @@ static int __maybe_unused twl_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(twl_dev_pm_ops, twl_suspend, twl_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(twl_dev_pm_ops, twl_suspend, twl_resume); static const struct i2c_device_id twl_ids[] = { { "twl4030", TWL4030_VAUX2 }, /* "Triton 2" */ @@ -942,7 +949,7 @@ static const struct i2c_device_id twl_ids[] = { /* One Client Driver , 4 Clients */ static struct i2c_driver twl_driver = { .driver.name = DRIVER_NAME, - .driver.pm = &twl_dev_pm_ops, + .driver.pm = pm_sleep_ptr(&twl_dev_pm_ops), .id_table = twl_ids, .probe = twl_probe, .remove = twl_remove, diff --git a/drivers/mfd/wcd934x.c b/drivers/mfd/wcd934x.c index 3c3080e8c8cf..d57796933d87 100644 --- a/drivers/mfd/wcd934x.c +++ b/drivers/mfd/wcd934x.c @@ -2,6 +2,7 @@ // Copyright (c) 2019, Linaro Limited #include +#include #include #include #include @@ -217,13 +218,18 @@ static int wcd934x_slim_probe(struct slim_device *sdev) struct gpio_desc *reset_gpio; int ret; + ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32)); + if (ret) + return dev_err_probe(dev, ret, + "Failed to set DMA mask\n"); + ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL); if (!ddata) return -ENOMEM; ddata->irq = of_irq_get(np, 0); if (ddata->irq < 0) - return dev_err_probe(ddata->dev, ddata->irq, + return dev_err_probe(dev, ddata->irq, "Failed to get IRQ\n"); ddata->extclk = devm_clk_get(dev, "extclk"); diff --git a/drivers/mfd/wm831x-auxadc.c b/drivers/mfd/wm831x-auxadc.c index 744e1d161c5a..6280d4f38981 100644 --- a/drivers/mfd/wm831x-auxadc.c +++ b/drivers/mfd/wm831x-auxadc.c @@ -132,7 +132,7 @@ static irqreturn_t wm831x_auxadc_irq(int irq, void *irq_data) 1 << input, 0); wm831x->auxadc_active &= ~(1 << input); - /* Turn off the entire convertor if idle */ + /* Turn off the entire converter if idle */ if (!wm831x->auxadc_active) wm831x_reg_write(wm831x, WM831X_AUXADC_CONTROL, 0); diff --git a/drivers/thermal/khadas_mcu_fan.c b/drivers/thermal/khadas_mcu_fan.c index 21b3d0a71bd0..1da639d05497 100644 --- a/drivers/thermal/khadas_mcu_fan.c +++ b/drivers/thermal/khadas_mcu_fan.c @@ -13,34 +13,33 @@ #include #include #include +#include +#include -#define MAX_LEVEL 3 +#define MAX_LEVEL 5 struct khadas_mcu_fan_ctx { struct khadas_mcu *mcu; + unsigned int fan_reg; unsigned int level; + const unsigned int *levels; + unsigned int nlevels; struct thermal_cooling_device *cdev; + struct regulator *power; }; static int khadas_mcu_fan_set_level(struct khadas_mcu_fan_ctx *ctx, unsigned int level) { - int ret; - - ret = regmap_write(ctx->mcu->regmap, KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG, - level); - if (ret) - return ret; - - ctx->level = level; - - return 0; + return regmap_write(ctx->mcu->regmap, ctx->fan_reg, level); } static int khadas_mcu_fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long *state) { - *state = MAX_LEVEL; + struct khadas_mcu_fan_ctx *ctx = cdev->devdata; + + *state = min_t(unsigned int, MAX_LEVEL, ctx->nlevels - 1); return 0; } @@ -60,14 +59,21 @@ khadas_mcu_fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state) { struct khadas_mcu_fan_ctx *ctx = cdev->devdata; + int ret; - if (state > MAX_LEVEL) + if (state > MAX_LEVEL || state >= ctx->nlevels) return -EINVAL; if (state == ctx->level) return 0; - return khadas_mcu_fan_set_level(ctx, state); + ret = khadas_mcu_fan_set_level(ctx, ctx->levels[state]); + if (ret) + return ret; + + ctx->level = state; + + return 0; } static const struct thermal_cooling_device_ops khadas_mcu_fan_cooling_ops = { @@ -76,22 +82,71 @@ static const struct thermal_cooling_device_ops khadas_mcu_fan_cooling_ops = { .set_cur_state = khadas_mcu_fan_set_cur_state, }; +static void khadas_mcu_fan_regulator_disable(void *data) +{ + struct regulator *power = data; + + regulator_disable(power); +} + +static const unsigned int khadas_mcu_fan_levels[] = { 0, 1, 2, 3 }; + +static const unsigned int khadas_mcu_vim4_fan_levels[] = { 0, 30, 40, 55, 75, 100 }; + static int khadas_mcu_fan_probe(struct platform_device *pdev) { + const struct platform_device_id *id = platform_get_device_id(pdev); struct khadas_mcu *mcu = dev_get_drvdata(pdev->dev.parent); struct thermal_cooling_device *cdev; struct device *dev = &pdev->dev; struct khadas_mcu_fan_ctx *ctx; int ret; + + if (!dev->of_node) + dev->of_node = of_node_get(dev->parent->of_node); + + if (!id) + return -EINVAL; + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; + ctx->mcu = mcu; + switch (id->driver_data) { + case KHADAS_MCU_GENERIC: + ctx->fan_reg = KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG; + ctx->levels = khadas_mcu_fan_levels; + ctx->nlevels = ARRAY_SIZE(khadas_mcu_fan_levels); + break; + case KHADAS_MCU_VIM4: + ctx->fan_reg = KHADAS_MCU_VIM4_FAN_CTRL_REG; + ctx->levels = khadas_mcu_vim4_fan_levels; + ctx->nlevels = ARRAY_SIZE(khadas_mcu_vim4_fan_levels); + break; + default: + return -ENODEV; + } + + ctx->power = devm_regulator_get(dev, "fan"); + if (IS_ERR(ctx->power)) + return PTR_ERR(ctx->power); + + ret = regulator_enable(ctx->power); + if (ret) { + dev_err(dev, "Failed to enable fan power supply: %d\n", ret); + return ret; + } + + ret = devm_add_action_or_reset(dev, khadas_mcu_fan_regulator_disable, ctx->power); + if (ret) + return ret; + platform_set_drvdata(pdev, ctx); - cdev = devm_thermal_of_child_cooling_device_register(dev->parent, - dev->parent->of_node, + cdev = devm_thermal_of_child_cooling_device_register(dev, + dev->of_node, "khadas-mcu-fan", ctx, &khadas_mcu_fan_cooling_ops); if (IS_ERR(cdev)) { @@ -109,21 +164,24 @@ static void khadas_mcu_fan_shutdown(struct platform_device *pdev) { struct khadas_mcu_fan_ctx *ctx = platform_get_drvdata(pdev); - khadas_mcu_fan_set_level(ctx, 0); + khadas_mcu_fan_set_level(ctx, ctx->levels[0]); } #ifdef CONFIG_PM_SLEEP static int khadas_mcu_fan_suspend(struct device *dev) { struct khadas_mcu_fan_ctx *ctx = dev_get_drvdata(dev); - unsigned int level_save = ctx->level; int ret; - ret = khadas_mcu_fan_set_level(ctx, 0); + ret = khadas_mcu_fan_set_level(ctx, ctx->levels[0]); if (ret) return ret; - ctx->level = level_save; + ret = regulator_disable(ctx->power); + if (ret) { + khadas_mcu_fan_set_level(ctx, ctx->levels[ctx->level]); + return ret; + } return 0; } @@ -131,8 +189,13 @@ static int khadas_mcu_fan_suspend(struct device *dev) static int khadas_mcu_fan_resume(struct device *dev) { struct khadas_mcu_fan_ctx *ctx = dev_get_drvdata(dev); + int ret; - return khadas_mcu_fan_set_level(ctx, ctx->level); + ret = regulator_enable(ctx->power); + if (ret) + return ret; + + return khadas_mcu_fan_set_level(ctx, ctx->levels[ctx->level]); } #endif @@ -140,7 +203,8 @@ static SIMPLE_DEV_PM_OPS(khadas_mcu_fan_pm, khadas_mcu_fan_suspend, khadas_mcu_fan_resume); static const struct platform_device_id khadas_mcu_fan_id_table[] = { - { .name = "khadas-mcu-fan-ctrl", }, + { .name = "khadas-mcu-fan-ctrl", .driver_data = KHADAS_MCU_GENERIC }, + { .name = "khadas-mcu-vim4-fan", .driver_data = KHADAS_MCU_VIM4 }, {}, }; MODULE_DEVICE_TABLE(platform, khadas_mcu_fan_id_table); diff --git a/drivers/video/backlight/lm3533_bl.c b/drivers/video/backlight/lm3533_bl.c index babfd3ceec86..adcd6ac7cf22 100644 --- a/drivers/video/backlight/lm3533_bl.c +++ b/drivers/video/backlight/lm3533_bl.c @@ -10,7 +10,9 @@ #include #include #include +#include #include +#include #include #include @@ -20,13 +22,21 @@ #define LM3533_BL_MAX_BRIGHTNESS 255 #define LM3533_REG_CTRLBANK_AB_BCONF 0x1a +#define CTRLBANK_AB_BCONF_ALS(n) BIT(2 * (n)) +#define CTRLBANK_AB_BCONF_MODE(n) BIT(2 * (n) + 1) struct lm3533_bl { - struct lm3533 *lm3533; + struct regmap *regmap; struct lm3533_ctrlbank cb; struct backlight_device *bd; int id; + + u32 max_current; + u32 pwm; + + bool have_als; + bool linear; }; @@ -45,7 +55,7 @@ static int lm3533_bl_update_status(struct backlight_device *bd) static int lm3533_bl_get_brightness(struct backlight_device *bd) { struct lm3533_bl *bl = bl_get_data(bd); - u8 val; + u32 val; int ret; ret = lm3533_ctrlbank_get_brightness(&bl->cb, &val); @@ -77,103 +87,75 @@ static ssize_t show_als_channel(struct device *dev, return scnprintf(buf, PAGE_SIZE, "%u\n", channel); } -static ssize_t show_als_en(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_als_en(struct device *dev, struct device_attribute *attr, + char *buf) { struct lm3533_bl *bl = dev_get_drvdata(dev); int ctrlbank = lm3533_bl_get_ctrlbank_id(bl); - u8 val; - u8 mask; - bool enable; int ret; - ret = lm3533_read(bl->lm3533, LM3533_REG_CTRLBANK_AB_BCONF, &val); - if (ret) + ret = regmap_test_bits(bl->regmap, LM3533_REG_CTRLBANK_AB_BCONF, + CTRLBANK_AB_BCONF_ALS(ctrlbank)); + if (ret < 0) return ret; - mask = 1 << (2 * ctrlbank); - enable = val & mask; - - return scnprintf(buf, PAGE_SIZE, "%d\n", enable); + return scnprintf(buf, PAGE_SIZE, "%d\n", ret); } -static ssize_t store_als_en(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) +static ssize_t store_als_en(struct device *dev, struct device_attribute *attr, + const char *buf, size_t len) { struct lm3533_bl *bl = dev_get_drvdata(dev); int ctrlbank = lm3533_bl_get_ctrlbank_id(bl); int enable; - u8 val; - u8 mask; int ret; if (kstrtoint(buf, 0, &enable)) return -EINVAL; - mask = 1 << (2 * ctrlbank); - - if (enable) - val = mask; - else - val = 0; - - ret = lm3533_update(bl->lm3533, LM3533_REG_CTRLBANK_AB_BCONF, val, - mask); + ret = regmap_assign_bits(bl->regmap, LM3533_REG_CTRLBANK_AB_BCONF, + CTRLBANK_AB_BCONF_ALS(ctrlbank), enable); if (ret) return ret; return len; } -static ssize_t show_linear(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_linear(struct device *dev, struct device_attribute *attr, + char *buf) { struct lm3533_bl *bl = dev_get_drvdata(dev); - u8 val; - u8 mask; - int linear; + int ctrlbank = lm3533_bl_get_ctrlbank_id(bl); int ret; - ret = lm3533_read(bl->lm3533, LM3533_REG_CTRLBANK_AB_BCONF, &val); - if (ret) + ret = regmap_test_bits(bl->regmap, LM3533_REG_CTRLBANK_AB_BCONF, + CTRLBANK_AB_BCONF_MODE(ctrlbank)); + if (ret < 0) return ret; - mask = 1 << (2 * lm3533_bl_get_ctrlbank_id(bl) + 1); - - if (val & mask) - linear = 1; - else - linear = 0; - - return scnprintf(buf, PAGE_SIZE, "%x\n", linear); + return scnprintf(buf, PAGE_SIZE, "%x\n", ret); } -static ssize_t store_linear(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) +static ssize_t store_linear(struct device *dev, struct device_attribute *attr, + const char *buf, size_t len) { struct lm3533_bl *bl = dev_get_drvdata(dev); + int ctrlbank = lm3533_bl_get_ctrlbank_id(bl); + struct backlight_device *bd = bl->bd; unsigned long linear; - u8 mask; - u8 val; int ret; if (kstrtoul(buf, 0, &linear)) return -EINVAL; - mask = 1 << (2 * lm3533_bl_get_ctrlbank_id(bl) + 1); - - if (linear) - val = mask; - else - val = 0; - - ret = lm3533_update(bl->lm3533, LM3533_REG_CTRLBANK_AB_BCONF, val, - mask); + ret = regmap_assign_bits(bl->regmap, LM3533_REG_CTRLBANK_AB_BCONF, + CTRLBANK_AB_BCONF_MODE(ctrlbank), linear); if (ret) return ret; + bd->props.scale = linear ? BACKLIGHT_SCALE_LINEAR : + BACKLIGHT_SCALE_NON_LINEAR; + return len; } @@ -182,7 +164,7 @@ static ssize_t show_pwm(struct device *dev, char *buf) { struct lm3533_bl *bl = dev_get_drvdata(dev); - u8 val; + u32 val; int ret; ret = lm3533_ctrlbank_get_pwm(&bl->cb, &val); @@ -197,10 +179,10 @@ static ssize_t store_pwm(struct device *dev, const char *buf, size_t len) { struct lm3533_bl *bl = dev_get_drvdata(dev); - u8 val; + u32 val; int ret; - if (kstrtou8(buf, 0, &val)) + if (kstrtou32(buf, 0, &val)) return -EINVAL; ret = lm3533_ctrlbank_set_pwm(&bl->cb, val); @@ -234,7 +216,7 @@ static umode_t lm3533_bl_attr_is_visible(struct kobject *kobj, if (attr == &dev_attr_als_channel.attr || attr == &dev_attr_als_en.attr) { - if (!bl->lm3533->have_als) + if (!bl->have_als) mode = 0; } @@ -246,25 +228,36 @@ static struct attribute_group lm3533_bl_attribute_group = { .attrs = lm3533_bl_attributes }; -static int lm3533_bl_setup(struct lm3533_bl *bl, - struct lm3533_bl_platform_data *pdata) +static const struct attribute_group *lm3533_bl_attribute_groups[] = { + &lm3533_bl_attribute_group, + NULL, +}; + +static int lm3533_bl_setup(struct lm3533_bl *bl) { + int ctrlbank = lm3533_bl_get_ctrlbank_id(bl); int ret; - ret = lm3533_ctrlbank_set_max_current(&bl->cb, pdata->max_current); + ret = regmap_assign_bits(bl->regmap, LM3533_REG_CTRLBANK_AB_BCONF, + CTRLBANK_AB_BCONF_MODE(ctrlbank), bl->linear); if (ret) return ret; - return lm3533_ctrlbank_set_pwm(&bl->cb, pdata->pwm); + ret = lm3533_ctrlbank_set_max_current(&bl->cb, bl->max_current); + if (ret) + return ret; + + return lm3533_ctrlbank_set_pwm(&bl->cb, bl->pwm); } static int lm3533_bl_probe(struct platform_device *pdev) { struct lm3533 *lm3533; - struct lm3533_bl_platform_data *pdata; struct lm3533_bl *bl; struct backlight_device *bd; struct backlight_properties props; + char *name = NULL; + u32 default_brightness = LM3533_BL_MAX_BRIGHTNESS; int ret; dev_dbg(&pdev->dev, "%s\n", __func__); @@ -273,12 +266,6 @@ static int lm3533_bl_probe(struct platform_device *pdev) if (!lm3533) return -EINVAL; - pdata = dev_get_platdata(&pdev->dev); - if (!pdata) { - dev_err(&pdev->dev, "no platform data\n"); - return -EINVAL; - } - if (pdev->id < 0 || pdev->id >= LM3533_HVCTRLBANK_COUNT) { dev_err(&pdev->dev, "illegal backlight id %d\n", pdev->id); return -EINVAL; @@ -288,20 +275,34 @@ static int lm3533_bl_probe(struct platform_device *pdev) if (!bl) return -ENOMEM; - bl->lm3533 = lm3533; + bl->regmap = lm3533->regmap; + bl->have_als = lm3533->have_als; bl->id = pdev->id; - bl->cb.lm3533 = lm3533; + bl->cb.regmap = lm3533->regmap; bl->cb.id = lm3533_bl_get_ctrlbank_id(bl); bl->cb.dev = NULL; /* until registered */ + name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s-%d", + pdev->name, pdev->id); + if (!name) + return -ENOMEM; + + device_property_read_u32(&pdev->dev, "default-brightness", + &default_brightness); + memset(&props, 0, sizeof(props)); props.type = BACKLIGHT_RAW; props.max_brightness = LM3533_BL_MAX_BRIGHTNESS; - props.brightness = pdata->default_brightness; - bd = devm_backlight_device_register(&pdev->dev, pdata->name, - pdev->dev.parent, bl, &lm3533_bl_ops, - &props); + props.brightness = default_brightness; + + bl->linear = device_property_read_bool(&pdev->dev, + "ti,linear-mapping-mode"); + props.scale = bl->linear ? BACKLIGHT_SCALE_LINEAR : + BACKLIGHT_SCALE_NON_LINEAR; + + bd = devm_backlight_device_register(&pdev->dev, name, &pdev->dev, + bl, &lm3533_bl_ops, &props); if (IS_ERR(bd)) { dev_err(&pdev->dev, "failed to register backlight device\n"); return PTR_ERR(bd); @@ -312,28 +313,24 @@ static int lm3533_bl_probe(struct platform_device *pdev) platform_set_drvdata(pdev, bl); - ret = sysfs_create_group(&bd->dev.kobj, &lm3533_bl_attribute_group); - if (ret < 0) { - dev_err(&pdev->dev, "failed to create sysfs attributes\n"); + device_property_read_u32(&pdev->dev, "led-max-microamp", + &bl->max_current); + bl->max_current = clamp(bl->max_current, LM3533_MAX_CURRENT_MIN, + LM3533_MAX_CURRENT_MAX); + + device_property_read_u32(&pdev->dev, "ti,pwm-config-mask", &bl->pwm); + + ret = lm3533_bl_setup(bl); + if (ret) return ret; - } backlight_update_status(bd); - ret = lm3533_bl_setup(bl, pdata); - if (ret) - goto err_sysfs_remove; - ret = lm3533_ctrlbank_enable(&bl->cb); if (ret) - goto err_sysfs_remove; + return ret; return 0; - -err_sysfs_remove: - sysfs_remove_group(&bd->dev.kobj, &lm3533_bl_attribute_group); - - return ret; } static void lm3533_bl_remove(struct platform_device *pdev) @@ -347,7 +344,6 @@ static void lm3533_bl_remove(struct platform_device *pdev) bd->props.brightness = 0; lm3533_ctrlbank_disable(&bl->cb); - sysfs_remove_group(&bd->dev.kobj, &lm3533_bl_attribute_group); } #ifdef CONFIG_PM_SLEEP @@ -381,10 +377,18 @@ static void lm3533_bl_shutdown(struct platform_device *pdev) lm3533_ctrlbank_disable(&bl->cb); } +static const struct of_device_id lm3533_bl_match_table[] = { + { .compatible = "ti,lm3533-backlight" }, + { } +}; +MODULE_DEVICE_TABLE(of, lm3533_bl_match_table); + static struct platform_driver lm3533_bl_driver = { .driver = { .name = "lm3533-backlight", .pm = &lm3533_bl_pm_ops, + .dev_groups = lm3533_bl_attribute_groups, + .of_match_table = lm3533_bl_match_table, }, .probe = lm3533_bl_probe, .remove = lm3533_bl_remove, diff --git a/include/linux/mfd/cs42l43-regs.h b/include/linux/mfd/cs42l43-regs.h index 68831f113589..4c00ceae8b46 100644 --- a/include/linux/mfd/cs42l43-regs.h +++ b/include/linux/mfd/cs42l43-regs.h @@ -1183,6 +1183,7 @@ /* CS42L43B VARIANT REGISTERS */ #define CS42L43B_DEVID_VAL 0x0042A43B +#define CS42L44_DEVID_VAL 0x00042A44 #define CS42L43B_DECIM_VOL_CTRL_CH1_CH2 0x00008280 #define CS42L43B_DECIM_VOL_CTRL_CH3_CH4 0x00008284 diff --git a/include/linux/mfd/da9063/registers.h b/include/linux/mfd/da9063/registers.h index 7b8364bd08a0..376c5d330599 100644 --- a/include/linux/mfd/da9063/registers.h +++ b/include/linux/mfd/da9063/registers.h @@ -14,7 +14,7 @@ #define DA9063_I2C_PAGE_SEL_SHIFT 1 #define DA9063_EVENT_REG_NUM 4 -/* Page selection I2C or SPI always in the begining of any page. */ +/* Page selection I2C or SPI always in the beginning of any page. */ /* Page 0 : I2C access 0x000 - 0x0FF SPI access 0x000 - 0x07F */ /* Page 1 : SPI access 0x080 - 0x0FF */ /* Page 2 : I2C access 0x100 - 0x1FF SPI access 0x100 - 0x17F */ diff --git a/include/linux/mfd/da9150/core.h b/include/linux/mfd/da9150/core.h index d116d5f3ef56..369698036d1a 100644 --- a/include/linux/mfd/da9150/core.h +++ b/include/linux/mfd/da9150/core.h @@ -65,6 +65,7 @@ struct da9150 { struct regmap_irq_chip_data *regmap_irq_data; int irq; int irq_base; + bool irq_wake_enabled; }; /* Device I/O - Query Interface for FG and standard register access */ diff --git a/include/linux/mfd/db8500-prcmu.h b/include/linux/mfd/db8500-prcmu.h index c939c9a1170a..87a28c4f1d81 100644 --- a/include/linux/mfd/db8500-prcmu.h +++ b/include/linux/mfd/db8500-prcmu.h @@ -337,31 +337,31 @@ enum sia_mmdsp_stat { * @SYSCLKOK_ERR: The SYSCLK is not available in the given time * @BOOT_ERR: Romcode has not validated the XP70 self reset in the given time * @ROMCODESAVECONTEXT: The Romcode didn.t correctly save it secure context - * @VARMHIGHSPEEDVALTO_ERR: The ARM high speed supply value transfered + * @VARMHIGHSPEEDVALTO_ERR: The ARM high speed supply value transferred * through I2C has not been correctly executed in the given time - * @VARMHIGHSPEEDACCESS_ERR: The command value of VarmHighSpeedVal transfered + * @VARMHIGHSPEEDACCESS_ERR: The command value of VarmHighSpeedVal transferred * through I2C has not been correctly executed in the given time - * @VARMLOWSPEEDVALTO_ERR:The ARM low speed supply value transfered through + * @VARMLOWSPEEDVALTO_ERR:The ARM low speed supply value transferred through * I2C has not been correctly executed in the given time - * @VARMLOWSPEEDACCESS_ERR: The command value of VarmLowSpeedVal transfered + * @VARMLOWSPEEDACCESS_ERR: The command value of VarmLowSpeedVal transferred * through I2C has not been correctly executed in the given time - * @VARMRETENTIONVALTO_ERR: The ARM retention supply value transfered through + * @VARMRETENTIONVALTO_ERR: The ARM retention supply value transferred through * I2C has not been correctly executed in the given time - * @VARMRETENTIONACCESS_ERR: The command value of VarmRetentionVal transfered + * @VARMRETENTIONACCESS_ERR: The command value of VarmRetentionVal transferred * through I2C has not been correctly executed in the given time - * @VAPEHIGHSPEEDVALTO_ERR: The APE highspeed supply value transfered through + * @VAPEHIGHSPEEDVALTO_ERR: The APE highspeed supply value transferred through * I2C has not been correctly executed in the given time - * @VSAFEHPVALTO_ERR: The SAFE high power supply value transfered through I2C + * @VSAFEHPVALTO_ERR: The SAFE high power supply value transferred through I2C * has not been correctly executed in the given time - * @VMODSEL1VALTO_ERR: The MODEM sel1 supply value transfered through I2C has + * @VMODSEL1VALTO_ERR: The MODEM sel1 supply value transferred through I2C has * not been correctly executed in the given time - * @VMODSEL2VALTO_ERR: The MODEM sel2 supply value transfered through I2C has + * @VMODSEL2VALTO_ERR: The MODEM sel2 supply value transferred through I2C has * not been correctly executed in the given time - * @VARMOFFACCESS_ERR: The command value of Varm ON/OFF transfered through + * @VARMOFFACCESS_ERR: The command value of Varm ON/OFF transferred through * I2C has not been correctly executed in the given time - * @VAPEOFFACCESS_ERR: The command value of Vape ON/OFF transfered through + * @VAPEOFFACCESS_ERR: The command value of Vape ON/OFF transferred through * I2C has not been correctly executed in the given time - * @VARMRETACCES_ERR: The command value of Varm retention ON/OFF transfered + * @VARMRETACCES_ERR: The command value of Varm retention ON/OFF transferred * through I2C has not been correctly executed in the given time * @CURAPPWRSTISNOTBOOT:Generated when Arm want to do power state transition * ApBoot to ApExecute but the power current state is not Apboot @@ -376,11 +376,11 @@ enum sia_mmdsp_stat { * been correctly executed in the given time * @ARMREGU2VALTO_ERR: The ArmRegu2 value transferred through I2C has not * been correctly executed in the given time - * @VAPEREGUVALTO_ERR: The VApeRegu value transfered through I2C has not + * @VAPEREGUVALTO_ERR: The VApeRegu value transferred through I2C has not * been correctly executed in the given time - * @VSMPS3REGUVALTO_ERR: The VSmps3Regu value transfered through I2C has not + * @VSMPS3REGUVALTO_ERR: The VSmps3Regu value transferred through I2C has not * been correctly executed in the given time - * @VMODREGUVALTO_ERR: The VModemRegu value transfered through I2C has not + * @VMODREGUVALTO_ERR: The VModemRegu value transferred through I2C has not * been correctly executed in the given time */ enum mbox_to_arm_err { diff --git a/include/linux/mfd/khadas-mcu.h b/include/linux/mfd/khadas-mcu.h index a99ba2ed0e4e..acd3291061b4 100644 --- a/include/linux/mfd/khadas-mcu.h +++ b/include/linux/mfd/khadas-mcu.h @@ -70,6 +70,13 @@ #define KHADAS_MCU_WOL_INIT_START_REG 0x87 /* WO */ #define KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG 0x88 /* WO */ +/* VIM4 specific registers */ +#define KHADAS_MCU_VIM4_REST_CONF_REG 0x2c /* WO - reset EEPROM */ +#define KHADAS_MCU_VIM4_LED_ON_RAM_REG 0x89 /* WO - LED volatile */ +#define KHADAS_MCU_VIM4_FAN_CTRL_REG 0x8a /* WO */ +#define KHADAS_MCU_VIM4_WDT_EN_REG 0x8b /* WO */ +#define KHADAS_MCU_VIM4_SYS_RST_REG 0x91 /* WO */ + enum { KHADAS_BOARD_VIM1 = 0x1, KHADAS_BOARD_VIM2, @@ -80,7 +87,7 @@ enum { /** * struct khadas_mcu - Khadas MCU structure - * @device: device reference used for logs + * @dev: device reference used for logs * @regmap: register map */ struct khadas_mcu { @@ -88,4 +95,14 @@ struct khadas_mcu { struct regmap *regmap; }; +/** + * enum khadas_mcu_type - Khadas MCU hardware variant + * @KHADAS_MCU_GENERIC: VIM1, VIM2, VIM3, Edge, Edge-V (shared register map) + * @KHADAS_MCU_VIM4: VIM4 (extended register map, distinct fan/LED/WDT regs) + */ +enum khadas_mcu_type { + KHADAS_MCU_GENERIC = 1, + KHADAS_MCU_VIM4, +}; + #endif /* MFD_KHADAS_MCU_H */ diff --git a/include/linux/mfd/lm3533.h b/include/linux/mfd/lm3533.h index 69059a7a2ce5..8f72dd41e8f0 100644 --- a/include/linux/mfd/lm3533.h +++ b/include/linux/mfd/lm3533.h @@ -15,9 +15,14 @@ #define LM3533_ATTR_RW(_name) \ DEVICE_ATTR(_name, S_IRUGO | S_IWUSR , show_##_name, store_##_name) +#define LM3533_MAX_CURRENT_MIN 5000 +#define LM3533_MAX_CURRENT_MAX 29800 +#define LM3533_MAX_CURRENT_STEP 800 + struct device; struct gpio_desc; struct regmap; +struct regulator; struct lm3533 { struct device *dev; @@ -25,7 +30,10 @@ struct lm3533 { struct regmap *regmap; struct gpio_desc *hwen; - int irq; + struct regulator *vin_supply; + + u32 boost_ovp; + u32 boost_freq; unsigned have_als:1; unsigned have_backlights:1; @@ -33,67 +41,18 @@ struct lm3533 { }; struct lm3533_ctrlbank { - struct lm3533 *lm3533; + struct regmap *regmap; struct device *dev; int id; }; -struct lm3533_als_platform_data { - unsigned pwm_mode:1; /* PWM input mode (default analog) */ - u8 r_select; /* 1 - 127 (ignored in PWM-mode) */ -}; +int lm3533_ctrlbank_enable(struct lm3533_ctrlbank *cb); +int lm3533_ctrlbank_disable(struct lm3533_ctrlbank *cb); -struct lm3533_bl_platform_data { - char *name; - u16 max_current; /* 5000 - 29800 uA (800 uA step) */ - u8 default_brightness; /* 0 - 255 */ - u8 pwm; /* 0 - 0x3f */ -}; - -struct lm3533_led_platform_data { - char *name; - const char *default_trigger; - u16 max_current; /* 5000 - 29800 uA (800 uA step) */ - u8 pwm; /* 0 - 0x3f */ -}; - -enum lm3533_boost_freq { - LM3533_BOOST_FREQ_500KHZ, - LM3533_BOOST_FREQ_1000KHZ, -}; - -enum lm3533_boost_ovp { - LM3533_BOOST_OVP_16V, - LM3533_BOOST_OVP_24V, - LM3533_BOOST_OVP_32V, - LM3533_BOOST_OVP_40V, -}; - -struct lm3533_platform_data { - enum lm3533_boost_ovp boost_ovp; - enum lm3533_boost_freq boost_freq; - - struct lm3533_als_platform_data *als; - - struct lm3533_bl_platform_data *backlights; - int num_backlights; - - struct lm3533_led_platform_data *leds; - int num_leds; -}; - -extern int lm3533_ctrlbank_enable(struct lm3533_ctrlbank *cb); -extern int lm3533_ctrlbank_disable(struct lm3533_ctrlbank *cb); - -extern int lm3533_ctrlbank_set_brightness(struct lm3533_ctrlbank *cb, u8 val); -extern int lm3533_ctrlbank_get_brightness(struct lm3533_ctrlbank *cb, u8 *val); -extern int lm3533_ctrlbank_set_max_current(struct lm3533_ctrlbank *cb, - u16 imax); -extern int lm3533_ctrlbank_set_pwm(struct lm3533_ctrlbank *cb, u8 val); -extern int lm3533_ctrlbank_get_pwm(struct lm3533_ctrlbank *cb, u8 *val); - -extern int lm3533_read(struct lm3533 *lm3533, u8 reg, u8 *val); -extern int lm3533_write(struct lm3533 *lm3533, u8 reg, u8 val); -extern int lm3533_update(struct lm3533 *lm3533, u8 reg, u8 val, u8 mask); +int lm3533_ctrlbank_set_brightness(struct lm3533_ctrlbank *cb, u32 val); +int lm3533_ctrlbank_get_brightness(struct lm3533_ctrlbank *cb, u32 *val); +int lm3533_ctrlbank_set_max_current(struct lm3533_ctrlbank *cb, u32 imax); +int lm3533_ctrlbank_set_pwm(struct lm3533_ctrlbank *cb, u32 val); +int lm3533_ctrlbank_get_pwm(struct lm3533_ctrlbank *cb, u32 *val); #endif /* __LINUX_MFD_LM3533_H */ diff --git a/include/linux/mfd/lp8788.h b/include/linux/mfd/lp8788.h index fd17bec2a33e..e8c50bd38a8a 100644 --- a/include/linux/mfd/lp8788.h +++ b/include/linux/mfd/lp8788.h @@ -34,7 +34,7 @@ #define LP8788_ALM_IRQ "ALARM_IRQ" enum lp8788_int_id { - /* interrup register 1 : Addr 00h */ + /* interrupt register 1 : Addr 00h */ LP8788_INT_TSDL, LP8788_INT_TSDH, LP8788_INT_UVLO, diff --git a/include/linux/mfd/max8998.h b/include/linux/mfd/max8998.h index 5473f1983e31..ad2ad24412fb 100644 --- a/include/linux/mfd/max8998.h +++ b/include/linux/mfd/max8998.h @@ -45,7 +45,7 @@ enum { /** * max8998_regulator_data - regulator data * @id: regulator id - * @initdata: regulator init data (contraints, supplies, ...) + * @initdata: regulator init data (constraints, supplies, ...) * @reg_node: DT node of regulator (unused on non-DT platforms) */ struct max8998_regulator_data { diff --git a/include/linux/mfd/motorola-cpcap.h b/include/linux/mfd/motorola-cpcap.h index 981e5777deb7..bb23363eeccd 100644 --- a/include/linux/mfd/motorola-cpcap.h +++ b/include/linux/mfd/motorola-cpcap.h @@ -25,6 +25,13 @@ #define CPCAP_REVISION_2_0 0x10 #define CPCAP_REVISION_2_1 0x11 +enum cpcap_variant { + CPCAP_DEFAULT = 1, + CPCAP_MAPPHONE, + CPCAP_MOT, + CPCAP_MAX +}; + /* CPCAP registers */ #define CPCAP_REG_INT1 0x0000 /* Interrupt 1 */ #define CPCAP_REG_INT2 0x0004 /* Interrupt 2 */ diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h index dabcc0dea802..1d872363820a 100644 --- a/include/linux/mfd/palmas.h +++ b/include/linux/mfd/palmas.h @@ -251,7 +251,7 @@ enum tps65917_regulators { TPS65917_NUM_REGS, }; -/* External controll signal name */ +/* External control signal name */ enum { PALMAS_EXT_CONTROL_ENABLE1 = 0x1, PALMAS_EXT_CONTROL_ENABLE2 = 0x2, diff --git a/include/linux/mfd/rohm-bd71828.h b/include/linux/mfd/rohm-bd71828.h index 39fe275a8117..ea9b1a8f495f 100644 --- a/include/linux/mfd/rohm-bd71828.h +++ b/include/linux/mfd/rohm-bd71828.h @@ -186,7 +186,7 @@ enum { #define BD71828_REG_RTC_ALM2 0x63 #define BD71828_REG_RTC_START BD71828_REG_RTC_SEC -/* Charger/Battey */ +/* Charger/Battery */ #define BD71828_REG_CHG_STATE 0x65 #define BD71828_REG_CHG_FULL 0xd2 #define BD71828_REG_CHG_EN 0x6F diff --git a/include/linux/mfd/samsung/core.h b/include/linux/mfd/samsung/core.h index 6191f409de94..e489ca0d55ed 100644 --- a/include/linux/mfd/samsung/core.h +++ b/include/linux/mfd/samsung/core.h @@ -106,7 +106,7 @@ struct sec_platform_data { /** * sec_regulator_data - regulator data * @id: regulator id - * @initdata: regulator init data (contraints, supplies, ...) + * @initdata: regulator init data (constraints, supplies, ...) */ struct sec_regulator_data { int id; diff --git a/include/linux/mfd/si476x-core.h b/include/linux/mfd/si476x-core.h index d9e3a322134c..3e924ca4db00 100644 --- a/include/linux/mfd/si476x-core.h +++ b/include/linux/mfd/si476x-core.h @@ -94,10 +94,10 @@ enum si476x_power_state { * of the @rds_fifo_drainer. * @rds_drainer_status_lock: Lock used to guard access to the * @rds_drainer_is_working variable. - * @command: Wait queue for wainting on the command comapletion. + * @command: Wait queue for waiting on the command completion. * @cts: Clear To Send flag set upon receiving first status with CTS * set. - * @tuning: Wait queue used for wainting for tune/seek comand + * @tuning: Wait queue used for waiting for tune/seek command * completion. * @stc: Similar to @cts, but for the STC bit of the status value. * @power_up_parameters: Parameters used as argument for POWER_UP diff --git a/include/linux/mfd/twl.h b/include/linux/mfd/twl.h index b31e07fa4d51..238d9dcefc35 100644 --- a/include/linux/mfd/twl.h +++ b/include/linux/mfd/twl.h @@ -739,7 +739,7 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base); #define TWL4030_REG_VUSB3V1 19 /* TWL6030 SMPS/LDO's */ -/* EXTERNAL dc-to-dc buck convertor controllable via SR */ +/* EXTERNAL dc-to-dc buck converter controllable via SR */ #define TWL6030_REG_VDD1 30 #define TWL6030_REG_VDD2 31 #define TWL6030_REG_VDD3 32