aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/leds/maxim,max77693.yaml105
-rw-r--r--Documentation/devicetree/bindings/mfd/ab8500.txt282
-rw-r--r--Documentation/devicetree/bindings/mfd/max77693.txt194
-rw-r--r--Documentation/devicetree/bindings/mfd/maxim,max77693.yaml143
-rw-r--r--Documentation/devicetree/bindings/mfd/maxim,max77714.yaml68
-rw-r--r--Documentation/devicetree/bindings/mfd/mt6397.txt2
-rw-r--r--Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.txt1
-rw-r--r--Documentation/devicetree/bindings/mfd/qcom,tcsr.txt1
-rw-r--r--Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt72
-rw-r--r--Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.yaml117
-rw-r--r--Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml82
-rw-r--r--Documentation/devicetree/bindings/mfd/stericsson,ab8500.yaml500
-rw-r--r--Documentation/devicetree/bindings/mfd/stericsson,db8500-prcmu.yaml1
-rw-r--r--Documentation/devicetree/bindings/mfd/syscon.yaml5
-rw-r--r--Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml70
-rw-r--r--Documentation/devicetree/bindings/regulator/maxim,max77693.yaml60
-rw-r--r--Documentation/hwmon/index.rst1
-rw-r--r--Documentation/hwmon/sy7636a-hwmon.rst26
-rw-r--r--MAINTAINERS11
-rw-r--r--drivers/hwmon/Kconfig9
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/sy7636a-hwmon.c106
-rw-r--r--drivers/iio/temperature/iqs620at-temp.c4
-rw-r--r--drivers/mfd/Kconfig24
-rw-r--r--drivers/mfd/Makefile2
-rw-r--r--drivers/mfd/ab8500-core.c32
-rw-r--r--drivers/mfd/ab8500-debugfs.c2096
-rw-r--r--drivers/mfd/arizona-i2c.c2
-rw-r--r--drivers/mfd/arizona-spi.c87
-rw-r--r--drivers/mfd/asic3.c10
-rw-r--r--drivers/mfd/atmel-flexcom.c2
-rw-r--r--drivers/mfd/exynos-lpass.c1
-rw-r--r--drivers/mfd/intel-lpss-acpi.c41
-rw-r--r--drivers/mfd/intel-lpss-pci.c15
-rw-r--r--drivers/mfd/intel_soc_pmic_core.c4
-rw-r--r--drivers/mfd/intel_soc_pmic_crc.c35
-rw-r--r--drivers/mfd/iqs62x.c6
-rw-r--r--drivers/mfd/max77686.c2
-rw-r--r--drivers/mfd/max77714.c152
-rw-r--r--drivers/mfd/mc13xxx-core.c4
-rw-r--r--drivers/mfd/mt6358-irq.c1
-rw-r--r--drivers/mfd/rk808.c44
-rw-r--r--drivers/mfd/rohm-bd9576.c2
-rw-r--r--drivers/mfd/simple-mfd-i2c.c11
-rw-r--r--drivers/mfd/sta2x11-mfd.c2
-rw-r--r--drivers/mfd/stmfx.c17
-rw-r--r--drivers/regulator/Kconfig1
-rw-r--r--drivers/regulator/sy7636a-regulator.c7
-rw-r--r--drivers/rtc/Kconfig2
-rw-r--r--drivers/rtc/rtc-max77686.c75
-rw-r--r--drivers/watchdog/Kconfig2
-rw-r--r--drivers/watchdog/max77620_wdt.c85
-rw-r--r--include/linux/mfd/dbx500-prcmu.h22
-rw-r--r--include/linux/mfd/iqs62x.h7
-rw-r--r--include/linux/mfd/max77686-private.h4
-rw-r--r--include/linux/mfd/max77714.h60
-rw-r--r--include/linux/mfd/mt6358/registers.h7
-rw-r--r--include/linux/mfd/mt6397/core.h1
-rw-r--r--include/linux/mfd/rk808.h1
-rw-r--r--include/linux/mfd/sy7636a.h34
60 files changed, 1947 insertions, 2814 deletions
diff --git a/Documentation/devicetree/bindings/leds/maxim,max77693.yaml b/Documentation/devicetree/bindings/leds/maxim,max77693.yaml
new file mode 100644
index 000000000000..86a0005cf156
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/maxim,max77693.yaml
@@ -0,0 +1,105 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/maxim,max77693.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX77693 MicroUSB and Companion Power Management IC LEDs
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+description: |
+ This is a part of device tree bindings for Maxim MAX77693 MicroUSB Integrated
+ Circuit (MUIC).
+
+ There are two LED outputs available - FLED1 and FLED2. Each of them can
+ control a separate LED or they can be connected together to double the
+ maximum current for a single connected LED. One LED is represented by one
+ child node.
+
+ See also Documentation/devicetree/bindings/mfd/maxim,max77693.yaml for
+ additional information and example.
+
+properties:
+ compatible:
+ const: maxim,max77693-led
+
+ maxim,boost-mode:
+ description:
+ In boost mode the device can produce up to 1.2A of total current on both
+ outputs. The maximum current on each output is reduced to 625mA then. If
+ not enabled explicitly, boost setting defaults to LEDS_BOOST_FIXED in
+ case both current sources are used.
+ See LEDS_BOOST_* in include/dt-bindings/leds/common.h.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1, 2]
+
+ maxim,boost-mvout:
+ description: |
+ Output voltage of the boost module in millivolts.
+ Valid values: 3300 - 5500, step by 25 (rounded down)
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 3300
+ maximum: 5500
+ default: 3300
+
+ maxim,mvsys-min:
+ description: |
+ Low input voltage level in millivolts. Flash is not fired if chip
+ estimates that system voltage could drop below this level due to flash
+ power consumption.
+ Valid values: 2400 - 3400, step by 33 (rounded down)
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 2400
+ maximum: 3400
+ default: 2400
+
+patternProperties:
+ "^([a-z]+-)?led[01]?$":
+ type: object
+ $ref: common.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ led-sources:
+ allOf:
+ - minItems: 1
+ maxItems: 2
+ items:
+ minimum: 0
+ maximum: 1
+
+ led-max-microamp:
+ description: |
+ Valid values for a LED connected to one FLED output:
+ 15625 - 250000, step by 15625 (rounded down)
+ Valid values for a LED connected to both FLED outputs:
+ 15625 - 500000, step by 15625 (rounded down)
+
+ flash-max-microamp:
+ description: |
+ Valid values for a single LED connected to one FLED output
+ (boost mode must be turned off):
+ 15625 - 1000000, step by 15625 (rounded down)
+ Valid values for a single LED connected to both FLED outputs:
+ 15625 - 1250000, step by 15625 (rounded down)
+ Valid values for two LEDs case:
+ 15625 - 625000, step by 15625 (rounded down)
+
+ flash-max-timeout-us:
+ description: |
+ Valid values: 62500 - 1000000, step by 62500 (rounded down)
+ minimum: 62500
+ maximum: 1000000
+
+ required:
+ - flash-max-microamp
+ - flash-max-timeout-us
+ - led-max-microamp
+ - led-sources
+
+required:
+ - compatible
+
+additionalProperties: false
diff --git a/Documentation/devicetree/bindings/mfd/ab8500.txt b/Documentation/devicetree/bindings/mfd/ab8500.txt
deleted file mode 100644
index 937b3e5505e0..000000000000
--- a/Documentation/devicetree/bindings/mfd/ab8500.txt
+++ /dev/null
@@ -1,282 +0,0 @@
-* AB8500 Multi-Functional Device (MFD)
-
-Required parent device properties:
-- compatible : contains "stericsson,ab8500" or "stericsson,ab8505";
-- interrupts : contains the IRQ line for the AB8500
-- interrupt-controller : describes the AB8500 as an Interrupt Controller (has its own domain)
-- #interrupt-cells : should be 2, for 2-cell format
- - The first cell is the AB8500 local IRQ number
- - The second cell is used to specify optional parameters
- - bits[3:0] trigger type and level flags:
- 1 = low-to-high edge triggered
- 2 = high-to-low edge triggered
- 4 = active high level-sensitive
- 8 = active low level-sensitive
-
-The AB8500 consists of a large and varied group of sub-devices:
-
-Device IRQ Names Supply Names Description
------- --------- ------------ -----------
-ab8500-bm : : : Battery Manager
-ab8500-btemp : : : Battery Temperature
-ab8500-charger : : : Battery Charger
-ab8500-codec : : : Audio Codec
-ab8500-fg : : vddadc : Fuel Gauge
- : NCONV_ACCU : : Accumulate N Sample Conversion
- : BATT_OVV : : Battery Over Voltage
- : LOW_BAT_F : : LOW threshold battery voltage
- : CC_INT_CALIB : : Coulomb Counter Internal Calibration
- : CCEOC : : Coulomb Counter End of Conversion
-ab8500-btemp : : vtvout : Battery Temperature
- : BAT_CTRL_INDB : : Battery Removal Indicator
- : BTEMP_LOW : : Btemp < BtempLow, if battery temperature is lower than -10°C
- : BTEMP_LOW_MEDIUM : : BtempLow < Btemp < BtempMedium,if battery temperature is between -10 and 0°C
- : BTEMP_MEDIUM_HIGH : : BtempMedium < Btemp < BtempHigh,if battery temperature is between 0°C and MaxTemp
- : BTEMP_HIGH : : Btemp > BtempHigh, if battery temperature is higher than MaxTemp
-ab8500-charger : : vddadc : Charger interface
- : MAIN_CH_UNPLUG_DET : : main charger unplug detection management (not in 8505)
- : MAIN_CHARGE_PLUG_DET : : main charger plug detection management (not in 8505)
- : MAIN_EXT_CH_NOT_OK : : main charger not OK
- : MAIN_CH_TH_PROT_R : : Die temp is above main charger
- : MAIN_CH_TH_PROT_F : : Die temp is below main charger
- : VBUS_DET_F : : VBUS falling detected
- : VBUS_DET_R : : VBUS rising detected
- : USB_LINK_STATUS : : USB link status has changed
- : USB_CH_TH_PROT_R : : Die temp is above usb charger
- : USB_CH_TH_PROT_F : : Die temp is below usb charger
- : USB_CHARGER_NOT_OKR : : allowed USB charger not ok detection
- : VBUS_OVV : : Overvoltage on Vbus ball detected (USB charge is stopped)
- : CH_WD_EXP : : Charger watchdog detected
-ab8500-gpadc : HW_CONV_END : vddadc : Analogue to Digital Converter
- SW_CONV_END : :
-ab8500-gpio : : : GPIO Controller (AB8500)
-ab8505-gpio : : : GPIO Controller (AB8505)
-ab8500-ponkey : ONKEY_DBF : : Power-on Key
- ONKEY_DBR : :
-ab8500-pwm : : : Pulse Width Modulator
-ab8500-regulator : : : Regulators (AB8500)
-ab8505-regulator : : : Regulators (AB8505)
-ab8500-rtc : 60S : : Real Time Clock
- : ALARM : :
-ab8500-sysctrl : : : System Control
-ab8500-usb : ID_WAKEUP_R : vddulpivio18 : Universal Serial Bus
- : ID_WAKEUP_F : v-ape :
- : VBUS_DET_F : musb_1v8 :
- : VBUS_DET_R : :
- : USB_LINK_STATUS : :
- : USB_ADP_PROBE_PLUG : :
- : USB_ADP_PROBE_UNPLUG : :
-
-Required child device properties:
-- compatible : "stericsson,ab8500-[bm|btemp|charger|fg|gpadc|gpio|ponkey|
- pwm|regulator|rtc|sysctrl|usb]";
-
- A few child devices require ADC channels from the GPADC node. Those follow the
- standard bindings from
- https://github.com/devicetree-org/dt-schema/blob/master/schemas/iio/iio-consumer.yaml
- and Documentation/devicetree/bindings/iio/adc/adc.yaml
-
- abx500-temp : io-channels "aux1" and "aux2" for measuring external
- temperatures.
- ab8500-fg : io-channel "main_bat_v" for measuring main battery voltage,
- ab8500-btemp : io-channels "btemp_ball" and "bat_ctrl" for measuring the
- battery voltage.
- ab8500-charger : io-channels "main_charger_v", "main_charger_c", "vbus_v",
- "usb_charger_c" for measuring voltage and current of the
- different charging supplies.
-
-Optional child device properties:
-- interrupts : contains the device IRQ(s) using the 2-cell format (see above)
-- interrupt-names : contains names of IRQ resource in the order in which they were
- supplied in the interrupts property
-- <supply_name>-supply : contains a phandle to the regulator supply node in Device Tree
-
-Non-standard child device properties:
- - Audio CODEC:
- - stericsson,amic[1|2]-type-single-ended : Single-ended Analoge Mic (default: differential)
- - stericsson,amic1a-bias-vamic2 : Analoge Mic wishes to use a non-standard Vamic
- - stericsson,amic1b-bias-vamic2 : Analoge Mic wishes to use a non-standard Vamic
- - stericsson,amic2-bias-vamic1 : Analoge Mic wishes to use a non-standard Vamic
- - stericsson,earpeice-cmv : Earpeice voltage (only: 950 | 1100 | 1270 | 1580)
-
-ab8500 {
- compatible = "stericsson,ab8500";
- interrupts = <0 40 0x4>;
- interrupt-controller;
- #interrupt-cells = <2>;
-
- ab8500-rtc {
- compatible = "stericsson,ab8500-rtc";
- interrupts = <17 0x4
- 18 0x4>;
- interrupt-names = "60S", "ALARM";
- };
-
- ab8500-gpadc {
- compatible = "stericsson,ab8500-gpadc";
- interrupts = <32 0x4
- 39 0x4>;
- interrupt-names = "HW_CONV_END", "SW_CONV_END";
- vddadc-supply = <&ab8500_ldo_tvout_reg>;
- #address-cells = <1>;
- #size-cells = <0>;
- #io-channel-cells = <1>;
-
- /* GPADC channels */
- bat_ctrl: channel@1 {
- reg = <0x01>;
- };
- btemp_ball: channel@2 {
- reg = <0x02>;
- };
- main_charger_v: channel@3 {
- reg = <0x03>;
- };
- acc_detect1: channel@4 {
- reg = <0x04>;
- };
- acc_detect2: channel@5 {
- reg = <0x05>;
- };
- adc_aux1: channel@6 {
- reg = <0x06>;
- };
- adc_aux2: channel@7 {
- reg = <0x07>;
- };
- main_batt_v: channel@8 {
- reg = <0x08>;
- };
- vbus_v: channel@9 {
- reg = <0x09>;
- };
- main_charger_c: channel@a {
- reg = <0x0a>;
- };
- usb_charger_c: channel@b {
- reg = <0x0b>;
- };
- bk_bat_v: channel@c {
- reg = <0x0c>;
- };
- die_temp: channel@d {
- reg = <0x0d>;
- };
- usb_id: channel@e {
- reg = <0x0e>;
- };
- xtal_temp: channel@12 {
- reg = <0x12>;
- };
- vbat_true_meas: channel@13 {
- reg = <0x13>;
- };
- bat_ctrl_and_ibat: channel@1c {
- reg = <0x1c>;
- };
- vbat_meas_and_ibat: channel@1d {
- reg = <0x1d>;
- };
- vbat_true_meas_and_ibat: channel@1e {
- reg = <0x1e>;
- };
- bat_temp_and_ibat: channel@1f {
- reg = <0x1f>;
- };
- };
-
- ab8500_temp {
- compatible = "stericsson,abx500-temp";
- io-channels = <&gpadc 0x06>,
- <&gpadc 0x07>;
- io-channel-name = "aux1", "aux2";
- };
-
- ab8500_battery: ab8500_battery {
- stericsson,battery-type = "LIPO";
- thermistor-on-batctrl;
- };
-
- ab8500_fg {
- compatible = "stericsson,ab8500-fg";
- battery = <&ab8500_battery>;
- io-channels = <&gpadc 0x08>;
- io-channel-name = "main_bat_v";
- };
-
- ab8500_btemp {
- compatible = "stericsson,ab8500-btemp";
- battery = <&ab8500_battery>;
- io-channels = <&gpadc 0x02>,
- <&gpadc 0x01>;
- io-channel-name = "btemp_ball",
- "bat_ctrl";
- };
-
- ab8500_charger {
- compatible = "stericsson,ab8500-charger";
- battery = <&ab8500_battery>;
- vddadc-supply = <&ab8500_ldo_tvout_reg>;
- io-channels = <&gpadc 0x03>,
- <&gpadc 0x0a>,
- <&gpadc 0x09>,
- <&gpadc 0x0b>;
- io-channel-name = "main_charger_v",
- "main_charger_c",
- "vbus_v",
- "usb_charger_c";
- };
-
- ab8500-usb {
- compatible = "stericsson,ab8500-usb";
- interrupts = < 90 0x4
- 96 0x4
- 14 0x4
- 15 0x4
- 79 0x4
- 74 0x4
- 75 0x4>;
- interrupt-names = "ID_WAKEUP_R",
- "ID_WAKEUP_F",
- "VBUS_DET_F",
- "VBUS_DET_R",
- "USB_LINK_STATUS",
- "USB_ADP_PROBE_PLUG",
- "USB_ADP_PROBE_UNPLUG";
- vddulpivio18-supply = <&ab8500_ldo_intcore_reg>;
- v-ape-supply = <&db8500_vape_reg>;
- musb_1v8-supply = <&db8500_vsmps2_reg>;
- };
-
- ab8500-ponkey {
- compatible = "stericsson,ab8500-ponkey";
- interrupts = <6 0x4
- 7 0x4>;
- interrupt-names = "ONKEY_DBF", "ONKEY_DBR";
- };
-
- ab8500-sysctrl {
- compatible = "stericsson,ab8500-sysctrl";
- };
-
- ab8500-pwm {
- compatible = "stericsson,ab8500-pwm";
- };
-
- codec: ab8500-codec {
- compatible = "stericsson,ab8500-codec";
-
- stericsson,earpeice-cmv = <950>; /* Units in mV. */
- };
-
- ab8500-regulators {
- compatible = "stericsson,ab8500-regulator";
-
- ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
- /*
- * See: Documentation/devicetree/bindings/regulator/regulator.txt
- * for more information on regulators
- */
- };
- };
-};
diff --git a/Documentation/devicetree/bindings/mfd/max77693.txt b/Documentation/devicetree/bindings/mfd/max77693.txt
deleted file mode 100644
index 1032df14498b..000000000000
--- a/Documentation/devicetree/bindings/mfd/max77693.txt
+++ /dev/null
@@ -1,194 +0,0 @@
-Maxim MAX77693 multi-function device
-
-MAX77693 is a Multifunction device with the following submodules:
-- PMIC,
-- CHARGER,
-- LED,
-- MUIC,
-- HAPTIC
-
-It is interfaced to host controller using i2c.
-This document describes the bindings for the mfd device.
-
-Required properties:
-- compatible : Must be "maxim,max77693".
-- reg : Specifies the i2c slave address of PMIC block.
-- interrupts : This i2c device has an IRQ line connected to the main SoC.
-
-Optional properties:
-- regulators : The regulators of max77693 have to be instantiated under subnode
- named "regulators" using the following format.
-
- regulators {
- regulator-compatible = ESAFEOUT1/ESAFEOUT2/CHARGER
- standard regulator constraints[*].
- };
-
- [*] refer Documentation/devicetree/bindings/regulator/regulator.txt
-
-- haptic : The MAX77693 haptic device utilises a PWM controlled motor to provide
- users with tactile feedback. PWM period and duty-cycle are varied in
- order to provide the appropriate level of feedback.
-
- Required properties:
- - compatible : Must be "maxim,max77693-haptic"
- - haptic-supply : power supply for the haptic motor
- [*] refer Documentation/devicetree/bindings/regulator/regulator.txt
- - pwms : phandle to the physical PWM(Pulse Width Modulation) device.
- PWM properties should be named "pwms". And number of cell is different
- for each pwm device.
- To get more information, please refer to documentation.
- [*] refer Documentation/devicetree/bindings/pwm/pwm.txt
-
-- charger : Node configuring the charger driver.
- If present, required properties:
- - compatible : Must be "maxim,max77693-charger".
-
- Optional properties (if not set, defaults will be used):
- - maxim,constant-microvolt : Battery constant voltage in uV. The charger
- will operate in fast charge constant current mode till battery voltage
- reaches this level. Then the charger will switch to fast charge constant
- voltage mode. Also vsys (system voltage) will be set to this value when
- DC power is supplied but charger is not enabled.
- Valid values: 3650000 - 4400000, step by 25000 (rounded down)
- Default: 4200000
-
- - maxim,min-system-microvolt : Minimal system voltage in uV.
- Valid values: 3000000 - 3700000, step by 100000 (rounded down)
- Default: 3600000
-
- - maxim,thermal-regulation-celsius : Temperature in Celsius for entering
- high temperature charging mode. If die temperature exceeds this value
- the charging current will be reduced by 105 mA/Celsius.
- Valid values: 70, 85, 100, 115
- Default: 100
-
- - maxim,battery-overcurrent-microamp : Overcurrent protection threshold
- in uA (current from battery to system).
- Valid values: 2000000 - 3500000, step by 250000 (rounded down)
- Default: 3500000
-
- - maxim,charge-input-threshold-microvolt : Threshold voltage in uV for
- triggering input voltage regulation loop. If input voltage decreases
- below this value, the input current will be reduced to reach the
- threshold voltage.
- Valid values: 4300000, 4700000, 4800000, 4900000
- Default: 4300000
-
-- led : the LED submodule device node
-
-There are two LED outputs available - FLED1 and FLED2. Each of them can
-control a separate LED or they can be connected together to double
-the maximum current for a single connected LED. One LED is represented
-by one child node.
-
-Required properties:
-- compatible : Must be "maxim,max77693-led".
-
-Optional properties:
-- maxim,boost-mode :
- In boost mode the device can produce up to 1.2A of total current
- on both outputs. The maximum current on each output is reduced
- to 625mA then. If not enabled explicitly, boost setting defaults to
- LEDS_BOOST_FIXED in case both current sources are used.
- Possible values:
- LEDS_BOOST_OFF (0) - no boost,
- LEDS_BOOST_ADAPTIVE (1) - adaptive mode,
- LEDS_BOOST_FIXED (2) - fixed mode.
-- maxim,boost-mvout : Output voltage of the boost module in millivolts.
- Valid values: 3300 - 5500, step by 25 (rounded down)
- Default: 3300
-- maxim,mvsys-min : Low input voltage level in millivolts. Flash is not fired
- if chip estimates that system voltage could drop below this level due
- to flash power consumption.
- Valid values: 2400 - 3400, step by 33 (rounded down)
- Default: 2400
-
-Required properties for the LED child node:
-- led-sources : see Documentation/devicetree/bindings/leds/common.txt;
- device current output identifiers: 0 - FLED1, 1 - FLED2
-- led-max-microamp : see Documentation/devicetree/bindings/leds/common.txt
- Valid values for a LED connected to one FLED output:
- 15625 - 250000, step by 15625 (rounded down)
- Valid values for a LED connected to both FLED outputs:
- 15625 - 500000, step by 15625 (rounded down)
-- flash-max-microamp : see Documentation/devicetree/bindings/leds/common.txt
- Valid values for a single LED connected to one FLED output
- (boost mode must be turned off):
- 15625 - 1000000, step by 15625 (rounded down)
- Valid values for a single LED connected to both FLED outputs:
- 15625 - 1250000, step by 15625 (rounded down)
- Valid values for two LEDs case:
- 15625 - 625000, step by 15625 (rounded down)
-- flash-max-timeout-us : see Documentation/devicetree/bindings/leds/common.txt
- Valid values: 62500 - 1000000, step by 62500 (rounded down)
-
-Optional properties for the LED child node:
-- label : see Documentation/devicetree/bindings/leds/common.txt
-
-Optional nodes:
-- max77693-muic :
- Node used only by extcon consumers.
- Required properties:
- - compatible : "maxim,max77693-muic"
-
-Example:
-#include <dt-bindings/leds/common.h>
-
- max77693@66 {
- compatible = "maxim,max77693";
- reg = <0x66>;
- interrupt-parent = <&gpx1>;
- interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
-
- regulators {
- esafeout@1 {
- regulator-compatible = "ESAFEOUT1";
- regulator-name = "ESAFEOUT1";
- regulator-boot-on;
- };
- esafeout@2 {
- regulator-compatible = "ESAFEOUT2";
- regulator-name = "ESAFEOUT2";
- };
- charger@0 {
- regulator-compatible = "CHARGER";
- regulator-name = "CHARGER";
- regulator-min-microamp = <60000>;
- regulator-max-microamp = <2580000>;
- regulator-boot-on;
- };
- };
-
- haptic {
- compatible = "maxim,max77693-haptic";
- haptic-supply = <&haptic_supply>;
- pwms = <&pwm 0 40000 0>;
- pwm-names = "haptic";
- };
-
- charger {
- compatible = "maxim,max77693-charger";
-
- maxim,constant-microvolt = <4200000>;
- maxim,min-system-microvolt = <3600000>;
- maxim,thermal-regulation-celsius = <75>;
- maxim,battery-overcurrent-microamp = <3000000>;
- maxim,charge-input-threshold-microvolt = <4300000>;
- };
-
- led {
- compatible = "maxim,max77693-led";
- maxim,boost-mode = <LEDS_BOOST_FIXED>;
- maxim,boost-mvout = <5000>;
- maxim,mvsys-min = <2400>;
-
- camera_flash: flash-led {
- label = "max77693-flash";
- led-sources = <0>, <1>;
- led-max-microamp = <500000>;
- flash-max-microamp = <1250000>;
- flash-max-timeout-us = <1000000>;
- };
- };
- };
diff --git a/Documentation/devicetree/bindings/mfd/maxim,max77693.yaml b/Documentation/devicetree/bindings/mfd/maxim,max77693.yaml
new file mode 100644
index 000000000000..906101197e11
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/maxim,max77693.yaml
@@ -0,0 +1,143 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/maxim,max77693.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX77693 MicroUSB and Companion Power Management IC
+
+maintainers:
+ - Chanwoo Choi <cw00.choi@samsung.com>
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+description: |
+ This is a part of device tree bindings for Maxim MAX77693 MicroUSB
+ Integrated Circuit (MUIC).
+
+ The Maxim MAX77693 is a MicroUSB and Companion Power Management IC which
+ includes voltage current regulators, charger, LED/flash, haptic motor driver
+ and MicroUSB management IC.
+
+properties:
+ compatible:
+ const: maxim,max77693
+
+ interrupts:
+ maxItems: 1
+
+ reg:
+ maxItems: 1
+
+ charger:
+ $ref: /schemas/power/supply/maxim,max77693.yaml
+
+ led:
+ $ref: /schemas/leds/maxim,max77693.yaml
+
+ max77693-muic:
+ type: object
+ additionalProperties: false
+
+ properties:
+ compatible:
+ const: maxim,max77693-muic
+
+ required:
+ - compatible
+
+ motor-driver:
+ type: object
+ additionalProperties: false
+
+ properties:
+ compatible:
+ const: maxim,max77693-haptic
+
+ haptic-supply:
+ description: Power supply to the haptic motor
+
+ pwms:
+ maxItems: 1
+
+ required:
+ - compatible
+ - haptic-supply
+ - pwms
+
+ regulators:
+ $ref: ../regulator/maxim,max77693.yaml
+ description:
+ List of child nodes that specify the regulators.
+
+required:
+ - compatible
+ - interrupts
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/leds/common.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmic@66 {
+ compatible = "maxim,max77693";
+ reg = <0x66>;
+ interrupt-parent = <&gpx1>;
+ interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
+
+ regulators {
+ ESAFEOUT1 {
+ regulator-name = "ESAFEOUT1";
+ };
+
+ ESAFEOUT2 {
+ regulator-name = "ESAFEOUT2";
+ };
+
+ CHARGER {
+ regulator-name = "CHARGER";
+ regulator-min-microamp = <60000>;
+ regulator-max-microamp = <2580000>;
+ };
+ };
+
+ motor-driver {
+ compatible = "maxim,max77693-haptic";
+ haptic-supply = <&ldo26_reg>;
+ pwms = <&pwm 0 38022 0>;
+ };
+
+ charger {
+ compatible = "maxim,max77693-charger";
+
+ maxim,constant-microvolt = <4350000>;
+ maxim,min-system-microvolt = <3600000>;
+ maxim,thermal-regulation-celsius = <100>;
+ maxim,battery-overcurrent-microamp = <3500000>;
+ maxim,charge-input-threshold-microvolt = <4300000>;
+ };
+
+ led {
+ compatible = "maxim,max77693-led";
+ maxim,boost-mode = <LEDS_BOOST_FIXED>;
+ maxim,boost-mvout = <5000>;
+ maxim,mvsys-min = <2400>;
+
+ flash-led {
+ label = "max77693-flash";
+ function = LED_FUNCTION_FLASH;
+ color = <LED_COLOR_ID_WHITE>;
+ led-sources = <0>, <1>;
+ led-max-microamp = <500000>;
+ flash-max-microamp = <1250000>;
+ flash-max-timeout-us = <1000000>;
+ };
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/mfd/maxim,max77714.yaml b/Documentation/devicetree/bindings/mfd/maxim,max77714.yaml
new file mode 100644
index 000000000000..74a6867d3c82
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/maxim,max77714.yaml
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/maxim,max77714.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MAX77714 PMIC with GPIO, RTC and watchdog from Maxim Integrated.
+
+maintainers:
+ - Luca Ceresoli <luca@lucaceresoli.net>
+
+description: |
+ MAX77714 is a Power Management IC with 4 buck regulators, 9
+ low-dropout regulators, 8 GPIOs, RTC and watchdog.
+
+properties:
+ compatible:
+ const: maxim,max77714
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ interrupt-controller: true
+
+ "#interrupt-cells":
+ const: 2
+ description:
+ The first cell is the IRQ number, the second cell is the trigger type.
+
+ regulators:
+ type: object
+ additionalProperties: false
+
+ patternProperties:
+ '^(buck[0-3]|ldo[0-8])$':
+ type: object
+ unevaluatedProperties: false
+ $ref: /schemas/regulator/regulator.yaml#
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - interrupt-controller
+ - "#interrupt-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmic@1c {
+ compatible = "maxim,max77714";
+ reg = <0x1c>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/mfd/mt6397.txt b/Documentation/devicetree/bindings/mfd/mt6397.txt
index 99a84b69a29f..293db2a71ef2 100644
--- a/Documentation/devicetree/bindings/mfd/mt6397.txt
+++ b/Documentation/devicetree/bindings/mfd/mt6397.txt
@@ -20,7 +20,7 @@ This document describes the binding for MFD device and its sub module.
Required properties:
compatible:
"mediatek,mt6323" for PMIC MT6323
- "mediatek,mt6358" for PMIC MT6358
+ "mediatek,mt6358" for PMIC MT6358 and MT6366
"mediatek,mt6359" for PMIC MT6359
"mediatek,mt6397" for PMIC MT6397
diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.txt b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.txt
index 7a27c500ff63..a461ec2f758f 100644
--- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.txt
+++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.txt
@@ -35,6 +35,7 @@ Required properties:
"qcom,pm8916",
"qcom,pm8941",
"qcom,pm8950",
+ "qcom,pm8953",
"qcom,pm8994",
"qcom,pm8998",
"qcom,pma8084",
diff --git a/Documentation/devicetree/bindings/mfd/qcom,tcsr.txt b/Documentation/devicetree/bindings/mfd/qcom,tcsr.txt
index c5f4f0ddfcc3..add61bcc3c74 100644
--- a/Documentation/devicetree/bindings/mfd/qcom,tcsr.txt
+++ b/Documentation/devicetree/bindings/mfd/qcom,tcsr.txt
@@ -10,6 +10,7 @@ Required properties:
"qcom,tcsr-ipq8064", "syscon" for IPQ8064
"qcom,tcsr-apq8064", "syscon" for APQ8064
"qcom,tcsr-msm8660", "syscon" for MSM8660
+ "qcom,tcsr-msm8953", "syscon" for MSM8953
"qcom,tcsr-msm8960", "syscon" for MSM8960
"qcom,tcsr-msm8974", "syscon" for MSM8974
"qcom,tcsr-apq8084", "syscon" for APQ8084
diff --git a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt
deleted file mode 100644
index 30ea27c3936d..000000000000
--- a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt
+++ /dev/null
@@ -1,72 +0,0 @@
-Samsung Exynos SoC Low Power Audio Subsystem (LPASS)
-
-Required properties:
-
- - compatible : "samsung,exynos5433-lpass"
- - reg : should contain the LPASS top SFR region location
- and size
- - clock-names : should contain following required clocks: "sfr0_ctrl"
- - clocks : should contain clock specifiers of all clocks, which
- input names have been specified in clock-names
- property, in same order.
- - #address-cells : should be 1
- - #size-cells : should be 1
- - ranges : must be present
-
-Each IP block of the Low Power Audio Subsystem should be specified as
-an optional sub-node. For "samsung,exynos5433-lpass" compatible this includes:
-UART, SLIMBUS, PCM, I2S, DMAC, Timers 0...4, VIC, WDT 0...1 devices.
-
-Bindings of the sub-nodes are described in:
- ../serial/samsung_uart.yaml
- ../sound/samsung-i2s.txt
- ../dma/arm-pl330.txt
-
-
-Example:
-
-audio-subsystem {
- compatible = "samsung,exynos5433-lpass";
- reg = <0x11400000 0x100>, <0x11500000 0x08>;
- clocks = <&cmu_aud CLK_PCLK_SFR0_CTRL>;
- clock-names = "sfr0_ctrl";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
-
- adma: adma@11420000 {
- compatible = "arm,pl330", "arm,primecell";
- reg = <0x11420000 0x1000>;
- interrupts = <0 73 0>;
- clocks = <&cmu_aud CLK_ACLK_DMAC>;
- clock-names = "apb_pclk";
- #dma-cells = <1>;
- #dma-channels = <8>;
- #dma-requests = <32>;
- };
-
- i2s0: i2s0@11440000 {
- compatible = "samsung,exynos7-i2s";
- reg = <0x11440000 0x100>;
- dmas = <&adma 0 &adma 2>;
- dma-names = "tx", "rx";
- interrupts = <0 70 0>;
- clocks = <&cmu_aud CLK_PCLK_AUD_I2S>,
- <&cmu_aud CLK_SCLK_AUD_I2S>,
- <&cmu_aud CLK_SCLK_I2S_BCLK>;
- clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
- pinctrl-names = "default";
- pinctrl-0 = <&i2s0_bus>;
- };
-
- serial_3: serial@11460000 {
- compatible = "samsung,exynos5433-uart";
- reg = <0x11460000 0x100>;
- interrupts = <0 67 0>;
- clocks = <&cmu_aud CLK_PCLK_AUD_UART>,
- <&cmu_aud CLK_SCLK_AUD_UART>;
- clock-names = "uart", "clk_uart_baud0";
- pinctrl-names = "default";
- pinctrl-0 = <&uart_aud_bus>;
- };
- };
diff --git a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.yaml b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.yaml
new file mode 100644
index 000000000000..bae55c98961c
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.yaml
@@ -0,0 +1,117 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/samsung,exynos5433-lpass.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos SoC Low Power Audio Subsystem (LPASS)
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+ - Sylwester Nawrocki <s.nawrocki@samsung.com>
+
+properties:
+ compatible:
+ const: samsung,exynos5433-lpass
+
+ '#address-cells':
+ const: 1
+
+ clocks:
+ maxItems: 1
+
+ clock-names:
+ items:
+ - const: sfr0_ctrl
+
+ power-domains:
+ maxItems: 1
+
+ ranges: true
+
+ reg:
+ minItems: 2
+ maxItems: 2
+
+ '#size-cells':
+ const: 1
+
+patternProperties:
+ "^dma-controller@[0-9a-f]+$":
+ $ref: /schemas/dma/arm,pl330.yaml
+
+ "^i2s@[0-9a-f]+$":
+ $ref: /schemas/sound/samsung-i2s.yaml
+
+ "^serial@[0-9a-f]+$":
+ $ref: /schemas/serial/samsung_uart.yaml
+
+required:
+ - compatible
+ - '#address-cells'
+ - clocks
+ - clock-names
+ - ranges
+ - reg
+ - '#size-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/exynos5433.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ audio-subsystem@11400000 {
+ compatible = "samsung,exynos5433-lpass";
+ reg = <0x11400000 0x100>, <0x11500000 0x08>;
+ clocks = <&cmu_aud CLK_PCLK_SFR0_CTRL>;
+ clock-names = "sfr0_ctrl";
+ power-domains = <&pd_aud>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ dma-controller@11420000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x11420000 0x1000>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cmu_aud CLK_ACLK_DMAC>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <32>;
+ power-domains = <&pd_aud>;
+ };
+
+ i2s@11440000 {
+ compatible = "samsung,exynos7-i2s";
+ reg = <0x11440000 0x100>;
+ dmas = <&adma 0>, <&adma 2>;
+ dma-names = "tx", "rx";
+ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&cmu_aud CLK_PCLK_AUD_I2S>,
+ <&cmu_aud CLK_SCLK_AUD_I2S>,
+ <&cmu_aud CLK_SCLK_I2S_BCLK>;
+ clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
+ #clock-cells = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_bus>;
+ power-domains = <&pd_aud>;
+ #sound-dai-cells = <1>;
+ };
+
+ serial@11460000 {
+ compatible = "samsung,exynos5433-uart";
+ reg = <0x11460000 0x100>;
+ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cmu_aud CLK_PCLK_AUD_UART>,
+ <&cmu_aud CLK_SCLK_AUD_UART>;
+ clock-names = "uart", "clk_uart_baud0";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart_aud_bus>;
+ power-domains = <&pd_aud>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml b/Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml
new file mode 100644
index 000000000000..6de74c701635
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/silergy,sy7636a.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: silergy sy7636a PMIC
+
+maintainers:
+ - Alistair Francis <alistair@alistair23.me>
+
+properties:
+ compatible:
+ const: silergy,sy7636a
+
+ reg:
+ description:
+ I2C device address.
+ maxItems: 1
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 0
+
+ '#thermal-sensor-cells':
+ const: 0
+
+ epd-pwr-good-gpios:
+ description:
+ Specifying the power good GPIOs.
+ maxItems: 1
+
+ regulators:
+ type: object
+
+ properties:
+ compatible:
+ const: silergy,sy7636a-regulator
+
+ vcom:
+ type: object
+ $ref: /schemas/regulator/regulator.yaml#
+ description:
+ The regulator for the compenstation voltage. Enabling/disabling this
+ enables/disables the entire device.
+ properties:
+ regulator-name:
+ const: vcom
+
+ additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - '#thermal-sensor-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pmic@62 {
+ compatible = "silergy,sy7636a";
+ reg = <0x62>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_epdpmic>;
+ #thermal-sensor-cells = <0>;
+
+ regulators {
+ reg_epdpmic: vcom {
+ regulator-name = "vcom";
+ regulator-boot-on;
+ };
+ };
+ };
+ };
+...
diff --git a/Documentation/devicetree/bindings/mfd/stericsson,ab8500.yaml b/Documentation/devicetree/bindings/mfd/stericsson,ab8500.yaml
new file mode 100644
index 000000000000..623a4b5cd27a
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/stericsson,ab8500.yaml
@@ -0,0 +1,500 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/stericsson,ab8500.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ST-Ericsson Analog Baseband AB8500 and AB8505
+
+maintainers:
+ - Linus Walleij <linus.walleij@linaro.org>
+
+description:
+ the AB8500 "Analog Baseband" is the mixed-signals integrated circuit
+ handling power management (regulators), analog-to-digital conversion
+ (ADC), battery charging, fuel gauging of the battery, battery-backed
+ RTC, PWM, USB PHY and some GPIO lines in the ST-Ericsson U8500 platforms
+ in connection with the DB8500 digital baseband. The DB8500 PRCMU
+ communicates directly and autonomously with the AB8500 and thus it
+ appears as a subnode of the DB8500 PRCMU. An altered version called
+ AB8505 also exist, the difference in AB8505 is that some of the USB and
+ USB charging handling has changed, and it has an embedded USB-to-serial
+ converter. Most subblocks takes their interrupts directly from the
+ AB8500 embedded interrupt controller.
+
+properties:
+ $nodename:
+ pattern: '^ab850[05]$'
+
+ compatible:
+ enum:
+ - stericsson,ab8500
+ - stericsson,ab8505
+
+ interrupts:
+ maxItems: 1
+
+ interrupt-controller: true
+
+ '#interrupt-cells':
+ const: 2
+
+ # Some subnodes use a reg, some don't. Those that do use a single cell.
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 0
+
+ clock-controller:
+ description: Node describing the AB8500 clock controller. This
+ provides the reference clock for the entire U8500 system and
+ the DB8500 counterpart.
+ type: object
+
+ properties:
+ compatible:
+ const: stericsson,ab8500-clk
+
+ '#clock-cells':
+ const: 1
+
+ gpio:
+ description: Node describing the AB8500 GPIO controller. A few
+ GPIO pins available for misc usage.
+ type: object
+
+ properties:
+ compatible:
+ enum:
+ - stericsson,ab8500-gpio
+ - stericsson,ab8505-gpio
+
+ gpio-controller: true
+
+ '#gpio-cells':
+ const: 2
+
+ rtc:
+ description: Node describing the AB8500 battery-backed RTC.
+ type: object
+
+ properties:
+ compatible:
+ const: stericsson,ab8500-rtc
+
+ interrupts:
+ items:
+ - description: 60 second interval alarm interrupt
+ - description: RTC alarm
+
+ interrupt-names:
+ items:
+ - const: 60S
+ - const: ALARM
+
+ adc:
+ description: Node describing the AB8500 general purpose analog to digital
+ converter, GPADC.
+ type: object
+
+ properties:
+ compatible:
+ const: stericsson,ab8500-gpadc
+
+ # AB8505 only supports one (software) EOC interrupt
+ interrupts:
+ minItems: 1
+ maxItems: 2
+
+ interrupt-names: true
+
+ vddadc-supply: true
+
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 0
+
+ '#io-channel-cells':
+ const: 1
+
+ patternProperties:
+ "^channel@[0-9a-f]+$":
+ type: object
+ $ref: ../iio/adc/adc.yaml#
+ description: Represents each of the external channels which are
+ connected to the ADC.
+
+ properties:
+ reg:
+ items:
+ minimum: 1
+ maximum: 31
+
+ required:
+ - reg
+
+ additionalProperties: false
+
+ required:
+ - compatible
+ - interrupts
+ - interrupt-names
+ - vddadc-supply
+ - '#address-cells'
+ - '#size-cells'
+ - '#io-channel-cells'
+
+ additionalProperties: false
+
+ thermal:
+ description: Node describing the AB8500 thermal control block. All this block
+ really does is to fire an interrupt when the die becomes 130 degrees Celsius
+ in temperature.
+ type: object
+
+ properties:
+ compatible:
+ const: stericsson,abx500-temp
+
+ interrupts:
+ items:
+ - description: Thermal warm warning interrupt
+
+ interrupt-names:
+ items:
+ - const: ABX500_TEMP_WARM
+
+ required:
+ - compatible
+ - interrupts
+ - interrupt-names
+
+ additionalProperties: false
+
+ ab8500_fg:
+ description: Node describing the AB8500 fuel gauge control block.
+ type: object
+ $ref: ../power/supply/stericsson,ab8500-fg.yaml
+
+ ab8500_btemp:
+ description: Node describing the AB8500 battery temperature control block.
+ type: object
+ $ref: ../power/supply/stericsson,ab8500-btemp.yaml
+
+ ab8500_charger:
+ description: Node describing the AB8500 battery charger control block.
+ type: object
+ $ref: ../power/supply/stericsson,ab8500-charger.yaml
+
+ ab8500_chargalg:
+ description: Node describing the AB8500 battery charger algorithm.
+ type: object
+ $ref: ../power/supply/stericsson,ab8500-chargalg.yaml
+
+ phy:
+ description: Node describing the AB8500 USB PHY control block.
+ type: object
+
+ properties:
+ compatible:
+ const: stericsson,ab8500-usb
+
+ interrupts:
+ items:
+ - description: ID wakeup rising IRQ
+ - description: ID wakeup falling IRQ
+ - description: VBUS detection falling IRQ
+ - description: VBUS detection rising IRQ
+ - description: USB link status change IRQ
+ - description: ADP probe plug IRQ
+ - description: ADP probe unplug IRQ
+
+ interrupt-names:
+ items:
+ - const: ID_WAKEUP_R
+ - const: ID_WAKEUP_F
+ - const: VBUS_DET_F
+ - const: VBUS_DET_R
+ - const: USB_LINK_STATUS
+ - const: USB_ADP_PROBE_PLUG
+ - const: USB_ADP_PROBE_UNPLUG
+
+ vddulpivio18-supply: true
+ v-ape-supply: true
+ musb_1v8-supply: true
+
+ clocks:
+ items:
+ - description: PRCMY system clock
+
+ clock-names:
+ items:
+ - const: sysclk
+
+ '#phy-cells':
+ const: 0
+
+ required:
+ - compatible
+ - interrupts
+ - interrupt-names
+ - vddulpivio18-supply
+ - v-ape-supply
+ - musb_1v8-supply
+ - clocks
+ - clock-names
+ - '#phy-cells'
+
+ additionalProperties: false
+
+ key:
+ description: Node describing the AB8500 power-on key control block.
+ type: object
+
+ properties:
+ compatible:
+ const: stericsson,ab8500-poweron-key
+
+ interrupts:
+ items:
+ - description: ON key falling IRQ
+ - description: ON key rising IRQ
+
+ interrupt-names:
+ items:
+ - const: ONKEY_DBF
+ - const: ONKEY_DBR
+
+ required:
+ - compatible
+ - interrupts
+ - interrupt-names
+
+ additionalProperties: false
+
+ ab8500-sysctrl:
+ description: Node describing the AB8500 system control block.
+ type: object
+
+ properties:
+ compatible:
+ const: stericsson,ab8500-sysctrl
+
+ required:
+ - compatible
+
+ additionalProperties: false
+
+ codec:
+ description: Node describing the AB8500 audio codec block.
+ type: object
+
+ properties:
+ compatible:
+ const: stericsson,ab8500-codec
+
+ V-AUD-supply: true
+ V-AMIC1-supply: true
+ V-AMIC2-supply: true
+ V-DMIC-supply: true
+
+ clocks:
+ items:
+ - description: Audio system clock
+
+ clock-names:
+ items:
+ - const: audioclk
+
+ stericsson,earpeice-cmv:
+ description: Earpeice voltage
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [ 950, 1100, 1270, 1580 ]
+
+ required:
+ - compatible
+
+ additionalProperties: false
+
+ regulator:
+ description: Node describing the AB8500 internal regulators.
+ type: object
+
+ properties:
+ compatible:
+ enum:
+ - stericsson,ab8500-regulator
+ - stericsson,ab8505-regulator
+
+ vin-supply:
+ description: The regulator supplying all of the internal regulators
+ with power.
+
+ ab8500_ldo_aux1:
+ description: The voltage for the auxilary LDO regulator 1
+ type: object
+ $ref: ../regulator/regulator.yaml#
+
+ ab8500_ldo_aux2:
+ description: The voltage for the auxilary LDO regulator 2
+ type: object
+ $ref: ../regulator/regulator.yaml#
+
+ ab8500_ldo_aux3:
+ description: The voltage for the auxilary LDO regulator 3
+ type: object
+ $ref: ../regulator/regulator.yaml#
+
+ ab8500_ldo_aux4:
+ description: The voltage for the auxilary LDO regulator 4
+ only present on AB8505
+ type: object
+ $ref: ../regulator/regulator.yaml#
+
+ ab8500_ldo_aux5:
+ description: The voltage for the auxilary LDO regulator 5
+ only present on AB8505
+ type: object
+ $ref: ../regulator/regulator.yaml#
+
+ ab8500_ldo_aux6:
+ description: The voltage for the auxilary LDO regulator 6
+ only present on AB8505
+ type: object
+ $ref: ../regulator/regulator.yaml#
+
+ # There is never any AUX7 regulator which is confusing
+
+ ab8500_ldo_aux8:
+ description: The voltage for the auxilary LDO regulator 8
+ only present on AB8505
+ type: object
+ $ref: ../regulator/regulator.yaml#
+
+ ab8500_ldo_intcore:
+ description: The LDO regulator for the internal core voltage
+ of the AB8500
+ type: object
+ $ref: ../regulator/regulator.yaml#
+
+ ab8500_ldo_adc:
+ description: Analog power regulator for the analog to digital converter
+ ADC, only present on AB8505
+ type: object
+ $ref: ../regulator/regulator.yaml#
+
+ ab8500_ldo_tvout:
+ description: The voltage for the TV output regulator, incidentally
+ this voltage is also used for other purposes such as measuring
+ the temperature of the NTC thermistor on the battery.
+ Only present on AB8500.
+ type: object
+ $ref: ../regulator/regulator.yaml#
+
+ ab8500_ldo_audio:
+ description: The LDO regulator for the audio codec output
+ type: object
+ $ref: ../regulator/regulator.yaml#
+
+ ab8500_ldo_anamic1:
+ description: The LDO regulator for the analog microphone 1
+ type: object
+ $ref: ../regulator/regulator.yaml#
+
+ ab8500_ldo_anamic2:
+ description: The LDO regulator for the analog microphone 2
+ type: object
+ $ref: ../regulator/regulator.yaml#
+
+ ab8500_ldo_dmic:
+ description: The LDO regulator for the digital microphone
+ only present on AB8500
+ type: object
+ $ref: ../regulator/regulator.yaml#
+
+ ab8500_ldo_ana:
+ description: Analog power regulator for CSI and DSI interfaces,
+ Camera Serial Interface CSI and Display Serial Interface DSI.
+ type: object
+ $ref: ../regulator/regulator.yaml#
+
+ required:
+ - compatible
+
+ additionalProperties: 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.
+ type: object
+
+ properties:
+ compatible:
+ const: stericsson,ab8500-ext-regulator
+
+ ab8500_ext1:
+ description: The voltage for the VSMPS1 external regulator
+ type: object
+ $ref: ../regulator/regulator.yaml#
+
+ ab8500_ext2:
+ description: The voltage for the VSMPS2 external regulator
+ type: object
+ $ref: ../regulator/regulator.yaml#
+
+ ab8500_ext3:
+ description: The voltage for the VSMPS3 external regulator
+ type: object
+ $ref: ../regulator/regulator.yaml#
+
+ required:
+ - compatible
+
+ additionalProperties: false
+
+patternProperties:
+ "^pwm@[1-9]+?$":
+ type: object
+ $ref: ../pwm/pwm.yaml#
+ description: Represents each of the PWM blocks in the AB8500
+
+ properties:
+ compatible:
+ const: stericsson,ab8500-pwm
+
+ reg: true
+
+ clocks:
+ items:
+ - description: internal clock
+
+ clock-names:
+ items:
+ - const: intclk
+
+ required:
+ - compatible
+ - reg
+
+required:
+ - compatible
+ - clock-controller
+ - gpio
+ - rtc
+ - adc
+ - thermal
+ - ab8500_fg
+ - ab8500_btemp
+ - ab8500_charger
+ - ab8500_chargalg
+ - phy
+ - key
+ - regulator
+
+additionalProperties: false
diff --git a/Documentation/devicetree/bindings/mfd/stericsson,db8500-prcmu.yaml b/Documentation/devicetree/bindings/mfd/stericsson,db8500-prcmu.yaml
index a0d4bad5dc81..1d4d88f7e82d 100644
--- a/Documentation/devicetree/bindings/mfd/stericsson,db8500-prcmu.yaml
+++ b/Documentation/devicetree/bindings/mfd/stericsson,db8500-prcmu.yaml
@@ -263,6 +263,7 @@ patternProperties:
set of devicetree bindings. The AB8505 is a newer version of the
same ASIC.
type: object
+ $ref: stericsson,ab8500.yaml#
required:
- compatible
diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
index eeac1cbc5a17..13baa452cc9d 100644
--- a/Documentation/devicetree/bindings/mfd/syscon.yaml
+++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
@@ -44,6 +44,11 @@ properties:
- hisilicon,hi6220-sramctrl
- hisilicon,pcie-sas-subctrl
- hisilicon,peri-subctrl
+ - intel,lgm-syscon
+ - marvell,armada-3700-usb2-host-misc
+ - mediatek,mt8135-pctl-a-syscfg
+ - mediatek,mt8135-pctl-b-syscfg
+ - microchip,lan966x-cpu-syscon
- microchip,sparx5-cpu-syscon
- mstar,msc313-pmsleep
- rockchip,px30-qos
diff --git a/Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml b/Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml
new file mode 100644
index 000000000000..a21dc1a8890f
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/power/supply/maxim,max77693.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX77693 MicroUSB and Companion Power Management IC Charger
+
+maintainers:
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+description: |
+ This is a part of device tree bindings for Maxim MAX77693 MicroUSB Integrated
+ Circuit (MUIC).
+
+ See also Documentation/devicetree/bindings/mfd/maxim,max77693.yaml for
+ additional information and example.
+
+properties:
+ compatible:
+ const: maxim,max77693-charger
+
+ maxim,constant-microvolt:
+ description: |
+ Battery constant voltage in uV. The charger will operate in fast
+ charge constant current mode till battery voltage reaches this level.
+ Then the charger will switch to fast charge constant voltage mode.
+ Also vsys (system voltage) will be set to this value when DC power is
+ supplied but charger is not enabled.
+ Valid values: 3650000 - 4400000, step by 25000 (rounded down)
+ minimum: 3650000
+ maximum: 4400000
+ default: 4200000
+
+ maxim,min-system-microvolt:
+ description: |
+ Minimal system voltage in uV.
+ enum: [3000000, 3100000, 3200000, 3300000, 3400000, 3500000,
+ 3600000, 3700000]
+ default: 3600000
+
+ maxim,thermal-regulation-celsius:
+ description: |
+ Temperature in Celsius for entering high temperature charging mode.
+ If die temperature exceeds this value the charging current will be
+ reduced by 105 mA/Celsius.
+ enum: [70, 85, 100, 115]
+ default: 100
+
+ maxim,battery-overcurrent-microamp:
+ description: |
+ Overcurrent protection threshold in uA (current from battery to
+ system).
+ Valid values: 2000000 - 3500000, step by 250000 (rounded down)
+ minimum: 2000000
+ maximum: 3500000
+ default: 3500000
+
+ maxim,charge-input-threshold-microvolt:
+ description: |
+ Threshold voltage in uV for triggering input voltage regulation loop.
+ If input voltage decreases below this value, the input current will
+ be reduced to reach the threshold voltage.
+ enum: [4300000, 4700000, 4800000, 4900000]
+ default: 4300000
+
+required:
+ - compatible
+
+additionalProperties: false
diff --git a/Documentation/devicetree/bindings/regulator/maxim,max77693.yaml b/Documentation/devicetree/bindings/regulator/maxim,max77693.yaml
new file mode 100644
index 000000000000..20d8559bdc2b
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/maxim,max77693.yaml
@@ -0,0 +1,60 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/maxim,max77693.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX77693 MicroUSB and Companion Power Management IC regulators
+
+maintainers:
+ - Chanwoo Choi <cw00.choi@samsung.com>
+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+description: |
+ This is a part of device tree bindings for Maxim MAX77693 MicroUSB Integrated
+ Circuit (MUIC).
+
+ See also Documentation/devicetree/bindings/mfd/maxim,max77693.yaml for
+ additional information and example.
+
+properties:
+ CHARGER:
+ type: object
+ $ref: regulator.yaml#
+ additionalProperties: false
+ description: |
+ Current regulator.
+
+ properties:
+ regulator-name: true
+ regulator-always-on: true
+ regulator-boot-on: true
+ regulator-min-microamp:
+ minimum: 60000
+ regulator-max-microamp:
+ maximum: 2580000
+
+ required:
+ - regulator-name
+
+patternProperties:
+ "^ESAFEOUT[12]$":
+ type: object
+ $ref: regulator.yaml#
+ additionalProperties: false
+ description: |
+ Safeout LDO regulator.
+
+ properties:
+ regulator-name: true
+ regulator-always-on: true
+ regulator-boot-on: true
+ regulator-min-microvolt:
+ minimum: 3300000
+ regulator-max-microvolt:
+ maximum: 4950000
+
+ required:
+ - regulator-name
+
+additionalProperties: false
diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index 9d2787a12a69..a8838cb0d17e 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -187,6 +187,7 @@ Hardware Monitoring Kernel Drivers
smsc47m1
sparx5-temp
stpddc60
+ sy7636a-hwmon
tc654
tc74
thmc50
diff --git a/Documentation/hwmon/sy7636a-hwmon.rst b/Documentation/hwmon/sy7636a-hwmon.rst
new file mode 100644
index 000000000000..c85db7b32941
--- /dev/null
+++ b/Documentation/hwmon/sy7636a-hwmon.rst
@@ -0,0 +1,26 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+Kernel driver sy7636a-hwmon
+===========================
+
+Supported chips:
+
+ * Silergy SY7636A PMIC
+
+
+Description
+-----------
+
+This driver adds hardware temperature reading support for
+the Silergy SY7636A PMIC.
+
+The following sensors are supported
+
+ * Temperature
+ - SoC on-die temperature in milli-degree C
+
+sysfs-Interface
+---------------
+
+temp0_input
+ - SoC on-die temperature (milli-degree C)
diff --git a/MAINTAINERS b/MAINTAINERS
index 8b57f24c659f..2f3056772c3a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11824,6 +11824,13 @@ F: drivers/power/supply/max77650-charger.c
F: drivers/regulator/max77650-regulator.c
F: include/linux/mfd/max77650.h
+MAXIM MAX77714 PMIC MFD DRIVER
+M: Luca Ceresoli <luca@lucaceresoli.net>
+S: Maintained
+F: Documentation/devicetree/bindings/mfd/maxim,max77714.yaml
+F: drivers/mfd/max77714.c
+F: include/linux/mfd/max77714.h
+
MAXIM MAX77802 PMIC REGULATOR DEVICE DRIVER
M: Javier Martinez Canillas <javier@dowhile0.org>
L: linux-kernel@vger.kernel.org
@@ -11844,6 +11851,7 @@ M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
L: linux-pm@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml
+F: Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml
F: drivers/power/supply/max14577_charger.c
F: drivers/power/supply/max77693_charger.c
@@ -11855,6 +11863,7 @@ L: linux-kernel@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/*/maxim,max14577.yaml
F: Documentation/devicetree/bindings/*/maxim,max77686.yaml
+F: Documentation/devicetree/bindings/*/maxim,max77693.yaml
F: Documentation/devicetree/bindings/*/maxim,max77843.yaml
F: Documentation/devicetree/bindings/clock/maxim,max77686.txt
F: Documentation/devicetree/bindings/mfd/max77693.txt
@@ -16842,7 +16851,7 @@ M: Marek Vasut <marek.vasut+renesas@gmail.com>
L: linux-kernel@vger.kernel.org
L: linux-renesas-soc@vger.kernel.org
S: Supported
-F: Documentation/devicetree/bindings/mfd/bd9571mwv.txt
+F: Documentation/devicetree/bindings/mfd/rohm,bd9571mwv.yaml
F: drivers/gpio/gpio-bd9571mwv.c
F: drivers/mfd/bd9571mwv.c
F: drivers/regulator/bd9571mwv-regulator.c
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 9ab4e9b3d27b..db8bc55e5f50 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1689,6 +1689,15 @@ config SENSORS_SIS5595
This driver can also be built as a module. If so, the module
will be called sis5595.
+config SENSORS_SY7636A
+ tristate "Silergy SY7636A"
+ help
+ If you say yes here you get support for the thermistor readout of
+ the Silergy SY7636A PMIC.
+
+ This driver can also be built as a module. If so, the module
+ will be called sy7636a-hwmon.
+
config SENSORS_DME1737
tristate "SMSC DME1737, SCH311x and compatibles"
depends on I2C && !PPC
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 4ed138d0621f..7fd5e94d88f6 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -187,6 +187,7 @@ obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
obj-$(CONFIG_SENSORS_SPARX5) += sparx5-temp.o
obj-$(CONFIG_SENSORS_STTS751) += stts751.o
+obj-$(CONFIG_SENSORS_SY7636A) += sy7636a-hwmon.o
obj-$(CONFIG_SENSORS_AMC6821) += amc6821.o
obj-$(CONFIG_SENSORS_TC74) += tc74.o
obj-$(CONFIG_SENSORS_THMC50) += thmc50.o
diff --git a/drivers/hwmon/sy7636a-hwmon.c b/drivers/hwmon/sy7636a-hwmon.c
new file mode 100644
index 000000000000..6dd9c2a0f0e0
--- /dev/null
+++ b/drivers/hwmon/sy7636a-hwmon.c
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Functions to access SY3686A power management chip temperature
+ *
+ * Copyright (C) 2021 reMarkable AS - http://www.remarkable.com/
+ *
+ * Authors: Lars Ivar Miljeteig <lars.ivar.miljeteig@remarkable.com>
+ * Alistair Francis <alistair@alistair23.me>
+ */
+
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/machine.h>
+
+#include <linux/mfd/sy7636a.h>
+
+static int sy7636a_read(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, long *temp)
+{
+ struct regmap *regmap = dev_get_drvdata(dev);
+ int ret, reg_val;
+
+ ret = regmap_read(regmap,
+ SY7636A_REG_TERMISTOR_READOUT, &reg_val);
+ if (ret)
+ return ret;
+
+ *temp = reg_val * 1000;
+
+ return 0;
+}
+
+static umode_t sy7636a_is_visible(const void *data,
+ enum hwmon_sensor_types type,
+ u32 attr, int channel)
+{
+ if (type != hwmon_temp)
+ return 0;
+
+ if (attr != hwmon_temp_input)
+ return 0;
+
+ return 0444;
+}
+
+static const struct hwmon_ops sy7636a_hwmon_ops = {
+ .is_visible = sy7636a_is_visible,
+ .read = sy7636a_read,
+};
+
+static const struct hwmon_channel_info *sy7636a_info[] = {
+ HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
+ HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
+ NULL
+};
+
+static const struct hwmon_chip_info sy7636a_chip_info = {
+ .ops = &sy7636a_hwmon_ops,
+ .info = sy7636a_info,
+};
+
+static int sy7636a_sensor_probe(struct platform_device *pdev)
+{
+ struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL);
+ struct regulator *regulator;
+ struct device *hwmon_dev;
+ int err;
+
+ if (!regmap)
+ return -EPROBE_DEFER;
+
+ regulator = devm_regulator_get(&pdev->dev, "vcom");
+ if (IS_ERR(regulator))
+ return PTR_ERR(regulator);
+
+ err = regulator_enable(regulator);
+ if (err)
+ return err;
+
+ hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev,
+ "sy7636a_temperature", regmap,
+ &sy7636a_chip_info, NULL);
+
+ if (IS_ERR(hwmon_dev)) {
+ err = PTR_ERR(hwmon_dev);
+ dev_err(&pdev->dev, "Unable to register hwmon device, returned %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static struct platform_driver sy7636a_sensor_driver = {
+ .probe = sy7636a_sensor_probe,
+ .driver = {
+ .name = "sy7636a-temperature",
+ },
+};
+module_platform_driver(sy7636a_sensor_driver);
+
+MODULE_DESCRIPTION("SY7636A sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/temperature/iqs620at-temp.c b/drivers/iio/temperature/iqs620at-temp.c
index fe126e1fb783..e2f878d57af7 100644
--- a/drivers/iio/temperature/iqs620at-temp.c
+++ b/drivers/iio/temperature/iqs620at-temp.c
@@ -17,6 +17,7 @@
#define IQS620_TEMP_SCALE 1000
#define IQS620_TEMP_OFFSET (-100)
+#define IQS620_TEMP_OFFSET_V3 (-40)
static int iqs620_temp_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
@@ -41,7 +42,8 @@ static int iqs620_temp_read_raw(struct iio_dev *indio_dev,
return IIO_VAL_INT;
case IIO_CHAN_INFO_OFFSET:
- *val = IQS620_TEMP_OFFSET;
+ *val = iqs62x->hw_num < IQS620_HW_NUM_V3 ? IQS620_TEMP_OFFSET
+ : IQS620_TEMP_OFFSET_V3;
return IIO_VAL_INT;
default:
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index ba0b3eb131f1..3b59456f5545 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -849,6 +849,20 @@ config MFD_MAX77693
additional drivers must be enabled in order to use the functionality
of the device.
+config MFD_MAX77714
+ tristate "Maxim Semiconductor MAX77714 PMIC Support"
+ depends on I2C
+ depends on OF || COMPILE_TEST
+ select MFD_CORE
+ select REGMAP_I2C
+ help
+ Say yes here to add support for Maxim Semiconductor MAX77714.
+ This is a Power Management IC with 4 buck regulators, 9
+ low-dropout regulators, 8 GPIOs, RTC, watchdog etc. This driver
+ provides common support for accessing the device; additional
+ drivers must be enabled in order to use each functionality of the
+ device.
+
config MFD_MAX77843
bool "Maxim Semiconductor MAX77843 PMIC Support"
depends on I2C=y
@@ -1188,7 +1202,7 @@ config MFD_SI476X_CORE
module will be called si476x-core.
config MFD_SIMPLE_MFD_I2C
- tristate
+ tristate "Simple Multi-Functional Device support (I2C)"
depends on I2C
select MFD_CORE
select REGMAP_I2C
@@ -1283,14 +1297,6 @@ config AB8500_CORE
the irq_chip parts for handling the Mixed Signal chip events.
This chip embeds various other multimedia functionalities as well.
-config AB8500_DEBUG
- bool "Enable debug info via debugfs"
- depends on AB8500_GPADC && DEBUG_FS
- default y if DEBUG_FS
- help
- Select this option if you want debug information using the debug
- filesystem, debugfs.
-
config MFD_DB8500_PRCMU
bool "ST-Ericsson DB8500 Power Reset Control Management Unit"
depends on UX500_SOC_DB8500
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index df1ecc4a4c95..858cacf659d6 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -162,6 +162,7 @@ obj-$(CONFIG_MFD_MAX77620) += max77620.o
obj-$(CONFIG_MFD_MAX77650) += max77650.o
obj-$(CONFIG_MFD_MAX77686) += max77686.o
obj-$(CONFIG_MFD_MAX77693) += max77693.o
+obj-$(CONFIG_MFD_MAX77714) += max77714.o
obj-$(CONFIG_MFD_MAX77843) += max77843.o
obj-$(CONFIG_MFD_MAX8907) += max8907.o
max8925-objs := max8925-core.o max8925-i2c.o
@@ -176,7 +177,6 @@ obj-$(CONFIG_MFD_PCF50633) += pcf50633.o
obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o
obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o
obj-$(CONFIG_ABX500_CORE) += abx500-core.o
-obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o
obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o
# ab8500-core need to come after db8500-prcmu (which provides the channel)
obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index cca0aac26148..9d9e9787d5e8 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -613,10 +613,6 @@ static const struct mfd_cell ab8500_bm_devs[] = {
};
static const struct mfd_cell ab8500_devs[] = {
-#ifdef CONFIG_DEBUG_FS
- MFD_CELL_OF("ab8500-debug",
- NULL, NULL, 0, 0, "stericsson,ab8500-debug"),
-#endif
MFD_CELL_OF("ab8500-sysctrl",
NULL, NULL, 0, 0, "stericsson,ab8500-sysctrl"),
MFD_CELL_OF("ab8500-ext-regulator",
@@ -652,11 +648,6 @@ static const struct mfd_cell ab8500_devs[] = {
};
static const struct mfd_cell ab9540_devs[] = {
-#ifdef CONFIG_DEBUG_FS
- {
- .name = "ab8500-debug",
- },
-#endif
{
.name = "ab8500-sysctrl",
},
@@ -707,12 +698,6 @@ static const struct mfd_cell ab9540_devs[] = {
/* Device list for ab8505 */
static const struct mfd_cell ab8505_devs[] = {
-#ifdef CONFIG_DEBUG_FS
- {
- .name = "ab8500-debug",
- .of_compatible = "stericsson,ab8500-debug",
- },
-#endif
{
.name = "ab8500-sysctrl",
.of_compatible = "stericsson,ab8500-sysctrl",
@@ -764,11 +749,6 @@ static const struct mfd_cell ab8505_devs[] = {
};
static const struct mfd_cell ab8540_devs[] = {
-#ifdef CONFIG_DEBUG_FS
- {
- .name = "ab8500-debug",
- },
-#endif
{
.name = "ab8500-sysctrl",
},
@@ -1042,9 +1022,9 @@ static int ab8500_probe(struct platform_device *pdev)
enum ab8500_version version = AB8500_VERSION_UNDEFINED;
struct device_node *np = pdev->dev.of_node;
struct ab8500 *ab8500;
- struct resource *resource;
int ret;
int i;
+ int irq;
u8 value;
ab8500 = devm_kzalloc(&pdev->dev, sizeof(*ab8500), GFP_KERNEL);
@@ -1053,13 +1033,11 @@ static int ab8500_probe(struct platform_device *pdev)
ab8500->dev = &pdev->dev;
- resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!resource) {
- dev_err(&pdev->dev, "no IRQ resource\n");
- return -ENODEV;
- }
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
- ab8500->irq = resource->start;
+ ab8500->irq = irq;
ab8500->read = ab8500_prcmu_read;
ab8500->write = ab8500_prcmu_write;
diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c
deleted file mode 100644
index e43dea89b094..000000000000
--- a/drivers/mfd/ab8500-debugfs.c
+++ /dev/null
@@ -1,2096 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) ST-Ericsson SA 2010
- *
- * Author: Mattias Wallin <mattias.wallin@stericsson.com> for ST-Ericsson.
- */
-/*
- * AB8500 register access
- * ======================
- *
- * read:
- * # echo BANK > <debugfs>/ab8500/register-bank
- * # echo ADDR > <debugfs>/ab8500/register-address
- * # cat <debugfs>/ab8500/register-value
- *
- * write:
- * # echo BANK > <debugfs>/ab8500/register-bank
- * # echo ADDR > <debugfs>/ab8500/register-address
- * # echo VALUE > <debugfs>/ab8500/register-value
- *
- * read all registers from a bank:
- * # echo BANK > <debugfs>/ab8500/register-bank
- * # cat <debugfs>/ab8500/all-bank-register
- *
- * BANK target AB8500 register bank
- * ADDR target AB8500 register address
- * VALUE decimal or 0x-prefixed hexadecimal
- *
- *
- * User Space notification on AB8500 IRQ
- * =====================================
- *
- * Allows user space entity to be notified when target AB8500 IRQ occurs.
- * When subscribed, a sysfs entry is created in ab8500.i2c platform device.
- * One can pool this file to get target IRQ occurence information.
- *
- * subscribe to an AB8500 IRQ:
- * # echo IRQ > <debugfs>/ab8500/irq-subscribe
- *
- * unsubscribe from an AB8500 IRQ:
- * # echo IRQ > <debugfs>/ab8500/irq-unsubscribe
- *
- *
- * AB8500 register formated read/write access
- * ==========================================
- *
- * Read: read data, data>>SHIFT, data&=MASK, output data
- * [0xABCDEF98] shift=12 mask=0xFFF => 0x00000CDE
- * Write: read data, data &= ~(MASK<<SHIFT), data |= (VALUE<<SHIFT), write data
- * [0xABCDEF98] shift=12 mask=0xFFF value=0x123 => [0xAB123F98]
- *
- * Usage:
- * # echo "CMD [OPTIONS] BANK ADRESS [VALUE]" > $debugfs/ab8500/hwreg
- *
- * CMD read read access
- * write write access
- *
- * BANK target reg bank
- * ADDRESS target reg address
- * VALUE (write) value to be updated
- *
- * OPTIONS
- * -d|-dec (read) output in decimal
- * -h|-hexa (read) output in 0x-hexa (default)
- * -l|-w|-b 32bit (default), 16bit or 8bit reg access
- * -m|-mask MASK 0x-hexa mask (default 0xFFFFFFFF)
- * -s|-shift SHIFT bit shift value (read:left, write:right)
- * -o|-offset OFFSET address offset to add to ADDRESS value
- *
- * Warning: bit shift operation is applied to bit-mask.
- * Warning: bit shift direction depends on read or right command.
- */
-
-#include <linux/seq_file.h>
-#include <linux/uaccess.h>
-#include <linux/fs.h>
-#include <linux/init.h>
-#include <linux/debugfs.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/kobject.h>
-#include <linux/slab.h>
-#include <linux/irq.h>
-
-#include <linux/mfd/abx500.h>
-#include <linux/mfd/abx500/ab8500.h>
-
-#ifdef CONFIG_DEBUG_FS
-#include <linux/string.h>
-#include <linux/ctype.h>
-#endif
-
-static u32 debug_bank;
-static u32 debug_address;
-
-static int irq_ab8500;
-static int irq_first;
-static int irq_last;
-static u32 *irq_count;
-static int num_irqs;
-
-static struct device_attribute **dev_attr;
-static char **event_name;
-
-/**
- * struct ab8500_reg_range
- * @first: the first address of the range
- * @last: the last address of the range
- * @perm: access permissions for the range
- */
-struct ab8500_reg_range {
- u8 first;
- u8 last;
- u8 perm;
-};
-
-/**
- * struct ab8500_prcmu_ranges
- * @num_ranges: the number of ranges in the list
- * @bankid: bank identifier
- * @range: the list of register ranges
- */
-struct ab8500_prcmu_ranges {
- u8 num_ranges;
- u8 bankid;
- const struct ab8500_reg_range *range;
-};
-
-/* hwreg- "mask" and "shift" entries ressources */
-struct hwreg_cfg {
- u32 bank; /* target bank */
- unsigned long addr; /* target address */
- uint fmt; /* format */
- unsigned long mask; /* read/write mask, applied before any bit shift */
- long shift; /* bit shift (read:right shift, write:left shift */
-};
-/* fmt bit #0: 0=hexa, 1=dec */
-#define REG_FMT_DEC(c) ((c)->fmt & 0x1)
-#define REG_FMT_HEX(c) (!REG_FMT_DEC(c))
-
-static struct hwreg_cfg hwreg_cfg = {
- .addr = 0, /* default: invalid phys addr */
- .fmt = 0, /* default: 32bit access, hex output */
- .mask = 0xFFFFFFFF, /* default: no mask */
- .shift = 0, /* default: no bit shift */
-};
-
-#define AB8500_NAME_STRING "ab8500"
-#define AB8500_NUM_BANKS AB8500_DEBUG_FIELD_LAST
-
-#define AB8500_REV_REG 0x80
-
-static struct ab8500_prcmu_ranges *debug_ranges;
-
-static struct ab8500_prcmu_ranges ab8500_debug_ranges[AB8500_NUM_BANKS] = {
- [AB8500_M_FSM_RANK] = {
- .num_ranges = 0,
- .range = NULL,
- },
- [AB8500_SYS_CTRL1_BLOCK] = {
- .num_ranges = 3,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x02,
- },
- {
- .first = 0x42,
- .last = 0x42,
- },
- {
- .first = 0x80,
- .last = 0x81,
- },
- },
- },
- [AB8500_SYS_CTRL2_BLOCK] = {
- .num_ranges = 4,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x0D,
- },
- {
- .first = 0x0F,
- .last = 0x17,
- },
- {
- .first = 0x30,
- .last = 0x30,
- },
- {
- .first = 0x32,
- .last = 0x33,
- },
- },
- },
- [AB8500_REGU_CTRL1] = {
- .num_ranges = 3,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x00,
- },
- {
- .first = 0x03,
- .last = 0x10,
- },
- {
- .first = 0x80,
- .last = 0x84,
- },
- },
- },
- [AB8500_REGU_CTRL2] = {
- .num_ranges = 5,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x15,
- },
- {
- .first = 0x17,
- .last = 0x19,
- },
- {
- .first = 0x1B,
- .last = 0x1D,
- },
- {
- .first = 0x1F,
- .last = 0x22,
- },
- {
- .first = 0x40,
- .last = 0x44,
- },
- /*
- * 0x80-0x8B are SIM registers and should
- * not be accessed from here
- */
- },
- },
- [AB8500_USB] = {
- .num_ranges = 2,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x80,
- .last = 0x83,
- },
- {
- .first = 0x87,
- .last = 0x8A,
- },
- },
- },
- [AB8500_TVOUT] = {
- .num_ranges = 9,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x12,
- },
- {
- .first = 0x15,
- .last = 0x17,
- },
- {
- .first = 0x19,
- .last = 0x21,
- },
- {
- .first = 0x27,
- .last = 0x2C,
- },
- {
- .first = 0x41,
- .last = 0x41,
- },
- {
- .first = 0x45,
- .last = 0x5B,
- },
- {
- .first = 0x5D,
- .last = 0x5D,
- },
- {
- .first = 0x69,
- .last = 0x69,
- },
- {
- .first = 0x80,
- .last = 0x81,
- },
- },
- },
- [AB8500_DBI] = {
- .num_ranges = 0,
- .range = NULL,
- },
- [AB8500_ECI_AV_ACC] = {
- .num_ranges = 1,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x80,
- .last = 0x82,
- },
- },
- },
- [AB8500_RESERVED] = {
- .num_ranges = 0,
- .range = NULL,
- },
- [AB8500_GPADC] = {
- .num_ranges = 1,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x08,
- },
- },
- },
- [AB8500_CHARGER] = {
- .num_ranges = 9,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x03,
- },
- {
- .first = 0x05,
- .last = 0x05,
- },
- {
- .first = 0x40,
- .last = 0x40,
- },
- {
- .first = 0x42,
- .last = 0x42,
- },
- {
- .first = 0x44,
- .last = 0x44,
- },
- {
- .first = 0x50,
- .last = 0x55,
- },
- {
- .first = 0x80,
- .last = 0x82,
- },
- {
- .first = 0xC0,
- .last = 0xC2,
- },
- {
- .first = 0xf5,
- .last = 0xf6,
- },
- },
- },
- [AB8500_GAS_GAUGE] = {
- .num_ranges = 3,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x00,
- },
- {
- .first = 0x07,
- .last = 0x0A,
- },
- {
- .first = 0x10,
- .last = 0x14,
- },
- },
- },
- [AB8500_AUDIO] = {
- .num_ranges = 1,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x6F,
- },
- },
- },
- [AB8500_INTERRUPT] = {
- .num_ranges = 0,
- .range = NULL,
- },
- [AB8500_RTC] = {
- .num_ranges = 1,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x0F,
- },
- },
- },
- [AB8500_MISC] = {
- .num_ranges = 8,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x05,
- },
- {
- .first = 0x10,
- .last = 0x15,
- },
- {
- .first = 0x20,
- .last = 0x25,
- },
- {
- .first = 0x30,
- .last = 0x35,
- },
- {
- .first = 0x40,
- .last = 0x45,
- },
- {
- .first = 0x50,
- .last = 0x50,
- },
- {
- .first = 0x60,
- .last = 0x67,
- },
- {
- .first = 0x80,
- .last = 0x80,
- },
- },
- },
- [AB8500_DEVELOPMENT] = {
- .num_ranges = 1,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x00,
- },
- },
- },
- [AB8500_DEBUG] = {
- .num_ranges = 1,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x05,
- .last = 0x07,
- },
- },
- },
- [AB8500_PROD_TEST] = {
- .num_ranges = 0,
- .range = NULL,
- },
- [AB8500_STE_TEST] = {
- .num_ranges = 0,
- .range = NULL,
- },
- [AB8500_OTP_EMUL] = {
- .num_ranges = 1,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x01,
- .last = 0x0F,
- },
- },
- },
-};
-
-static struct ab8500_prcmu_ranges ab8505_debug_ranges[AB8500_NUM_BANKS] = {
- [0x0] = {
- .num_ranges = 0,
- .range = NULL,
- },
- [AB8500_SYS_CTRL1_BLOCK] = {
- .num_ranges = 5,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x04,
- },
- {
- .first = 0x42,
- .last = 0x42,
- },
- {
- .first = 0x52,
- .last = 0x52,
- },
- {
- .first = 0x54,
- .last = 0x57,
- },
- {
- .first = 0x80,
- .last = 0x83,
- },
- },
- },
- [AB8500_SYS_CTRL2_BLOCK] = {
- .num_ranges = 5,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x0D,
- },
- {
- .first = 0x0F,
- .last = 0x17,
- },
- {
- .first = 0x20,
- .last = 0x20,
- },
- {
- .first = 0x30,
- .last = 0x30,
- },
- {
- .first = 0x32,
- .last = 0x3A,
- },
- },
- },
- [AB8500_REGU_CTRL1] = {
- .num_ranges = 3,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x00,
- },
- {
- .first = 0x03,
- .last = 0x11,
- },
- {
- .first = 0x80,
- .last = 0x86,
- },
- },
- },
- [AB8500_REGU_CTRL2] = {
- .num_ranges = 6,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x06,
- },
- {
- .first = 0x08,
- .last = 0x15,
- },
- {
- .first = 0x17,
- .last = 0x19,
- },
- {
- .first = 0x1B,
- .last = 0x1D,
- },
- {
- .first = 0x1F,
- .last = 0x30,
- },
- {
- .first = 0x40,
- .last = 0x48,
- },
- /*
- * 0x80-0x8B are SIM registers and should
- * not be accessed from here
- */
- },
- },
- [AB8500_USB] = {
- .num_ranges = 3,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x80,
- .last = 0x83,
- },
- {
- .first = 0x87,
- .last = 0x8A,
- },
- {
- .first = 0x91,
- .last = 0x94,
- },
- },
- },
- [AB8500_TVOUT] = {
- .num_ranges = 0,
- .range = NULL,
- },
- [AB8500_DBI] = {
- .num_ranges = 0,
- .range = NULL,
- },
- [AB8500_ECI_AV_ACC] = {
- .num_ranges = 1,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x80,
- .last = 0x82,
- },
- },
- },
- [AB8500_RESERVED] = {
- .num_ranges = 0,
- .range = NULL,
- },
- [AB8500_GPADC] = {
- .num_ranges = 1,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x08,
- },
- },
- },
- [AB8500_CHARGER] = {
- .num_ranges = 9,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x02,
- .last = 0x03,
- },
- {
- .first = 0x05,
- .last = 0x05,
- },
- {
- .first = 0x40,
- .last = 0x44,
- },
- {
- .first = 0x50,
- .last = 0x57,
- },
- {
- .first = 0x60,
- .last = 0x60,
- },
- {
- .first = 0xA0,
- .last = 0xA7,
- },
- {
- .first = 0xAF,
- .last = 0xB2,
- },
- {
- .first = 0xC0,
- .last = 0xC2,
- },
- {
- .first = 0xF5,
- .last = 0xF5,
- },
- },
- },
- [AB8500_GAS_GAUGE] = {
- .num_ranges = 3,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x00,
- },
- {
- .first = 0x07,
- .last = 0x0A,
- },
- {
- .first = 0x10,
- .last = 0x14,
- },
- },
- },
- [AB8500_AUDIO] = {
- .num_ranges = 1,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x83,
- },
- },
- },
- [AB8500_INTERRUPT] = {
- .num_ranges = 11,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x04,
- },
- {
- .first = 0x06,
- .last = 0x07,
- },
- {
- .first = 0x09,
- .last = 0x09,
- },
- {
- .first = 0x0B,
- .last = 0x0C,
- },
- {
- .first = 0x12,
- .last = 0x15,
- },
- {
- .first = 0x18,
- .last = 0x18,
- },
- /* Latch registers should not be read here */
- {
- .first = 0x40,
- .last = 0x44,
- },
- {
- .first = 0x46,
- .last = 0x49,
- },
- {
- .first = 0x4B,
- .last = 0x4D,
- },
- {
- .first = 0x52,
- .last = 0x55,
- },
- {
- .first = 0x58,
- .last = 0x58,
- },
- /* LatchHier registers should not be read here */
- },
- },
- [AB8500_RTC] = {
- .num_ranges = 2,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x14,
- },
- {
- .first = 0x16,
- .last = 0x17,
- },
- },
- },
- [AB8500_MISC] = {
- .num_ranges = 8,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x06,
- },
- {
- .first = 0x10,
- .last = 0x16,
- },
- {
- .first = 0x20,
- .last = 0x26,
- },
- {
- .first = 0x30,
- .last = 0x36,
- },
- {
- .first = 0x40,
- .last = 0x46,
- },
- {
- .first = 0x50,
- .last = 0x50,
- },
- {
- .first = 0x60,
- .last = 0x6B,
- },
- {
- .first = 0x80,
- .last = 0x82,
- },
- },
- },
- [AB8500_DEVELOPMENT] = {
- .num_ranges = 2,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x00,
- },
- {
- .first = 0x05,
- .last = 0x05,
- },
- },
- },
- [AB8500_DEBUG] = {
- .num_ranges = 1,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x05,
- .last = 0x07,
- },
- },
- },
- [AB8500_PROD_TEST] = {
- .num_ranges = 0,
- .range = NULL,
- },
- [AB8500_STE_TEST] = {
- .num_ranges = 0,
- .range = NULL,
- },
- [AB8500_OTP_EMUL] = {
- .num_ranges = 1,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x01,
- .last = 0x15,
- },
- },
- },
-};
-
-static struct ab8500_prcmu_ranges ab8540_debug_ranges[AB8500_NUM_BANKS] = {
- [AB8500_M_FSM_RANK] = {
- .num_ranges = 1,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x0B,
- },
- },
- },
- [AB8500_SYS_CTRL1_BLOCK] = {
- .num_ranges = 6,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x04,
- },
- {
- .first = 0x42,
- .last = 0x42,
- },
- {
- .first = 0x50,
- .last = 0x54,
- },
- {
- .first = 0x57,
- .last = 0x57,
- },
- {
- .first = 0x80,
- .last = 0x83,
- },
- {
- .first = 0x90,
- .last = 0x90,
- },
- },
- },
- [AB8500_SYS_CTRL2_BLOCK] = {
- .num_ranges = 5,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x0D,
- },
- {
- .first = 0x0F,
- .last = 0x10,
- },
- {
- .first = 0x20,
- .last = 0x21,
- },
- {
- .first = 0x32,
- .last = 0x3C,
- },
- {
- .first = 0x40,
- .last = 0x42,
- },
- },
- },
- [AB8500_REGU_CTRL1] = {
- .num_ranges = 4,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x03,
- .last = 0x15,
- },
- {
- .first = 0x20,
- .last = 0x20,
- },
- {
- .first = 0x80,
- .last = 0x85,
- },
- {
- .first = 0x87,
- .last = 0x88,
- },
- },
- },
- [AB8500_REGU_CTRL2] = {
- .num_ranges = 8,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x06,
- },
- {
- .first = 0x08,
- .last = 0x15,
- },
- {
- .first = 0x17,
- .last = 0x19,
- },
- {
- .first = 0x1B,
- .last = 0x1D,
- },
- {
- .first = 0x1F,
- .last = 0x2F,
- },
- {
- .first = 0x31,
- .last = 0x3A,
- },
- {
- .first = 0x43,
- .last = 0x44,
- },
- {
- .first = 0x48,
- .last = 0x49,
- },
- },
- },
- [AB8500_USB] = {
- .num_ranges = 3,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x80,
- .last = 0x83,
- },
- {
- .first = 0x87,
- .last = 0x8A,
- },
- {
- .first = 0x91,
- .last = 0x94,
- },
- },
- },
- [AB8500_TVOUT] = {
- .num_ranges = 0,
- .range = NULL
- },
- [AB8500_DBI] = {
- .num_ranges = 4,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x07,
- },
- {
- .first = 0x10,
- .last = 0x11,
- },
- {
- .first = 0x20,
- .last = 0x21,
- },
- {
- .first = 0x30,
- .last = 0x43,
- },
- },
- },
- [AB8500_ECI_AV_ACC] = {
- .num_ranges = 2,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x03,
- },
- {
- .first = 0x80,
- .last = 0x82,
- },
- },
- },
- [AB8500_RESERVED] = {
- .num_ranges = 0,
- .range = NULL,
- },
- [AB8500_GPADC] = {
- .num_ranges = 4,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x01,
- },
- {
- .first = 0x04,
- .last = 0x06,
- },
- {
- .first = 0x09,
- .last = 0x0A,
- },
- {
- .first = 0x10,
- .last = 0x14,
- },
- },
- },
- [AB8500_CHARGER] = {
- .num_ranges = 10,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x00,
- },
- {
- .first = 0x02,
- .last = 0x05,
- },
- {
- .first = 0x40,
- .last = 0x44,
- },
- {
- .first = 0x50,
- .last = 0x57,
- },
- {
- .first = 0x60,
- .last = 0x60,
- },
- {
- .first = 0x70,
- .last = 0x70,
- },
- {
- .first = 0xA0,
- .last = 0xA9,
- },
- {
- .first = 0xAF,
- .last = 0xB2,
- },
- {
- .first = 0xC0,
- .last = 0xC6,
- },
- {
- .first = 0xF5,
- .last = 0xF5,
- },
- },
- },
- [AB8500_GAS_GAUGE] = {
- .num_ranges = 3,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x00,
- },
- {
- .first = 0x07,
- .last = 0x0A,
- },
- {
- .first = 0x10,
- .last = 0x14,
- },
- },
- },
- [AB8500_AUDIO] = {
- .num_ranges = 1,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x9f,
- },
- },
- },
- [AB8500_INTERRUPT] = {
- .num_ranges = 6,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x05,
- },
- {
- .first = 0x0B,
- .last = 0x0D,
- },
- {
- .first = 0x12,
- .last = 0x20,
- },
- /* Latch registers should not be read here */
- {
- .first = 0x40,
- .last = 0x45,
- },
- {
- .first = 0x4B,
- .last = 0x4D,
- },
- {
- .first = 0x52,
- .last = 0x60,
- },
- /* LatchHier registers should not be read here */
- },
- },
- [AB8500_RTC] = {
- .num_ranges = 3,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x07,
- },
- {
- .first = 0x0B,
- .last = 0x18,
- },
- {
- .first = 0x20,
- .last = 0x25,
- },
- },
- },
- [AB8500_MISC] = {
- .num_ranges = 9,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x06,
- },
- {
- .first = 0x10,
- .last = 0x16,
- },
- {
- .first = 0x20,
- .last = 0x26,
- },
- {
- .first = 0x30,
- .last = 0x36,
- },
- {
- .first = 0x40,
- .last = 0x49,
- },
- {
- .first = 0x50,
- .last = 0x50,
- },
- {
- .first = 0x60,
- .last = 0x6B,
- },
- {
- .first = 0x70,
- .last = 0x74,
- },
- {
- .first = 0x80,
- .last = 0x82,
- },
- },
- },
- [AB8500_DEVELOPMENT] = {
- .num_ranges = 3,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x01,
- },
- {
- .first = 0x06,
- .last = 0x06,
- },
- {
- .first = 0x10,
- .last = 0x21,
- },
- },
- },
- [AB8500_DEBUG] = {
- .num_ranges = 3,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x01,
- .last = 0x0C,
- },
- {
- .first = 0x0E,
- .last = 0x11,
- },
- {
- .first = 0x80,
- .last = 0x81,
- },
- },
- },
- [AB8500_PROD_TEST] = {
- .num_ranges = 0,
- .range = NULL,
- },
- [AB8500_STE_TEST] = {
- .num_ranges = 0,
- .range = NULL,
- },
- [AB8500_OTP_EMUL] = {
- .num_ranges = 1,
- .range = (struct ab8500_reg_range[]) {
- {
- .first = 0x00,
- .last = 0x3F,
- },
- },
- },
-};
-
-static irqreturn_t ab8500_debug_handler(int irq, void *data)
-{
- char buf[16];
- struct kobject *kobj = (struct kobject *)data;
- unsigned int irq_abb = irq - irq_first;
-
- if (irq_abb < num_irqs)
- irq_count[irq_abb]++;
- /*
- * This makes it possible to use poll for events (EPOLLPRI | EPOLLERR)
- * from userspace on sysfs file named <irq-nr>
- */
- sprintf(buf, "%d", irq);
- sysfs_notify(kobj, NULL, buf);
-
- return IRQ_HANDLED;
-}
-
-/* Prints to seq_file or log_buf */
-static int ab8500_registers_print(struct device *dev, u32 bank,
- struct seq_file *s)
-{
- unsigned int i;
-
- for (i = 0; i < debug_ranges[bank].num_ranges; i++) {
- u32 reg;
-
- for (reg = debug_ranges[bank].range[i].first;
- reg <= debug_ranges[bank].range[i].last;
- reg++) {
- u8 value;
- int err;
-
- err = abx500_get_register_interruptible(dev,
- (u8)bank, (u8)reg, &value);
- if (err < 0) {
- dev_err(dev, "ab->read fail %d\n", err);
- return err;
- }
-
- if (s) {
- seq_printf(s, " [0x%02X/0x%02X]: 0x%02X\n",
- bank, reg, value);
- /*
- * Error is not returned here since
- * the output is wanted in any case
- */
- if (seq_has_overflowed(s))
- return 0;
- } else {
- dev_info(dev, " [0x%02X/0x%02X]: 0x%02X\n",
- bank, reg, value);
- }
- }
- }
-
- return 0;
-}
-
-static int ab8500_bank_registers_show(struct seq_file *s, void *p)
-{
- struct device *dev = s->private;
- u32 bank = debug_bank;
-
- seq_puts(s, AB8500_NAME_STRING " register values:\n");
-
- seq_printf(s, " bank 0x%02X:\n", bank);
-
- return ab8500_registers_print(dev, bank, s);
-}
-
-DEFINE_SHOW_ATTRIBUTE(ab8500_bank_registers);
-
-static int ab8500_print_all_banks(struct seq_file *s, void *p)
-{
- struct device *dev = s->private;
- unsigned int i;
-
- seq_puts(s, AB8500_NAME_STRING " register values:\n");
-
- for (i = 0; i < AB8500_NUM_BANKS; i++) {
- int err;
-
- seq_printf(s, " bank 0x%02X:\n", i);
- err = ab8500_registers_print(dev, i, s);
- if (err)
- return err;
- }
- return 0;
-}
-
-/* Dump registers to kernel log */
-void ab8500_dump_all_banks(struct device *dev)
-{
- unsigned int i;
-
- dev_info(dev, "ab8500 register values:\n");
-
- for (i = 1; i < AB8500_NUM_BANKS; i++) {
- dev_info(dev, " bank 0x%02X:\n", i);
- ab8500_registers_print(dev, i, NULL);
- }
-}
-
-static int ab8500_all_banks_open(struct inode *inode, struct file *file)
-{
- struct seq_file *s;
- int err;
-
- err = single_open(file, ab8500_print_all_banks, inode->i_private);
- if (!err) {
- /* Default buf size in seq_read is not enough */
- s = (struct seq_file *)file->private_data;
- s->size = (PAGE_SIZE * 2);
- s->buf = kmalloc(s->size, GFP_KERNEL);
- if (!s->buf) {
- single_release(inode, file);
- err = -ENOMEM;
- }
- }
- return err;
-}
-
-static const struct file_operations ab8500_all_banks_fops = {
- .open = ab8500_all_banks_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .owner = THIS_MODULE,
-};
-
-static int ab8500_bank_print(struct seq_file *s, void *p)
-{
- seq_printf(s, "0x%02X\n", debug_bank);
- return 0;
-}
-
-static int ab8500_bank_open(struct inode *inode, struct file *file)
-{
- return single_open(file, ab8500_bank_print, inode->i_private);
-}
-
-static ssize_t ab8500_bank_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct device *dev = ((struct seq_file *)(file->private_data))->private;
- unsigned long user_bank;
- int err;
-
- err = kstrtoul_from_user(user_buf, count, 0, &user_bank);
- if (err)
- return err;
-
- if (user_bank >= AB8500_NUM_BANKS) {
- dev_err(dev, "debugfs error input > number of banks\n");
- return -EINVAL;
- }
-
- debug_bank = user_bank;
-
- return count;
-}
-
-static int ab8500_address_print(struct seq_file *s, void *p)
-{
- seq_printf(s, "0x%02X\n", debug_address);
- return 0;
-}
-
-static int ab8500_address_open(struct inode *inode, struct file *file)
-{
- return single_open(file, ab8500_address_print, inode->i_private);
-}
-
-static ssize_t ab8500_address_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct device *dev = ((struct seq_file *)(file->private_data))->private;
- unsigned long user_address;
- int err;
-
- err = kstrtoul_from_user(user_buf, count, 0, &user_address);
- if (err)
- return err;
-
- if (user_address > 0xff) {
- dev_err(dev, "debugfs error input > 0xff\n");
- return -EINVAL;
- }
- debug_address = user_address;
-
- return count;
-}
-
-static int ab8500_val_print(struct seq_file *s, void *p)
-{
- struct device *dev = s->private;
- int ret;
- u8 regvalue;
-
- ret = abx500_get_register_interruptible(dev,
- (u8)debug_bank, (u8)debug_address, &regvalue);
- if (ret < 0) {
- dev_err(dev, "abx500_get_reg fail %d, %d\n",
- ret, __LINE__);
- return -EINVAL;
- }
- seq_printf(s, "0x%02X\n", regvalue);
-
- return 0;
-}
-
-static int ab8500_val_open(struct inode *inode, struct file *file)
-{
- return single_open(file, ab8500_val_print, inode->i_private);
-}
-
-static ssize_t ab8500_val_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct device *dev = ((struct seq_file *)(file->private_data))->private;
- unsigned long user_val;
- int err;
-
- err = kstrtoul_from_user(user_buf, count, 0, &user_val);
- if (err)
- return err;
-
- if (user_val > 0xff) {
- dev_err(dev, "debugfs error input > 0xff\n");
- return -EINVAL;
- }
- err = abx500_set_register_interruptible(dev,
- (u8)debug_bank, debug_address, (u8)user_val);
- if (err < 0) {
- pr_err("abx500_set_reg failed %d, %d", err, __LINE__);
- return -EINVAL;
- }
-
- return count;
-}
-
-/*
- * Interrupt status
- */
-static u32 num_interrupts[AB8500_MAX_NR_IRQS];
-static u32 num_wake_interrupts[AB8500_MAX_NR_IRQS];
-static int num_interrupt_lines;
-
-void ab8500_debug_register_interrupt(int line)
-{
- if (line < num_interrupt_lines)
- num_interrupts[line]++;
-}
-
-static int ab8500_interrupts_show(struct seq_file *s, void *p)
-{
- int line;
-
- seq_puts(s, "name: number: irq: number of: wake:\n");
-
- for (line = 0; line < num_interrupt_lines; line++) {
- seq_printf(s, "%3i: %4i %6i %4i\n",
- line,
- line + irq_first,
- num_interrupts[line],
- num_wake_interrupts[line]);
- }
-
- return 0;
-}
-
-DEFINE_SHOW_ATTRIBUTE(ab8500_interrupts);
-
-/*
- * - HWREG DB8500 formated routines
- */
-static int ab8500_hwreg_print(struct seq_file *s, void *d)
-{
- struct device *dev = s->private;
- int ret;
- u8 regvalue;
-
- ret = abx500_get_register_interruptible(dev,
- (u8)hwreg_cfg.bank, (u8)hwreg_cfg.addr, &regvalue);
- if (ret < 0) {
- dev_err(dev, "abx500_get_reg fail %d, %d\n",
- ret, __LINE__);
- return -EINVAL;
- }
-
- if (hwreg_cfg.shift >= 0)
- regvalue >>= hwreg_cfg.shift;
- else
- regvalue <<= -hwreg_cfg.shift;
- regvalue &= hwreg_cfg.mask;
-
- if (REG_FMT_DEC(&hwreg_cfg))
- seq_printf(s, "%d\n", regvalue);
- else
- seq_printf(s, "0x%02X\n", regvalue);
- return 0;
-}
-
-static int ab8500_hwreg_open(struct inode *inode, struct file *file)
-{
- return single_open(file, ab8500_hwreg_print, inode->i_private);
-}
-
-#define AB8500_SUPPLY_CONTROL_CONFIG_1 0x01
-#define AB8500_SUPPLY_CONTROL_REG 0x00
-#define AB8500_FIRST_SIM_REG 0x80
-#define AB8500_LAST_SIM_REG 0x8B
-#define AB8505_LAST_SIM_REG 0x8C
-
-static int ab8500_modem_show(struct seq_file *s, void *p)
-{
- struct device *dev = s->private;
- struct ab8500 *ab8500;
- int err;
- u8 value;
- u8 orig_value;
- u32 bank = AB8500_REGU_CTRL2;
- u32 last_sim_reg = AB8500_LAST_SIM_REG;
- u32 reg;
-
- ab8500 = dev_get_drvdata(dev->parent);
- dev_warn(dev, "WARNING! This operation can interfer with modem side\n"
- "and should only be done with care\n");
-
- err = abx500_get_register_interruptible(dev,
- AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG, &orig_value);
- if (err < 0)
- goto report_read_failure;
-
- /* Config 1 will allow APE side to read SIM registers */
- err = abx500_set_register_interruptible(dev,
- AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG,
- AB8500_SUPPLY_CONTROL_CONFIG_1);
- if (err < 0)
- goto report_write_failure;
-
- seq_printf(s, " bank 0x%02X:\n", bank);
-
- if (is_ab9540(ab8500) || is_ab8505(ab8500))
- last_sim_reg = AB8505_LAST_SIM_REG;
-
- for (reg = AB8500_FIRST_SIM_REG; reg <= last_sim_reg; reg++) {
- err = abx500_get_register_interruptible(dev,
- bank, reg, &value);
- if (err < 0)
- goto report_read_failure;
-
- seq_printf(s, " [0x%02X/0x%02X]: 0x%02X\n", bank, reg, value);
- }
- err = abx500_set_register_interruptible(dev,
- AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG, orig_value);
- if (err < 0)
- goto report_write_failure;
-
- return 0;
-
-report_read_failure:
- dev_err(dev, "ab->read fail %d\n", err);
- return err;
-
-report_write_failure:
- dev_err(dev, "ab->write fail %d\n", err);
- return err;
-}
-
-DEFINE_SHOW_ATTRIBUTE(ab8500_modem);
-
-/*
- * return length of an ASCII numerical value, 0 is string is not a
- * numerical value.
- * string shall start at value 1st char.
- * string can be tailed with \0 or space or newline chars only.
- * value can be decimal or hexadecimal (prefixed 0x or 0X).
- */
-static int strval_len(char *b)
-{
- char *s = b;
-
- if ((*s == '0') && ((*(s+1) == 'x') || (*(s+1) == 'X'))) {
- s += 2;
- for (; *s && (*s != ' ') && (*s != '\n'); s++) {
- if (!isxdigit(*s))
- return 0;
- }
- } else {
- if (*s == '-')
- s++;
- for (; *s && (*s != ' ') && (*s != '\n'); s++) {
- if (!isdigit(*s))
- return 0;
- }
- }
- return (int) (s-b);
-}
-
-/*
- * parse hwreg input data.
- * update global hwreg_cfg only if input data syntax is ok.
- */
-static ssize_t hwreg_common_write(char *b, struct hwreg_cfg *cfg,
- struct device *dev)
-{
- uint write, val = 0;
- u8 regvalue;
- int ret;
- struct hwreg_cfg loc = {
- .bank = 0, /* default: invalid phys addr */
- .addr = 0, /* default: invalid phys addr */
- .fmt = 0, /* default: 32bit access, hex output */
- .mask = 0xFFFFFFFF, /* default: no mask */
- .shift = 0, /* default: no bit shift */
- };
-
- /* read or write ? */
- if (!strncmp(b, "read ", 5)) {
- write = 0;
- b += 5;
- } else if (!strncmp(b, "write ", 6)) {
- write = 1;
- b += 6;
- } else
- return -EINVAL;
-
- /* OPTIONS -l|-w|-b -s -m -o */
- while ((*b == ' ') || (*b == '-')) {
- if (*(b-1) != ' ') {
- b++;
- continue;
- }
- if ((!strncmp(b, "-d ", 3)) ||
- (!strncmp(b, "-dec ", 5))) {
- b += (*(b+2) == ' ') ? 3 : 5;
- loc.fmt |= (1<<0);
- } else if ((!strncmp(b, "-h ", 3)) ||
- (!strncmp(b, "-hex ", 5))) {
- b += (*(b+2) == ' ') ? 3 : 5;
- loc.fmt &= ~(1<<0);
- } else if ((!strncmp(b, "-m ", 3)) ||
- (!strncmp(b, "-mask ", 6))) {
- b += (*(b+2) == ' ') ? 3 : 6;
- if (strval_len(b) == 0)
- return -EINVAL;
- ret = kstrtoul(b, 0, &loc.mask);
- if (ret)
- return ret;
- } else if ((!strncmp(b, "-s ", 3)) ||
- (!strncmp(b, "-shift ", 7))) {
- b += (*(b+2) == ' ') ? 3 : 7;
- if (strval_len(b) == 0)
- return -EINVAL;
- ret = kstrtol(b, 0, &loc.shift);
- if (ret)
- return ret;
- } else {
- return -EINVAL;
- }
- }
- /* get arg BANK and ADDRESS */
- if (strval_len(b) == 0)
- return -EINVAL;
- ret = kstrtouint(b, 0, &loc.bank);
- if (ret)
- return ret;
- while (*b == ' ')
- b++;
- if (strval_len(b) == 0)
- return -EINVAL;
- ret = kstrtoul(b, 0, &loc.addr);
- if (ret)
- return ret;
-
- if (write) {
- while (*b == ' ')
- b++;
- if (strval_len(b) == 0)
- return -EINVAL;
- ret = kstrtouint(b, 0, &val);
- if (ret)
- return ret;
- }
-
- /* args are ok, update target cfg (mainly for read) */
- *cfg = loc;
-
-#ifdef ABB_HWREG_DEBUG
- pr_warn("HWREG request: %s, %s,\n", (write) ? "write" : "read",
- REG_FMT_DEC(cfg) ? "decimal" : "hexa");
- pr_warn(" addr=0x%08X, mask=0x%X, shift=%d" "value=0x%X\n",
- cfg->addr, cfg->mask, cfg->shift, val);
-#endif
-
- if (!write)
- return 0;
-
- ret = abx500_get_register_interruptible(dev,
- (u8)cfg->bank, (u8)cfg->addr, &regvalue);
- if (ret < 0) {
- dev_err(dev, "abx500_get_reg fail %d, %d\n",
- ret, __LINE__);
- return -EINVAL;
- }
-
- if (cfg->shift >= 0) {
- regvalue &= ~(cfg->mask << (cfg->shift));
- val = (val & cfg->mask) << (cfg->shift);
- } else {
- regvalue &= ~(cfg->mask >> (-cfg->shift));
- val = (val & cfg->mask) >> (-cfg->shift);
- }
- val = val | regvalue;
-
- ret = abx500_set_register_interruptible(dev,
- (u8)cfg->bank, (u8)cfg->addr, (u8)val);
- if (ret < 0) {
- pr_err("abx500_set_reg failed %d, %d", ret, __LINE__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static ssize_t ab8500_hwreg_write(struct file *file,
- const char __user *user_buf, size_t count, loff_t *ppos)
-{
- struct device *dev = ((struct seq_file *)(file->private_data))->private;
- char buf[128];
- int buf_size, ret;
-
- /* Get userspace string and assure termination */
- buf_size = min((int)count, (int)(sizeof(buf)-1));
- if (copy_from_user(buf, user_buf, buf_size))
- return -EFAULT;
- buf[buf_size] = 0;
-
- /* get args and process */
- ret = hwreg_common_write(buf, &hwreg_cfg, dev);
- return (ret) ? ret : buf_size;
-}
-
-/*
- * - irq subscribe/unsubscribe stuff
- */
-static int ab8500_subscribe_unsubscribe_print(struct seq_file *s, void *p)
-{
- seq_printf(s, "%d\n", irq_first);
-
- return 0;
-}
-
-static int ab8500_subscribe_unsubscribe_open(struct inode *inode,
- struct file *file)
-{
- return single_open(file, ab8500_subscribe_unsubscribe_print,
- inode->i_private);
-}
-
-/*
- * Userspace should use poll() on this file. When an event occur
- * the blocking poll will be released.
- */
-static ssize_t show_irq(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- unsigned long name;
- unsigned int irq_index;
- int err;
-
- err = kstrtoul(attr->attr.name, 0, &name);
- if (err)
- return err;
-
- irq_index = name - irq_first;
- if (irq_index >= num_irqs)
- return -EINVAL;
-
- return sprintf(buf, "%u\n", irq_count[irq_index]);
-}
-
-static ssize_t ab8500_subscribe_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct device *dev = ((struct seq_file *)(file->private_data))->private;
- unsigned long user_val;
- int err;
- unsigned int irq_index;
-
- err = kstrtoul_from_user(user_buf, count, 0, &user_val);
- if (err)
- return err;
-
- if (user_val < irq_first) {
- dev_err(dev, "debugfs error input < %d\n", irq_first);
- return -EINVAL;
- }
- if (user_val > irq_last) {
- dev_err(dev, "debugfs error input > %d\n", irq_last);
- return -EINVAL;
- }
-
- irq_index = user_val - irq_first;
- if (irq_index >= num_irqs)
- return -EINVAL;
-
- /*
- * This will create a sysfs file named <irq-nr> which userspace can
- * use to select or poll and get the AB8500 events
- */
- dev_attr[irq_index] = kmalloc(sizeof(struct device_attribute),
- GFP_KERNEL);
- if (!dev_attr[irq_index])
- return -ENOMEM;
-
- event_name[irq_index] = kasprintf(GFP_KERNEL, "%lu", user_val);
- if (!event_name[irq_index])
- return -ENOMEM;
-
- dev_attr[irq_index]->show = show_irq;
- dev_attr[irq_index]->store = NULL;
- dev_attr[irq_index]->attr.name = event_name[irq_index];
- dev_attr[irq_index]->attr.mode = S_IRUGO;
- err = sysfs_create_file(&dev->kobj, &dev_attr[irq_index]->attr);
- if (err < 0) {
- pr_info("sysfs_create_file failed %d\n", err);
- return err;
- }
-
- err = request_threaded_irq(user_val, NULL, ab8500_debug_handler,
- IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT,
- "ab8500-debug", &dev->kobj);
- if (err < 0) {
- pr_info("request_threaded_irq failed %d, %lu\n",
- err, user_val);
- sysfs_remove_file(&dev->kobj, &dev_attr[irq_index]->attr);
- return err;
- }
-
- return count;
-}
-
-static ssize_t ab8500_unsubscribe_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct device *dev = ((struct seq_file *)(file->private_data))->private;
- unsigned long user_val;
- int err;
- unsigned int irq_index;
-
- err = kstrtoul_from_user(user_buf, count, 0, &user_val);
- if (err)
- return err;
-
- if (user_val < irq_first) {
- dev_err(dev, "debugfs error input < %d\n", irq_first);
- return -EINVAL;
- }
- if (user_val > irq_last) {
- dev_err(dev, "debugfs error input > %d\n", irq_last);
- return -EINVAL;
- }
-
- irq_index = user_val - irq_first;
- if (irq_index >= num_irqs)
- return -EINVAL;
-
- /* Set irq count to 0 when unsubscribe */
- irq_count[irq_index] = 0;
-
- if (dev_attr[irq_index])
- sysfs_remove_file(&dev->kobj, &dev_attr[irq_index]->attr);
-
-
- free_irq(user_val, &dev->kobj);
- kfree(event_name[irq_index]);
- kfree(dev_attr[irq_index]);
-
- return count;
-}
-
-/*
- * - several debugfs nodes fops
- */
-
-static const struct file_operations ab8500_bank_fops = {
- .open = ab8500_bank_open,
- .write = ab8500_bank_write,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .owner = THIS_MODULE,
-};
-
-static const struct file_operations ab8500_address_fops = {
- .open = ab8500_address_open,
- .write = ab8500_address_write,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .owner = THIS_MODULE,
-};
-
-static const struct file_operations ab8500_val_fops = {
- .open = ab8500_val_open,
- .write = ab8500_val_write,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .owner = THIS_MODULE,
-};
-
-static const struct file_operations ab8500_subscribe_fops = {
- .open = ab8500_subscribe_unsubscribe_open,
- .write = ab8500_subscribe_write,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .owner = THIS_MODULE,
-};
-
-static const struct file_operations ab8500_unsubscribe_fops = {
- .open = ab8500_subscribe_unsubscribe_open,
- .write = ab8500_unsubscribe_write,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .owner = THIS_MODULE,
-};
-
-static const struct file_operations ab8500_hwreg_fops = {
- .open = ab8500_hwreg_open,
- .write = ab8500_hwreg_write,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .owner = THIS_MODULE,
-};
-
-static int ab8500_debug_probe(struct platform_device *plf)
-{
- struct dentry *ab8500_dir;
- struct ab8500 *ab8500;
- struct resource *res;
-
- debug_bank = AB8500_MISC;
- debug_address = AB8500_REV_REG & 0x00FF;
-
- ab8500 = dev_get_drvdata(plf->dev.parent);
- num_irqs = ab8500->mask_size;
-
- irq_count = devm_kcalloc(&plf->dev,
- num_irqs, sizeof(*irq_count), GFP_KERNEL);
- if (!irq_count)
- return -ENOMEM;
-
- dev_attr = devm_kcalloc(&plf->dev,
- num_irqs, sizeof(*dev_attr), GFP_KERNEL);
- if (!dev_attr)
- return -ENOMEM;
-
- event_name = devm_kcalloc(&plf->dev,
- num_irqs, sizeof(*event_name), GFP_KERNEL);
- if (!event_name)
- return -ENOMEM;
-
- res = platform_get_resource_byname(plf, 0, "IRQ_AB8500");
- if (!res) {
- dev_err(&plf->dev, "AB8500 irq not found, err %d\n", irq_first);
- return -ENXIO;
- }
- irq_ab8500 = res->start;
-
- irq_first = platform_get_irq_byname(plf, "IRQ_FIRST");
- if (irq_first < 0)
- return irq_first;
-
- irq_last = platform_get_irq_byname(plf, "IRQ_LAST");
- if (irq_last < 0)
- return irq_last;
-
- ab8500_dir = debugfs_create_dir(AB8500_NAME_STRING, NULL);
-
- debugfs_create_file("all-bank-registers", S_IRUGO, ab8500_dir,
- &plf->dev, &ab8500_bank_registers_fops);
- debugfs_create_file("all-banks", S_IRUGO, ab8500_dir,
- &plf->dev, &ab8500_all_banks_fops);
- debugfs_create_file("register-bank", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_dir, &plf->dev, &ab8500_bank_fops);
- debugfs_create_file("register-address", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_dir, &plf->dev, &ab8500_address_fops);
- debugfs_create_file("register-value", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_dir, &plf->dev, &ab8500_val_fops);
- debugfs_create_file("irq-subscribe", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_dir, &plf->dev, &ab8500_subscribe_fops);
-
- if (is_ab8500(ab8500)) {
- debug_ranges = ab8500_debug_ranges;
- num_interrupt_lines = AB8500_NR_IRQS;
- } else if (is_ab8505(ab8500)) {
- debug_ranges = ab8505_debug_ranges;
- num_interrupt_lines = AB8505_NR_IRQS;
- } else if (is_ab9540(ab8500)) {
- debug_ranges = ab8505_debug_ranges;
- num_interrupt_lines = AB9540_NR_IRQS;
- } else if (is_ab8540(ab8500)) {
- debug_ranges = ab8540_debug_ranges;
- num_interrupt_lines = AB8540_NR_IRQS;
- }
-
- debugfs_create_file("interrupts", (S_IRUGO), ab8500_dir, &plf->dev,
- &ab8500_interrupts_fops);
- debugfs_create_file("irq-unsubscribe", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_dir, &plf->dev, &ab8500_unsubscribe_fops);
- debugfs_create_file("hwreg", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_dir,
- &plf->dev, &ab8500_hwreg_fops);
- debugfs_create_file("all-modem-registers", (S_IRUGO | S_IWUSR | S_IWGRP),
- ab8500_dir, &plf->dev, &ab8500_modem_fops);
-
- return 0;
-}
-
-static struct platform_driver ab8500_debug_driver = {
- .driver = {
- .name = "ab8500-debug",
- .suppress_bind_attrs = true,
- },
- .probe = ab8500_debug_probe,
-};
-
-static int __init ab8500_debug_init(void)
-{
- return platform_driver_register(&ab8500_debug_driver);
-}
-subsys_initcall(ab8500_debug_init);
diff --git a/drivers/mfd/arizona-i2c.c b/drivers/mfd/arizona-i2c.c
index 3ed810e81f63..6d83e6b9a692 100644
--- a/drivers/mfd/arizona-i2c.c
+++ b/drivers/mfd/arizona-i2c.c
@@ -105,7 +105,7 @@ static const struct i2c_device_id arizona_i2c_id[] = {
MODULE_DEVICE_TABLE(i2c, arizona_i2c_id);
#ifdef CONFIG_OF
-const struct of_device_id arizona_i2c_of_match[] = {
+static const struct of_device_id arizona_i2c_of_match[] = {
{ .compatible = "wlf,wm5102", .data = (void *)WM5102 },
{ .compatible = "wlf,wm5110", .data = (void *)WM5110 },
{ .compatible = "wlf,wm8280", .data = (void *)WM8280 },
diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c
index 03620c8efe34..941b0267d09d 100644
--- a/drivers/mfd/arizona-spi.c
+++ b/drivers/mfd/arizona-spi.c
@@ -43,31 +43,13 @@ static const struct gpiod_lookup arizona_soc_gpios[] = {
{ "arizona", 4, "wlf,micd-pol", 0, GPIO_ACTIVE_LOW },
};
-/*
- * The AOSP 3.5 mm Headset: Accessory Specification gives the following values:
- * Function A Play/Pause: 0 ohm
- * Function D Voice assistant: 135 ohm
- * Function B Volume Up 240 ohm
- * Function C Volume Down 470 ohm
- * Minimum Mic DC resistance 1000 ohm
- * Minimum Ear speaker impedance 16 ohm
- * Note the first max value below must be less then the min. speaker impedance,
- * to allow CTIA/OMTP detection to work. The other max values are the closest
- * value from extcon-arizona.c:arizona_micd_levels halfway 2 button resistances.
- */
-static const struct arizona_micd_range arizona_micd_aosp_ranges[] = {
- { .max = 11, .key = KEY_PLAYPAUSE },
- { .max = 186, .key = KEY_VOICECOMMAND },
- { .max = 348, .key = KEY_VOLUMEUP },
- { .max = 752, .key = KEY_VOLUMEDOWN },
-};
-
static void arizona_spi_acpi_remove_lookup(void *lookup)
{
gpiod_remove_lookup_table(lookup);
}
-static int arizona_spi_acpi_probe(struct arizona *arizona)
+/* For ACPI tables from boards which ship with Windows as factory OS */
+static int arizona_spi_acpi_windows_probe(struct arizona *arizona)
{
struct gpiod_lookup_table *lookup;
acpi_status status;
@@ -96,6 +78,65 @@ static int arizona_spi_acpi_probe(struct arizona *arizona)
if (ACPI_FAILURE(status))
dev_warn(arizona->dev, "Failed to enable 32KHz clk ACPI error %d\n", status);
+ return 0;
+}
+
+/* For ACPI tables from boards which ship with Android as factory OS */
+static int arizona_spi_acpi_android_probe(struct arizona *arizona)
+{
+ int ret;
+
+ /*
+ * Get the reset GPIO, treating -ENOENT as -EPROBE_DEFER to wait for
+ * the x86-android-tablets module to register the board specific GPIO
+ * lookup table.
+ */
+ arizona->pdata.reset = devm_gpiod_get(arizona->dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(arizona->pdata.reset)) {
+ ret = PTR_ERR(arizona->pdata.reset);
+ if (ret == -ENOENT) {
+ dev_info_once(arizona->dev,
+ "Deferring probe till GPIO lookup is registered\n");
+ ret = -EPROBE_DEFER;
+ }
+ return dev_err_probe(arizona->dev, ret, "getting reset GPIO\n");
+ }
+
+ return 0;
+}
+
+/*
+ * The AOSP 3.5 mm Headset: Accessory Specification gives the following values:
+ * Function A Play/Pause: 0 ohm
+ * Function D Voice assistant: 135 ohm
+ * Function B Volume Up 240 ohm
+ * Function C Volume Down 470 ohm
+ * Minimum Mic DC resistance 1000 ohm
+ * Minimum Ear speaker impedance 16 ohm
+ * Note the first max value below must be less then the min. speaker impedance,
+ * to allow CTIA/OMTP detection to work. The other max values are the closest
+ * value from extcon-arizona.c:arizona_micd_levels halfway 2 button resistances.
+ */
+static const struct arizona_micd_range arizona_micd_aosp_ranges[] = {
+ { .max = 11, .key = KEY_PLAYPAUSE },
+ { .max = 186, .key = KEY_VOICECOMMAND },
+ { .max = 348, .key = KEY_VOLUMEUP },
+ { .max = 752, .key = KEY_VOLUMEDOWN },
+};
+
+static int arizona_spi_acpi_probe(struct arizona *arizona)
+{
+ struct acpi_device *adev = ACPI_COMPANION(arizona->dev);
+ int ret;
+
+ if (acpi_dev_hid_uid_match(adev, "10WM5102", NULL))
+ ret = arizona_spi_acpi_android_probe(arizona);
+ else
+ ret = arizona_spi_acpi_windows_probe(arizona);
+
+ if (ret)
+ return ret;
+
/*
* Some DSDTs wrongly declare the IRQ trigger-type as IRQF_TRIGGER_FALLING
* The IRQ line will stay low when a new IRQ event happens between reading
@@ -130,6 +171,10 @@ static const struct acpi_device_id arizona_acpi_match[] = {
.id = "WM510205",
.driver_data = WM5102,
},
+ {
+ .id = "10WM5102",
+ .driver_data = WM5102,
+ },
{ }
};
MODULE_DEVICE_TABLE(acpi, arizona_acpi_match);
@@ -224,7 +269,7 @@ static const struct spi_device_id arizona_spi_ids[] = {
MODULE_DEVICE_TABLE(spi, arizona_spi_ids);
#ifdef CONFIG_OF
-const struct of_device_id arizona_spi_of_match[] = {
+static const struct of_device_id arizona_spi_of_match[] = {
{ .compatible = "wlf,wm5102", .data = (void *)WM5102 },
{ .compatible = "wlf,wm5110", .data = (void *)WM5110 },
{ .compatible = "wlf,wm8280", .data = (void *)WM8280 },
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c
index 8d58c8df46cf..56338f9dbd0b 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -906,14 +906,14 @@ static int __init asic3_mfd_probe(struct platform_device *pdev,
ret = mfd_add_devices(&pdev->dev, pdev->id,
&asic3_cell_ds1wm, 1, mem, asic->irq_base, NULL);
if (ret < 0)
- goto out;
+ goto out_unmap;
}
if (mem_sdio && (irq >= 0)) {
ret = mfd_add_devices(&pdev->dev, pdev->id,
&asic3_cell_mmc, 1, mem_sdio, irq, NULL);
if (ret < 0)
- goto out;
+ goto out_unmap;
}
ret = 0;
@@ -927,8 +927,12 @@ static int __init asic3_mfd_probe(struct platform_device *pdev,
ret = mfd_add_devices(&pdev->dev, 0,
asic3_cell_leds, ASIC3_NUM_LEDS, NULL, 0, NULL);
}
+ return ret;
- out:
+out_unmap:
+ if (asic->tmio_cnf)
+ iounmap(asic->tmio_cnf);
+out:
return ret;
}
diff --git a/drivers/mfd/atmel-flexcom.c b/drivers/mfd/atmel-flexcom.c
index 559eb4d352b6..33caa4fba6af 100644
--- a/drivers/mfd/atmel-flexcom.c
+++ b/drivers/mfd/atmel-flexcom.c
@@ -105,7 +105,7 @@ static int __maybe_unused atmel_flexcom_resume_noirq(struct device *dev)
return 0;
}
-static const struct dev_pm_ops atmel_flexcom_pm_ops = {
+static const struct dev_pm_ops __maybe_unused atmel_flexcom_pm_ops = {
.resume_noirq = atmel_flexcom_resume_noirq,
};
diff --git a/drivers/mfd/exynos-lpass.c b/drivers/mfd/exynos-lpass.c
index 99bd0e73c19c..166cd21088cd 100644
--- a/drivers/mfd/exynos-lpass.c
+++ b/drivers/mfd/exynos-lpass.c
@@ -15,7 +15,6 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
-#include <linux/mfd/syscon.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
diff --git a/drivers/mfd/intel-lpss-acpi.c b/drivers/mfd/intel-lpss-acpi.c
index f2ea6540a01e..a143c8dca2d9 100644
--- a/drivers/mfd/intel-lpss-acpi.c
+++ b/drivers/mfd/intel-lpss-acpi.c
@@ -15,11 +15,22 @@
#include <linux/pm_runtime.h>
#include <linux/platform_device.h>
#include <linux/property.h>
+#include <linux/pxa2xx_ssp.h>
#include "intel-lpss.h"
+static const struct property_entry spt_spi_properties[] = {
+ PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_SPT_SSP),
+ { }
+};
+
+static const struct software_node spt_spi_node = {
+ .properties = spt_spi_properties,
+};
+
static const struct intel_lpss_platform_info spt_info = {
.clk_rate = 120000000,
+ .swnode = &spt_spi_node,
};
static const struct property_entry spt_i2c_properties[] = {
@@ -53,8 +64,18 @@ static const struct intel_lpss_platform_info spt_uart_info = {
.swnode = &uart_node,
};
+static const struct property_entry bxt_spi_properties[] = {
+ PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_BXT_SSP),
+ { }
+};
+
+static const struct software_node bxt_spi_node = {
+ .properties = bxt_spi_properties,
+};
+
static const struct intel_lpss_platform_info bxt_info = {
.clk_rate = 100000000,
+ .swnode = &bxt_spi_node,
};
static const struct property_entry bxt_i2c_properties[] = {
@@ -89,6 +110,20 @@ static const struct intel_lpss_platform_info apl_i2c_info = {
.swnode = &apl_i2c_node,
};
+static const struct property_entry cnl_spi_properties[] = {
+ PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_CNL_SSP),
+ { }
+};
+
+static const struct software_node cnl_spi_node = {
+ .properties = cnl_spi_properties,
+};
+
+static const struct intel_lpss_platform_info cnl_info = {
+ .clk_rate = 120000000,
+ .swnode = &cnl_spi_node,
+};
+
static const struct intel_lpss_platform_info cnl_i2c_info = {
.clk_rate = 216000000,
.swnode = &spt_i2c_node,
@@ -108,8 +143,8 @@ static const struct acpi_device_id intel_lpss_acpi_ids[] = {
{ "INT3449", (kernel_ulong_t)&spt_uart_info },
{ "INT344A", (kernel_ulong_t)&spt_uart_info },
/* CNL */
- { "INT34B0", (kernel_ulong_t)&spt_info },
- { "INT34B1", (kernel_ulong_t)&spt_info },
+ { "INT34B0", (kernel_ulong_t)&cnl_info },
+ { "INT34B1", (kernel_ulong_t)&cnl_info },
{ "INT34B2", (kernel_ulong_t)&cnl_i2c_info },
{ "INT34B3", (kernel_ulong_t)&cnl_i2c_info },
{ "INT34B4", (kernel_ulong_t)&cnl_i2c_info },
@@ -119,7 +154,7 @@ static const struct acpi_device_id intel_lpss_acpi_ids[] = {
{ "INT34B8", (kernel_ulong_t)&spt_uart_info },
{ "INT34B9", (kernel_ulong_t)&spt_uart_info },
{ "INT34BA", (kernel_ulong_t)&spt_uart_info },
- { "INT34BC", (kernel_ulong_t)&spt_info },
+ { "INT34BC", (kernel_ulong_t)&cnl_info },
/* BXT */
{ "80860AAC", (kernel_ulong_t)&bxt_i2c_info },
{ "80860ABC", (kernel_ulong_t)&bxt_info },
diff --git a/drivers/mfd/intel-lpss-pci.c b/drivers/mfd/intel-lpss-pci.c
index 5513fae6be92..962ee14c62dd 100644
--- a/drivers/mfd/intel-lpss-pci.c
+++ b/drivers/mfd/intel-lpss-pci.c
@@ -353,6 +353,21 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
{ PCI_VDEVICE(INTEL, 0x5ac4), (kernel_ulong_t)&bxt_info },
{ PCI_VDEVICE(INTEL, 0x5ac6), (kernel_ulong_t)&bxt_info },
{ PCI_VDEVICE(INTEL, 0x5aee), (kernel_ulong_t)&bxt_uart_info },
+ /* RPL-S */
+ { PCI_VDEVICE(INTEL, 0x7a28), (kernel_ulong_t)&bxt_uart_info },
+ { PCI_VDEVICE(INTEL, 0x7a29), (kernel_ulong_t)&bxt_uart_info },
+ { PCI_VDEVICE(INTEL, 0x7a2a), (kernel_ulong_t)&bxt_info },
+ { PCI_VDEVICE(INTEL, 0x7a2b), (kernel_ulong_t)&bxt_info },
+ { PCI_VDEVICE(INTEL, 0x7a4c), (kernel_ulong_t)&bxt_i2c_info },
+ { PCI_VDEVICE(INTEL, 0x7a4d), (kernel_ulong_t)&bxt_i2c_info },
+ { PCI_VDEVICE(INTEL, 0x7a4e), (kernel_ulong_t)&bxt_i2c_info },
+ { PCI_VDEVICE(INTEL, 0x7a4f), (kernel_ulong_t)&bxt_i2c_info },
+ { PCI_VDEVICE(INTEL, 0x7a5c), (kernel_ulong_t)&bxt_uart_info },
+ { PCI_VDEVICE(INTEL, 0x7a79), (kernel_ulong_t)&bxt_info },
+ { PCI_VDEVICE(INTEL, 0x7a7b), (kernel_ulong_t)&bxt_info },
+ { PCI_VDEVICE(INTEL, 0x7a7c), (kernel_ulong_t)&bxt_i2c_info },
+ { PCI_VDEVICE(INTEL, 0x7a7d), (kernel_ulong_t)&bxt_i2c_info },
+ { PCI_VDEVICE(INTEL, 0x7a7e), (kernel_ulong_t)&bxt_uart_info },
/* ADL-S */
{ PCI_VDEVICE(INTEL, 0x7aa8), (kernel_ulong_t)&bxt_uart_info },
{ PCI_VDEVICE(INTEL, 0x7aa9), (kernel_ulong_t)&bxt_uart_info },
diff --git a/drivers/mfd/intel_soc_pmic_core.c b/drivers/mfd/intel_soc_pmic_core.c
index 47cb7f00dfcf..5e8c94e008ed 100644
--- a/drivers/mfd/intel_soc_pmic_core.c
+++ b/drivers/mfd/intel_soc_pmic_core.c
@@ -64,6 +64,10 @@ static int intel_soc_pmic_i2c_probe(struct i2c_client *i2c,
/* Add lookup table for crc-pwm */
pwm_add_table(crc_pwm_lookup, ARRAY_SIZE(crc_pwm_lookup));
+ /* To distuingish this domain from the GPIO/charger's irqchip domains */
+ irq_domain_update_bus_token(regmap_irq_get_domain(pmic->irq_chip_data),
+ DOMAIN_BUS_NEXUS);
+
ret = mfd_add_devices(dev, -1, config->cell_dev,
config->n_cell_devs, NULL, 0,
regmap_irq_get_domain(pmic->irq_chip_data));
diff --git a/drivers/mfd/intel_soc_pmic_crc.c b/drivers/mfd/intel_soc_pmic_crc.c
index 38acb20e2d60..5bb0367bd974 100644
--- a/drivers/mfd/intel_soc_pmic_crc.c
+++ b/drivers/mfd/intel_soc_pmic_crc.c
@@ -28,18 +28,10 @@
#define CRYSTAL_COVE_IRQ_GPIO 5
#define CRYSTAL_COVE_IRQ_VHDMIOCP 6
-static const struct resource gpio_resources[] = {
- DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_GPIO, "GPIO"),
-};
-
static const struct resource pwrsrc_resources[] = {
DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_PWRSRC, "PWRSRC"),
};
-static const struct resource adc_resources[] = {
- DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_ADC, "ADC"),
-};
-
static const struct resource thermal_resources[] = {
DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_THRM, "THERMAL"),
};
@@ -48,6 +40,18 @@ static const struct resource bcu_resources[] = {
DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_BCU, "BCU"),
};
+static const struct resource adc_resources[] = {
+ DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_ADC, "ADC"),
+};
+
+static const struct resource charger_resources[] = {
+ DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_CHGR, "CHGR"),
+};
+
+static const struct resource gpio_resources[] = {
+ DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_GPIO, "GPIO"),
+};
+
static struct mfd_cell crystal_cove_byt_dev[] = {
{
.name = "crystal_cove_pwrsrc",
@@ -55,11 +59,6 @@ static struct mfd_cell crystal_cove_byt_dev[] = {
.resources = pwrsrc_resources,
},
{
- .name = "crystal_cove_adc",
- .num_resources = ARRAY_SIZE(adc_resources),
- .resources = adc_resources,
- },
- {
.name = "crystal_cove_thermal",
.num_resources = ARRAY_SIZE(thermal_resources),
.resources = thermal_resources,
@@ -70,6 +69,16 @@ static struct mfd_cell crystal_cove_byt_dev[] = {
.resources = bcu_resources,
},
{
+ .name = "crystal_cove_adc",
+ .num_resources = ARRAY_SIZE(adc_resources),
+ .resources = adc_resources,
+ },
+ {
+ .name = "crystal_cove_charger",
+ .num_resources = ARRAY_SIZE(charger_resources),
+ .resources = charger_resources,
+ },
+ {
.name = "crystal_cove_gpio",
.num_resources = ARRAY_SIZE(gpio_resources),
.resources = gpio_resources,
diff --git a/drivers/mfd/iqs62x.c b/drivers/mfd/iqs62x.c
index 9805cf191245..575ab67e243d 100644
--- a/drivers/mfd/iqs62x.c
+++ b/drivers/mfd/iqs62x.c
@@ -898,7 +898,6 @@ static int iqs62x_probe(struct i2c_client *client)
struct iqs62x_info info;
unsigned int val;
int ret, i, j;
- u8 sw_num = 0;
const char *fw_name = NULL;
iqs62x = devm_kzalloc(&client->dev, sizeof(*iqs62x), GFP_KERNEL);
@@ -949,7 +948,8 @@ static int iqs62x_probe(struct i2c_client *client)
if (info.sw_num < iqs62x->dev_desc->sw_num)
continue;
- sw_num = info.sw_num;
+ iqs62x->sw_num = info.sw_num;
+ iqs62x->hw_num = info.hw_num;
/*
* Read each of the device's designated calibration registers,
@@ -985,7 +985,7 @@ static int iqs62x_probe(struct i2c_client *client)
return -EINVAL;
}
- if (!sw_num) {
+ if (!iqs62x->sw_num) {
dev_err(&client->dev, "Unrecognized software number: 0x%02X\n",
info.sw_num);
return -EINVAL;
diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c
index f9e12ab2bc75..2ac64277fb84 100644
--- a/drivers/mfd/max77686.c
+++ b/drivers/mfd/max77686.c
@@ -87,7 +87,7 @@ static bool max77802_rtc_is_volatile_reg(struct device *dev, unsigned int reg)
reg == MAX77802_RTC_WEEKDAY ||
reg == MAX77802_RTC_MONTH ||
reg == MAX77802_RTC_YEAR ||
- reg == MAX77802_RTC_DATE);
+ reg == MAX77802_RTC_MONTHDAY);
}
static bool max77802_is_volatile_reg(struct device *dev, unsigned int reg)
diff --git a/drivers/mfd/max77714.c b/drivers/mfd/max77714.c
new file mode 100644
index 000000000000..d1e4247800d2
--- /dev/null
+++ b/drivers/mfd/max77714.c
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Maxim MAX77714 Core Driver
+ *
+ * Copyright (C) 2022 Luca Ceresoli
+ * Author: Luca Ceresoli <luca@lucaceresoli.net>
+ */
+
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/max77714.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+
+static const struct mfd_cell max77714_cells[] = {
+ { .name = "max77714-watchdog" },
+ { .name = "max77714-rtc" },
+};
+
+static const struct regmap_range max77714_readable_ranges[] = {
+ regmap_reg_range(MAX77714_INT_TOP, MAX77714_INT_TOP),
+ regmap_reg_range(MAX77714_INT_TOPM, MAX77714_INT_TOPM),
+ regmap_reg_range(MAX77714_32K_STATUS, MAX77714_32K_CONFIG),
+ regmap_reg_range(MAX77714_CNFG_GLBL2, MAX77714_CNFG2_ONOFF),
+};
+
+static const struct regmap_range max77714_writable_ranges[] = {
+ regmap_reg_range(MAX77714_INT_TOPM, MAX77714_INT_TOPM),
+ regmap_reg_range(MAX77714_32K_CONFIG, MAX77714_32K_CONFIG),
+ regmap_reg_range(MAX77714_CNFG_GLBL2, MAX77714_CNFG2_ONOFF),
+};
+
+static const struct regmap_access_table max77714_readable_table = {
+ .yes_ranges = max77714_readable_ranges,
+ .n_yes_ranges = ARRAY_SIZE(max77714_readable_ranges),
+};
+
+static const struct regmap_access_table max77714_writable_table = {
+ .yes_ranges = max77714_writable_ranges,
+ .n_yes_ranges = ARRAY_SIZE(max77714_writable_ranges),
+};
+
+static const struct regmap_config max77714_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = MAX77714_CNFG2_ONOFF,
+ .rd_table = &max77714_readable_table,
+ .wr_table = &max77714_writable_table,
+};
+
+static const struct regmap_irq max77714_top_irqs[] = {
+ REGMAP_IRQ_REG(MAX77714_IRQ_TOP_ONOFF, 0, MAX77714_INT_TOP_ONOFF),
+ REGMAP_IRQ_REG(MAX77714_IRQ_TOP_RTC, 0, MAX77714_INT_TOP_RTC),
+ REGMAP_IRQ_REG(MAX77714_IRQ_TOP_GPIO, 0, MAX77714_INT_TOP_GPIO),
+ REGMAP_IRQ_REG(MAX77714_IRQ_TOP_LDO, 0, MAX77714_INT_TOP_LDO),
+ REGMAP_IRQ_REG(MAX77714_IRQ_TOP_SD, 0, MAX77714_INT_TOP_SD),
+ REGMAP_IRQ_REG(MAX77714_IRQ_TOP_GLBL, 0, MAX77714_INT_TOP_GLBL),
+};
+
+static const struct regmap_irq_chip max77714_irq_chip = {
+ .name = "max77714-pmic",
+ .status_base = MAX77714_INT_TOP,
+ .mask_base = MAX77714_INT_TOPM,
+ .num_regs = 1,
+ .irqs = max77714_top_irqs,
+ .num_irqs = ARRAY_SIZE(max77714_top_irqs),
+};
+
+/*
+ * MAX77714 initially uses the internal, low precision oscillator. Enable
+ * the external oscillator by setting the XOSC_RETRY bit. If the external
+ * oscillator is not OK (probably not installed) this has no effect.
+ */
+static int max77714_setup_xosc(struct device *dev, struct regmap *regmap)
+{
+ /* Internal Crystal Load Capacitance, indexed by value of 32KLOAD bits */
+ static const unsigned int load_cap[4] = {0, 10, 12, 22}; /* pF */
+ unsigned int load_cap_idx;
+ unsigned int status;
+ int err;
+
+ err = regmap_update_bits(regmap, MAX77714_32K_CONFIG,
+ MAX77714_32K_CONFIG_XOSC_RETRY,
+ MAX77714_32K_CONFIG_XOSC_RETRY);
+ if (err)
+ return dev_err_probe(dev, err, "Failed to configure the external oscillator\n");
+
+ err = regmap_read(regmap, MAX77714_32K_STATUS, &status);
+ if (err)
+ return dev_err_probe(dev, err, "Failed to read external oscillator status\n");
+
+ load_cap_idx = (status >> MAX77714_32K_STATUS_32KLOAD_SHF)
+ & MAX77714_32K_STATUS_32KLOAD_MSK;
+
+ dev_info(dev, "Using %s oscillator, %d pF load cap\n",
+ status & MAX77714_32K_STATUS_32KSOURCE ? "internal" : "external",
+ load_cap[load_cap_idx]);
+
+ return 0;
+}
+
+static int max77714_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct regmap *regmap;
+ struct regmap_irq_chip_data *irq_data;
+ int err;
+
+ regmap = devm_regmap_init_i2c(client, &max77714_regmap_config);
+ if (IS_ERR(regmap))
+ return dev_err_probe(dev, PTR_ERR(regmap),
+ "Failed to initialise regmap\n");
+
+ err = max77714_setup_xosc(dev, regmap);
+ if (err)
+ return err;
+
+ err = devm_regmap_add_irq_chip(dev, regmap, client->irq,
+ IRQF_ONESHOT | IRQF_SHARED, 0,
+ &max77714_irq_chip, &irq_data);
+ if (err)
+ return dev_err_probe(dev, err, "Failed to add PMIC IRQ chip\n");
+
+ err = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
+ max77714_cells, ARRAY_SIZE(max77714_cells),
+ NULL, 0, NULL);
+ if (err)
+ return dev_err_probe(dev, err, "Failed to register child devices\n");
+
+ return 0;
+}
+
+static const struct of_device_id max77714_dt_match[] = {
+ { .compatible = "maxim,max77714" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, max77714_dt_match);
+
+static struct i2c_driver max77714_driver = {
+ .driver = {
+ .name = "max77714",
+ .of_match_table = max77714_dt_match,
+ },
+ .probe_new = max77714_probe,
+};
+module_i2c_driver(max77714_driver);
+
+MODULE_DESCRIPTION("Maxim MAX77714 MFD core driver");
+MODULE_AUTHOR("Luca Ceresoli <luca@lucaceresoli.net>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c
index 8a4f1d90dcfd..1000572761a8 100644
--- a/drivers/mfd/mc13xxx-core.c
+++ b/drivers/mfd/mc13xxx-core.c
@@ -323,8 +323,10 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode,
adc1 |= MC13783_ADC1_ATOX;
dev_dbg(mc13xxx->dev, "%s: request irq\n", __func__);
- mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE,
+ ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE,
mc13xxx_handler_adcdone, __func__, &adcdone_data);
+ if (ret)
+ goto out;
mc13xxx_reg_write(mc13xxx, MC13XXX_ADC0, adc0);
mc13xxx_reg_write(mc13xxx, MC13XXX_ADC1, adc1);
diff --git a/drivers/mfd/mt6358-irq.c b/drivers/mfd/mt6358-irq.c
index 83f3ffbdbb4c..ea5e452510eb 100644
--- a/drivers/mfd/mt6358-irq.c
+++ b/drivers/mfd/mt6358-irq.c
@@ -212,6 +212,7 @@ int mt6358_irq_init(struct mt6397_chip *chip)
switch (chip->chip_id) {
case MT6358_CHIP_ID:
+ case MT6366_CHIP_ID:
chip->irq_data = &mt6358_irqd;
break;
diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
index b181fe401330..4142b638e5fa 100644
--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk808.c
@@ -19,6 +19,7 @@
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
+#include <linux/reboot.h>
struct rk808_reg_data {
int addr;
@@ -543,6 +544,7 @@ static void rk808_pm_power_off(void)
reg = RK808_DEVCTRL_REG,
bit = DEV_OFF_RST;
break;
+ case RK809_ID:
case RK817_ID:
reg = RK817_SYS_CFG(3);
bit = DEV_OFF;
@@ -559,6 +561,34 @@ static void rk808_pm_power_off(void)
dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n");
}
+static int rk808_restart_notify(struct notifier_block *this, unsigned long mode, void *cmd)
+{
+ struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
+ unsigned int reg, bit;
+ int ret;
+
+ switch (rk808->variant) {
+ case RK809_ID:
+ case RK817_ID:
+ reg = RK817_SYS_CFG(3);
+ bit = DEV_RST;
+ break;
+
+ default:
+ return NOTIFY_DONE;
+ }
+ ret = regmap_update_bits(rk808->regmap, reg, bit, bit);
+ if (ret)
+ dev_err(&rk808_i2c_client->dev, "Failed to restart device!\n");
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block rk808_restart_handler = {
+ .notifier_call = rk808_restart_notify,
+ .priority = 192,
+};
+
static void rk8xx_shutdown(struct i2c_client *client)
{
struct rk808 *rk808 = i2c_get_clientdata(client);
@@ -727,6 +757,18 @@ static int rk808_probe(struct i2c_client *client,
if (of_property_read_bool(np, "rockchip,system-power-controller")) {
rk808_i2c_client = client;
pm_power_off = rk808_pm_power_off;
+
+ switch (rk808->variant) {
+ case RK809_ID:
+ case RK817_ID:
+ ret = register_restart_handler(&rk808_restart_handler);
+ if (ret)
+ dev_warn(&client->dev, "failed to register rst handler, %d\n", ret);
+ break;
+ default:
+ dev_dbg(&client->dev, "pmic controlled board reset not supported\n");
+ break;
+ }
}
return 0;
@@ -749,6 +791,8 @@ static int rk808_remove(struct i2c_client *client)
if (pm_power_off == rk808_pm_power_off)
pm_power_off = NULL;
+ unregister_restart_handler(&rk808_restart_handler);
+
return 0;
}
diff --git a/drivers/mfd/rohm-bd9576.c b/drivers/mfd/rohm-bd9576.c
index 6661a27d69a8..f37cd4f27aeb 100644
--- a/drivers/mfd/rohm-bd9576.c
+++ b/drivers/mfd/rohm-bd9576.c
@@ -23,7 +23,7 @@ enum {
};
/*
- * Due to the BD9576MUF nasty IRQ behaiour we don't always populate IRQs.
+ * Due to the BD9576MUF nasty IRQ behaviour we don't always populate IRQs.
* These will be added to regulator resources only if IRQ information for the
* PMIC is populated in device-tree.
*/
diff --git a/drivers/mfd/simple-mfd-i2c.c b/drivers/mfd/simple-mfd-i2c.c
index 51536691ad9d..f4c8fc3ee463 100644
--- a/drivers/mfd/simple-mfd-i2c.c
+++ b/drivers/mfd/simple-mfd-i2c.c
@@ -62,8 +62,19 @@ static int simple_mfd_i2c_probe(struct i2c_client *i2c)
return ret;
}
+static const struct mfd_cell sy7636a_cells[] = {
+ { .name = "sy7636a-regulator", },
+ { .name = "sy7636a-temperature", },
+};
+
+static const struct simple_mfd_data silergy_sy7636a = {
+ .mfd_cell = sy7636a_cells,
+ .mfd_cell_size = ARRAY_SIZE(sy7636a_cells),
+};
+
static const struct of_device_id simple_mfd_i2c_of_match[] = {
{ .compatible = "kontron,sl28cpld" },
+ { .compatible = "silergy,sy7636a", .data = &silergy_sy7636a},
{}
};
MODULE_DEVICE_TABLE(of, simple_mfd_i2c_of_match);
diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c
index 1819c8fe4d8f..02cc49daf2e3 100644
--- a/drivers/mfd/sta2x11-mfd.c
+++ b/drivers/mfd/sta2x11-mfd.c
@@ -590,7 +590,7 @@ static int sta2x11_mfd_probe(struct pci_dev *pdev,
/* Record this pdev before mfd_add_devices: their probe looks for it */
if (!sta2x11_mfd_find(pdev))
- sta2x11_mfd_add(pdev, GFP_ATOMIC);
+ sta2x11_mfd_add(pdev, GFP_KERNEL);
/* Just 2 bars for all mfd's at present */
for (i = 0; i < 2; i++) {
diff --git a/drivers/mfd/stmfx.c b/drivers/mfd/stmfx.c
index e095a3930142..122f96094410 100644
--- a/drivers/mfd/stmfx.c
+++ b/drivers/mfd/stmfx.c
@@ -392,17 +392,22 @@ err:
return ret;
}
-static int stmfx_chip_exit(struct i2c_client *client)
+static void stmfx_chip_exit(struct i2c_client *client)
{
struct stmfx *stmfx = i2c_get_clientdata(client);
regmap_write(stmfx->map, STMFX_REG_IRQ_SRC_EN, 0);
regmap_write(stmfx->map, STMFX_REG_SYS_CTRL, 0);
- if (stmfx->vdd)
- return regulator_disable(stmfx->vdd);
+ if (stmfx->vdd) {
+ int ret;
- return 0;
+ ret = regulator_disable(stmfx->vdd);
+ if (ret)
+ dev_err(&client->dev,
+ "Failed to disable vdd regulator: %pe\n",
+ ERR_PTR(ret));
+ }
}
static int stmfx_probe(struct i2c_client *client,
@@ -466,7 +471,9 @@ static int stmfx_remove(struct i2c_client *client)
{
stmfx_irq_exit(client);
- return stmfx_chip_exit(client);
+ stmfx_chip_exit(client);
+
+ return 0;
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index c8ce6e5eea24..5ef2306fce04 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1219,7 +1219,6 @@ config REGULATOR_STW481X_VMMC
config REGULATOR_SY7636A
tristate "Silergy SY7636A voltage regulator"
- depends on MFD_SY7636A
help
This driver supports Silergy SY3686A voltage regulator.
diff --git a/drivers/regulator/sy7636a-regulator.c b/drivers/regulator/sy7636a-regulator.c
index 22fddf868e4c..29fc27c2cda0 100644
--- a/drivers/regulator/sy7636a-regulator.c
+++ b/drivers/regulator/sy7636a-regulator.c
@@ -7,11 +7,14 @@
// Authors: Lars Ivar Miljeteig <lars.ivar.miljeteig@remarkable.com>
// Alistair Francis <alistair@alistair23.me>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/mfd/sy7636a.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
#include <linux/regmap.h>
-#include <linux/gpio/consumer.h>
-#include <linux/mfd/sy7636a.h>
struct sy7636a_data {
struct regmap *regmap;
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index d85a3c31347c..f6d6d4c26361 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -375,7 +375,7 @@ config RTC_DRV_MAX8997
config RTC_DRV_MAX77686
tristate "Maxim MAX77686"
- depends on MFD_MAX77686 || MFD_MAX77620 || COMPILE_TEST
+ depends on MFD_MAX77686 || MFD_MAX77620 || MFD_MAX77714 || COMPILE_TEST
help
If you say yes here you will get support for the
RTC of Maxim MAX77686/MAX77620/MAX77802 PMIC.
diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c
index eae7cb9faf1e..b0250d91fb00 100644
--- a/drivers/rtc/rtc-max77686.c
+++ b/drivers/rtc/rtc-max77686.c
@@ -19,6 +19,7 @@
#define MAX77686_I2C_ADDR_RTC (0x0C >> 1)
#define MAX77620_I2C_ADDR_RTC 0x68
+#define MAX77714_I2C_ADDR_RTC 0x48
#define MAX77686_INVALID_I2C_ADDR (-1)
/* Define non existing register */
@@ -34,9 +35,6 @@
#define RTC_UDR_MASK BIT(RTC_UDR_SHIFT)
#define RTC_RBUDR_SHIFT 4
#define RTC_RBUDR_MASK BIT(RTC_RBUDR_SHIFT)
-/* RTC Hour register */
-#define HOUR_PM_SHIFT 6
-#define HOUR_PM_MASK BIT(HOUR_PM_SHIFT)
/* RTC Alarm Enable */
#define ALARM_ENABLE_SHIFT 7
#define ALARM_ENABLE_MASK BIT(ALARM_ENABLE_SHIFT)
@@ -57,28 +55,31 @@ enum {
RTC_WEEKDAY,
RTC_MONTH,
RTC_YEAR,
- RTC_DATE,
+ RTC_MONTHDAY,
RTC_NR_TIME
};
+/**
+ * struct max77686_rtc_driver_data - model-specific configuration
+ * @delay: Minimum usecs needed for a RTC update
+ * @mask: Mask used to read RTC registers value
+ * @map: Registers offset to I2C addresses map
+ * @alarm_enable_reg: Has a separate alarm enable register?
+ * @rtc_i2c_addr: I2C address for RTC block
+ * @rtc_irq_from_platform: RTC interrupt via platform resource
+ * @alarm_pending_status_reg: Pending alarm status register
+ * @rtc_irq_chip: RTC IRQ CHIP for regmap
+ * @regmap_config: regmap configuration for the chip
+ */
struct max77686_rtc_driver_data {
- /* Minimum usecs needed for a RTC update */
unsigned long delay;
- /* Mask used to read RTC registers value */
u8 mask;
- /* Registers offset to I2C addresses map */
const unsigned int *map;
- /* Has a separate alarm enable register? */
bool alarm_enable_reg;
- /* I2C address for RTC block */
int rtc_i2c_addr;
- /* RTC interrupt via platform resource */
bool rtc_irq_from_platform;
- /* Pending alarm status register */
int alarm_pending_status_reg;
- /* RTC IRQ CHIP for regmap */
const struct regmap_irq_chip *rtc_irq_chip;
- /* regmap configuration for the chip */
const struct regmap_config *regmap_config;
};
@@ -96,7 +97,6 @@ struct max77686_rtc_info {
int rtc_irq;
int virq;
- int rtc_24hr_mode;
};
enum MAX77686_RTC_OP {
@@ -116,7 +116,7 @@ enum max77686_rtc_reg_offset {
REG_RTC_WEEKDAY,
REG_RTC_MONTH,
REG_RTC_YEAR,
- REG_RTC_DATE,
+ REG_RTC_MONTHDAY,
REG_ALARM1_SEC,
REG_ALARM1_MIN,
REG_ALARM1_HOUR,
@@ -147,7 +147,7 @@ static const unsigned int max77686_map[REG_RTC_END] = {
[REG_RTC_WEEKDAY] = MAX77686_RTC_WEEKDAY,
[REG_RTC_MONTH] = MAX77686_RTC_MONTH,
[REG_RTC_YEAR] = MAX77686_RTC_YEAR,
- [REG_RTC_DATE] = MAX77686_RTC_DATE,
+ [REG_RTC_MONTHDAY] = MAX77686_RTC_MONTHDAY,
[REG_ALARM1_SEC] = MAX77686_ALARM1_SEC,
[REG_ALARM1_MIN] = MAX77686_ALARM1_MIN,
[REG_ALARM1_HOUR] = MAX77686_ALARM1_HOUR,
@@ -201,6 +201,28 @@ static const struct max77686_rtc_driver_data max77686_drv_data = {
.regmap_config = &max77686_rtc_regmap_config,
};
+static const struct regmap_irq_chip max77714_rtc_irq_chip = {
+ .name = "max77714-rtc",
+ .status_base = MAX77686_RTC_INT,
+ .mask_base = MAX77686_RTC_INTM,
+ .num_regs = 1,
+ .irqs = max77686_rtc_irqs,
+ .num_irqs = ARRAY_SIZE(max77686_rtc_irqs) - 1, /* no WTSR on 77714 */
+};
+
+static const struct max77686_rtc_driver_data max77714_drv_data = {
+ .delay = 16000,
+ .mask = 0x7f,
+ .map = max77686_map,
+ .alarm_enable_reg = false,
+ .rtc_irq_from_platform = false,
+ /* On MAX77714 RTCA1 is BIT 1 of RTCINT (0x00). Not supported by this driver. */
+ .alarm_pending_status_reg = MAX77686_INVALID_REG,
+ .rtc_i2c_addr = MAX77714_I2C_ADDR_RTC,
+ .rtc_irq_chip = &max77714_rtc_irq_chip,
+ .regmap_config = &max77686_rtc_regmap_config,
+};
+
static const struct regmap_config max77620_rtc_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
@@ -230,7 +252,7 @@ static const unsigned int max77802_map[REG_RTC_END] = {
[REG_RTC_WEEKDAY] = MAX77802_RTC_WEEKDAY,
[REG_RTC_MONTH] = MAX77802_RTC_MONTH,
[REG_RTC_YEAR] = MAX77802_RTC_YEAR,
- [REG_RTC_DATE] = MAX77802_RTC_DATE,
+ [REG_RTC_MONTHDAY] = MAX77802_RTC_MONTHDAY,
[REG_ALARM1_SEC] = MAX77802_ALARM1_SEC,
[REG_ALARM1_MIN] = MAX77802_ALARM1_MIN,
[REG_ALARM1_HOUR] = MAX77802_ALARM1_HOUR,
@@ -275,17 +297,11 @@ static void max77686_rtc_data_to_tm(u8 *data, struct rtc_time *tm,
tm->tm_sec = data[RTC_SEC] & mask;
tm->tm_min = data[RTC_MIN] & mask;
- if (info->rtc_24hr_mode) {
- tm->tm_hour = data[RTC_HOUR] & 0x1f;
- } else {
- tm->tm_hour = data[RTC_HOUR] & 0x0f;
- if (data[RTC_HOUR] & HOUR_PM_MASK)
- tm->tm_hour += 12;
- }
+ tm->tm_hour = data[RTC_HOUR] & 0x1f;
/* Only a single bit is set in data[], so fls() would be equivalent */
tm->tm_wday = ffs(data[RTC_WEEKDAY] & mask) - 1;
- tm->tm_mday = data[RTC_DATE] & 0x1f;
+ tm->tm_mday = data[RTC_MONTHDAY] & 0x1f;
tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1;
tm->tm_year = data[RTC_YEAR] & mask;
tm->tm_yday = 0;
@@ -306,7 +322,7 @@ static int max77686_rtc_tm_to_data(struct rtc_time *tm, u8 *data,
data[RTC_MIN] = tm->tm_min;
data[RTC_HOUR] = tm->tm_hour;
data[RTC_WEEKDAY] = 1 << tm->tm_wday;
- data[RTC_DATE] = tm->tm_mday;
+ data[RTC_MONTHDAY] = tm->tm_mday;
data[RTC_MONTH] = tm->tm_mon + 1;
if (info->drv_data->alarm_enable_reg) {
@@ -562,8 +578,8 @@ static int max77686_rtc_start_alarm(struct max77686_rtc_info *info)
data[RTC_MONTH] |= (1 << ALARM_ENABLE_SHIFT);
if (data[RTC_YEAR] & info->drv_data->mask)
data[RTC_YEAR] |= (1 << ALARM_ENABLE_SHIFT);
- if (data[RTC_DATE] & 0x1f)
- data[RTC_DATE] |= (1 << ALARM_ENABLE_SHIFT);
+ if (data[RTC_MONTHDAY] & 0x1f)
+ data[RTC_MONTHDAY] |= (1 << ALARM_ENABLE_SHIFT);
ret = regmap_bulk_write(info->rtc_regmap, map[REG_ALARM1_SEC],
data, ARRAY_SIZE(data));
@@ -659,8 +675,6 @@ static int max77686_rtc_init_reg(struct max77686_rtc_info *info)
data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
- info->rtc_24hr_mode = 1;
-
ret = regmap_bulk_write(info->rtc_regmap,
info->drv_data->map[REG_RTC_CONTROLM],
data, ARRAY_SIZE(data));
@@ -852,6 +866,7 @@ static const struct platform_device_id rtc_id[] = {
{ "max77686-rtc", .driver_data = (kernel_ulong_t)&max77686_drv_data, },
{ "max77802-rtc", .driver_data = (kernel_ulong_t)&max77802_drv_data, },
{ "max77620-rtc", .driver_data = (kernel_ulong_t)&max77620_drv_data, },
+ { "max77714-rtc", .driver_data = (kernel_ulong_t)&max77714_drv_data, },
{},
};
MODULE_DEVICE_TABLE(platform, rtc_id);
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index aa42f0686591..085f5a4ad06c 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -678,7 +678,7 @@ config MAX63XX_WATCHDOG
config MAX77620_WATCHDOG
tristate "Maxim Max77620 Watchdog Timer"
- depends on MFD_MAX77620 || COMPILE_TEST
+ depends on MFD_MAX77620 || MFD_MAX77714 || COMPILE_TEST
select WATCHDOG_CORE
help
This is the driver for the Max77620 watchdog timer.
diff --git a/drivers/watchdog/max77620_wdt.c b/drivers/watchdog/max77620_wdt.c
index be6a53c30002..b76ad6ba0915 100644
--- a/drivers/watchdog/max77620_wdt.c
+++ b/drivers/watchdog/max77620_wdt.c
@@ -3,8 +3,10 @@
* Maxim MAX77620 Watchdog Driver
*
* Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2022 Luca Ceresoli
*
* Author: Laxman Dewangan <ldewangan@nvidia.com>
+ * Author: Luca Ceresoli <luca@lucaceresoli.net>
*/
#include <linux/err.h>
@@ -13,6 +15,7 @@
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/mfd/max77620.h>
+#include <linux/mfd/max77714.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
@@ -20,17 +23,57 @@
static bool nowayout = WATCHDOG_NOWAYOUT;
+/**
+ * struct max77620_variant - Data specific to a chip variant
+ * @wdt_info: watchdog descriptor
+ * @reg_onoff_cnfg2: ONOFF_CNFG2 register offset
+ * @reg_cnfg_glbl2: CNFG_GLBL2 register offset
+ * @reg_cnfg_glbl3: CNFG_GLBL3 register offset
+ * @wdtc_mask: WDTC bit mask in CNFG_GLBL3 (=bits to update to ping the watchdog)
+ * @bit_wd_rst_wk: WD_RST_WK bit offset within ONOFF_CNFG2
+ * @cnfg_glbl2_cfg_bits: configuration bits to enable in CNFG_GLBL2 register
+ */
+struct max77620_variant {
+ u8 reg_onoff_cnfg2;
+ u8 reg_cnfg_glbl2;
+ u8 reg_cnfg_glbl3;
+ u8 wdtc_mask;
+ u8 bit_wd_rst_wk;
+ u8 cnfg_glbl2_cfg_bits;
+};
+
struct max77620_wdt {
struct device *dev;
struct regmap *rmap;
+ const struct max77620_variant *drv_data;
struct watchdog_device wdt_dev;
};
+static const struct max77620_variant max77620_wdt_data = {
+ .reg_onoff_cnfg2 = MAX77620_REG_ONOFFCNFG2,
+ .reg_cnfg_glbl2 = MAX77620_REG_CNFGGLBL2,
+ .reg_cnfg_glbl3 = MAX77620_REG_CNFGGLBL3,
+ .wdtc_mask = MAX77620_WDTC_MASK,
+ .bit_wd_rst_wk = MAX77620_ONOFFCNFG2_WD_RST_WK,
+ /* Set WDT clear in OFF and sleep mode */
+ .cnfg_glbl2_cfg_bits = MAX77620_WDTSLPC | MAX77620_WDTOFFC,
+};
+
+static const struct max77620_variant max77714_wdt_data = {
+ .reg_onoff_cnfg2 = MAX77714_CNFG2_ONOFF,
+ .reg_cnfg_glbl2 = MAX77714_CNFG_GLBL2,
+ .reg_cnfg_glbl3 = MAX77714_CNFG_GLBL3,
+ .wdtc_mask = MAX77714_WDTC,
+ .bit_wd_rst_wk = MAX77714_WD_RST_WK,
+ /* Set WDT clear in sleep mode (there is no WDTOFFC on MAX77714) */
+ .cnfg_glbl2_cfg_bits = MAX77714_WDTSLPC,
+};
+
static int max77620_wdt_start(struct watchdog_device *wdt_dev)
{
struct max77620_wdt *wdt = watchdog_get_drvdata(wdt_dev);
- return regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL2,
+ return regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2,
MAX77620_WDTEN, MAX77620_WDTEN);
}
@@ -38,7 +81,7 @@ static int max77620_wdt_stop(struct watchdog_device *wdt_dev)
{
struct max77620_wdt *wdt = watchdog_get_drvdata(wdt_dev);
- return regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL2,
+ return regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2,
MAX77620_WDTEN, 0);
}
@@ -46,8 +89,8 @@ static int max77620_wdt_ping(struct watchdog_device *wdt_dev)
{
struct max77620_wdt *wdt = watchdog_get_drvdata(wdt_dev);
- return regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL3,
- MAX77620_WDTC_MASK, 0x1);
+ return regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl3,
+ wdt->drv_data->wdtc_mask, 0x1);
}
static int max77620_wdt_set_timeout(struct watchdog_device *wdt_dev,
@@ -80,12 +123,17 @@ static int max77620_wdt_set_timeout(struct watchdog_device *wdt_dev,
break;
}
- ret = regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL3,
- MAX77620_WDTC_MASK, 0x1);
+ /*
+ * "If the value of TWD needs to be changed, clear the system
+ * watchdog timer first [...], then change the value of TWD."
+ * (MAX77714 datasheet but applies to MAX77620 too)
+ */
+ ret = regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl3,
+ wdt->drv_data->wdtc_mask, 0x1);
if (ret < 0)
return ret;
- ret = regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL2,
+ ret = regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2,
MAX77620_TWD_MASK, regval);
if (ret < 0)
return ret;
@@ -109,6 +157,7 @@ static const struct watchdog_ops max77620_wdt_ops = {
static int max77620_wdt_probe(struct platform_device *pdev)
{
+ const struct platform_device_id *id = platform_get_device_id(pdev);
struct device *dev = &pdev->dev;
struct max77620_wdt *wdt;
struct watchdog_device *wdt_dev;
@@ -120,6 +169,8 @@ static int max77620_wdt_probe(struct platform_device *pdev)
return -ENOMEM;
wdt->dev = dev;
+ wdt->drv_data = (const struct max77620_variant *) id->driver_data;
+
wdt->rmap = dev_get_regmap(dev->parent, NULL);
if (!wdt->rmap) {
dev_err(wdt->dev, "Failed to get parent regmap\n");
@@ -136,25 +187,25 @@ static int max77620_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, wdt);
/* Enable WD_RST_WK - WDT expire results in a restart */
- ret = regmap_update_bits(wdt->rmap, MAX77620_REG_ONOFFCNFG2,
- MAX77620_ONOFFCNFG2_WD_RST_WK,
- MAX77620_ONOFFCNFG2_WD_RST_WK);
+ ret = regmap_update_bits(wdt->rmap, wdt->drv_data->reg_onoff_cnfg2,
+ wdt->drv_data->bit_wd_rst_wk,
+ wdt->drv_data->bit_wd_rst_wk);
if (ret < 0) {
dev_err(wdt->dev, "Failed to set WD_RST_WK: %d\n", ret);
return ret;
}
- /* Set WDT clear in OFF and sleep mode */
- ret = regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL2,
- MAX77620_WDTOFFC | MAX77620_WDTSLPC,
- MAX77620_WDTOFFC | MAX77620_WDTSLPC);
+ /* Set the "auto WDT clear" bits available on the chip */
+ ret = regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2,
+ wdt->drv_data->cnfg_glbl2_cfg_bits,
+ wdt->drv_data->cnfg_glbl2_cfg_bits);
if (ret < 0) {
dev_err(wdt->dev, "Failed to set WDT OFF mode: %d\n", ret);
return ret;
}
/* Check if WDT running and if yes then set flags properly */
- ret = regmap_read(wdt->rmap, MAX77620_REG_CNFGGLBL2, &regval);
+ ret = regmap_read(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2, &regval);
if (ret < 0) {
dev_err(wdt->dev, "Failed to read WDT CFG register: %d\n", ret);
return ret;
@@ -186,7 +237,8 @@ static int max77620_wdt_probe(struct platform_device *pdev)
}
static const struct platform_device_id max77620_wdt_devtype[] = {
- { .name = "max77620-watchdog", },
+ { "max77620-watchdog", (kernel_ulong_t)&max77620_wdt_data },
+ { "max77714-watchdog", (kernel_ulong_t)&max77714_wdt_data },
{ },
};
MODULE_DEVICE_TABLE(platform, max77620_wdt_devtype);
@@ -208,4 +260,5 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
"(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
+MODULE_AUTHOR("Luca Ceresoli <luca@lucaceresoli.net>");
MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mfd/dbx500-prcmu.h b/include/linux/mfd/dbx500-prcmu.h
index cbf9d7619493..e7a7e70fdb38 100644
--- a/include/linux/mfd/dbx500-prcmu.h
+++ b/include/linux/mfd/dbx500-prcmu.h
@@ -556,31 +556,11 @@ static inline void prcmu_clear(unsigned int reg, u32 bits)
#define PRCMU_QOS_ARM_OPP 3
#define PRCMU_QOS_DEFAULT_VALUE -1
-#ifdef CONFIG_DBX500_PRCMU_QOS_POWER
-
-unsigned long prcmu_qos_get_cpufreq_opp_delay(void);
-void prcmu_qos_set_cpufreq_opp_delay(unsigned long);
-void prcmu_qos_force_opp(int, s32);
-int prcmu_qos_requirement(int pm_qos_class);
-int prcmu_qos_add_requirement(int pm_qos_class, char *name, s32 value);
-int prcmu_qos_update_requirement(int pm_qos_class, char *name, s32 new_value);
-void prcmu_qos_remove_requirement(int pm_qos_class, char *name);
-int prcmu_qos_add_notifier(int prcmu_qos_class,
- struct notifier_block *notifier);
-int prcmu_qos_remove_notifier(int prcmu_qos_class,
- struct notifier_block *notifier);
-
-#else
-
static inline unsigned long prcmu_qos_get_cpufreq_opp_delay(void)
{
return 0;
}
-static inline void prcmu_qos_set_cpufreq_opp_delay(unsigned long n) {}
-
-static inline void prcmu_qos_force_opp(int prcmu_qos_class, s32 i) {}
-
static inline int prcmu_qos_requirement(int prcmu_qos_class)
{
return 0;
@@ -613,6 +593,4 @@ static inline int prcmu_qos_remove_notifier(int prcmu_qos_class,
return 0;
}
-#endif
-
#endif /* __MACH_PRCMU_H */
diff --git a/include/linux/mfd/iqs62x.h b/include/linux/mfd/iqs62x.h
index 5ced55eae11b..ffc86010af74 100644
--- a/include/linux/mfd/iqs62x.h
+++ b/include/linux/mfd/iqs62x.h
@@ -14,6 +14,11 @@
#define IQS624_PROD_NUM 0x43
#define IQS625_PROD_NUM 0x4E
+#define IQS620_HW_NUM_V0 0x82
+#define IQS620_HW_NUM_V1 IQS620_HW_NUM_V0
+#define IQS620_HW_NUM_V2 IQS620_HW_NUM_V0
+#define IQS620_HW_NUM_V3 0x92
+
#define IQS621_ALS_FLAGS 0x16
#define IQS622_ALS_FLAGS 0x14
@@ -129,6 +134,8 @@ struct iqs62x_core {
struct completion fw_done;
enum iqs62x_ui_sel ui_sel;
unsigned long event_cache;
+ u8 sw_num;
+ u8 hw_num;
};
extern const struct iqs62x_event_desc iqs62x_events[IQS62X_NUM_EVENTS];
diff --git a/include/linux/mfd/max77686-private.h b/include/linux/mfd/max77686-private.h
index b1482b3cf353..3acceeedbaba 100644
--- a/include/linux/mfd/max77686-private.h
+++ b/include/linux/mfd/max77686-private.h
@@ -152,7 +152,7 @@ enum max77686_rtc_reg {
MAX77686_RTC_WEEKDAY = 0x0A,
MAX77686_RTC_MONTH = 0x0B,
MAX77686_RTC_YEAR = 0x0C,
- MAX77686_RTC_DATE = 0x0D,
+ MAX77686_RTC_MONTHDAY = 0x0D,
MAX77686_ALARM1_SEC = 0x0E,
MAX77686_ALARM1_MIN = 0x0F,
MAX77686_ALARM1_HOUR = 0x10,
@@ -352,7 +352,7 @@ enum max77802_rtc_reg {
MAX77802_RTC_WEEKDAY = 0xCA,
MAX77802_RTC_MONTH = 0xCB,
MAX77802_RTC_YEAR = 0xCC,
- MAX77802_RTC_DATE = 0xCD,
+ MAX77802_RTC_MONTHDAY = 0xCD,
MAX77802_RTC_AE1 = 0xCE,
MAX77802_ALARM1_SEC = 0xCF,
MAX77802_ALARM1_MIN = 0xD0,
diff --git a/include/linux/mfd/max77714.h b/include/linux/mfd/max77714.h
new file mode 100644
index 000000000000..a970dc455426
--- /dev/null
+++ b/include/linux/mfd/max77714.h
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Maxim MAX77714 Register and data structures definition.
+ *
+ * Copyright (C) 2022 Luca Ceresoli
+ * Author: Luca Ceresoli <luca@lucaceresoli.net>
+ */
+
+#ifndef __LINUX_MFD_MAX77714_H_
+#define __LINUX_MFD_MAX77714_H_
+
+#include <linux/bits.h>
+
+#define MAX77714_INT_TOP 0x00
+#define MAX77714_INT_TOPM 0x07 /* Datasheet says "read only", but it is RW */
+
+#define MAX77714_INT_TOP_ONOFF BIT(1)
+#define MAX77714_INT_TOP_RTC BIT(3)
+#define MAX77714_INT_TOP_GPIO BIT(4)
+#define MAX77714_INT_TOP_LDO BIT(5)
+#define MAX77714_INT_TOP_SD BIT(6)
+#define MAX77714_INT_TOP_GLBL BIT(7)
+
+#define MAX77714_32K_STATUS 0x30
+#define MAX77714_32K_STATUS_SIOSCOK BIT(5)
+#define MAX77714_32K_STATUS_XOSCOK BIT(4)
+#define MAX77714_32K_STATUS_32KSOURCE BIT(3)
+#define MAX77714_32K_STATUS_32KLOAD_MSK 0x3
+#define MAX77714_32K_STATUS_32KLOAD_SHF 1
+#define MAX77714_32K_STATUS_CRYSTAL_CFG BIT(0)
+
+#define MAX77714_32K_CONFIG 0x31
+#define MAX77714_32K_CONFIG_XOSC_RETRY BIT(4)
+
+#define MAX77714_CNFG_GLBL2 0x91
+#define MAX77714_WDTEN BIT(2)
+#define MAX77714_WDTSLPC BIT(3)
+#define MAX77714_TWD_MASK 0x3
+#define MAX77714_TWD_2s 0x0
+#define MAX77714_TWD_16s 0x1
+#define MAX77714_TWD_64s 0x2
+#define MAX77714_TWD_128s 0x3
+
+#define MAX77714_CNFG_GLBL3 0x92
+#define MAX77714_WDTC BIT(0)
+
+#define MAX77714_CNFG2_ONOFF 0x94
+#define MAX77714_WD_RST_WK BIT(5)
+
+/* Interrupts */
+enum {
+ MAX77714_IRQ_TOP_ONOFF,
+ MAX77714_IRQ_TOP_RTC, /* Real-time clock */
+ MAX77714_IRQ_TOP_GPIO, /* GPIOs */
+ MAX77714_IRQ_TOP_LDO, /* Low-dropout regulators */
+ MAX77714_IRQ_TOP_SD, /* Step-down regulators */
+ MAX77714_IRQ_TOP_GLBL, /* "Global resources": Low-Battery, overtemp... */
+};
+
+#endif /* __LINUX_MFD_MAX77714_H_ */
diff --git a/include/linux/mfd/mt6358/registers.h b/include/linux/mfd/mt6358/registers.h
index 201139b12140..3d33517f178c 100644
--- a/include/linux/mfd/mt6358/registers.h
+++ b/include/linux/mfd/mt6358/registers.h
@@ -94,6 +94,10 @@
#define MT6358_BUCK_VCORE_CON0 0x1488
#define MT6358_BUCK_VCORE_DBG0 0x149e
#define MT6358_BUCK_VCORE_DBG1 0x14a0
+#define MT6358_BUCK_VCORE_SSHUB_CON0 0x14a4
+#define MT6358_BUCK_VCORE_SSHUB_CON1 0x14a6
+#define MT6358_BUCK_VCORE_SSHUB_ELR0 MT6358_BUCK_VCORE_SSHUB_CON1
+#define MT6358_BUCK_VCORE_SSHUB_DBG1 MT6358_BUCK_VCORE_DBG1
#define MT6358_BUCK_VCORE_ELR0 0x14aa
#define MT6358_BUCK_VGPU_CON0 0x1508
#define MT6358_BUCK_VGPU_DBG0 0x151e
@@ -169,6 +173,9 @@
#define MT6358_LDO_VSRAM_OTHERS_CON0 0x1ba6
#define MT6358_LDO_VSRAM_OTHERS_DBG0 0x1bc0
#define MT6358_LDO_VSRAM_OTHERS_DBG1 0x1bc2
+#define MT6358_LDO_VSRAM_OTHERS_SSHUB_CON0 0x1bc4
+#define MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1 0x1bc6
+#define MT6358_LDO_VSRAM_OTHERS_SSHUB_DBG1 MT6358_LDO_VSRAM_OTHERS_DBG1
#define MT6358_LDO_VSRAM_GPU_CON0 0x1bc8
#define MT6358_LDO_VSRAM_GPU_DBG0 0x1be2
#define MT6358_LDO_VSRAM_GPU_DBG1 0x1be4
diff --git a/include/linux/mfd/mt6397/core.h b/include/linux/mfd/mt6397/core.h
index 56f210eebc54..1cf78726503b 100644
--- a/include/linux/mfd/mt6397/core.h
+++ b/include/linux/mfd/mt6397/core.h
@@ -14,6 +14,7 @@ enum chip_id {
MT6323_CHIP_ID = 0x23,
MT6358_CHIP_ID = 0x58,
MT6359_CHIP_ID = 0x59,
+ MT6366_CHIP_ID = 0x66,
MT6391_CHIP_ID = 0x91,
MT6397_CHIP_ID = 0x97,
};
diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
index a96e6d43ca06..58602032e642 100644
--- a/include/linux/mfd/rk808.h
+++ b/include/linux/mfd/rk808.h
@@ -373,6 +373,7 @@ enum rk805_reg {
#define SWITCH2_EN BIT(6)
#define SWITCH1_EN BIT(5)
#define DEV_OFF_RST BIT(3)
+#define DEV_RST BIT(2)
#define DEV_OFF BIT(0)
#define RTC_STOP BIT(0)
diff --git a/include/linux/mfd/sy7636a.h b/include/linux/mfd/sy7636a.h
new file mode 100644
index 000000000000..22f03b2f851e
--- /dev/null
+++ b/include/linux/mfd/sy7636a.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Functions to access SY3686A power management chip.
+ *
+ * Copyright (C) 2021 reMarkable AS - http://www.remarkable.com/
+ */
+
+#ifndef __MFD_SY7636A_H
+#define __MFD_SY7636A_H
+
+#define SY7636A_REG_OPERATION_MODE_CRL 0x00
+/* It is set if a gpio is used to control the regulator */
+#define SY7636A_OPERATION_MODE_CRL_VCOMCTL BIT(6)
+#define SY7636A_OPERATION_MODE_CRL_ONOFF BIT(7)
+#define SY7636A_REG_VCOM_ADJUST_CTRL_L 0x01
+#define SY7636A_REG_VCOM_ADJUST_CTRL_H 0x02
+#define SY7636A_REG_VCOM_ADJUST_CTRL_MASK 0x01ff
+#define SY7636A_REG_VLDO_VOLTAGE_ADJULST_CTRL 0x03
+#define SY7636A_REG_POWER_ON_DELAY_TIME 0x06
+#define SY7636A_REG_FAULT_FLAG 0x07
+#define SY7636A_FAULT_FLAG_PG BIT(0)
+#define SY7636A_REG_TERMISTOR_READOUT 0x08
+
+#define SY7636A_REG_MAX 0x08
+
+#define VCOM_ADJUST_CTRL_MASK 0x1ff
+// Used to shift the high byte
+#define VCOM_ADJUST_CTRL_SHIFT 8
+// Used to scale from VCOM_ADJUST_CTRL to mv
+#define VCOM_ADJUST_CTRL_SCAL 10000
+
+#define FAULT_FLAG_SHIFT 1
+
+#endif /* __LINUX_MFD_SY7636A_H */