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

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

Pull mfd updates from Lee Jones:
"New Drivers:
- Add support for IQS620A/621/622/624/625 Azoteq IQS62X Sensors

New Device Support:
- Add support for ADC, IRQ, Regulator, RTC and WDT to Ricoh RN5T618 PMIC
- Add support for Comet Lake to Intel LPSS

New Functionality:
- Add support for Charger Detection to Spreadtrum SC27xx PMICs
- Add support for Interrupt Polarity to Dialog Semi DA9062/61 PMIC
- Add ACPI enumeration support to Diolan DLN2 USB Adaptor

Fix-ups:
- Device Tree; iqs62x, rn5t618, cros_ec_dev, stm32-lptimer, rohm,bd71837, rohm,bd71847
- I2C registration; rn5t618
- Kconfig; MFD_CPCAP, AB8500_CORE, MFD_WM8994, MFD_WM97xx, MFD_STPMIC1
- Use flexible-array members; omap-usb-tll, qcom-pm8xxx
- Remove unnecessary casts; omap-usb-host, omap-usb-tll
- Power (suspend/resume/poweroff) enhancements; rk808
- Improve error/sanity checking; dln2
- Use snprintf(); aat2870-core

Bug Fixes:
- Fix PCI IDs in intel-lpss-pci"

* tag 'mfd-next-5.7' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (33 commits)
mfd: intel-lpss: Fix Intel Elkhart Lake LPSS I2C input clock
mfd: aat2870: Use scnprintf() for avoiding potential buffer overflow
mfd: dln2: Allow to be enumerated via ACPI
mfd: da9062: Add support for interrupt polarity defined in device tree
dt-bindings: bd718x7: Yamlify and add BD71850
mfd: dln2: Fix sanity checking for endpoints
mfd: intel-lpss: Add Intel Comet Lake PCH-V PCI IDs
mfd: sc27xx: Add USB charger type detection support
dt-bindings: mfd: Document STM32 low power timer bindings
mfd: rk808: Convert RK805 to shutdown/suspend hooks
mfd: rk808: Reduce shutdown duplication
mfd: rk808: Stop using syscore ops
mfd: rk808: Ensure suspend/resume hooks always work
mfd: rk808: Always use poweroff when requested
mfd: omap: Remove useless cast for driver.name
mfd: Kconfig: Fix some misspelling of the word functionality
mfd: pm8xxx: Replace zero-length array with flexible-array member
mfd: omap-usb-tll: Replace zero-length array with flexible-array member
mfd: cpcap: Fix compile if MFD_CORE is not selected
mfd: cros_ec: Check DT node for usbpd-notify add
...

+4688 -379
+132
Documentation/devicetree/bindings/input/iqs62x-keys.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/input/iqs62x-keys.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Azoteq IQS620A/621/622/624/625 Keys and Switches 8 + 9 + maintainers: 10 + - Jeff LaBundy <jeff@labundy.com> 11 + 12 + description: | 13 + The Azoteq IQS620A, IQS621, IQS622, IQS624 and IQS625 multi-function sensors 14 + feature a variety of self-capacitive, mutual-inductive and Hall-effect sens- 15 + ing capabilities that can facilitate a variety of contactless key and switch 16 + applications. 17 + 18 + These functions are collectively represented by a "keys" child node from the 19 + parent MFD driver. See Documentation/devicetree/bindings/mfd/iqs62x.yaml for 20 + further details and examples. Sensor hardware configuration (self-capacitive 21 + vs. mutual-inductive, etc.) is selected based on the device's firmware. 22 + 23 + properties: 24 + compatible: 25 + enum: 26 + - azoteq,iqs620a-keys 27 + - azoteq,iqs621-keys 28 + - azoteq,iqs622-keys 29 + - azoteq,iqs624-keys 30 + - azoteq,iqs625-keys 31 + 32 + linux,keycodes: 33 + allOf: 34 + - $ref: /schemas/types.yaml#/definitions/uint32-array 35 + - minItems: 1 36 + maxItems: 16 37 + description: | 38 + Specifies the numeric keycodes associated with each available touch or 39 + proximity event according to the following table. An 'x' indicates the 40 + event is supported for a given device. Specify 0 for unused events. 41 + 42 + ------------------------------------------------------------------------- 43 + | # | Event | IQS620A | IQS621 | IQS622 | IQS624 | IQS625 | 44 + ------------------------------------------------------------------------- 45 + | 0 | CH0 Touch | x | x | x | x | x | 46 + | | Antenna 1 Touch* | x | | | | | 47 + ------------------------------------------------------------------------- 48 + | 1 | CH0 Proximity | x | x | x | x | x | 49 + | | Antenna 1 Prox.* | x | | | | | 50 + ------------------------------------------------------------------------- 51 + | 2 | CH1 Touch | x | x | x | x | x | 52 + | | Ant. 1 Deep Touch* | x | | | | | 53 + ------------------------------------------------------------------------- 54 + | 3 | CH1 Proximity | x | x | x | x | x | 55 + ------------------------------------------------------------------------- 56 + | 4 | CH2 Touch | x | | | | | 57 + ------------------------------------------------------------------------- 58 + | 5 | CH2 Proximity | x | | | | | 59 + | | Antenna 2 Prox.* | x | | | | | 60 + ------------------------------------------------------------------------- 61 + | 6 | Metal (+) Touch** | x | x | | | | 62 + | | Ant. 2 Deep Touch* | x | | | | | 63 + ------------------------------------------------------------------------- 64 + | 7 | Metal (+) Prox.** | x | x | | | | 65 + | | Antenna 2 Touch* | x | | | | | 66 + ------------------------------------------------------------------------- 67 + | 8 | Metal (-) Touch** | x | x | | | | 68 + ------------------------------------------------------------------------- 69 + | 9 | Metal (-) Prox.** | x | x | | | | 70 + ------------------------------------------------------------------------- 71 + | 10 | SAR Active*** | x | | x | | | 72 + ------------------------------------------------------------------------- 73 + | 11 | SAR Quick Rel.*** | x | | x | | | 74 + ------------------------------------------------------------------------- 75 + | 12 | SAR Movement*** | x | | x | | | 76 + ------------------------------------------------------------------------- 77 + | 13 | SAR Filter Halt*** | x | | x | | | 78 + ------------------------------------------------------------------------- 79 + | 14 | Wheel Up | | | | x | | 80 + ------------------------------------------------------------------------- 81 + | 15 | Wheel Down | | | | x | | 82 + ------------------------------------------------------------------------- 83 + * Two-channel SAR. Replaces CH0-2 plus metal touch and proximity events 84 + if enabled via firmware. 85 + ** "+" and "-" refer to the polarity of a channel's delta (LTA - counts), 86 + where "LTA" is defined as the channel's long-term average. 87 + *** One-channel SAR. Replaces CH0-2 touch and proximity events if enabled 88 + via firmware. 89 + 90 + patternProperties: 91 + "^hall-switch-(north|south)$": 92 + type: object 93 + description: 94 + Represents north/south-field Hall-effect sensor touch or proximity 95 + events. Note that north/south-field orientation is reversed on the 96 + IQS620AXzCSR device due to its flip-chip package. 97 + 98 + properties: 99 + linux,code: 100 + $ref: /schemas/types.yaml#/definitions/uint32 101 + description: Numeric switch code associated with the event. 102 + 103 + azoteq,use-prox: 104 + $ref: /schemas/types.yaml#/definitions/flag 105 + description: 106 + If present, specifies that Hall-effect sensor reporting should 107 + use the device's wide-range proximity threshold instead of its 108 + close-range touch threshold (default). 109 + 110 + required: 111 + - linux,code 112 + 113 + additionalProperties: false 114 + 115 + if: 116 + properties: 117 + compatible: 118 + contains: 119 + enum: 120 + - azoteq,iqs624-keys 121 + - azoteq,iqs625-keys 122 + then: 123 + patternProperties: 124 + "^hall-switch-(north|south)$": false 125 + 126 + required: 127 + - compatible 128 + - linux,keycodes 129 + 130 + additionalProperties: false 131 + 132 + ...
+179
Documentation/devicetree/bindings/mfd/iqs62x.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/mfd/iqs62x.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Azoteq IQS620A/621/622/624/625 Multi-Function Sensors 8 + 9 + maintainers: 10 + - Jeff LaBundy <jeff@labundy.com> 11 + 12 + description: | 13 + The Azoteq IQS620A, IQS621, IQS622, IQS624 and IQS625 multi-function sensors 14 + integrate multiple sensing technologies in a single package. 15 + 16 + Link to datasheets: https://www.azoteq.com/ 17 + 18 + properties: 19 + compatible: 20 + enum: 21 + - azoteq,iqs620a 22 + - azoteq,iqs621 23 + - azoteq,iqs622 24 + - azoteq,iqs624 25 + - azoteq,iqs625 26 + 27 + reg: 28 + maxItems: 1 29 + 30 + interrupts: 31 + maxItems: 1 32 + 33 + firmware-name: 34 + $ref: /schemas/types.yaml#/definitions/string 35 + description: 36 + Specifies the name of the calibration and configuration file selected by 37 + the driver. If this property is omitted, the name is chosen based on the 38 + device name with ".bin" as the extension (e.g. iqs620a.bin for IQS620A). 39 + 40 + keys: 41 + $ref: ../input/iqs62x-keys.yaml 42 + 43 + pwm: 44 + $ref: ../pwm/iqs620a-pwm.yaml 45 + 46 + required: 47 + - compatible 48 + - reg 49 + - interrupts 50 + 51 + additionalProperties: false 52 + 53 + examples: 54 + - | 55 + /* 56 + * Dual capacitive buttons with proximity-activated function, unipolar lid 57 + * switch and panel-mounted LED. 58 + */ 59 + #include <dt-bindings/input/input.h> 60 + #include <dt-bindings/interrupt-controller/irq.h> 61 + 62 + i2c { 63 + #address-cells = <1>; 64 + #size-cells = <0>; 65 + 66 + iqs620a@44 { 67 + compatible = "azoteq,iqs620a"; 68 + reg = <0x44>; 69 + interrupt-parent = <&gpio>; 70 + interrupts = <17 IRQ_TYPE_LEVEL_LOW>; 71 + 72 + keys { 73 + compatible = "azoteq,iqs620a-keys"; 74 + 75 + linux,keycodes = <KEY_SELECT>, 76 + <KEY_MENU>, 77 + <KEY_OK>, 78 + <KEY_MENU>; 79 + 80 + hall-switch-south { 81 + linux,code = <SW_LID>; 82 + azoteq,use-prox; 83 + }; 84 + }; 85 + 86 + iqs620a_pwm: pwm { 87 + compatible = "azoteq,iqs620a-pwm"; 88 + #pwm-cells = <2>; 89 + }; 90 + }; 91 + }; 92 + 93 + pwmleds { 94 + compatible = "pwm-leds"; 95 + 96 + panel { 97 + pwms = <&iqs620a_pwm 0 1000000>; 98 + max-brightness = <255>; 99 + }; 100 + }; 101 + 102 + - | 103 + /* Single inductive button with bipolar dock/tablet-mode switch. */ 104 + #include <dt-bindings/input/input.h> 105 + #include <dt-bindings/interrupt-controller/irq.h> 106 + 107 + i2c { 108 + #address-cells = <1>; 109 + #size-cells = <0>; 110 + 111 + iqs620a@44 { 112 + compatible = "azoteq,iqs620a"; 113 + reg = <0x44>; 114 + interrupt-parent = <&gpio>; 115 + interrupts = <17 IRQ_TYPE_LEVEL_LOW>; 116 + 117 + firmware-name = "iqs620a_coil.bin"; 118 + 119 + keys { 120 + compatible = "azoteq,iqs620a-keys"; 121 + 122 + linux,keycodes = <0>, 123 + <0>, 124 + <0>, 125 + <0>, 126 + <0>, 127 + <0>, 128 + <KEY_MUTE>; 129 + 130 + hall-switch-north { 131 + linux,code = <SW_DOCK>; 132 + }; 133 + 134 + hall-switch-south { 135 + linux,code = <SW_TABLET_MODE>; 136 + }; 137 + }; 138 + }; 139 + }; 140 + 141 + - | 142 + /* Dual capacitive buttons with volume knob. */ 143 + #include <dt-bindings/input/input.h> 144 + #include <dt-bindings/interrupt-controller/irq.h> 145 + 146 + i2c { 147 + #address-cells = <1>; 148 + #size-cells = <0>; 149 + 150 + iqs624@44 { 151 + compatible = "azoteq,iqs624"; 152 + reg = <0x44>; 153 + interrupt-parent = <&gpio>; 154 + interrupts = <17 IRQ_TYPE_LEVEL_LOW>; 155 + 156 + keys { 157 + compatible = "azoteq,iqs624-keys"; 158 + 159 + linux,keycodes = <BTN_0>, 160 + <0>, 161 + <BTN_1>, 162 + <0>, 163 + <0>, 164 + <0>, 165 + <0>, 166 + <0>, 167 + <0>, 168 + <0>, 169 + <0>, 170 + <0>, 171 + <0>, 172 + <0>, 173 + <KEY_VOLUMEUP>, 174 + <KEY_VOLUMEDOWN>; 175 + }; 176 + }; 177 + }; 178 + 179 + ...
+4
Documentation/devicetree/bindings/mfd/rn5t618.txt
··· 15 15 - reg: the I2C slave address of the device 16 16 17 17 Optional properties: 18 + - interrupts: interrupt mapping for IRQ 19 + See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt 18 20 - system-power-controller: 19 21 See Documentation/devicetree/bindings/power/power-controller.txt 20 22 ··· 34 32 pmic@32 { 35 33 compatible = "ricoh,rn5t618"; 36 34 reg = <0x32>; 35 + interrupt-parent = <&gpio5>; 36 + interrupts = <11 IRQ_TYPE_EDGE_FALLING>; 37 37 system-power-controller; 38 38 39 39 regulators {
-90
Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.txt
··· 1 - * ROHM BD71837 and BD71847 Power Management Integrated Circuit bindings 2 - 3 - BD71837MWV and BD71847MWV are programmable Power Management ICs for powering 4 - single-core, dual-core, and quad-core SoCs such as NXP-i.MX 8M. They are 5 - optimized for low BOM cost and compact solution footprint. BD71837MWV 6 - integrates 8 Buck regulators and 7 LDOs. BD71847MWV contains 6 Buck regulators 7 - and 6 LDOs. 8 - 9 - Datasheet for BD71837 is available at: 10 - https://www.rohm.com/datasheet/BD71837MWV/bd71837mwv-e 11 - Datasheet for BD71847 is available at: 12 - https://www.rohm.com/datasheet/BD71847AMWV/bd71847amwv-e 13 - 14 - Required properties: 15 - - compatible : Should be "rohm,bd71837" for bd71837 16 - "rohm,bd71847" for bd71847. 17 - - reg : I2C slave address. 18 - - interrupt-parent : Phandle to the parent interrupt controller. 19 - - interrupts : The interrupt line the device is connected to. 20 - - clocks : The parent clock connected to PMIC. If this is missing 21 - 32768 KHz clock is assumed. 22 - - #clock-cells : Should be 0. 23 - - regulators: : List of child nodes that specify the regulators. 24 - Please see ../regulator/rohm,bd71837-regulator.txt 25 - 26 - Optional properties: 27 - - clock-output-names : Should contain name for output clock. 28 - - rohm,reset-snvs-powered : Transfer BD718x7 to SNVS state at reset. 29 - 30 - The BD718x7 supports two different HW states as reset target states. States 31 - are called as SNVS and READY. At READY state all the PMIC power outputs go 32 - down and OTP is reload. At the SNVS state all other logic and external 33 - devices apart from the SNVS power domain are shut off. Please refer to NXP 34 - i.MX8 documentation for further information regarding SNVS state. When a 35 - reset is done via SNVS state the PMIC OTP data is not reload. This causes 36 - power outputs that have been under SW control to stay down when reset has 37 - switched power state to SNVS. If reset is done via READY state the power 38 - outputs will be returned to HW control by OTP loading. Thus the reset 39 - target state is set to READY by default. If SNVS state is used the boot 40 - crucial regulators must have the regulator-always-on and regulator-boot-on 41 - properties set in regulator node. 42 - 43 - - rohm,short-press-ms : Short press duration in milliseconds 44 - - rohm,long-press-ms : Long press duration in milliseconds 45 - 46 - Configure the "short press" and "long press" timers for the power button. 47 - Values are rounded to what hardware supports (500ms multiple for short and 48 - 1000ms multiple for long). If these properties are not present the existing 49 - configuration (from bootloader or OTP) is not touched. 50 - 51 - Example: 52 - 53 - /* external oscillator node */ 54 - osc: oscillator { 55 - compatible = "fixed-clock"; 56 - #clock-cells = <1>; 57 - clock-frequency = <32768>; 58 - clock-output-names = "osc"; 59 - }; 60 - 61 - pmic: pmic@4b { 62 - compatible = "rohm,bd71837"; 63 - reg = <0x4b>; 64 - interrupt-parent = <&gpio1>; 65 - interrupts = <29 GPIO_ACTIVE_LOW>; 66 - interrupt-names = "irq"; 67 - #clock-cells = <0>; 68 - clocks = <&osc 0>; 69 - clock-output-names = "bd71837-32k-out"; 70 - rohm,reset-snvs-powered; 71 - 72 - regulators { 73 - buck1: BUCK1 { 74 - regulator-name = "buck1"; 75 - regulator-min-microvolt = <700000>; 76 - regulator-max-microvolt = <1300000>; 77 - regulator-boot-on; 78 - regulator-always-on; 79 - regulator-ramp-delay = <1250>; 80 - }; 81 - // [...] 82 - }; 83 - }; 84 - 85 - /* Clock consumer node */ 86 - rtc@0 { 87 - compatible = "company,my-rtc"; 88 - clock-names = "my-clock"; 89 - clocks = <&pmic>; 90 - };
+236
Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/mfd/rohm,bd71837-pmic.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: ROHM BD71837 Power Management Integrated Circuit bindings 8 + 9 + maintainers: 10 + - Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> 11 + 12 + description: | 13 + BD71837MWV is programmable Power Management ICs for powering single-core, 14 + dual-core, and quad-core SoCs such as NXP-i.MX 8M. It is optimized for low 15 + BOM cost and compact solution footprint. BD71837MWV integrates 8 Buck 16 + regulators and 7 LDOs. 17 + Datasheet for BD71837 is available at 18 + https://www.rohm.com/products/power-management/power-management-ic-for-system/industrial-consumer-applications/nxp-imx/bd71837amwv-product 19 + 20 + properties: 21 + compatible: 22 + const: rohm,bd71837 23 + 24 + reg: 25 + description: 26 + I2C slave address. 27 + maxItems: 1 28 + 29 + interrupts: 30 + maxItems: 1 31 + 32 + clocks: 33 + maxItems: 1 34 + 35 + "#clock-cells": 36 + const: 0 37 + 38 + # The BD718x7 supports two different HW states as reset target states. States 39 + # are called as SNVS and READY. At READY state all the PMIC power outputs go 40 + # down and OTP is reload. At the SNVS state all other logic and external 41 + # devices apart from the SNVS power domain are shut off. Please refer to NXP 42 + # i.MX8 documentation for further information regarding SNVS state. When a 43 + # reset is done via SNVS state the PMIC OTP data is not reload. This causes 44 + # power outputs that have been under SW control to stay down when reset has 45 + # switched power state to SNVS. If reset is done via READY state the power 46 + # outputs will be returned to HW control by OTP loading. Thus the reset 47 + # target state is set to READY by default. If SNVS state is used the boot 48 + # crucial regulators must have the regulator-always-on and regulator-boot-on 49 + # properties set in regulator node. 50 + 51 + rohm,reset-snvs-powered: 52 + description: | 53 + Transfer PMIC to SNVS state at reset 54 + type: boolean 55 + 56 + # Configure the "short press" and "long press" timers for the power button. 57 + # Values are rounded to what hardware supports 58 + # Short-press: 59 + # Shortest being 10ms, next 500ms and then multiple of 500ms up to 7,5s 60 + # Long-press: 61 + # Shortest being 10ms, next 1000ms and then multiple of 1000ms up to 15s 62 + # If these properties are not present the existing configuration (from 63 + # bootloader or OTP) is not touched. 64 + 65 + rohm,short-press-ms: 66 + description: 67 + Short press duration in milliseconds 68 + enum: 69 + - 10 70 + - 500 71 + - 1000 72 + - 1500 73 + - 2000 74 + - 2500 75 + - 3000 76 + - 3500 77 + - 4000 78 + - 4500 79 + - 5000 80 + - 5500 81 + - 6000 82 + - 6500 83 + - 7000 84 + 85 + rohm,long-press-ms: 86 + description: 87 + Long press duration in milliseconds 88 + enum: 89 + - 10 90 + - 1000 91 + - 2000 92 + - 3000 93 + - 4000 94 + - 5000 95 + - 6000 96 + - 7000 97 + - 8000 98 + - 9000 99 + - 10000 100 + - 11000 101 + - 12000 102 + - 13000 103 + - 14000 104 + 105 + regulators: 106 + $ref: ../regulator/rohm,bd71837-regulator.yaml 107 + description: 108 + List of child nodes that specify the regulators. 109 + 110 + required: 111 + - compatible 112 + - reg 113 + - interrupts 114 + - clocks 115 + - "#clock-cells" 116 + - regulators 117 + 118 + additionalProperties: false 119 + 120 + examples: 121 + - | 122 + #include <dt-bindings/interrupt-controller/irq.h> 123 + #include <dt-bindings/leds/common.h> 124 + 125 + i2c { 126 + pmic: pmic@4b { 127 + compatible = "rohm,bd71837"; 128 + reg = <0x4b>; 129 + interrupt-parent = <&gpio1>; 130 + interrupts = <29 IRQ_TYPE_LEVEL_LOW>; 131 + #clock-cells = <0>; 132 + clocks = <&osc 0>; 133 + rohm,reset-snvs-powered; 134 + rohm,short-press-ms = <10>; 135 + rohm,long-press-ms = <2000>; 136 + 137 + regulators { 138 + buck1: BUCK1 { 139 + regulator-name = "buck1"; 140 + regulator-min-microvolt = <700000>; 141 + regulator-max-microvolt = <1300000>; 142 + regulator-boot-on; 143 + regulator-always-on; 144 + regulator-ramp-delay = <1250>; 145 + rohm,dvs-run-voltage = <900000>; 146 + rohm,dvs-idle-voltage = <850000>; 147 + rohm,dvs-suspend-voltage = <800000>; 148 + }; 149 + buck2: BUCK2 { 150 + regulator-name = "buck2"; 151 + regulator-min-microvolt = <700000>; 152 + regulator-max-microvolt = <1300000>; 153 + regulator-boot-on; 154 + regulator-always-on; 155 + regulator-ramp-delay = <1250>; 156 + rohm,dvs-run-voltage = <1000000>; 157 + rohm,dvs-idle-voltage = <900000>; 158 + }; 159 + buck3: BUCK3 { 160 + regulator-name = "buck3"; 161 + regulator-min-microvolt = <700000>; 162 + regulator-max-microvolt = <1300000>; 163 + regulator-boot-on; 164 + rohm,dvs-run-voltage = <1000000>; 165 + }; 166 + buck4: BUCK4 { 167 + regulator-name = "buck4"; 168 + regulator-min-microvolt = <700000>; 169 + regulator-max-microvolt = <1300000>; 170 + regulator-boot-on; 171 + rohm,dvs-run-voltage = <1000000>; 172 + }; 173 + buck5: BUCK5 { 174 + regulator-name = "buck5"; 175 + regulator-min-microvolt = <700000>; 176 + regulator-max-microvolt = <1350000>; 177 + regulator-boot-on; 178 + }; 179 + buck6: BUCK6 { 180 + regulator-name = "buck6"; 181 + regulator-min-microvolt = <3000000>; 182 + regulator-max-microvolt = <3300000>; 183 + regulator-boot-on; 184 + }; 185 + buck7: BUCK7 { 186 + regulator-name = "buck7"; 187 + regulator-min-microvolt = <1605000>; 188 + regulator-max-microvolt = <1995000>; 189 + regulator-boot-on; 190 + }; 191 + buck8: BUCK8 { 192 + regulator-name = "buck8"; 193 + regulator-min-microvolt = <800000>; 194 + regulator-max-microvolt = <1400000>; 195 + }; 196 + 197 + ldo1: LDO1 { 198 + regulator-name = "ldo1"; 199 + regulator-min-microvolt = <3000000>; 200 + regulator-max-microvolt = <3300000>; 201 + regulator-boot-on; 202 + }; 203 + ldo2: LDO2 { 204 + regulator-name = "ldo2"; 205 + regulator-min-microvolt = <900000>; 206 + regulator-max-microvolt = <900000>; 207 + regulator-boot-on; 208 + }; 209 + ldo3: LDO3 { 210 + regulator-name = "ldo3"; 211 + regulator-min-microvolt = <1800000>; 212 + regulator-max-microvolt = <3300000>; 213 + }; 214 + ldo4: LDO4 { 215 + regulator-name = "ldo4"; 216 + regulator-min-microvolt = <900000>; 217 + regulator-max-microvolt = <1800000>; 218 + }; 219 + ldo5: LDO5 { 220 + regulator-name = "ldo5"; 221 + regulator-min-microvolt = <1800000>; 222 + regulator-max-microvolt = <3300000>; 223 + }; 224 + ldo6: LDO6 { 225 + regulator-name = "ldo6"; 226 + regulator-min-microvolt = <900000>; 227 + regulator-max-microvolt = <1800000>; 228 + }; 229 + ldo7_reg: LDO7 { 230 + regulator-name = "ldo7"; 231 + regulator-min-microvolt = <1800000>; 232 + regulator-max-microvolt = <3300000>; 233 + }; 234 + }; 235 + }; 236 + };
+222
Documentation/devicetree/bindings/mfd/rohm,bd71847-pmic.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/mfd/rohm,bd71847-pmic.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: ROHM BD71847 and BD71850 Power Management Integrated Circuit bindings 8 + 9 + maintainers: 10 + - Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> 11 + 12 + description: | 13 + BD71847AMWV and BD71850MWV are programmable Power Management ICs for powering 14 + single-core, dual-core, and quad-core SoCs such as NXP-i.MX 8M. It is 15 + optimized for low BOM cost and compact solution footprint. BD71847MWV and 16 + BD71850MWV integrate 6 Buck regulators and 6 LDOs. 17 + Datasheets are available at 18 + https://www.rohm.com/products/power-management/power-management-ic-for-system/industrial-consumer-applications/nxp-imx/bd71847amwv-product 19 + https://www.rohm.com/products/power-management/power-management-ic-for-system/industrial-consumer-applications/nxp-imx/bd71850mwv-product 20 + 21 + properties: 22 + compatible: 23 + enum: 24 + - rohm,bd71847 25 + - rohm,bd71850 26 + 27 + reg: 28 + description: 29 + I2C slave address. 30 + maxItems: 1 31 + 32 + interrupts: 33 + maxItems: 1 34 + 35 + clocks: 36 + maxItems: 1 37 + 38 + "#clock-cells": 39 + const: 0 40 + 41 + # The BD71847 abd BD71850 support two different HW states as reset target 42 + # states. States are called as SNVS and READY. At READY state all the PMIC 43 + # power outputs go down and OTP is reload. At the SNVS state all other logic 44 + # and external devices apart from the SNVS power domain are shut off. Please 45 + # refer to NXP i.MX8 documentation for further information regarding SNVS 46 + # state. When a reset is done via SNVS state the PMIC OTP data is not reload. 47 + # This causes power outputs that have been under SW control to stay down when 48 + # reset has switched power state to SNVS. If reset is done via READY state the 49 + # power outputs will be returned to HW control by OTP loading. Thus the reset 50 + # target state is set to READY by default. If SNVS state is used the boot 51 + # crucial regulators must have the regulator-always-on and regulator-boot-on 52 + # properties set in regulator node. 53 + 54 + rohm,reset-snvs-powered: 55 + description: 56 + Transfer PMIC to SNVS state at reset. 57 + type: boolean 58 + 59 + # Configure the "short press" and "long press" timers for the power button. 60 + # Values are rounded to what hardware supports 61 + # Short-press: 62 + # Shortest being 10ms, next 500ms and then multiple of 500ms up to 7,5s 63 + # Long-press: 64 + # Shortest being 10ms, next 1000ms and then multiple of 1000ms up to 15s 65 + # If these properties are not present the existing # configuration (from 66 + # bootloader or OTP) is not touched. 67 + 68 + rohm,short-press-ms: 69 + description: 70 + Short press duration in milliseconds 71 + enum: 72 + - 10 73 + - 500 74 + - 1000 75 + - 1500 76 + - 2000 77 + - 2500 78 + - 3000 79 + - 3500 80 + - 4000 81 + - 4500 82 + - 5000 83 + - 5500 84 + - 6000 85 + - 6500 86 + - 7000 87 + - 7500 88 + 89 + rohm,long-press-ms: 90 + description: 91 + Long press duration in milliseconds 92 + enum: 93 + - 10 94 + - 1000 95 + - 2000 96 + - 3000 97 + - 4000 98 + - 5000 99 + - 6000 100 + - 7000 101 + - 8000 102 + - 9000 103 + - 10000 104 + - 11000 105 + - 12000 106 + - 13000 107 + - 14000 108 + - 15000 109 + 110 + regulators: 111 + $ref: ../regulator/rohm,bd71847-regulator.yaml 112 + description: 113 + List of child nodes that specify the regulators. 114 + 115 + required: 116 + - compatible 117 + - reg 118 + - interrupts 119 + - clocks 120 + - "#clock-cells" 121 + - regulators 122 + 123 + additionalProperties: false 124 + 125 + examples: 126 + - | 127 + #include <dt-bindings/interrupt-controller/irq.h> 128 + #include <dt-bindings/leds/common.h> 129 + 130 + i2c { 131 + pmic: pmic@4b { 132 + compatible = "rohm,bd71847"; 133 + reg = <0x4b>; 134 + interrupt-parent = <&gpio1>; 135 + interrupts = <29 IRQ_TYPE_LEVEL_LOW>; 136 + #clock-cells = <0>; 137 + clocks = <&osc 0>; 138 + rohm,reset-snvs-powered; 139 + rohm,short-press-ms = <10>; 140 + rohm,long-press-ms = <2000>; 141 + 142 + regulators { 143 + buck1: BUCK1 { 144 + regulator-name = "buck1"; 145 + regulator-min-microvolt = <700000>; 146 + regulator-max-microvolt = <1300000>; 147 + regulator-boot-on; 148 + regulator-always-on; 149 + regulator-ramp-delay = <1250>; 150 + rohm,dvs-run-voltage = <900000>; 151 + rohm,dvs-idle-voltage = <850000>; 152 + rohm,dvs-suspend-voltage = <800000>; 153 + }; 154 + buck2: BUCK2 { 155 + regulator-name = "buck2"; 156 + regulator-min-microvolt = <700000>; 157 + regulator-max-microvolt = <1300000>; 158 + regulator-boot-on; 159 + regulator-always-on; 160 + regulator-ramp-delay = <1250>; 161 + rohm,dvs-run-voltage = <1000000>; 162 + rohm,dvs-idle-voltage = <900000>; 163 + }; 164 + buck3: BUCK3 { 165 + regulator-name = "buck3"; 166 + regulator-min-microvolt = <550000>; 167 + regulator-max-microvolt = <1350000>; 168 + regulator-boot-on; 169 + }; 170 + buck4: BUCK4 { 171 + regulator-name = "buck4"; 172 + regulator-min-microvolt = <2600000>; 173 + regulator-max-microvolt = <3300000>; 174 + regulator-boot-on; 175 + }; 176 + buck5: BUCK5 { 177 + regulator-name = "buck5"; 178 + regulator-min-microvolt = <1605000>; 179 + regulator-max-microvolt = <1995000>; 180 + regulator-boot-on; 181 + }; 182 + buck8: BUCK6 { 183 + regulator-name = "buck6"; 184 + regulator-min-microvolt = <800000>; 185 + regulator-max-microvolt = <1400000>; 186 + }; 187 + 188 + ldo1: LDO1 { 189 + regulator-name = "ldo1"; 190 + regulator-min-microvolt = <1600000>; 191 + regulator-max-microvolt = <3300000>; 192 + regulator-boot-on; 193 + }; 194 + ldo2: LDO2 { 195 + regulator-name = "ldo2"; 196 + regulator-min-microvolt = <800000>; 197 + regulator-max-microvolt = <900000>; 198 + regulator-boot-on; 199 + }; 200 + ldo3: LDO3 { 201 + regulator-name = "ldo3"; 202 + regulator-min-microvolt = <1800000>; 203 + regulator-max-microvolt = <3300000>; 204 + }; 205 + ldo4: LDO4 { 206 + regulator-name = "ldo4"; 207 + regulator-min-microvolt = <900000>; 208 + regulator-max-microvolt = <1800000>; 209 + }; 210 + ldo5: LDO5 { 211 + regulator-name = "ldo5"; 212 + regulator-min-microvolt = <800000>; 213 + regulator-max-microvolt = <3300000>; 214 + }; 215 + ldo6: LDO6 { 216 + regulator-name = "ldo6"; 217 + regulator-min-microvolt = <900000>; 218 + regulator-max-microvolt = <1800000>; 219 + }; 220 + }; 221 + }; 222 + };
+16
Documentation/devicetree/bindings/mfd/st,stm32-lptimer.yaml
··· 39 39 "#size-cells": 40 40 const: 0 41 41 42 + wakeup-source: true 43 + 42 44 pwm: 43 45 type: object 44 46 ··· 83 81 required: 84 82 - compatible 85 83 84 + timer: 85 + type: object 86 + 87 + properties: 88 + compatible: 89 + const: st,stm32-lptimer-timer 90 + 91 + required: 92 + - compatible 93 + 86 94 required: 87 95 - "#address-cells" 88 96 - "#size-cells" ··· 126 114 127 115 counter { 128 116 compatible = "st,stm32-lptimer-counter"; 117 + }; 118 + 119 + timer { 120 + compatible = "st,stm32-lptimer-timer"; 129 121 }; 130 122 }; 131 123
+32
Documentation/devicetree/bindings/pwm/iqs620a-pwm.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/pwm/iqs620a-pwm.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Azoteq IQS620A PWM Generator 8 + 9 + maintainers: 10 + - Jeff LaBundy <jeff@labundy.com> 11 + 12 + description: | 13 + The Azoteq IQS620A multi-function sensor generates a fixed-frequency PWM 14 + output represented by a "pwm" child node from the parent MFD driver. See 15 + Documentation/devicetree/bindings/mfd/iqs62x.yaml for further details as 16 + well as an example. 17 + 18 + properties: 19 + compatible: 20 + enum: 21 + - azoteq,iqs620a-pwm 22 + 23 + "#pwm-cells": 24 + const: 2 25 + 26 + required: 27 + - compatible 28 + - "#pwm-cells" 29 + 30 + additionalProperties: false 31 + 32 + ...
-162
Documentation/devicetree/bindings/regulator/rohm,bd71837-regulator.txt
··· 1 - ROHM BD71837 and BD71847 Power Management Integrated Circuit regulator bindings 2 - 3 - Required properties: 4 - - regulator-name: should be "buck1", ..., "buck8" and "ldo1", ..., "ldo7" for 5 - BD71837. For BD71847 names should be "buck1", ..., "buck6" 6 - and "ldo1", ..., "ldo6" 7 - 8 - List of regulators provided by this controller. BD71837 regulators node 9 - should be sub node of the BD71837 MFD node. See BD71837 MFD bindings at 10 - Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.txt 11 - Regulator nodes should be named to BUCK_<number> and LDO_<number>. The 12 - definition for each of these nodes is defined using the standard 13 - binding for regulators at 14 - Documentation/devicetree/bindings/regulator/regulator.txt. 15 - Note that if BD71837 starts at RUN state you probably want to use 16 - regulator-boot-on at least for BUCK6 and BUCK7 so that those are not 17 - disabled by driver at startup. LDO5 and LDO6 are supplied by those and 18 - if they are disabled at startup the voltage monitoring for LDO5/LDO6 will 19 - cause PMIC to reset. 20 - 21 - The valid names for BD71837 regulator nodes are: 22 - BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, BUCK7, BUCK8 23 - LDO1, LDO2, LDO3, LDO4, LDO5, LDO6, LDO7 24 - 25 - The valid names for BD71847 regulator nodes are: 26 - BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6 27 - LDO1, LDO2, LDO3, LDO4, LDO5, LDO6 28 - 29 - Optional properties: 30 - - rohm,dvs-run-voltage : PMIC default "RUN" state voltage in uV. 31 - See below table for bucks which support this. 32 - - rohm,dvs-idle-voltage : PMIC default "IDLE" state voltage in uV. 33 - See below table for bucks which support this. 34 - - rohm,dvs-suspend-voltage : PMIC default "SUSPEND" state voltage in uV. 35 - See below table for bucks which support this. 36 - - Any optional property defined in bindings/regulator/regulator.txt 37 - 38 - Supported default DVS states: 39 - 40 - BD71837: 41 - buck | dvs-run-voltage | dvs-idle-voltage | dvs-suspend-voltage 42 - ----------------------------------------------------------------------------- 43 - 1 | supported | supported | supported 44 - ---------------------------------------------------------------------------- 45 - 2 | supported | supported | not supported 46 - ---------------------------------------------------------------------------- 47 - 3 | supported | not supported | not supported 48 - ---------------------------------------------------------------------------- 49 - 4 | supported | not supported | not supported 50 - ---------------------------------------------------------------------------- 51 - rest | not supported | not supported | not supported 52 - 53 - BD71847: 54 - buck | dvs-run-voltage | dvs-idle-voltage | dvs-suspend-voltage 55 - ----------------------------------------------------------------------------- 56 - 1 | supported | supported | supported 57 - ---------------------------------------------------------------------------- 58 - 2 | supported | supported | not supported 59 - ---------------------------------------------------------------------------- 60 - rest | not supported | not supported | not supported 61 - 62 - Example: 63 - regulators { 64 - buck1: BUCK1 { 65 - regulator-name = "buck1"; 66 - regulator-min-microvolt = <700000>; 67 - regulator-max-microvolt = <1300000>; 68 - regulator-boot-on; 69 - regulator-always-on; 70 - regulator-ramp-delay = <1250>; 71 - rohm,dvs-run-voltage = <900000>; 72 - rohm,dvs-idle-voltage = <850000>; 73 - rohm,dvs-suspend-voltage = <800000>; 74 - }; 75 - buck2: BUCK2 { 76 - regulator-name = "buck2"; 77 - regulator-min-microvolt = <700000>; 78 - regulator-max-microvolt = <1300000>; 79 - regulator-boot-on; 80 - regulator-always-on; 81 - regulator-ramp-delay = <1250>; 82 - rohm,dvs-run-voltage = <1000000>; 83 - rohm,dvs-idle-voltage = <900000>; 84 - }; 85 - buck3: BUCK3 { 86 - regulator-name = "buck3"; 87 - regulator-min-microvolt = <700000>; 88 - regulator-max-microvolt = <1300000>; 89 - regulator-boot-on; 90 - rohm,dvs-run-voltage = <1000000>; 91 - }; 92 - buck4: BUCK4 { 93 - regulator-name = "buck4"; 94 - regulator-min-microvolt = <700000>; 95 - regulator-max-microvolt = <1300000>; 96 - regulator-boot-on; 97 - rohm,dvs-run-voltage = <1000000>; 98 - }; 99 - buck5: BUCK5 { 100 - regulator-name = "buck5"; 101 - regulator-min-microvolt = <700000>; 102 - regulator-max-microvolt = <1350000>; 103 - regulator-boot-on; 104 - }; 105 - buck6: BUCK6 { 106 - regulator-name = "buck6"; 107 - regulator-min-microvolt = <3000000>; 108 - regulator-max-microvolt = <3300000>; 109 - regulator-boot-on; 110 - }; 111 - buck7: BUCK7 { 112 - regulator-name = "buck7"; 113 - regulator-min-microvolt = <1605000>; 114 - regulator-max-microvolt = <1995000>; 115 - regulator-boot-on; 116 - }; 117 - buck8: BUCK8 { 118 - regulator-name = "buck8"; 119 - regulator-min-microvolt = <800000>; 120 - regulator-max-microvolt = <1400000>; 121 - }; 122 - 123 - ldo1: LDO1 { 124 - regulator-name = "ldo1"; 125 - regulator-min-microvolt = <3000000>; 126 - regulator-max-microvolt = <3300000>; 127 - regulator-boot-on; 128 - }; 129 - ldo2: LDO2 { 130 - regulator-name = "ldo2"; 131 - regulator-min-microvolt = <900000>; 132 - regulator-max-microvolt = <900000>; 133 - regulator-boot-on; 134 - }; 135 - ldo3: LDO3 { 136 - regulator-name = "ldo3"; 137 - regulator-min-microvolt = <1800000>; 138 - regulator-max-microvolt = <3300000>; 139 - }; 140 - ldo4: LDO4 { 141 - regulator-name = "ldo4"; 142 - regulator-min-microvolt = <900000>; 143 - regulator-max-microvolt = <1800000>; 144 - }; 145 - ldo5: LDO5 { 146 - regulator-name = "ldo5"; 147 - regulator-min-microvolt = <1800000>; 148 - regulator-max-microvolt = <3300000>; 149 - }; 150 - ldo6: LDO6 { 151 - regulator-name = "ldo6"; 152 - regulator-min-microvolt = <900000>; 153 - regulator-max-microvolt = <1800000>; 154 - }; 155 - ldo7_reg: LDO7 { 156 - regulator-name = "ldo7"; 157 - regulator-min-microvolt = <1800000>; 158 - regulator-max-microvolt = <3300000>; 159 - }; 160 - }; 161 - 162 -
+103
Documentation/devicetree/bindings/regulator/rohm,bd71837-regulator.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/regulator/rohm,bd71837-regulator.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: ROHM BD71837 Power Management Integrated Circuit regulators 8 + 9 + maintainers: 10 + - Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> 11 + 12 + description: | 13 + List of regulators provided by this controller. BD71837 regulators node 14 + should be sub node of the BD71837 MFD node. See BD71837 MFD bindings at 15 + Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.yaml 16 + Regulator nodes should be named to BUCK_<number> and LDO_<number>. The 17 + definition for each of these nodes is defined using the standard 18 + binding for regulators at 19 + Documentation/devicetree/bindings/regulator/regulator.txt. 20 + Note that if BD71837 starts at RUN state you probably want to use 21 + regulator-boot-on at least for BUCK6 and BUCK7 so that those are not 22 + disabled by driver at startup. LDO5 and LDO6 are supplied by those and 23 + if they are disabled at startup the voltage monitoring for LDO5/LDO6 will 24 + cause PMIC to reset. 25 + 26 + #The valid names for BD71837 regulator nodes are: 27 + #BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, BUCK7, BUCK8 28 + #LDO1, LDO2, LDO3, LDO4, LDO5, LDO6, LDO7 29 + 30 + patternProperties: 31 + "^LDO[1-7]$": 32 + type: object 33 + allOf: 34 + - $ref: regulator.yaml# 35 + description: 36 + Properties for single LDO regulator. 37 + 38 + properties: 39 + regulator-name: 40 + pattern: "^ldo[1-7]$" 41 + description: 42 + should be "ldo1", ..., "ldo7" 43 + 44 + "^BUCK[1-8]$": 45 + type: object 46 + allOf: 47 + - $ref: regulator.yaml# 48 + description: 49 + Properties for single BUCK regulator. 50 + 51 + properties: 52 + regulator-name: 53 + pattern: "^buck[1-8]$" 54 + description: 55 + should be "buck1", ..., "buck8" 56 + 57 + rohm,dvs-run-voltage: 58 + allOf: 59 + - $ref: "/schemas/types.yaml#/definitions/uint32" 60 + - minimum: 0 61 + maximum: 1300000 62 + description: 63 + PMIC default "RUN" state voltage in uV. See below table for 64 + bucks which support this. 0 means disabled. 65 + 66 + rohm,dvs-idle-voltage: 67 + allOf: 68 + - $ref: "/schemas/types.yaml#/definitions/uint32" 69 + - minimum: 0 70 + maximum: 1300000 71 + description: 72 + PMIC default "IDLE" state voltage in uV. See below table for 73 + bucks which support this. 0 means disabled. 74 + 75 + rohm,dvs-suspend-voltage: 76 + allOf: 77 + - $ref: "/schemas/types.yaml#/definitions/uint32" 78 + - minimum: 0 79 + maximum: 1300000 80 + description: 81 + PMIC default "SUSPEND" state voltage in uV. See below table for 82 + bucks which support this. 0 means disabled. 83 + 84 + # Supported default DVS states: 85 + # 86 + # BD71837: 87 + # buck | dvs-run-voltage | dvs-idle-voltage | dvs-suspend-voltage 88 + # ---------------------------------------------------------------- 89 + # 1 | supported | supported | supported 90 + # ---------------------------------------------------------------- 91 + # 2 | supported | supported | not supported 92 + # ---------------------------------------------------------------- 93 + # 3 | supported | not supported | not supported 94 + # ---------------------------------------------------------------- 95 + # 4 | supported | not supported | not supported 96 + # ---------------------------------------------------------------- 97 + # rest | not supported | not supported | not supported 98 + 99 + 100 + required: 101 + - regulator-name 102 + additionalProperties: false 103 + additionalProperties: false
+97
Documentation/devicetree/bindings/regulator/rohm,bd71847-regulator.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/regulator/rohm,bd71847-regulator.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: ROHM BD71847 and BD71850 Power Management Integrated Circuit regulators 8 + 9 + maintainers: 10 + - Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> 11 + 12 + description: | 13 + List of regulators provided by this controller. BD71847 regulators node 14 + should be sub node of the BD71847 MFD node. See BD71847 MFD bindings at 15 + Documentation/devicetree/bindings/mfd/rohm,bd71847-pmic.yaml 16 + Regulator nodes should be named to BUCK_<number> and LDO_<number>. The 17 + definition for each of these nodes is defined using the standard 18 + binding for regulators at 19 + Documentation/devicetree/bindings/regulator/regulator.txt. 20 + Note that if BD71847 starts at RUN state you probably want to use 21 + regulator-boot-on at least for BUCK5. LDO6 is supplied by it and it must 22 + not be disabled by driver at startup. If BUCK5 is disabled at startup the 23 + voltage monitoring for LDO5/LDO6 can cause PMIC to reset. 24 + 25 + #The valid names for BD71847 regulator nodes are: 26 + #BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6 27 + #LDO1, LDO2, LDO3, LDO4, LDO5, LDO6 28 + 29 + patternProperties: 30 + "^LDO[1-6]$": 31 + type: object 32 + allOf: 33 + - $ref: regulator.yaml# 34 + description: 35 + Properties for single LDO regulator. 36 + 37 + properties: 38 + regulator-name: 39 + pattern: "^ldo[1-6]$" 40 + description: 41 + should be "ldo1", ..., "ldo6" 42 + 43 + "^BUCK[1-6]$": 44 + type: object 45 + allOf: 46 + - $ref: regulator.yaml# 47 + description: 48 + Properties for single BUCK regulator. 49 + 50 + properties: 51 + regulator-name: 52 + pattern: "^buck[1-6]$" 53 + description: 54 + should be "buck1", ..., "buck6" 55 + 56 + rohm,dvs-run-voltage: 57 + allOf: 58 + - $ref: "/schemas/types.yaml#/definitions/uint32" 59 + - minimum: 0 60 + maximum: 1300000 61 + description: 62 + PMIC default "RUN" state voltage in uV. See below table for 63 + bucks which support this. 0 means disabled. 64 + 65 + rohm,dvs-idle-voltage: 66 + allOf: 67 + - $ref: "/schemas/types.yaml#/definitions/uint32" 68 + - minimum: 0 69 + maximum: 1300000 70 + description: 71 + PMIC default "IDLE" state voltage in uV. See below table for 72 + bucks which support this. 0 means disabled. 73 + 74 + rohm,dvs-suspend-voltage: 75 + allOf: 76 + - $ref: "/schemas/types.yaml#/definitions/uint32" 77 + - minimum: 0 78 + maximum: 1300000 79 + description: 80 + PMIC default "SUSPEND" state voltage in uV. See below table for 81 + bucks which support this. 0 means disabled. 82 + 83 + # Supported default DVS states: 84 + # 85 + # BD71847: 86 + # buck | dvs-run-voltage | dvs-idle-voltage | dvs-suspend-voltage 87 + # ---------------------------------------------------------------- 88 + # 1 | supported | supported | supported 89 + # ---------------------------------------------------------------- 90 + # 2 | supported | supported | not supported 91 + # ---------------------------------------------------------------- 92 + # rest | not supported | not supported | not supported 93 + 94 + required: 95 + - regulator-name 96 + additionalProperties: false 97 + additionalProperties: false
+1
drivers/iio/Kconfig
··· 88 88 if IIO_TRIGGER 89 89 source "drivers/iio/trigger/Kconfig" 90 90 endif #IIO_TRIGGER 91 + source "drivers/iio/position/Kconfig" 91 92 source "drivers/iio/potentiometer/Kconfig" 92 93 source "drivers/iio/potentiostat/Kconfig" 93 94 source "drivers/iio/pressure/Kconfig"
+1
drivers/iio/Makefile
··· 31 31 obj-y += magnetometer/ 32 32 obj-y += multiplexer/ 33 33 obj-y += orientation/ 34 + obj-y += position/ 34 35 obj-y += potentiometer/ 35 36 obj-y += potentiostat/ 36 37 obj-y += pressure/
+10
drivers/iio/adc/Kconfig
··· 795 795 To compile this driver as a module, choose M here: the 796 796 module will be called rcar-gyroadc. 797 797 798 + config RN5T618_ADC 799 + tristate "ADC for the RN5T618/RC5T619 family of chips" 800 + depends on MFD_RN5T618 801 + help 802 + Say yes here to build support for the integrated ADC inside the 803 + RN5T618/619 series PMICs: 804 + 805 + This driver can also be built as a module. If so, the module 806 + will be called rn5t618-adc. 807 + 798 808 config ROCKCHIP_SARADC 799 809 tristate "Rockchip SARADC driver" 800 810 depends on ARCH_ROCKCHIP || (ARM && COMPILE_TEST)
+1
drivers/iio/adc/Makefile
··· 75 75 obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o 76 76 obj-$(CONFIG_QCOM_PM8XXX_XOADC) += qcom-pm8xxx-xoadc.o 77 77 obj-$(CONFIG_RCAR_GYRO_ADC) += rcar-gyroadc.o 78 + obj-$(CONFIG_RN5T618_ADC) += rn5t618-adc.o 78 79 obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o 79 80 obj-$(CONFIG_SC27XX_ADC) += sc27xx_adc.o 80 81 obj-$(CONFIG_SPEAR_ADC) += spear_adc.o
+256
drivers/iio/adc/rn5t618-adc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * ADC driver for the RICOH RN5T618 power management chip family 4 + * 5 + * Copyright (C) 2019 Andreas Kemnade 6 + */ 7 + 8 + #include <linux/kernel.h> 9 + #include <linux/device.h> 10 + #include <linux/errno.h> 11 + #include <linux/interrupt.h> 12 + #include <linux/init.h> 13 + #include <linux/module.h> 14 + #include <linux/mfd/rn5t618.h> 15 + #include <linux/platform_device.h> 16 + #include <linux/completion.h> 17 + #include <linux/regmap.h> 18 + #include <linux/iio/iio.h> 19 + #include <linux/slab.h> 20 + 21 + #define RN5T618_ADC_CONVERSION_TIMEOUT (msecs_to_jiffies(500)) 22 + #define RN5T618_REFERENCE_VOLT 2500 23 + 24 + /* mask for selecting channels for single conversion */ 25 + #define RN5T618_ADCCNT3_CHANNEL_MASK 0x7 26 + /* average 4-time conversion mode */ 27 + #define RN5T618_ADCCNT3_AVG BIT(3) 28 + /* set for starting a single conversion, gets cleared by hw when done */ 29 + #define RN5T618_ADCCNT3_GODONE BIT(4) 30 + /* automatic conversion, period is in ADCCNT2, selected channels are 31 + * in ADCCNT1 32 + */ 33 + #define RN5T618_ADCCNT3_AUTO BIT(5) 34 + #define RN5T618_ADCEND_IRQ BIT(0) 35 + 36 + struct rn5t618_adc_data { 37 + struct device *dev; 38 + struct rn5t618 *rn5t618; 39 + struct completion conv_completion; 40 + int irq; 41 + }; 42 + 43 + struct rn5t618_channel_ratios { 44 + u16 numerator; 45 + u16 denominator; 46 + }; 47 + 48 + enum rn5t618_channels { 49 + LIMMON = 0, 50 + VBAT, 51 + VADP, 52 + VUSB, 53 + VSYS, 54 + VTHM, 55 + AIN1, 56 + AIN0 57 + }; 58 + 59 + static const struct rn5t618_channel_ratios rn5t618_ratios[8] = { 60 + [LIMMON] = {50, 32}, /* measured across 20mOhm, amplified by 32 */ 61 + [VBAT] = {2, 1}, 62 + [VADP] = {3, 1}, 63 + [VUSB] = {3, 1}, 64 + [VSYS] = {3, 1}, 65 + [VTHM] = {1, 1}, 66 + [AIN1] = {1, 1}, 67 + [AIN0] = {1, 1}, 68 + }; 69 + 70 + static int rn5t618_read_adc_reg(struct rn5t618 *rn5t618, int reg, u16 *val) 71 + { 72 + u8 data[2]; 73 + int ret; 74 + 75 + ret = regmap_bulk_read(rn5t618->regmap, reg, data, sizeof(data)); 76 + if (ret < 0) 77 + return ret; 78 + 79 + *val = (data[0] << 4) | (data[1] & 0xF); 80 + 81 + return 0; 82 + } 83 + 84 + static irqreturn_t rn5t618_adc_irq(int irq, void *data) 85 + { 86 + struct rn5t618_adc_data *adc = data; 87 + unsigned int r = 0; 88 + int ret; 89 + 90 + /* clear low & high threshold irqs */ 91 + regmap_write(adc->rn5t618->regmap, RN5T618_IR_ADC1, 0); 92 + regmap_write(adc->rn5t618->regmap, RN5T618_IR_ADC2, 0); 93 + 94 + ret = regmap_read(adc->rn5t618->regmap, RN5T618_IR_ADC3, &r); 95 + if (ret < 0) 96 + dev_err(adc->dev, "failed to read IRQ status: %d\n", ret); 97 + 98 + regmap_write(adc->rn5t618->regmap, RN5T618_IR_ADC3, 0); 99 + 100 + if (r & RN5T618_ADCEND_IRQ) 101 + complete(&adc->conv_completion); 102 + 103 + return IRQ_HANDLED; 104 + } 105 + 106 + static int rn5t618_adc_read(struct iio_dev *iio_dev, 107 + const struct iio_chan_spec *chan, 108 + int *val, int *val2, long mask) 109 + { 110 + struct rn5t618_adc_data *adc = iio_priv(iio_dev); 111 + u16 raw; 112 + int ret; 113 + 114 + if (mask == IIO_CHAN_INFO_SCALE) { 115 + *val = RN5T618_REFERENCE_VOLT * 116 + rn5t618_ratios[chan->channel].numerator; 117 + *val2 = rn5t618_ratios[chan->channel].denominator * 4095; 118 + 119 + return IIO_VAL_FRACTIONAL; 120 + } 121 + 122 + /* select channel */ 123 + ret = regmap_update_bits(adc->rn5t618->regmap, RN5T618_ADCCNT3, 124 + RN5T618_ADCCNT3_CHANNEL_MASK, 125 + chan->channel); 126 + if (ret < 0) 127 + return ret; 128 + 129 + ret = regmap_write(adc->rn5t618->regmap, RN5T618_EN_ADCIR3, 130 + RN5T618_ADCEND_IRQ); 131 + if (ret < 0) 132 + return ret; 133 + 134 + ret = regmap_update_bits(adc->rn5t618->regmap, RN5T618_ADCCNT3, 135 + RN5T618_ADCCNT3_AVG, 136 + mask == IIO_CHAN_INFO_AVERAGE_RAW ? 137 + RN5T618_ADCCNT3_AVG : 0); 138 + if (ret < 0) 139 + return ret; 140 + 141 + init_completion(&adc->conv_completion); 142 + /* single conversion */ 143 + ret = regmap_update_bits(adc->rn5t618->regmap, RN5T618_ADCCNT3, 144 + RN5T618_ADCCNT3_GODONE, 145 + RN5T618_ADCCNT3_GODONE); 146 + if (ret < 0) 147 + return ret; 148 + 149 + ret = wait_for_completion_timeout(&adc->conv_completion, 150 + RN5T618_ADC_CONVERSION_TIMEOUT); 151 + if (ret == 0) { 152 + dev_warn(adc->dev, "timeout waiting for adc result\n"); 153 + return -ETIMEDOUT; 154 + } 155 + 156 + ret = rn5t618_read_adc_reg(adc->rn5t618, 157 + RN5T618_ILIMDATAH + 2 * chan->channel, 158 + &raw); 159 + if (ret < 0) 160 + return ret; 161 + 162 + *val = raw; 163 + 164 + return IIO_VAL_INT; 165 + } 166 + 167 + static const struct iio_info rn5t618_adc_iio_info = { 168 + .read_raw = &rn5t618_adc_read, 169 + }; 170 + 171 + #define RN5T618_ADC_CHANNEL(_channel, _type, _name) { \ 172 + .type = _type, \ 173 + .channel = _channel, \ 174 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ 175 + BIT(IIO_CHAN_INFO_AVERAGE_RAW) | \ 176 + BIT(IIO_CHAN_INFO_SCALE), \ 177 + .datasheet_name = _name, \ 178 + .indexed = 1. \ 179 + } 180 + 181 + static const struct iio_chan_spec rn5t618_adc_iio_channels[] = { 182 + RN5T618_ADC_CHANNEL(LIMMON, IIO_CURRENT, "LIMMON"), 183 + RN5T618_ADC_CHANNEL(VBAT, IIO_VOLTAGE, "VBAT"), 184 + RN5T618_ADC_CHANNEL(VADP, IIO_VOLTAGE, "VADP"), 185 + RN5T618_ADC_CHANNEL(VUSB, IIO_VOLTAGE, "VUSB"), 186 + RN5T618_ADC_CHANNEL(VSYS, IIO_VOLTAGE, "VSYS"), 187 + RN5T618_ADC_CHANNEL(VTHM, IIO_VOLTAGE, "VTHM"), 188 + RN5T618_ADC_CHANNEL(AIN1, IIO_VOLTAGE, "AIN1"), 189 + RN5T618_ADC_CHANNEL(AIN0, IIO_VOLTAGE, "AIN0") 190 + }; 191 + 192 + static int rn5t618_adc_probe(struct platform_device *pdev) 193 + { 194 + int ret; 195 + struct iio_dev *iio_dev; 196 + struct rn5t618_adc_data *adc; 197 + struct rn5t618 *rn5t618 = dev_get_drvdata(pdev->dev.parent); 198 + 199 + iio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc)); 200 + if (!iio_dev) { 201 + dev_err(&pdev->dev, "failed allocating iio device\n"); 202 + return -ENOMEM; 203 + } 204 + 205 + adc = iio_priv(iio_dev); 206 + adc->dev = &pdev->dev; 207 + adc->rn5t618 = rn5t618; 208 + 209 + if (rn5t618->irq_data) 210 + adc->irq = regmap_irq_get_virq(rn5t618->irq_data, 211 + RN5T618_IRQ_ADC); 212 + 213 + if (adc->irq <= 0) { 214 + dev_err(&pdev->dev, "get virq failed\n"); 215 + return -EINVAL; 216 + } 217 + 218 + init_completion(&adc->conv_completion); 219 + 220 + iio_dev->name = dev_name(&pdev->dev); 221 + iio_dev->dev.parent = &pdev->dev; 222 + iio_dev->info = &rn5t618_adc_iio_info; 223 + iio_dev->modes = INDIO_DIRECT_MODE; 224 + iio_dev->channels = rn5t618_adc_iio_channels; 225 + iio_dev->num_channels = ARRAY_SIZE(rn5t618_adc_iio_channels); 226 + 227 + /* stop any auto-conversion */ 228 + ret = regmap_write(rn5t618->regmap, RN5T618_ADCCNT3, 0); 229 + if (ret < 0) 230 + return ret; 231 + 232 + platform_set_drvdata(pdev, iio_dev); 233 + 234 + ret = devm_request_threaded_irq(adc->dev, adc->irq, NULL, 235 + rn5t618_adc_irq, 236 + IRQF_ONESHOT, dev_name(adc->dev), 237 + adc); 238 + if (ret < 0) { 239 + dev_err(adc->dev, "request irq %d failed: %d\n", adc->irq, ret); 240 + return ret; 241 + } 242 + 243 + return devm_iio_device_register(adc->dev, iio_dev); 244 + } 245 + 246 + static struct platform_driver rn5t618_adc_driver = { 247 + .driver = { 248 + .name = "rn5t618-adc", 249 + }, 250 + .probe = rn5t618_adc_probe, 251 + }; 252 + 253 + module_platform_driver(rn5t618_adc_driver); 254 + MODULE_ALIAS("platform:rn5t618-adc"); 255 + MODULE_DESCRIPTION("RICOH RN5T618 ADC driver"); 256 + MODULE_LICENSE("GPL");
+10
drivers/iio/light/Kconfig
··· 194 194 To compile this driver as a module, choose M here: the 195 195 module will be called gp2ap020a00f. 196 196 197 + config IQS621_ALS 198 + tristate "Azoteq IQS621/622 ambient light sensors" 199 + depends on MFD_IQS62X || COMPILE_TEST 200 + help 201 + Say Y here if you want to build support for the Azoteq IQS621 202 + and IQS622 ambient light sensors. 203 + 204 + To compile this driver as a module, choose M here: the module 205 + will be called iqs621-als. 206 + 197 207 config SENSORS_ISL29018 198 208 tristate "Intersil 29018 light and proximity sensor" 199 209 depends on I2C
+1
drivers/iio/light/Makefile
··· 23 23 obj-$(CONFIG_GP2AP020A00F) += gp2ap020a00f.o 24 24 obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o 25 25 obj-$(CONFIG_HID_SENSOR_PROX) += hid-sensor-prox.o 26 + obj-$(CONFIG_IQS621_ALS) += iqs621-als.o 26 27 obj-$(CONFIG_SENSORS_ISL29018) += isl29018.o 27 28 obj-$(CONFIG_SENSORS_ISL29028) += isl29028.o 28 29 obj-$(CONFIG_ISL29125) += isl29125.o
+617
drivers/iio/light/iqs621-als.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Azoteq IQS621/622 Ambient Light Sensors 4 + * 5 + * Copyright (C) 2019 Jeff LaBundy <jeff@labundy.com> 6 + */ 7 + 8 + #include <linux/device.h> 9 + #include <linux/iio/events.h> 10 + #include <linux/iio/iio.h> 11 + #include <linux/kernel.h> 12 + #include <linux/mfd/iqs62x.h> 13 + #include <linux/module.h> 14 + #include <linux/mutex.h> 15 + #include <linux/notifier.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/regmap.h> 18 + 19 + #define IQS621_ALS_FLAGS_LIGHT BIT(7) 20 + #define IQS621_ALS_FLAGS_RANGE GENMASK(3, 0) 21 + 22 + #define IQS621_ALS_UI_OUT 0x17 23 + 24 + #define IQS621_ALS_THRESH_DARK 0x80 25 + #define IQS621_ALS_THRESH_LIGHT 0x81 26 + 27 + #define IQS622_IR_RANGE 0x15 28 + #define IQS622_IR_FLAGS 0x16 29 + #define IQS622_IR_FLAGS_TOUCH BIT(1) 30 + #define IQS622_IR_FLAGS_PROX BIT(0) 31 + 32 + #define IQS622_IR_UI_OUT 0x17 33 + 34 + #define IQS622_IR_THRESH_PROX 0x91 35 + #define IQS622_IR_THRESH_TOUCH 0x92 36 + 37 + struct iqs621_als_private { 38 + struct iqs62x_core *iqs62x; 39 + struct notifier_block notifier; 40 + struct mutex lock; 41 + bool light_en; 42 + bool range_en; 43 + bool prox_en; 44 + u8 als_flags; 45 + u8 ir_flags_mask; 46 + u8 ir_flags; 47 + u8 thresh_light; 48 + u8 thresh_dark; 49 + u8 thresh_prox; 50 + }; 51 + 52 + static int iqs621_als_init(struct iqs621_als_private *iqs621_als) 53 + { 54 + struct iqs62x_core *iqs62x = iqs621_als->iqs62x; 55 + unsigned int event_mask = 0; 56 + int ret; 57 + 58 + switch (iqs621_als->ir_flags_mask) { 59 + case IQS622_IR_FLAGS_TOUCH: 60 + ret = regmap_write(iqs62x->regmap, IQS622_IR_THRESH_TOUCH, 61 + iqs621_als->thresh_prox); 62 + break; 63 + 64 + case IQS622_IR_FLAGS_PROX: 65 + ret = regmap_write(iqs62x->regmap, IQS622_IR_THRESH_PROX, 66 + iqs621_als->thresh_prox); 67 + break; 68 + 69 + default: 70 + ret = regmap_write(iqs62x->regmap, IQS621_ALS_THRESH_LIGHT, 71 + iqs621_als->thresh_light); 72 + if (ret) 73 + return ret; 74 + 75 + ret = regmap_write(iqs62x->regmap, IQS621_ALS_THRESH_DARK, 76 + iqs621_als->thresh_dark); 77 + } 78 + 79 + if (ret) 80 + return ret; 81 + 82 + if (iqs621_als->light_en || iqs621_als->range_en) 83 + event_mask |= iqs62x->dev_desc->als_mask; 84 + 85 + if (iqs621_als->prox_en) 86 + event_mask |= iqs62x->dev_desc->ir_mask; 87 + 88 + return regmap_update_bits(iqs62x->regmap, IQS620_GLBL_EVENT_MASK, 89 + event_mask, 0); 90 + } 91 + 92 + static int iqs621_als_notifier(struct notifier_block *notifier, 93 + unsigned long event_flags, void *context) 94 + { 95 + struct iqs62x_event_data *event_data = context; 96 + struct iqs621_als_private *iqs621_als; 97 + struct iio_dev *indio_dev; 98 + bool light_new, light_old; 99 + bool prox_new, prox_old; 100 + u8 range_new, range_old; 101 + s64 timestamp; 102 + int ret; 103 + 104 + iqs621_als = container_of(notifier, struct iqs621_als_private, 105 + notifier); 106 + indio_dev = iio_priv_to_dev(iqs621_als); 107 + timestamp = iio_get_time_ns(indio_dev); 108 + 109 + mutex_lock(&iqs621_als->lock); 110 + 111 + if (event_flags & BIT(IQS62X_EVENT_SYS_RESET)) { 112 + ret = iqs621_als_init(iqs621_als); 113 + if (ret) { 114 + dev_err(indio_dev->dev.parent, 115 + "Failed to re-initialize device: %d\n", ret); 116 + ret = NOTIFY_BAD; 117 + } else { 118 + ret = NOTIFY_OK; 119 + } 120 + 121 + goto err_mutex; 122 + } 123 + 124 + if (!iqs621_als->light_en && !iqs621_als->range_en && 125 + !iqs621_als->prox_en) { 126 + ret = NOTIFY_DONE; 127 + goto err_mutex; 128 + } 129 + 130 + /* IQS621 only */ 131 + light_new = event_data->als_flags & IQS621_ALS_FLAGS_LIGHT; 132 + light_old = iqs621_als->als_flags & IQS621_ALS_FLAGS_LIGHT; 133 + 134 + if (iqs621_als->light_en && light_new && !light_old) 135 + iio_push_event(indio_dev, 136 + IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0, 137 + IIO_EV_TYPE_THRESH, 138 + IIO_EV_DIR_RISING), 139 + timestamp); 140 + else if (iqs621_als->light_en && !light_new && light_old) 141 + iio_push_event(indio_dev, 142 + IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0, 143 + IIO_EV_TYPE_THRESH, 144 + IIO_EV_DIR_FALLING), 145 + timestamp); 146 + 147 + /* IQS621 and IQS622 */ 148 + range_new = event_data->als_flags & IQS621_ALS_FLAGS_RANGE; 149 + range_old = iqs621_als->als_flags & IQS621_ALS_FLAGS_RANGE; 150 + 151 + if (iqs621_als->range_en && (range_new > range_old)) 152 + iio_push_event(indio_dev, 153 + IIO_UNMOD_EVENT_CODE(IIO_INTENSITY, 0, 154 + IIO_EV_TYPE_CHANGE, 155 + IIO_EV_DIR_RISING), 156 + timestamp); 157 + else if (iqs621_als->range_en && (range_new < range_old)) 158 + iio_push_event(indio_dev, 159 + IIO_UNMOD_EVENT_CODE(IIO_INTENSITY, 0, 160 + IIO_EV_TYPE_CHANGE, 161 + IIO_EV_DIR_FALLING), 162 + timestamp); 163 + 164 + /* IQS622 only */ 165 + prox_new = event_data->ir_flags & iqs621_als->ir_flags_mask; 166 + prox_old = iqs621_als->ir_flags & iqs621_als->ir_flags_mask; 167 + 168 + if (iqs621_als->prox_en && prox_new && !prox_old) 169 + iio_push_event(indio_dev, 170 + IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0, 171 + IIO_EV_TYPE_THRESH, 172 + IIO_EV_DIR_RISING), 173 + timestamp); 174 + else if (iqs621_als->prox_en && !prox_new && prox_old) 175 + iio_push_event(indio_dev, 176 + IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0, 177 + IIO_EV_TYPE_THRESH, 178 + IIO_EV_DIR_FALLING), 179 + timestamp); 180 + 181 + iqs621_als->als_flags = event_data->als_flags; 182 + iqs621_als->ir_flags = event_data->ir_flags; 183 + ret = NOTIFY_OK; 184 + 185 + err_mutex: 186 + mutex_unlock(&iqs621_als->lock); 187 + 188 + return ret; 189 + } 190 + 191 + static void iqs621_als_notifier_unregister(void *context) 192 + { 193 + struct iqs621_als_private *iqs621_als = context; 194 + struct iio_dev *indio_dev = iio_priv_to_dev(iqs621_als); 195 + int ret; 196 + 197 + ret = blocking_notifier_chain_unregister(&iqs621_als->iqs62x->nh, 198 + &iqs621_als->notifier); 199 + if (ret) 200 + dev_err(indio_dev->dev.parent, 201 + "Failed to unregister notifier: %d\n", ret); 202 + } 203 + 204 + static int iqs621_als_read_raw(struct iio_dev *indio_dev, 205 + struct iio_chan_spec const *chan, 206 + int *val, int *val2, long mask) 207 + { 208 + struct iqs621_als_private *iqs621_als = iio_priv(indio_dev); 209 + struct iqs62x_core *iqs62x = iqs621_als->iqs62x; 210 + int ret; 211 + __le16 val_buf; 212 + 213 + switch (chan->type) { 214 + case IIO_INTENSITY: 215 + ret = regmap_read(iqs62x->regmap, chan->address, val); 216 + if (ret) 217 + return ret; 218 + 219 + *val &= IQS621_ALS_FLAGS_RANGE; 220 + return IIO_VAL_INT; 221 + 222 + case IIO_PROXIMITY: 223 + case IIO_LIGHT: 224 + ret = regmap_raw_read(iqs62x->regmap, chan->address, &val_buf, 225 + sizeof(val_buf)); 226 + if (ret) 227 + return ret; 228 + 229 + *val = le16_to_cpu(val_buf); 230 + return IIO_VAL_INT; 231 + 232 + default: 233 + return -EINVAL; 234 + } 235 + } 236 + 237 + static int iqs621_als_read_event_config(struct iio_dev *indio_dev, 238 + const struct iio_chan_spec *chan, 239 + enum iio_event_type type, 240 + enum iio_event_direction dir) 241 + { 242 + struct iqs621_als_private *iqs621_als = iio_priv(indio_dev); 243 + int ret; 244 + 245 + mutex_lock(&iqs621_als->lock); 246 + 247 + switch (chan->type) { 248 + case IIO_LIGHT: 249 + ret = iqs621_als->light_en; 250 + break; 251 + 252 + case IIO_INTENSITY: 253 + ret = iqs621_als->range_en; 254 + break; 255 + 256 + case IIO_PROXIMITY: 257 + ret = iqs621_als->prox_en; 258 + break; 259 + 260 + default: 261 + ret = -EINVAL; 262 + } 263 + 264 + mutex_unlock(&iqs621_als->lock); 265 + 266 + return ret; 267 + } 268 + 269 + static int iqs621_als_write_event_config(struct iio_dev *indio_dev, 270 + const struct iio_chan_spec *chan, 271 + enum iio_event_type type, 272 + enum iio_event_direction dir, 273 + int state) 274 + { 275 + struct iqs621_als_private *iqs621_als = iio_priv(indio_dev); 276 + struct iqs62x_core *iqs62x = iqs621_als->iqs62x; 277 + unsigned int val; 278 + int ret; 279 + 280 + mutex_lock(&iqs621_als->lock); 281 + 282 + ret = regmap_read(iqs62x->regmap, iqs62x->dev_desc->als_flags, &val); 283 + if (ret) 284 + goto err_mutex; 285 + iqs621_als->als_flags = val; 286 + 287 + switch (chan->type) { 288 + case IIO_LIGHT: 289 + ret = regmap_update_bits(iqs62x->regmap, IQS620_GLBL_EVENT_MASK, 290 + iqs62x->dev_desc->als_mask, 291 + iqs621_als->range_en || state ? 0 : 292 + 0xFF); 293 + if (!ret) 294 + iqs621_als->light_en = state; 295 + break; 296 + 297 + case IIO_INTENSITY: 298 + ret = regmap_update_bits(iqs62x->regmap, IQS620_GLBL_EVENT_MASK, 299 + iqs62x->dev_desc->als_mask, 300 + iqs621_als->light_en || state ? 0 : 301 + 0xFF); 302 + if (!ret) 303 + iqs621_als->range_en = state; 304 + break; 305 + 306 + case IIO_PROXIMITY: 307 + ret = regmap_read(iqs62x->regmap, IQS622_IR_FLAGS, &val); 308 + if (ret) 309 + goto err_mutex; 310 + iqs621_als->ir_flags = val; 311 + 312 + ret = regmap_update_bits(iqs62x->regmap, IQS620_GLBL_EVENT_MASK, 313 + iqs62x->dev_desc->ir_mask, 314 + state ? 0 : 0xFF); 315 + if (!ret) 316 + iqs621_als->prox_en = state; 317 + break; 318 + 319 + default: 320 + ret = -EINVAL; 321 + } 322 + 323 + err_mutex: 324 + mutex_unlock(&iqs621_als->lock); 325 + 326 + return ret; 327 + } 328 + 329 + static int iqs621_als_read_event_value(struct iio_dev *indio_dev, 330 + const struct iio_chan_spec *chan, 331 + enum iio_event_type type, 332 + enum iio_event_direction dir, 333 + enum iio_event_info info, 334 + int *val, int *val2) 335 + { 336 + struct iqs621_als_private *iqs621_als = iio_priv(indio_dev); 337 + int ret = IIO_VAL_INT; 338 + 339 + mutex_lock(&iqs621_als->lock); 340 + 341 + switch (dir) { 342 + case IIO_EV_DIR_RISING: 343 + *val = iqs621_als->thresh_light * 16; 344 + break; 345 + 346 + case IIO_EV_DIR_FALLING: 347 + *val = iqs621_als->thresh_dark * 4; 348 + break; 349 + 350 + case IIO_EV_DIR_EITHER: 351 + if (iqs621_als->ir_flags_mask == IQS622_IR_FLAGS_TOUCH) 352 + *val = iqs621_als->thresh_prox * 4; 353 + else 354 + *val = iqs621_als->thresh_prox; 355 + break; 356 + 357 + default: 358 + ret = -EINVAL; 359 + } 360 + 361 + mutex_unlock(&iqs621_als->lock); 362 + 363 + return ret; 364 + } 365 + 366 + static int iqs621_als_write_event_value(struct iio_dev *indio_dev, 367 + const struct iio_chan_spec *chan, 368 + enum iio_event_type type, 369 + enum iio_event_direction dir, 370 + enum iio_event_info info, 371 + int val, int val2) 372 + { 373 + struct iqs621_als_private *iqs621_als = iio_priv(indio_dev); 374 + struct iqs62x_core *iqs62x = iqs621_als->iqs62x; 375 + unsigned int thresh_reg, thresh_val; 376 + u8 ir_flags_mask, *thresh_cache; 377 + int ret = -EINVAL; 378 + 379 + mutex_lock(&iqs621_als->lock); 380 + 381 + switch (dir) { 382 + case IIO_EV_DIR_RISING: 383 + thresh_reg = IQS621_ALS_THRESH_LIGHT; 384 + thresh_val = val / 16; 385 + 386 + thresh_cache = &iqs621_als->thresh_light; 387 + ir_flags_mask = 0; 388 + break; 389 + 390 + case IIO_EV_DIR_FALLING: 391 + thresh_reg = IQS621_ALS_THRESH_DARK; 392 + thresh_val = val / 4; 393 + 394 + thresh_cache = &iqs621_als->thresh_dark; 395 + ir_flags_mask = 0; 396 + break; 397 + 398 + case IIO_EV_DIR_EITHER: 399 + /* 400 + * The IQS622 supports two detection thresholds, both measured 401 + * in the same arbitrary units reported by read_raw: proximity 402 + * (0 through 255 in steps of 1), and touch (0 through 1020 in 403 + * steps of 4). 404 + * 405 + * Based on the single detection threshold chosen by the user, 406 + * select the hardware threshold that gives the best trade-off 407 + * between range and resolution. 408 + * 409 + * By default, the close-range (but coarse) touch threshold is 410 + * chosen during probe. 411 + */ 412 + switch (val) { 413 + case 0 ... 255: 414 + thresh_reg = IQS622_IR_THRESH_PROX; 415 + thresh_val = val; 416 + 417 + ir_flags_mask = IQS622_IR_FLAGS_PROX; 418 + break; 419 + 420 + case 256 ... 1020: 421 + thresh_reg = IQS622_IR_THRESH_TOUCH; 422 + thresh_val = val / 4; 423 + 424 + ir_flags_mask = IQS622_IR_FLAGS_TOUCH; 425 + break; 426 + 427 + default: 428 + goto err_mutex; 429 + } 430 + 431 + thresh_cache = &iqs621_als->thresh_prox; 432 + break; 433 + 434 + default: 435 + goto err_mutex; 436 + } 437 + 438 + if (thresh_val > 0xFF) 439 + goto err_mutex; 440 + 441 + ret = regmap_write(iqs62x->regmap, thresh_reg, thresh_val); 442 + if (ret) 443 + goto err_mutex; 444 + 445 + *thresh_cache = thresh_val; 446 + iqs621_als->ir_flags_mask = ir_flags_mask; 447 + 448 + err_mutex: 449 + mutex_unlock(&iqs621_als->lock); 450 + 451 + return ret; 452 + } 453 + 454 + static const struct iio_info iqs621_als_info = { 455 + .read_raw = &iqs621_als_read_raw, 456 + .read_event_config = iqs621_als_read_event_config, 457 + .write_event_config = iqs621_als_write_event_config, 458 + .read_event_value = iqs621_als_read_event_value, 459 + .write_event_value = iqs621_als_write_event_value, 460 + }; 461 + 462 + static const struct iio_event_spec iqs621_als_range_events[] = { 463 + { 464 + .type = IIO_EV_TYPE_CHANGE, 465 + .dir = IIO_EV_DIR_EITHER, 466 + .mask_separate = BIT(IIO_EV_INFO_ENABLE), 467 + }, 468 + }; 469 + 470 + static const struct iio_event_spec iqs621_als_light_events[] = { 471 + { 472 + .type = IIO_EV_TYPE_THRESH, 473 + .dir = IIO_EV_DIR_EITHER, 474 + .mask_separate = BIT(IIO_EV_INFO_ENABLE), 475 + }, 476 + { 477 + .type = IIO_EV_TYPE_THRESH, 478 + .dir = IIO_EV_DIR_RISING, 479 + .mask_separate = BIT(IIO_EV_INFO_VALUE), 480 + }, 481 + { 482 + .type = IIO_EV_TYPE_THRESH, 483 + .dir = IIO_EV_DIR_FALLING, 484 + .mask_separate = BIT(IIO_EV_INFO_VALUE), 485 + }, 486 + }; 487 + 488 + static const struct iio_chan_spec iqs621_als_channels[] = { 489 + { 490 + .type = IIO_INTENSITY, 491 + .address = IQS621_ALS_FLAGS, 492 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 493 + .event_spec = iqs621_als_range_events, 494 + .num_event_specs = ARRAY_SIZE(iqs621_als_range_events), 495 + }, 496 + { 497 + .type = IIO_LIGHT, 498 + .address = IQS621_ALS_UI_OUT, 499 + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), 500 + .event_spec = iqs621_als_light_events, 501 + .num_event_specs = ARRAY_SIZE(iqs621_als_light_events), 502 + }, 503 + }; 504 + 505 + static const struct iio_event_spec iqs622_als_prox_events[] = { 506 + { 507 + .type = IIO_EV_TYPE_THRESH, 508 + .dir = IIO_EV_DIR_EITHER, 509 + .mask_separate = BIT(IIO_EV_INFO_ENABLE) | 510 + BIT(IIO_EV_INFO_VALUE), 511 + }, 512 + }; 513 + 514 + static const struct iio_chan_spec iqs622_als_channels[] = { 515 + { 516 + .type = IIO_INTENSITY, 517 + .channel2 = IIO_MOD_LIGHT_BOTH, 518 + .address = IQS622_ALS_FLAGS, 519 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 520 + .event_spec = iqs621_als_range_events, 521 + .num_event_specs = ARRAY_SIZE(iqs621_als_range_events), 522 + .modified = true, 523 + }, 524 + { 525 + .type = IIO_INTENSITY, 526 + .channel2 = IIO_MOD_LIGHT_IR, 527 + .address = IQS622_IR_RANGE, 528 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 529 + .modified = true, 530 + }, 531 + { 532 + .type = IIO_PROXIMITY, 533 + .address = IQS622_IR_UI_OUT, 534 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 535 + .event_spec = iqs622_als_prox_events, 536 + .num_event_specs = ARRAY_SIZE(iqs622_als_prox_events), 537 + }, 538 + }; 539 + 540 + static int iqs621_als_probe(struct platform_device *pdev) 541 + { 542 + struct iqs62x_core *iqs62x = dev_get_drvdata(pdev->dev.parent); 543 + struct iqs621_als_private *iqs621_als; 544 + struct iio_dev *indio_dev; 545 + unsigned int val; 546 + int ret; 547 + 548 + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*iqs621_als)); 549 + if (!indio_dev) 550 + return -ENOMEM; 551 + 552 + iqs621_als = iio_priv(indio_dev); 553 + iqs621_als->iqs62x = iqs62x; 554 + 555 + if (iqs62x->dev_desc->prod_num == IQS622_PROD_NUM) { 556 + ret = regmap_read(iqs62x->regmap, IQS622_IR_THRESH_TOUCH, 557 + &val); 558 + if (ret) 559 + return ret; 560 + iqs621_als->thresh_prox = val; 561 + iqs621_als->ir_flags_mask = IQS622_IR_FLAGS_TOUCH; 562 + 563 + indio_dev->channels = iqs622_als_channels; 564 + indio_dev->num_channels = ARRAY_SIZE(iqs622_als_channels); 565 + } else { 566 + ret = regmap_read(iqs62x->regmap, IQS621_ALS_THRESH_LIGHT, 567 + &val); 568 + if (ret) 569 + return ret; 570 + iqs621_als->thresh_light = val; 571 + 572 + ret = regmap_read(iqs62x->regmap, IQS621_ALS_THRESH_DARK, 573 + &val); 574 + if (ret) 575 + return ret; 576 + iqs621_als->thresh_dark = val; 577 + 578 + indio_dev->channels = iqs621_als_channels; 579 + indio_dev->num_channels = ARRAY_SIZE(iqs621_als_channels); 580 + } 581 + 582 + indio_dev->modes = INDIO_DIRECT_MODE; 583 + indio_dev->dev.parent = &pdev->dev; 584 + indio_dev->name = iqs62x->dev_desc->dev_name; 585 + indio_dev->info = &iqs621_als_info; 586 + 587 + mutex_init(&iqs621_als->lock); 588 + 589 + iqs621_als->notifier.notifier_call = iqs621_als_notifier; 590 + ret = blocking_notifier_chain_register(&iqs621_als->iqs62x->nh, 591 + &iqs621_als->notifier); 592 + if (ret) { 593 + dev_err(&pdev->dev, "Failed to register notifier: %d\n", ret); 594 + return ret; 595 + } 596 + 597 + ret = devm_add_action_or_reset(&pdev->dev, 598 + iqs621_als_notifier_unregister, 599 + iqs621_als); 600 + if (ret) 601 + return ret; 602 + 603 + return devm_iio_device_register(&pdev->dev, indio_dev); 604 + } 605 + 606 + static struct platform_driver iqs621_als_platform_driver = { 607 + .driver = { 608 + .name = "iqs621-als", 609 + }, 610 + .probe = iqs621_als_probe, 611 + }; 612 + module_platform_driver(iqs621_als_platform_driver); 613 + 614 + MODULE_AUTHOR("Jeff LaBundy <jeff@labundy.com>"); 615 + MODULE_DESCRIPTION("Azoteq IQS621/622 Ambient Light Sensors"); 616 + MODULE_LICENSE("GPL"); 617 + MODULE_ALIAS("platform:iqs621-als");
+19
drivers/iio/position/Kconfig
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + # 3 + # Linear and angular position sensors 4 + # 5 + # When adding new entries keep the list in alphabetical order 6 + 7 + menu "Linear and angular position sensors" 8 + 9 + config IQS624_POS 10 + tristate "Azoteq IQS624/625 angular position sensors" 11 + depends on MFD_IQS62X || COMPILE_TEST 12 + help 13 + Say Y here if you want to build support for the Azoteq IQS624 14 + and IQS625 angular position sensors. 15 + 16 + To compile this driver as a module, choose M here: the module 17 + will be called iqs624-pos. 18 + 19 + endmenu
+7
drivers/iio/position/Makefile
··· 1 + # 2 + # Makefile for IIO linear and angular position sensors 3 + # 4 + 5 + # When adding new entries keep the list in alphabetical order 6 + 7 + obj-$(CONFIG_IQS624_POS) += iqs624-pos.o
+284
drivers/iio/position/iqs624-pos.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Azoteq IQS624/625 Angular Position Sensors 4 + * 5 + * Copyright (C) 2019 Jeff LaBundy <jeff@labundy.com> 6 + */ 7 + 8 + #include <linux/device.h> 9 + #include <linux/iio/events.h> 10 + #include <linux/iio/iio.h> 11 + #include <linux/kernel.h> 12 + #include <linux/mfd/iqs62x.h> 13 + #include <linux/module.h> 14 + #include <linux/mutex.h> 15 + #include <linux/notifier.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/regmap.h> 18 + 19 + #define IQS624_POS_DEG_OUT 0x16 20 + 21 + #define IQS624_POS_SCALE1 (314159 / 180) 22 + #define IQS624_POS_SCALE2 100000 23 + 24 + struct iqs624_pos_private { 25 + struct iqs62x_core *iqs62x; 26 + struct notifier_block notifier; 27 + struct mutex lock; 28 + bool angle_en; 29 + u16 angle; 30 + }; 31 + 32 + static int iqs624_pos_angle_en(struct iqs62x_core *iqs62x, bool angle_en) 33 + { 34 + unsigned int event_mask = IQS624_HALL_UI_WHL_EVENT; 35 + 36 + /* 37 + * The IQS625 reports angular position in the form of coarse intervals, 38 + * so only interval change events are unmasked. Conversely, the IQS624 39 + * reports angular position down to one degree of resolution, so wheel 40 + * movement events are unmasked instead. 41 + */ 42 + if (iqs62x->dev_desc->prod_num == IQS625_PROD_NUM) 43 + event_mask = IQS624_HALL_UI_INT_EVENT; 44 + 45 + return regmap_update_bits(iqs62x->regmap, IQS624_HALL_UI, event_mask, 46 + angle_en ? 0 : 0xFF); 47 + } 48 + 49 + static int iqs624_pos_notifier(struct notifier_block *notifier, 50 + unsigned long event_flags, void *context) 51 + { 52 + struct iqs62x_event_data *event_data = context; 53 + struct iqs624_pos_private *iqs624_pos; 54 + struct iqs62x_core *iqs62x; 55 + struct iio_dev *indio_dev; 56 + u16 angle = event_data->ui_data; 57 + s64 timestamp; 58 + int ret; 59 + 60 + iqs624_pos = container_of(notifier, struct iqs624_pos_private, 61 + notifier); 62 + indio_dev = iio_priv_to_dev(iqs624_pos); 63 + timestamp = iio_get_time_ns(indio_dev); 64 + 65 + iqs62x = iqs624_pos->iqs62x; 66 + if (iqs62x->dev_desc->prod_num == IQS625_PROD_NUM) 67 + angle = event_data->interval; 68 + 69 + mutex_lock(&iqs624_pos->lock); 70 + 71 + if (event_flags & BIT(IQS62X_EVENT_SYS_RESET)) { 72 + ret = iqs624_pos_angle_en(iqs62x, iqs624_pos->angle_en); 73 + if (ret) { 74 + dev_err(indio_dev->dev.parent, 75 + "Failed to re-initialize device: %d\n", ret); 76 + ret = NOTIFY_BAD; 77 + } else { 78 + ret = NOTIFY_OK; 79 + } 80 + } else if (iqs624_pos->angle_en && (angle != iqs624_pos->angle)) { 81 + iio_push_event(indio_dev, 82 + IIO_UNMOD_EVENT_CODE(IIO_ANGL, 0, 83 + IIO_EV_TYPE_CHANGE, 84 + IIO_EV_DIR_NONE), 85 + timestamp); 86 + 87 + iqs624_pos->angle = angle; 88 + ret = NOTIFY_OK; 89 + } else { 90 + ret = NOTIFY_DONE; 91 + } 92 + 93 + mutex_unlock(&iqs624_pos->lock); 94 + 95 + return ret; 96 + } 97 + 98 + static void iqs624_pos_notifier_unregister(void *context) 99 + { 100 + struct iqs624_pos_private *iqs624_pos = context; 101 + struct iio_dev *indio_dev = iio_priv_to_dev(iqs624_pos); 102 + int ret; 103 + 104 + ret = blocking_notifier_chain_unregister(&iqs624_pos->iqs62x->nh, 105 + &iqs624_pos->notifier); 106 + if (ret) 107 + dev_err(indio_dev->dev.parent, 108 + "Failed to unregister notifier: %d\n", ret); 109 + } 110 + 111 + static int iqs624_pos_angle_get(struct iqs62x_core *iqs62x, unsigned int *val) 112 + { 113 + int ret; 114 + __le16 val_buf; 115 + 116 + if (iqs62x->dev_desc->prod_num == IQS625_PROD_NUM) 117 + return regmap_read(iqs62x->regmap, iqs62x->dev_desc->interval, 118 + val); 119 + 120 + ret = regmap_raw_read(iqs62x->regmap, IQS624_POS_DEG_OUT, &val_buf, 121 + sizeof(val_buf)); 122 + if (ret) 123 + return ret; 124 + 125 + *val = le16_to_cpu(val_buf); 126 + 127 + return 0; 128 + } 129 + 130 + static int iqs624_pos_read_raw(struct iio_dev *indio_dev, 131 + struct iio_chan_spec const *chan, 132 + int *val, int *val2, long mask) 133 + { 134 + struct iqs624_pos_private *iqs624_pos = iio_priv(indio_dev); 135 + struct iqs62x_core *iqs62x = iqs624_pos->iqs62x; 136 + unsigned int scale = 1; 137 + int ret; 138 + 139 + switch (mask) { 140 + case IIO_CHAN_INFO_RAW: 141 + ret = iqs624_pos_angle_get(iqs62x, val); 142 + if (ret) 143 + return ret; 144 + 145 + return IIO_VAL_INT; 146 + 147 + case IIO_CHAN_INFO_SCALE: 148 + if (iqs62x->dev_desc->prod_num == IQS625_PROD_NUM) { 149 + ret = regmap_read(iqs62x->regmap, IQS624_INTERVAL_DIV, 150 + &scale); 151 + if (ret) 152 + return ret; 153 + } 154 + 155 + *val = scale * IQS624_POS_SCALE1; 156 + *val2 = IQS624_POS_SCALE2; 157 + return IIO_VAL_FRACTIONAL; 158 + 159 + default: 160 + return -EINVAL; 161 + } 162 + } 163 + 164 + static int iqs624_pos_read_event_config(struct iio_dev *indio_dev, 165 + const struct iio_chan_spec *chan, 166 + enum iio_event_type type, 167 + enum iio_event_direction dir) 168 + { 169 + struct iqs624_pos_private *iqs624_pos = iio_priv(indio_dev); 170 + int ret; 171 + 172 + mutex_lock(&iqs624_pos->lock); 173 + ret = iqs624_pos->angle_en; 174 + mutex_unlock(&iqs624_pos->lock); 175 + 176 + return ret; 177 + } 178 + 179 + static int iqs624_pos_write_event_config(struct iio_dev *indio_dev, 180 + const struct iio_chan_spec *chan, 181 + enum iio_event_type type, 182 + enum iio_event_direction dir, 183 + int state) 184 + { 185 + struct iqs624_pos_private *iqs624_pos = iio_priv(indio_dev); 186 + struct iqs62x_core *iqs62x = iqs624_pos->iqs62x; 187 + unsigned int val; 188 + int ret; 189 + 190 + mutex_lock(&iqs624_pos->lock); 191 + 192 + ret = iqs624_pos_angle_get(iqs62x, &val); 193 + if (ret) 194 + goto err_mutex; 195 + 196 + ret = iqs624_pos_angle_en(iqs62x, state); 197 + if (ret) 198 + goto err_mutex; 199 + 200 + iqs624_pos->angle = val; 201 + iqs624_pos->angle_en = state; 202 + 203 + err_mutex: 204 + mutex_unlock(&iqs624_pos->lock); 205 + 206 + return ret; 207 + } 208 + 209 + static const struct iio_info iqs624_pos_info = { 210 + .read_raw = &iqs624_pos_read_raw, 211 + .read_event_config = iqs624_pos_read_event_config, 212 + .write_event_config = iqs624_pos_write_event_config, 213 + }; 214 + 215 + static const struct iio_event_spec iqs624_pos_events[] = { 216 + { 217 + .type = IIO_EV_TYPE_CHANGE, 218 + .dir = IIO_EV_DIR_NONE, 219 + .mask_separate = BIT(IIO_EV_INFO_ENABLE), 220 + }, 221 + }; 222 + 223 + static const struct iio_chan_spec iqs624_pos_channels[] = { 224 + { 225 + .type = IIO_ANGL, 226 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 227 + BIT(IIO_CHAN_INFO_SCALE), 228 + .event_spec = iqs624_pos_events, 229 + .num_event_specs = ARRAY_SIZE(iqs624_pos_events), 230 + }, 231 + }; 232 + 233 + static int iqs624_pos_probe(struct platform_device *pdev) 234 + { 235 + struct iqs62x_core *iqs62x = dev_get_drvdata(pdev->dev.parent); 236 + struct iqs624_pos_private *iqs624_pos; 237 + struct iio_dev *indio_dev; 238 + int ret; 239 + 240 + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*iqs624_pos)); 241 + if (!indio_dev) 242 + return -ENOMEM; 243 + 244 + iqs624_pos = iio_priv(indio_dev); 245 + iqs624_pos->iqs62x = iqs62x; 246 + 247 + indio_dev->modes = INDIO_DIRECT_MODE; 248 + indio_dev->dev.parent = &pdev->dev; 249 + indio_dev->channels = iqs624_pos_channels; 250 + indio_dev->num_channels = ARRAY_SIZE(iqs624_pos_channels); 251 + indio_dev->name = iqs62x->dev_desc->dev_name; 252 + indio_dev->info = &iqs624_pos_info; 253 + 254 + mutex_init(&iqs624_pos->lock); 255 + 256 + iqs624_pos->notifier.notifier_call = iqs624_pos_notifier; 257 + ret = blocking_notifier_chain_register(&iqs624_pos->iqs62x->nh, 258 + &iqs624_pos->notifier); 259 + if (ret) { 260 + dev_err(&pdev->dev, "Failed to register notifier: %d\n", ret); 261 + return ret; 262 + } 263 + 264 + ret = devm_add_action_or_reset(&pdev->dev, 265 + iqs624_pos_notifier_unregister, 266 + iqs624_pos); 267 + if (ret) 268 + return ret; 269 + 270 + return devm_iio_device_register(&pdev->dev, indio_dev); 271 + } 272 + 273 + static struct platform_driver iqs624_pos_platform_driver = { 274 + .driver = { 275 + .name = "iqs624-pos", 276 + }, 277 + .probe = iqs624_pos_probe, 278 + }; 279 + module_platform_driver(iqs624_pos_platform_driver); 280 + 281 + MODULE_AUTHOR("Jeff LaBundy <jeff@labundy.com>"); 282 + MODULE_DESCRIPTION("Azoteq IQS624/625 Angular Position Sensors"); 283 + MODULE_LICENSE("GPL"); 284 + MODULE_ALIAS("platform:iqs624-pos");
+10
drivers/iio/temperature/Kconfig
··· 4 4 # 5 5 menu "Temperature sensors" 6 6 7 + config IQS620AT_TEMP 8 + tristate "Azoteq IQS620AT temperature sensor" 9 + depends on MFD_IQS62X || COMPILE_TEST 10 + help 11 + Say Y here if you want to build support for the Azoteq IQS620AT 12 + temperature sensor. 13 + 14 + To compile this driver as a module, choose M here: the module 15 + will be called iqs620at-temp. 16 + 7 17 config LTC2983 8 18 tristate "Analog Devices Multi-Sensor Digital Temperature Measurement System" 9 19 depends on SPI
+1
drivers/iio/temperature/Makefile
··· 3 3 # Makefile for industrial I/O temperature drivers 4 4 # 5 5 6 + obj-$(CONFIG_IQS620AT_TEMP) += iqs620at-temp.o 6 7 obj-$(CONFIG_LTC2983) += ltc2983.o 7 8 obj-$(CONFIG_HID_SENSOR_TEMP) += hid-sensor-temperature.o 8 9 obj-$(CONFIG_MAXIM_THERMOCOUPLE) += maxim_thermocouple.o
+97
drivers/iio/temperature/iqs620at-temp.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Azoteq IQS620AT Temperature Sensor 4 + * 5 + * Copyright (C) 2019 Jeff LaBundy <jeff@labundy.com> 6 + */ 7 + 8 + #include <linux/device.h> 9 + #include <linux/iio/iio.h> 10 + #include <linux/kernel.h> 11 + #include <linux/mfd/iqs62x.h> 12 + #include <linux/module.h> 13 + #include <linux/platform_device.h> 14 + #include <linux/regmap.h> 15 + 16 + #define IQS620_TEMP_UI_OUT 0x1A 17 + 18 + #define IQS620_TEMP_SCALE 1000 19 + #define IQS620_TEMP_OFFSET (-100) 20 + 21 + static int iqs620_temp_read_raw(struct iio_dev *indio_dev, 22 + struct iio_chan_spec const *chan, 23 + int *val, int *val2, long mask) 24 + { 25 + struct iqs62x_core *iqs62x = iio_device_get_drvdata(indio_dev); 26 + int ret; 27 + __le16 val_buf; 28 + 29 + switch (mask) { 30 + case IIO_CHAN_INFO_RAW: 31 + ret = regmap_raw_read(iqs62x->regmap, IQS620_TEMP_UI_OUT, 32 + &val_buf, sizeof(val_buf)); 33 + if (ret) 34 + return ret; 35 + 36 + *val = le16_to_cpu(val_buf); 37 + return IIO_VAL_INT; 38 + 39 + case IIO_CHAN_INFO_SCALE: 40 + *val = IQS620_TEMP_SCALE; 41 + return IIO_VAL_INT; 42 + 43 + case IIO_CHAN_INFO_OFFSET: 44 + *val = IQS620_TEMP_OFFSET; 45 + return IIO_VAL_INT; 46 + 47 + default: 48 + return -EINVAL; 49 + } 50 + } 51 + 52 + static const struct iio_info iqs620_temp_info = { 53 + .read_raw = &iqs620_temp_read_raw, 54 + }; 55 + 56 + static const struct iio_chan_spec iqs620_temp_channels[] = { 57 + { 58 + .type = IIO_TEMP, 59 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 60 + BIT(IIO_CHAN_INFO_SCALE) | 61 + BIT(IIO_CHAN_INFO_OFFSET), 62 + }, 63 + }; 64 + 65 + static int iqs620_temp_probe(struct platform_device *pdev) 66 + { 67 + struct iqs62x_core *iqs62x = dev_get_drvdata(pdev->dev.parent); 68 + struct iio_dev *indio_dev; 69 + 70 + indio_dev = devm_iio_device_alloc(&pdev->dev, 0); 71 + if (!indio_dev) 72 + return -ENOMEM; 73 + 74 + iio_device_set_drvdata(indio_dev, iqs62x); 75 + 76 + indio_dev->modes = INDIO_DIRECT_MODE; 77 + indio_dev->dev.parent = &pdev->dev; 78 + indio_dev->channels = iqs620_temp_channels; 79 + indio_dev->num_channels = ARRAY_SIZE(iqs620_temp_channels); 80 + indio_dev->name = iqs62x->dev_desc->dev_name; 81 + indio_dev->info = &iqs620_temp_info; 82 + 83 + return devm_iio_device_register(&pdev->dev, indio_dev); 84 + } 85 + 86 + static struct platform_driver iqs620_temp_platform_driver = { 87 + .driver = { 88 + .name = "iqs620at-temp", 89 + }, 90 + .probe = iqs620_temp_probe, 91 + }; 92 + module_platform_driver(iqs620_temp_platform_driver); 93 + 94 + MODULE_AUTHOR("Jeff LaBundy <jeff@labundy.com>"); 95 + MODULE_DESCRIPTION("Azoteq IQS620AT Temperature Sensor"); 96 + MODULE_LICENSE("GPL"); 97 + MODULE_ALIAS("platform:iqs620at-temp");
+10
drivers/input/keyboard/Kconfig
··· 663 663 To compile this driver as a module, choose M here: the 664 664 module will be called ipaq-micro-keys. 665 665 666 + config KEYBOARD_IQS62X 667 + tristate "Azoteq IQS620A/621/622/624/625 keys and switches" 668 + depends on MFD_IQS62X 669 + help 670 + Say Y here to enable key and switch support for the Azoteq IQS620A, 671 + IQS621, IQS622, IQS624 and IQS625 multi-function sensors. 672 + 673 + To compile this driver as a module, choose M here: the module will 674 + be called iqs62x-keys. 675 + 666 676 config KEYBOARD_OMAP 667 677 tristate "TI OMAP keypad support" 668 678 depends on ARCH_OMAP1
+1
drivers/input/keyboard/Makefile
··· 28 28 obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o 29 29 obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o 30 30 obj-$(CONFIG_KEYBOARD_IPAQ_MICRO) += ipaq-micro-keys.o 31 + obj-$(CONFIG_KEYBOARD_IQS62X) += iqs62x-keys.o 31 32 obj-$(CONFIG_KEYBOARD_IMX) += imx_keypad.o 32 33 obj-$(CONFIG_KEYBOARD_IMX_SC_KEY) += imx_sc_key.o 33 34 obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o
+335
drivers/input/keyboard/iqs62x-keys.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Azoteq IQS620A/621/622/624/625 Keys and Switches 4 + * 5 + * Copyright (C) 2019 Jeff LaBundy <jeff@labundy.com> 6 + */ 7 + 8 + #include <linux/device.h> 9 + #include <linux/input.h> 10 + #include <linux/kernel.h> 11 + #include <linux/mfd/iqs62x.h> 12 + #include <linux/module.h> 13 + #include <linux/notifier.h> 14 + #include <linux/platform_device.h> 15 + #include <linux/property.h> 16 + #include <linux/regmap.h> 17 + #include <linux/slab.h> 18 + 19 + enum { 20 + IQS62X_SW_HALL_N, 21 + IQS62X_SW_HALL_S, 22 + }; 23 + 24 + static const char * const iqs62x_switch_names[] = { 25 + [IQS62X_SW_HALL_N] = "hall-switch-north", 26 + [IQS62X_SW_HALL_S] = "hall-switch-south", 27 + }; 28 + 29 + struct iqs62x_switch_desc { 30 + enum iqs62x_event_flag flag; 31 + unsigned int code; 32 + bool enabled; 33 + }; 34 + 35 + struct iqs62x_keys_private { 36 + struct iqs62x_core *iqs62x; 37 + struct input_dev *input; 38 + struct notifier_block notifier; 39 + struct iqs62x_switch_desc switches[ARRAY_SIZE(iqs62x_switch_names)]; 40 + unsigned int keycode[IQS62X_NUM_KEYS]; 41 + unsigned int keycodemax; 42 + u8 interval; 43 + }; 44 + 45 + static int iqs62x_keys_parse_prop(struct platform_device *pdev, 46 + struct iqs62x_keys_private *iqs62x_keys) 47 + { 48 + struct fwnode_handle *child; 49 + unsigned int val; 50 + int ret, i; 51 + 52 + ret = device_property_count_u32(&pdev->dev, "linux,keycodes"); 53 + if (ret > IQS62X_NUM_KEYS) { 54 + dev_err(&pdev->dev, "Too many keycodes present\n"); 55 + return -EINVAL; 56 + } else if (ret < 0) { 57 + dev_err(&pdev->dev, "Failed to count keycodes: %d\n", ret); 58 + return ret; 59 + } 60 + iqs62x_keys->keycodemax = ret; 61 + 62 + ret = device_property_read_u32_array(&pdev->dev, "linux,keycodes", 63 + iqs62x_keys->keycode, 64 + iqs62x_keys->keycodemax); 65 + if (ret) { 66 + dev_err(&pdev->dev, "Failed to read keycodes: %d\n", ret); 67 + return ret; 68 + } 69 + 70 + for (i = 0; i < ARRAY_SIZE(iqs62x_keys->switches); i++) { 71 + child = device_get_named_child_node(&pdev->dev, 72 + iqs62x_switch_names[i]); 73 + if (!child) 74 + continue; 75 + 76 + ret = fwnode_property_read_u32(child, "linux,code", &val); 77 + if (ret) { 78 + dev_err(&pdev->dev, "Failed to read switch code: %d\n", 79 + ret); 80 + return ret; 81 + } 82 + iqs62x_keys->switches[i].code = val; 83 + iqs62x_keys->switches[i].enabled = true; 84 + 85 + if (fwnode_property_present(child, "azoteq,use-prox")) 86 + iqs62x_keys->switches[i].flag = (i == IQS62X_SW_HALL_N ? 87 + IQS62X_EVENT_HALL_N_P : 88 + IQS62X_EVENT_HALL_S_P); 89 + else 90 + iqs62x_keys->switches[i].flag = (i == IQS62X_SW_HALL_N ? 91 + IQS62X_EVENT_HALL_N_T : 92 + IQS62X_EVENT_HALL_S_T); 93 + } 94 + 95 + return 0; 96 + } 97 + 98 + static int iqs62x_keys_init(struct iqs62x_keys_private *iqs62x_keys) 99 + { 100 + struct iqs62x_core *iqs62x = iqs62x_keys->iqs62x; 101 + enum iqs62x_event_flag flag; 102 + unsigned int event_reg, val; 103 + unsigned int event_mask = 0; 104 + int ret, i; 105 + 106 + switch (iqs62x->dev_desc->prod_num) { 107 + case IQS620_PROD_NUM: 108 + case IQS621_PROD_NUM: 109 + case IQS622_PROD_NUM: 110 + event_reg = IQS620_GLBL_EVENT_MASK; 111 + 112 + /* 113 + * Discreet button, hysteresis and SAR UI flags represent keys 114 + * and are unmasked if mapped to a valid keycode. 115 + */ 116 + for (i = 0; i < iqs62x_keys->keycodemax; i++) { 117 + if (iqs62x_keys->keycode[i] == KEY_RESERVED) 118 + continue; 119 + 120 + if (iqs62x_events[i].reg == IQS62X_EVENT_PROX) 121 + event_mask |= iqs62x->dev_desc->prox_mask; 122 + else if (iqs62x_events[i].reg == IQS62X_EVENT_HYST) 123 + event_mask |= (iqs62x->dev_desc->hyst_mask | 124 + iqs62x->dev_desc->sar_mask); 125 + } 126 + 127 + ret = regmap_read(iqs62x->regmap, iqs62x->dev_desc->hall_flags, 128 + &val); 129 + if (ret) 130 + return ret; 131 + 132 + /* 133 + * Hall UI flags represent switches and are unmasked if their 134 + * corresponding child nodes are present. 135 + */ 136 + for (i = 0; i < ARRAY_SIZE(iqs62x_keys->switches); i++) { 137 + if (!(iqs62x_keys->switches[i].enabled)) 138 + continue; 139 + 140 + flag = iqs62x_keys->switches[i].flag; 141 + 142 + if (iqs62x_events[flag].reg != IQS62X_EVENT_HALL) 143 + continue; 144 + 145 + event_mask |= iqs62x->dev_desc->hall_mask; 146 + 147 + input_report_switch(iqs62x_keys->input, 148 + iqs62x_keys->switches[i].code, 149 + (val & iqs62x_events[flag].mask) == 150 + iqs62x_events[flag].val); 151 + } 152 + 153 + input_sync(iqs62x_keys->input); 154 + break; 155 + 156 + case IQS624_PROD_NUM: 157 + event_reg = IQS624_HALL_UI; 158 + 159 + /* 160 + * Interval change events represent keys and are unmasked if 161 + * either wheel movement flag is mapped to a valid keycode. 162 + */ 163 + if (iqs62x_keys->keycode[IQS62X_EVENT_WHEEL_UP] != KEY_RESERVED) 164 + event_mask |= IQS624_HALL_UI_INT_EVENT; 165 + 166 + if (iqs62x_keys->keycode[IQS62X_EVENT_WHEEL_DN] != KEY_RESERVED) 167 + event_mask |= IQS624_HALL_UI_INT_EVENT; 168 + 169 + ret = regmap_read(iqs62x->regmap, iqs62x->dev_desc->interval, 170 + &val); 171 + if (ret) 172 + return ret; 173 + 174 + iqs62x_keys->interval = val; 175 + break; 176 + 177 + default: 178 + return 0; 179 + } 180 + 181 + return regmap_update_bits(iqs62x->regmap, event_reg, event_mask, 0); 182 + } 183 + 184 + static int iqs62x_keys_notifier(struct notifier_block *notifier, 185 + unsigned long event_flags, void *context) 186 + { 187 + struct iqs62x_event_data *event_data = context; 188 + struct iqs62x_keys_private *iqs62x_keys; 189 + int ret, i; 190 + 191 + iqs62x_keys = container_of(notifier, struct iqs62x_keys_private, 192 + notifier); 193 + 194 + if (event_flags & BIT(IQS62X_EVENT_SYS_RESET)) { 195 + ret = iqs62x_keys_init(iqs62x_keys); 196 + if (ret) { 197 + dev_err(iqs62x_keys->input->dev.parent, 198 + "Failed to re-initialize device: %d\n", ret); 199 + return NOTIFY_BAD; 200 + } 201 + 202 + return NOTIFY_OK; 203 + } 204 + 205 + for (i = 0; i < iqs62x_keys->keycodemax; i++) { 206 + if (iqs62x_events[i].reg == IQS62X_EVENT_WHEEL && 207 + event_data->interval == iqs62x_keys->interval) 208 + continue; 209 + 210 + input_report_key(iqs62x_keys->input, iqs62x_keys->keycode[i], 211 + event_flags & BIT(i)); 212 + } 213 + 214 + for (i = 0; i < ARRAY_SIZE(iqs62x_keys->switches); i++) 215 + if (iqs62x_keys->switches[i].enabled) 216 + input_report_switch(iqs62x_keys->input, 217 + iqs62x_keys->switches[i].code, 218 + event_flags & 219 + BIT(iqs62x_keys->switches[i].flag)); 220 + 221 + input_sync(iqs62x_keys->input); 222 + 223 + if (event_data->interval == iqs62x_keys->interval) 224 + return NOTIFY_OK; 225 + 226 + /* 227 + * Each frame contains at most one wheel event (up or down), in which 228 + * case a complementary release cycle is emulated. 229 + */ 230 + if (event_flags & BIT(IQS62X_EVENT_WHEEL_UP)) { 231 + input_report_key(iqs62x_keys->input, 232 + iqs62x_keys->keycode[IQS62X_EVENT_WHEEL_UP], 233 + 0); 234 + input_sync(iqs62x_keys->input); 235 + } else if (event_flags & BIT(IQS62X_EVENT_WHEEL_DN)) { 236 + input_report_key(iqs62x_keys->input, 237 + iqs62x_keys->keycode[IQS62X_EVENT_WHEEL_DN], 238 + 0); 239 + input_sync(iqs62x_keys->input); 240 + } 241 + 242 + iqs62x_keys->interval = event_data->interval; 243 + 244 + return NOTIFY_OK; 245 + } 246 + 247 + static int iqs62x_keys_probe(struct platform_device *pdev) 248 + { 249 + struct iqs62x_core *iqs62x = dev_get_drvdata(pdev->dev.parent); 250 + struct iqs62x_keys_private *iqs62x_keys; 251 + struct input_dev *input; 252 + int ret, i; 253 + 254 + iqs62x_keys = devm_kzalloc(&pdev->dev, sizeof(*iqs62x_keys), 255 + GFP_KERNEL); 256 + if (!iqs62x_keys) 257 + return -ENOMEM; 258 + 259 + platform_set_drvdata(pdev, iqs62x_keys); 260 + 261 + ret = iqs62x_keys_parse_prop(pdev, iqs62x_keys); 262 + if (ret) 263 + return ret; 264 + 265 + input = devm_input_allocate_device(&pdev->dev); 266 + if (!input) 267 + return -ENOMEM; 268 + 269 + input->keycodemax = iqs62x_keys->keycodemax; 270 + input->keycode = iqs62x_keys->keycode; 271 + input->keycodesize = sizeof(*iqs62x_keys->keycode); 272 + 273 + input->name = iqs62x->dev_desc->dev_name; 274 + input->id.bustype = BUS_I2C; 275 + 276 + for (i = 0; i < iqs62x_keys->keycodemax; i++) 277 + if (iqs62x_keys->keycode[i] != KEY_RESERVED) 278 + input_set_capability(input, EV_KEY, 279 + iqs62x_keys->keycode[i]); 280 + 281 + for (i = 0; i < ARRAY_SIZE(iqs62x_keys->switches); i++) 282 + if (iqs62x_keys->switches[i].enabled) 283 + input_set_capability(input, EV_SW, 284 + iqs62x_keys->switches[i].code); 285 + 286 + iqs62x_keys->iqs62x = iqs62x; 287 + iqs62x_keys->input = input; 288 + 289 + ret = iqs62x_keys_init(iqs62x_keys); 290 + if (ret) { 291 + dev_err(&pdev->dev, "Failed to initialize device: %d\n", ret); 292 + return ret; 293 + } 294 + 295 + ret = input_register_device(iqs62x_keys->input); 296 + if (ret) { 297 + dev_err(&pdev->dev, "Failed to register device: %d\n", ret); 298 + return ret; 299 + } 300 + 301 + iqs62x_keys->notifier.notifier_call = iqs62x_keys_notifier; 302 + ret = blocking_notifier_chain_register(&iqs62x_keys->iqs62x->nh, 303 + &iqs62x_keys->notifier); 304 + if (ret) 305 + dev_err(&pdev->dev, "Failed to register notifier: %d\n", ret); 306 + 307 + return ret; 308 + } 309 + 310 + static int iqs62x_keys_remove(struct platform_device *pdev) 311 + { 312 + struct iqs62x_keys_private *iqs62x_keys = platform_get_drvdata(pdev); 313 + int ret; 314 + 315 + ret = blocking_notifier_chain_unregister(&iqs62x_keys->iqs62x->nh, 316 + &iqs62x_keys->notifier); 317 + if (ret) 318 + dev_err(&pdev->dev, "Failed to unregister notifier: %d\n", ret); 319 + 320 + return ret; 321 + } 322 + 323 + static struct platform_driver iqs62x_keys_platform_driver = { 324 + .driver = { 325 + .name = "iqs62x-keys", 326 + }, 327 + .probe = iqs62x_keys_probe, 328 + .remove = iqs62x_keys_remove, 329 + }; 330 + module_platform_driver(iqs62x_keys_platform_driver); 331 + 332 + MODULE_AUTHOR("Jeff LaBundy <jeff@labundy.com>"); 333 + MODULE_DESCRIPTION("Azoteq IQS620A/621/622/624/625 Keys and Switches"); 334 + MODULE_LICENSE("GPL"); 335 + MODULE_ALIAS("platform:iqs62x-keys");
+19 -4
drivers/mfd/Kconfig
··· 642 642 AT90LS8535 microcontroller flashed with a special iPAQ 643 643 firmware using the custom protocol implemented in this driver. 644 644 645 + config MFD_IQS62X 646 + tristate "Azoteq IQS620A/621/622/624/625 core support" 647 + depends on I2C 648 + select MFD_CORE 649 + select REGMAP_I2C 650 + help 651 + Say Y here if you want to build core support for the Azoteq IQS620A, 652 + IQS621, IQS622, IQS624 and IQS625 multi-function sensors. Additional 653 + options must be selected to enable device-specific functions. 654 + 655 + To compile this driver as a module, choose M here: the module will 656 + be called iqs62x. 657 + 645 658 config MFD_JANZ_CMODIO 646 659 tristate "Janz CMOD-IO PCI MODULbus Carrier Board" 647 660 select MFD_CORE ··· 906 893 tristate "Support for Motorola CPCAP" 907 894 depends on SPI 908 895 depends on OF || COMPILE_TEST 896 + select MFD_CORE 909 897 select REGMAP_SPI 910 898 select REGMAP_IRQ 911 899 help ··· 1072 1058 depends on OF 1073 1059 select MFD_CORE 1074 1060 select REGMAP_I2C 1061 + select REGMAP_IRQ 1075 1062 help 1076 1063 Say yes here to add support for the Ricoh RN5T567, 1077 1064 RN5T618, RC5T619 PMIC. ··· 1216 1201 chip. This connects to U8500 either on the SSP/SPI bus (deprecated 1217 1202 since hardware version v1.0) or the I2C bus via PRCMU. It also adds 1218 1203 the irq_chip parts for handling the Mixed Signal chip events. 1219 - This chip embeds various other multimedia funtionalities as well. 1204 + This chip embeds various other multimedia functionalities as well. 1220 1205 1221 1206 config AB8500_DEBUG 1222 1207 bool "Enable debug info via debugfs" ··· 1866 1851 has on board GPIO and regulator functionality which is 1867 1852 supported via the relevant subsystems. This driver provides 1868 1853 core support for the WM8994, in order to use the actual 1869 - functionaltiy of the device other drivers must be enabled. 1854 + functionality of the device other drivers must be enabled. 1870 1855 1871 1856 config MFD_WM97xx 1872 1857 tristate "Wolfson Microelectronics WM97xx" ··· 1879 1864 designed for smartphone applications. As well as audio functionality 1880 1865 it has on board GPIO and a touchscreen functionality which is 1881 1866 supported via the relevant subsystems. This driver provides core 1882 - support for the WM97xx, in order to use the actual functionaltiy of 1867 + support for the WM97xx, in order to use the actual functionality of 1883 1868 the device other drivers must be enabled. 1884 1869 1885 1870 config MFD_STW481X ··· 1972 1957 Support for ST Microelectronics STPMIC1 PMIC. STPMIC1 has power on 1973 1958 key, watchdog and regulator functionalities which are supported via 1974 1959 the relevant subsystems. This driver provides core support for the 1975 - STPMIC1. In order to use the actual functionaltiy of the device other 1960 + STPMIC1. In order to use the actual functionality of the device other 1976 1961 drivers must be enabled. 1977 1962 1978 1963 To compile this driver as a module, choose M here: the
+1
drivers/mfd/Makefile
··· 226 226 obj-$(CONFIG_MFD_AS3722) += as3722.o 227 227 obj-$(CONFIG_MFD_STW481X) += stw481x.o 228 228 obj-$(CONFIG_MFD_IPAQ_MICRO) += ipaq-micro.o 229 + obj-$(CONFIG_MFD_IQS62X) += iqs62x.o 229 230 obj-$(CONFIG_MFD_MENF21BMC) += menf21bmc.o 230 231 obj-$(CONFIG_MFD_HI6421_PMIC) += hi6421-pmic-core.o 231 232 obj-$(CONFIG_MFD_HI655X_PMIC) += hi655x-pmic.o
+1 -1
drivers/mfd/aat2870-core.c
··· 221 221 222 222 count += sprintf(buf, "aat2870 registers\n"); 223 223 for (addr = 0; addr < AAT2870_REG_NUM; addr++) { 224 - count += sprintf(buf + count, "0x%02x: ", addr); 224 + count += snprintf(buf + count, PAGE_SIZE - count, "0x%02x: ", addr); 225 225 if (count >= PAGE_SIZE - 1) 226 226 break; 227 227
+1 -1
drivers/mfd/cros_ec_dev.c
··· 211 211 * explicitly added on platforms that don't have the PD notifier ACPI 212 212 * device entry defined. 213 213 */ 214 - if (IS_ENABLED(CONFIG_OF)) { 214 + if (IS_ENABLED(CONFIG_OF) && ec->ec_dev->dev->of_node) { 215 215 if (cros_ec_check_features(ec, EC_FEATURE_USB_PD)) { 216 216 retval = mfd_add_hotplug_devices(ec->dev, 217 217 cros_usbpd_notify_cells,
+41 -3
drivers/mfd/da9062-core.c
··· 21 21 #define DA9062_REG_EVENT_B_OFFSET 1 22 22 #define DA9062_REG_EVENT_C_OFFSET 2 23 23 24 + #define DA9062_IRQ_LOW 0 25 + #define DA9062_IRQ_HIGH 1 26 + 24 27 static struct regmap_irq da9061_irqs[] = { 25 28 /* EVENT A */ 26 29 [DA9061_IRQ_ONKEY] = { ··· 372 369 return ret; 373 370 } 374 371 372 + static u32 da9062_configure_irq_type(struct da9062 *chip, int irq, u32 *trigger) 373 + { 374 + u32 irq_type = 0; 375 + struct irq_data *irq_data = irq_get_irq_data(irq); 376 + 377 + if (!irq_data) { 378 + dev_err(chip->dev, "Invalid IRQ: %d\n", irq); 379 + return -EINVAL; 380 + } 381 + *trigger = irqd_get_trigger_type(irq_data); 382 + 383 + switch (*trigger) { 384 + case IRQ_TYPE_LEVEL_HIGH: 385 + irq_type = DA9062_IRQ_HIGH; 386 + break; 387 + case IRQ_TYPE_LEVEL_LOW: 388 + irq_type = DA9062_IRQ_LOW; 389 + break; 390 + default: 391 + dev_warn(chip->dev, "Unsupported IRQ type: %d\n", *trigger); 392 + return -EINVAL; 393 + } 394 + return regmap_update_bits(chip->regmap, DA9062AA_CONFIG_A, 395 + DA9062AA_IRQ_TYPE_MASK, 396 + irq_type << DA9062AA_IRQ_TYPE_SHIFT); 397 + } 398 + 375 399 static const struct regmap_range da9061_aa_readable_ranges[] = { 376 400 regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_STATUS_B), 377 401 regmap_reg_range(DA9062AA_STATUS_D, DA9062AA_EVENT_C), ··· 418 388 regmap_reg_range(DA9062AA_VBUCK1_A, DA9062AA_VBUCK4_A), 419 389 regmap_reg_range(DA9062AA_VBUCK3_A, DA9062AA_VBUCK3_A), 420 390 regmap_reg_range(DA9062AA_VLDO1_A, DA9062AA_VLDO4_A), 391 + regmap_reg_range(DA9062AA_CONFIG_A, DA9062AA_CONFIG_A), 421 392 regmap_reg_range(DA9062AA_VBUCK1_B, DA9062AA_VBUCK4_B), 422 393 regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B), 423 394 regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B), ··· 448 417 regmap_reg_range(DA9062AA_VBUCK1_A, DA9062AA_VBUCK4_A), 449 418 regmap_reg_range(DA9062AA_VBUCK3_A, DA9062AA_VBUCK3_A), 450 419 regmap_reg_range(DA9062AA_VLDO1_A, DA9062AA_VLDO4_A), 420 + regmap_reg_range(DA9062AA_CONFIG_A, DA9062AA_CONFIG_A), 451 421 regmap_reg_range(DA9062AA_VBUCK1_B, DA9062AA_VBUCK4_B), 452 422 regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B), 453 423 regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B), ··· 628 596 const struct regmap_irq_chip *irq_chip; 629 597 const struct regmap_config *config; 630 598 int cell_num; 599 + u32 trigger_type = 0; 631 600 int ret; 632 601 633 602 chip = devm_kzalloc(&i2c->dev, sizeof(*chip), GFP_KERNEL); ··· 687 654 if (ret) 688 655 return ret; 689 656 657 + ret = da9062_configure_irq_type(chip, i2c->irq, &trigger_type); 658 + if (ret < 0) { 659 + dev_err(chip->dev, "Failed to configure IRQ type\n"); 660 + return ret; 661 + } 662 + 690 663 ret = regmap_add_irq_chip(chip->regmap, i2c->irq, 691 - IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED, 692 - -1, irq_chip, 693 - &chip->regmap_irq); 664 + trigger_type | IRQF_SHARED | IRQF_ONESHOT, 665 + -1, irq_chip, &chip->regmap_irq); 694 666 if (ret) { 695 667 dev_err(chip->dev, "Failed to request IRQ %d: %d\n", 696 668 i2c->irq, ret);
+28 -2
drivers/mfd/dln2.c
··· 90 90 spinlock_t lock; 91 91 }; 92 92 93 + enum dln2_endpoint { 94 + DLN2_EP_OUT = 0, 95 + DLN2_EP_IN = 1, 96 + }; 97 + 93 98 struct dln2_dev { 94 99 struct usb_device *usb_dev; 95 100 struct usb_interface *interface; ··· 645 640 return 0; 646 641 } 647 642 643 + enum { 644 + DLN2_ACPI_MATCH_GPIO = 0, 645 + DLN2_ACPI_MATCH_I2C = 1, 646 + DLN2_ACPI_MATCH_SPI = 2, 647 + }; 648 + 648 649 static struct dln2_platform_data dln2_pdata_gpio = { 649 650 .handle = DLN2_HANDLE_GPIO, 651 + }; 652 + 653 + static struct mfd_cell_acpi_match dln2_acpi_match_gpio = { 654 + .adr = DLN2_ACPI_MATCH_GPIO, 650 655 }; 651 656 652 657 /* Only one I2C port seems to be supported on current hardware */ ··· 665 650 .port = 0, 666 651 }; 667 652 653 + static struct mfd_cell_acpi_match dln2_acpi_match_i2c = { 654 + .adr = DLN2_ACPI_MATCH_I2C, 655 + }; 656 + 668 657 /* Only one SPI port supported */ 669 658 static struct dln2_platform_data dln2_pdata_spi = { 670 659 .handle = DLN2_HANDLE_SPI, 671 660 .port = 0, 672 661 }; 673 662 663 + static struct mfd_cell_acpi_match dln2_acpi_match_spi = { 664 + .adr = DLN2_ACPI_MATCH_SPI, 665 + }; 666 + 674 667 static const struct mfd_cell dln2_devs[] = { 675 668 { 676 669 .name = "dln2-gpio", 670 + .acpi_match = &dln2_acpi_match_gpio, 677 671 .platform_data = &dln2_pdata_gpio, 678 672 .pdata_size = sizeof(struct dln2_platform_data), 679 673 }, 680 674 { 681 675 .name = "dln2-i2c", 676 + .acpi_match = &dln2_acpi_match_i2c, 682 677 .platform_data = &dln2_pdata_i2c, 683 678 .pdata_size = sizeof(struct dln2_platform_data), 684 679 }, 685 680 { 686 681 .name = "dln2-spi", 682 + .acpi_match = &dln2_acpi_match_spi, 687 683 .platform_data = &dln2_pdata_spi, 688 684 .pdata_size = sizeof(struct dln2_platform_data), 689 685 }, ··· 759 733 hostif->desc.bNumEndpoints < 2) 760 734 return -ENODEV; 761 735 762 - epin = &hostif->endpoint[0].desc; 763 - epout = &hostif->endpoint[1].desc; 736 + epout = &hostif->endpoint[DLN2_EP_OUT].desc; 764 737 if (!usb_endpoint_is_bulk_out(epout)) 765 738 return -ENODEV; 739 + epin = &hostif->endpoint[DLN2_EP_IN].desc; 766 740 if (!usb_endpoint_is_bulk_in(epin)) 767 741 return -ENODEV; 768 742
+23 -8
drivers/mfd/intel-lpss-pci.c
··· 139 139 .properties = spt_i2c_properties, 140 140 }; 141 141 142 + static const struct intel_lpss_platform_info ehl_i2c_info = { 143 + .clk_rate = 100000000, 144 + .properties = bxt_i2c_properties, 145 + }; 146 + 142 147 static const struct pci_device_id intel_lpss_pci_ids[] = { 143 148 /* CML-LP */ 144 149 { PCI_VDEVICE(INTEL, 0x02a8), (kernel_ulong_t)&spt_uart_info }, ··· 236 231 { PCI_VDEVICE(INTEL, 0x4b2a), (kernel_ulong_t)&bxt_info }, 237 232 { PCI_VDEVICE(INTEL, 0x4b2b), (kernel_ulong_t)&bxt_info }, 238 233 { PCI_VDEVICE(INTEL, 0x4b37), (kernel_ulong_t)&bxt_info }, 239 - { PCI_VDEVICE(INTEL, 0x4b44), (kernel_ulong_t)&bxt_i2c_info }, 240 - { PCI_VDEVICE(INTEL, 0x4b45), (kernel_ulong_t)&bxt_i2c_info }, 241 - { PCI_VDEVICE(INTEL, 0x4b4b), (kernel_ulong_t)&bxt_i2c_info }, 242 - { PCI_VDEVICE(INTEL, 0x4b4c), (kernel_ulong_t)&bxt_i2c_info }, 234 + { PCI_VDEVICE(INTEL, 0x4b44), (kernel_ulong_t)&ehl_i2c_info }, 235 + { PCI_VDEVICE(INTEL, 0x4b45), (kernel_ulong_t)&ehl_i2c_info }, 236 + { PCI_VDEVICE(INTEL, 0x4b4b), (kernel_ulong_t)&ehl_i2c_info }, 237 + { PCI_VDEVICE(INTEL, 0x4b4c), (kernel_ulong_t)&ehl_i2c_info }, 243 238 { PCI_VDEVICE(INTEL, 0x4b4d), (kernel_ulong_t)&bxt_uart_info }, 244 - { PCI_VDEVICE(INTEL, 0x4b78), (kernel_ulong_t)&bxt_i2c_info }, 245 - { PCI_VDEVICE(INTEL, 0x4b79), (kernel_ulong_t)&bxt_i2c_info }, 246 - { PCI_VDEVICE(INTEL, 0x4b7a), (kernel_ulong_t)&bxt_i2c_info }, 247 - { PCI_VDEVICE(INTEL, 0x4b7b), (kernel_ulong_t)&bxt_i2c_info }, 239 + { PCI_VDEVICE(INTEL, 0x4b78), (kernel_ulong_t)&ehl_i2c_info }, 240 + { PCI_VDEVICE(INTEL, 0x4b79), (kernel_ulong_t)&ehl_i2c_info }, 241 + { PCI_VDEVICE(INTEL, 0x4b7a), (kernel_ulong_t)&ehl_i2c_info }, 242 + { PCI_VDEVICE(INTEL, 0x4b7b), (kernel_ulong_t)&ehl_i2c_info }, 248 243 /* JSL */ 249 244 { PCI_VDEVICE(INTEL, 0x4da8), (kernel_ulong_t)&spt_uart_info }, 250 245 { PCI_VDEVICE(INTEL, 0x4da9), (kernel_ulong_t)&spt_uart_info }, ··· 352 347 { PCI_VDEVICE(INTEL, 0xa36a), (kernel_ulong_t)&cnl_i2c_info }, 353 348 { PCI_VDEVICE(INTEL, 0xa36b), (kernel_ulong_t)&cnl_i2c_info }, 354 349 { PCI_VDEVICE(INTEL, 0xa37b), (kernel_ulong_t)&spt_info }, 350 + /* CML-V */ 351 + { PCI_VDEVICE(INTEL, 0xa3a7), (kernel_ulong_t)&spt_uart_info }, 352 + { PCI_VDEVICE(INTEL, 0xa3a8), (kernel_ulong_t)&spt_uart_info }, 353 + { PCI_VDEVICE(INTEL, 0xa3a9), (kernel_ulong_t)&spt_info }, 354 + { PCI_VDEVICE(INTEL, 0xa3aa), (kernel_ulong_t)&spt_info }, 355 + { PCI_VDEVICE(INTEL, 0xa3e0), (kernel_ulong_t)&spt_i2c_info }, 356 + { PCI_VDEVICE(INTEL, 0xa3e1), (kernel_ulong_t)&spt_i2c_info }, 357 + { PCI_VDEVICE(INTEL, 0xa3e2), (kernel_ulong_t)&spt_i2c_info }, 358 + { PCI_VDEVICE(INTEL, 0xa3e3), (kernel_ulong_t)&spt_i2c_info }, 359 + { PCI_VDEVICE(INTEL, 0xa3e6), (kernel_ulong_t)&spt_uart_info }, 355 360 { } 356 361 }; 357 362 MODULE_DEVICE_TABLE(pci, intel_lpss_pci_ids);
+1063
drivers/mfd/iqs62x.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Azoteq IQS620A/621/622/624/625 Multi-Function Sensors 4 + * 5 + * Copyright (C) 2019 Jeff LaBundy <jeff@labundy.com> 6 + * 7 + * These devices rely on application-specific register settings and calibration 8 + * data developed in and exported from a suite of GUIs offered by the vendor. A 9 + * separate tool converts the GUIs' ASCII-based output into a standard firmware 10 + * file parsed by the driver. 11 + * 12 + * Link to datasheets and GUIs: https://www.azoteq.com/ 13 + * 14 + * Link to conversion tool: https://github.com/jlabundy/iqs62x-h2bin.git 15 + */ 16 + 17 + #include <linux/completion.h> 18 + #include <linux/delay.h> 19 + #include <linux/device.h> 20 + #include <linux/err.h> 21 + #include <linux/firmware.h> 22 + #include <linux/i2c.h> 23 + #include <linux/interrupt.h> 24 + #include <linux/kernel.h> 25 + #include <linux/list.h> 26 + #include <linux/mfd/core.h> 27 + #include <linux/mfd/iqs62x.h> 28 + #include <linux/module.h> 29 + #include <linux/notifier.h> 30 + #include <linux/of_device.h> 31 + #include <linux/property.h> 32 + #include <linux/regmap.h> 33 + #include <linux/slab.h> 34 + #include <asm/unaligned.h> 35 + 36 + #define IQS62X_PROD_NUM 0x00 37 + 38 + #define IQS62X_SYS_FLAGS 0x10 39 + #define IQS62X_SYS_FLAGS_IN_ATI BIT(2) 40 + 41 + #define IQS620_HALL_FLAGS 0x16 42 + #define IQS621_HALL_FLAGS 0x19 43 + #define IQS622_HALL_FLAGS IQS621_HALL_FLAGS 44 + 45 + #define IQS624_INTERVAL_NUM 0x18 46 + #define IQS625_INTERVAL_NUM 0x12 47 + 48 + #define IQS622_PROX_SETTINGS_4 0x48 49 + #define IQS620_PROX_SETTINGS_4 0x50 50 + #define IQS620_PROX_SETTINGS_4_SAR_EN BIT(7) 51 + 52 + #define IQS621_ALS_CAL_DIV_LUX 0x82 53 + #define IQS621_ALS_CAL_DIV_IR 0x83 54 + 55 + #define IQS620_TEMP_CAL_MULT 0xC2 56 + #define IQS620_TEMP_CAL_DIV 0xC3 57 + #define IQS620_TEMP_CAL_OFFS 0xC4 58 + 59 + #define IQS62X_SYS_SETTINGS 0xD0 60 + #define IQS62X_SYS_SETTINGS_SOFT_RESET BIT(7) 61 + #define IQS62X_SYS_SETTINGS_ACK_RESET BIT(6) 62 + #define IQS62X_SYS_SETTINGS_EVENT_MODE BIT(5) 63 + #define IQS62X_SYS_SETTINGS_CLK_DIV BIT(4) 64 + #define IQS62X_SYS_SETTINGS_REDO_ATI BIT(1) 65 + 66 + #define IQS62X_PWR_SETTINGS 0xD2 67 + #define IQS62X_PWR_SETTINGS_DIS_AUTO BIT(5) 68 + #define IQS62X_PWR_SETTINGS_PWR_MODE_MASK (BIT(4) | BIT(3)) 69 + #define IQS62X_PWR_SETTINGS_PWR_MODE_HALT (BIT(4) | BIT(3)) 70 + #define IQS62X_PWR_SETTINGS_PWR_MODE_NORM 0 71 + 72 + #define IQS62X_OTP_CMD 0xF0 73 + #define IQS62X_OTP_CMD_FG3 0x13 74 + #define IQS62X_OTP_DATA 0xF1 75 + #define IQS62X_MAX_REG 0xFF 76 + 77 + #define IQS62X_HALL_CAL_MASK GENMASK(3, 0) 78 + 79 + #define IQS62X_FW_REC_TYPE_INFO 0 80 + #define IQS62X_FW_REC_TYPE_PROD 1 81 + #define IQS62X_FW_REC_TYPE_HALL 2 82 + #define IQS62X_FW_REC_TYPE_MASK 3 83 + #define IQS62X_FW_REC_TYPE_DATA 4 84 + 85 + #define IQS62X_ATI_POLL_SLEEP_US 10000 86 + #define IQS62X_ATI_POLL_TIMEOUT_US 500000 87 + #define IQS62X_ATI_STABLE_DELAY_MS 150 88 + 89 + struct iqs62x_fw_rec { 90 + u8 type; 91 + u8 addr; 92 + u8 len; 93 + u8 data; 94 + } __packed; 95 + 96 + struct iqs62x_fw_blk { 97 + struct list_head list; 98 + u8 addr; 99 + u8 mask; 100 + u8 len; 101 + u8 data[]; 102 + }; 103 + 104 + struct iqs62x_info { 105 + u8 prod_num; 106 + u8 sw_num; 107 + u8 hw_num; 108 + } __packed; 109 + 110 + static int iqs62x_dev_init(struct iqs62x_core *iqs62x) 111 + { 112 + struct iqs62x_fw_blk *fw_blk; 113 + unsigned int val; 114 + int ret; 115 + u8 clk_div = 1; 116 + 117 + list_for_each_entry(fw_blk, &iqs62x->fw_blk_head, list) { 118 + if (fw_blk->mask) 119 + ret = regmap_update_bits(iqs62x->regmap, fw_blk->addr, 120 + fw_blk->mask, *fw_blk->data); 121 + else 122 + ret = regmap_raw_write(iqs62x->regmap, fw_blk->addr, 123 + fw_blk->data, fw_blk->len); 124 + if (ret) 125 + return ret; 126 + } 127 + 128 + switch (iqs62x->dev_desc->prod_num) { 129 + case IQS620_PROD_NUM: 130 + case IQS622_PROD_NUM: 131 + ret = regmap_read(iqs62x->regmap, 132 + iqs62x->dev_desc->prox_settings, &val); 133 + if (ret) 134 + return ret; 135 + 136 + if (val & IQS620_PROX_SETTINGS_4_SAR_EN) 137 + iqs62x->ui_sel = IQS62X_UI_SAR1; 138 + 139 + /* fall through */ 140 + 141 + case IQS621_PROD_NUM: 142 + ret = regmap_write(iqs62x->regmap, IQS620_GLBL_EVENT_MASK, 143 + IQS620_GLBL_EVENT_MASK_PMU | 144 + iqs62x->dev_desc->prox_mask | 145 + iqs62x->dev_desc->sar_mask | 146 + iqs62x->dev_desc->hall_mask | 147 + iqs62x->dev_desc->hyst_mask | 148 + iqs62x->dev_desc->temp_mask | 149 + iqs62x->dev_desc->als_mask | 150 + iqs62x->dev_desc->ir_mask); 151 + if (ret) 152 + return ret; 153 + break; 154 + 155 + default: 156 + ret = regmap_write(iqs62x->regmap, IQS624_HALL_UI, 157 + IQS624_HALL_UI_WHL_EVENT | 158 + IQS624_HALL_UI_INT_EVENT | 159 + IQS624_HALL_UI_AUTO_CAL); 160 + if (ret) 161 + return ret; 162 + 163 + /* 164 + * The IQS625 default interval divider is below the minimum 165 + * permissible value, and the datasheet mandates that it is 166 + * corrected during initialization (unless an updated value 167 + * has already been provided by firmware). 168 + * 169 + * To protect against an unacceptably low user-entered value 170 + * stored in the firmware, the same check is extended to the 171 + * IQS624 as well. 172 + */ 173 + ret = regmap_read(iqs62x->regmap, IQS624_INTERVAL_DIV, &val); 174 + if (ret) 175 + return ret; 176 + 177 + if (val >= iqs62x->dev_desc->interval_div) 178 + break; 179 + 180 + ret = regmap_write(iqs62x->regmap, IQS624_INTERVAL_DIV, 181 + iqs62x->dev_desc->interval_div); 182 + if (ret) 183 + return ret; 184 + } 185 + 186 + ret = regmap_read(iqs62x->regmap, IQS62X_SYS_SETTINGS, &val); 187 + if (ret) 188 + return ret; 189 + 190 + if (val & IQS62X_SYS_SETTINGS_CLK_DIV) 191 + clk_div = iqs62x->dev_desc->clk_div; 192 + 193 + ret = regmap_write(iqs62x->regmap, IQS62X_SYS_SETTINGS, val | 194 + IQS62X_SYS_SETTINGS_ACK_RESET | 195 + IQS62X_SYS_SETTINGS_EVENT_MODE | 196 + IQS62X_SYS_SETTINGS_REDO_ATI); 197 + if (ret) 198 + return ret; 199 + 200 + ret = regmap_read_poll_timeout(iqs62x->regmap, IQS62X_SYS_FLAGS, val, 201 + !(val & IQS62X_SYS_FLAGS_IN_ATI), 202 + IQS62X_ATI_POLL_SLEEP_US, 203 + IQS62X_ATI_POLL_TIMEOUT_US * clk_div); 204 + if (ret) 205 + return ret; 206 + 207 + msleep(IQS62X_ATI_STABLE_DELAY_MS * clk_div); 208 + 209 + return 0; 210 + } 211 + 212 + static int iqs62x_firmware_parse(struct iqs62x_core *iqs62x, 213 + const struct firmware *fw) 214 + { 215 + struct i2c_client *client = iqs62x->client; 216 + struct iqs62x_fw_rec *fw_rec; 217 + struct iqs62x_fw_blk *fw_blk; 218 + unsigned int val; 219 + size_t pos = 0; 220 + int ret = 0; 221 + u8 mask, len, *data; 222 + u8 hall_cal_index = 0; 223 + 224 + while (pos < fw->size) { 225 + if (pos + sizeof(*fw_rec) > fw->size) { 226 + ret = -EINVAL; 227 + break; 228 + } 229 + fw_rec = (struct iqs62x_fw_rec *)(fw->data + pos); 230 + pos += sizeof(*fw_rec); 231 + 232 + if (pos + fw_rec->len - 1 > fw->size) { 233 + ret = -EINVAL; 234 + break; 235 + } 236 + pos += fw_rec->len - 1; 237 + 238 + switch (fw_rec->type) { 239 + case IQS62X_FW_REC_TYPE_INFO: 240 + continue; 241 + 242 + case IQS62X_FW_REC_TYPE_PROD: 243 + if (fw_rec->data == iqs62x->dev_desc->prod_num) 244 + continue; 245 + 246 + dev_err(&client->dev, 247 + "Incompatible product number: 0x%02X\n", 248 + fw_rec->data); 249 + ret = -EINVAL; 250 + break; 251 + 252 + case IQS62X_FW_REC_TYPE_HALL: 253 + if (!hall_cal_index) { 254 + ret = regmap_write(iqs62x->regmap, 255 + IQS62X_OTP_CMD, 256 + IQS62X_OTP_CMD_FG3); 257 + if (ret) 258 + break; 259 + 260 + ret = regmap_read(iqs62x->regmap, 261 + IQS62X_OTP_DATA, &val); 262 + if (ret) 263 + break; 264 + 265 + hall_cal_index = val & IQS62X_HALL_CAL_MASK; 266 + if (!hall_cal_index) { 267 + dev_err(&client->dev, 268 + "Uncalibrated device\n"); 269 + ret = -ENODATA; 270 + break; 271 + } 272 + } 273 + 274 + if (hall_cal_index > fw_rec->len) { 275 + ret = -EINVAL; 276 + break; 277 + } 278 + 279 + mask = 0; 280 + data = &fw_rec->data + hall_cal_index - 1; 281 + len = sizeof(*data); 282 + break; 283 + 284 + case IQS62X_FW_REC_TYPE_MASK: 285 + if (fw_rec->len < (sizeof(mask) + sizeof(*data))) { 286 + ret = -EINVAL; 287 + break; 288 + } 289 + 290 + mask = fw_rec->data; 291 + data = &fw_rec->data + sizeof(mask); 292 + len = sizeof(*data); 293 + break; 294 + 295 + case IQS62X_FW_REC_TYPE_DATA: 296 + mask = 0; 297 + data = &fw_rec->data; 298 + len = fw_rec->len; 299 + break; 300 + 301 + default: 302 + dev_err(&client->dev, 303 + "Unrecognized record type: 0x%02X\n", 304 + fw_rec->type); 305 + ret = -EINVAL; 306 + } 307 + 308 + if (ret) 309 + break; 310 + 311 + fw_blk = devm_kzalloc(&client->dev, 312 + struct_size(fw_blk, data, len), 313 + GFP_KERNEL); 314 + if (!fw_blk) { 315 + ret = -ENOMEM; 316 + break; 317 + } 318 + 319 + fw_blk->addr = fw_rec->addr; 320 + fw_blk->mask = mask; 321 + fw_blk->len = len; 322 + memcpy(fw_blk->data, data, len); 323 + 324 + list_add(&fw_blk->list, &iqs62x->fw_blk_head); 325 + } 326 + 327 + release_firmware(fw); 328 + 329 + return ret; 330 + } 331 + 332 + const struct iqs62x_event_desc iqs62x_events[IQS62X_NUM_EVENTS] = { 333 + [IQS62X_EVENT_PROX_CH0_T] = { 334 + .reg = IQS62X_EVENT_PROX, 335 + .mask = BIT(4), 336 + .val = BIT(4), 337 + }, 338 + [IQS62X_EVENT_PROX_CH0_P] = { 339 + .reg = IQS62X_EVENT_PROX, 340 + .mask = BIT(0), 341 + .val = BIT(0), 342 + }, 343 + [IQS62X_EVENT_PROX_CH1_T] = { 344 + .reg = IQS62X_EVENT_PROX, 345 + .mask = BIT(5), 346 + .val = BIT(5), 347 + }, 348 + [IQS62X_EVENT_PROX_CH1_P] = { 349 + .reg = IQS62X_EVENT_PROX, 350 + .mask = BIT(1), 351 + .val = BIT(1), 352 + }, 353 + [IQS62X_EVENT_PROX_CH2_T] = { 354 + .reg = IQS62X_EVENT_PROX, 355 + .mask = BIT(6), 356 + .val = BIT(6), 357 + }, 358 + [IQS62X_EVENT_PROX_CH2_P] = { 359 + .reg = IQS62X_EVENT_PROX, 360 + .mask = BIT(2), 361 + .val = BIT(2), 362 + }, 363 + [IQS62X_EVENT_HYST_POS_T] = { 364 + .reg = IQS62X_EVENT_HYST, 365 + .mask = BIT(6) | BIT(7), 366 + .val = BIT(6), 367 + }, 368 + [IQS62X_EVENT_HYST_POS_P] = { 369 + .reg = IQS62X_EVENT_HYST, 370 + .mask = BIT(5) | BIT(7), 371 + .val = BIT(5), 372 + }, 373 + [IQS62X_EVENT_HYST_NEG_T] = { 374 + .reg = IQS62X_EVENT_HYST, 375 + .mask = BIT(6) | BIT(7), 376 + .val = BIT(6) | BIT(7), 377 + }, 378 + [IQS62X_EVENT_HYST_NEG_P] = { 379 + .reg = IQS62X_EVENT_HYST, 380 + .mask = BIT(5) | BIT(7), 381 + .val = BIT(5) | BIT(7), 382 + }, 383 + [IQS62X_EVENT_SAR1_ACT] = { 384 + .reg = IQS62X_EVENT_HYST, 385 + .mask = BIT(4), 386 + .val = BIT(4), 387 + }, 388 + [IQS62X_EVENT_SAR1_QRD] = { 389 + .reg = IQS62X_EVENT_HYST, 390 + .mask = BIT(2), 391 + .val = BIT(2), 392 + }, 393 + [IQS62X_EVENT_SAR1_MOVE] = { 394 + .reg = IQS62X_EVENT_HYST, 395 + .mask = BIT(1), 396 + .val = BIT(1), 397 + }, 398 + [IQS62X_EVENT_SAR1_HALT] = { 399 + .reg = IQS62X_EVENT_HYST, 400 + .mask = BIT(0), 401 + .val = BIT(0), 402 + }, 403 + [IQS62X_EVENT_WHEEL_UP] = { 404 + .reg = IQS62X_EVENT_WHEEL, 405 + .mask = BIT(7) | BIT(6), 406 + .val = BIT(7), 407 + }, 408 + [IQS62X_EVENT_WHEEL_DN] = { 409 + .reg = IQS62X_EVENT_WHEEL, 410 + .mask = BIT(7) | BIT(6), 411 + .val = BIT(7) | BIT(6), 412 + }, 413 + [IQS62X_EVENT_HALL_N_T] = { 414 + .reg = IQS62X_EVENT_HALL, 415 + .mask = BIT(2) | BIT(0), 416 + .val = BIT(2), 417 + }, 418 + [IQS62X_EVENT_HALL_N_P] = { 419 + .reg = IQS62X_EVENT_HALL, 420 + .mask = BIT(1) | BIT(0), 421 + .val = BIT(1), 422 + }, 423 + [IQS62X_EVENT_HALL_S_T] = { 424 + .reg = IQS62X_EVENT_HALL, 425 + .mask = BIT(2) | BIT(0), 426 + .val = BIT(2) | BIT(0), 427 + }, 428 + [IQS62X_EVENT_HALL_S_P] = { 429 + .reg = IQS62X_EVENT_HALL, 430 + .mask = BIT(1) | BIT(0), 431 + .val = BIT(1) | BIT(0), 432 + }, 433 + [IQS62X_EVENT_SYS_RESET] = { 434 + .reg = IQS62X_EVENT_SYS, 435 + .mask = BIT(7), 436 + .val = BIT(7), 437 + }, 438 + }; 439 + EXPORT_SYMBOL_GPL(iqs62x_events); 440 + 441 + static irqreturn_t iqs62x_irq(int irq, void *context) 442 + { 443 + struct iqs62x_core *iqs62x = context; 444 + struct i2c_client *client = iqs62x->client; 445 + struct iqs62x_event_data event_data; 446 + struct iqs62x_event_desc event_desc; 447 + enum iqs62x_event_reg event_reg; 448 + unsigned long event_flags = 0; 449 + int ret, i, j; 450 + u8 event_map[IQS62X_EVENT_SIZE]; 451 + 452 + /* 453 + * The device asserts the RDY output to signal the beginning of a 454 + * communication window, which is closed by an I2C stop condition. 455 + * As such, all interrupt status is captured in a single read and 456 + * broadcast to any interested sub-device drivers. 457 + */ 458 + ret = regmap_raw_read(iqs62x->regmap, IQS62X_SYS_FLAGS, event_map, 459 + sizeof(event_map)); 460 + if (ret) { 461 + dev_err(&client->dev, "Failed to read device status: %d\n", 462 + ret); 463 + return IRQ_NONE; 464 + } 465 + 466 + for (i = 0; i < sizeof(event_map); i++) { 467 + event_reg = iqs62x->dev_desc->event_regs[iqs62x->ui_sel][i]; 468 + 469 + switch (event_reg) { 470 + case IQS62X_EVENT_UI_LO: 471 + event_data.ui_data = get_unaligned_le16(&event_map[i]); 472 + 473 + /* fall through */ 474 + 475 + case IQS62X_EVENT_UI_HI: 476 + case IQS62X_EVENT_NONE: 477 + continue; 478 + 479 + case IQS62X_EVENT_ALS: 480 + event_data.als_flags = event_map[i]; 481 + continue; 482 + 483 + case IQS62X_EVENT_IR: 484 + event_data.ir_flags = event_map[i]; 485 + continue; 486 + 487 + case IQS62X_EVENT_INTER: 488 + event_data.interval = event_map[i]; 489 + continue; 490 + 491 + case IQS62X_EVENT_HYST: 492 + event_map[i] <<= iqs62x->dev_desc->hyst_shift; 493 + 494 + /* fall through */ 495 + 496 + case IQS62X_EVENT_WHEEL: 497 + case IQS62X_EVENT_HALL: 498 + case IQS62X_EVENT_PROX: 499 + case IQS62X_EVENT_SYS: 500 + break; 501 + } 502 + 503 + for (j = 0; j < IQS62X_NUM_EVENTS; j++) { 504 + event_desc = iqs62x_events[j]; 505 + 506 + if (event_desc.reg != event_reg) 507 + continue; 508 + 509 + if ((event_map[i] & event_desc.mask) == event_desc.val) 510 + event_flags |= BIT(j); 511 + } 512 + } 513 + 514 + /* 515 + * The device resets itself in response to the I2C master stalling 516 + * communication past a fixed timeout. In this case, all registers 517 + * are restored and any interested sub-device drivers are notified. 518 + */ 519 + if (event_flags & BIT(IQS62X_EVENT_SYS_RESET)) { 520 + dev_err(&client->dev, "Unexpected device reset\n"); 521 + 522 + ret = iqs62x_dev_init(iqs62x); 523 + if (ret) { 524 + dev_err(&client->dev, 525 + "Failed to re-initialize device: %d\n", ret); 526 + return IRQ_NONE; 527 + } 528 + } 529 + 530 + ret = blocking_notifier_call_chain(&iqs62x->nh, event_flags, 531 + &event_data); 532 + if (ret & NOTIFY_STOP_MASK) 533 + return IRQ_NONE; 534 + 535 + /* 536 + * Once the communication window is closed, a small delay is added to 537 + * ensure the device's RDY output has been deasserted by the time the 538 + * interrupt handler returns. 539 + */ 540 + usleep_range(50, 100); 541 + 542 + return IRQ_HANDLED; 543 + } 544 + 545 + static void iqs62x_firmware_load(const struct firmware *fw, void *context) 546 + { 547 + struct iqs62x_core *iqs62x = context; 548 + struct i2c_client *client = iqs62x->client; 549 + int ret; 550 + 551 + if (fw) { 552 + ret = iqs62x_firmware_parse(iqs62x, fw); 553 + if (ret) { 554 + dev_err(&client->dev, "Failed to parse firmware: %d\n", 555 + ret); 556 + goto err_out; 557 + } 558 + } 559 + 560 + ret = iqs62x_dev_init(iqs62x); 561 + if (ret) { 562 + dev_err(&client->dev, "Failed to initialize device: %d\n", ret); 563 + goto err_out; 564 + } 565 + 566 + ret = devm_request_threaded_irq(&client->dev, client->irq, 567 + NULL, iqs62x_irq, IRQF_ONESHOT, 568 + client->name, iqs62x); 569 + if (ret) { 570 + dev_err(&client->dev, "Failed to request IRQ: %d\n", ret); 571 + goto err_out; 572 + } 573 + 574 + ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE, 575 + iqs62x->dev_desc->sub_devs, 576 + iqs62x->dev_desc->num_sub_devs, 577 + NULL, 0, NULL); 578 + if (ret) 579 + dev_err(&client->dev, "Failed to add sub-devices: %d\n", ret); 580 + 581 + err_out: 582 + complete_all(&iqs62x->fw_done); 583 + } 584 + 585 + static const struct mfd_cell iqs620at_sub_devs[] = { 586 + { 587 + .name = "iqs62x-keys", 588 + .of_compatible = "azoteq,iqs620a-keys", 589 + }, 590 + { 591 + .name = "iqs620a-pwm", 592 + .of_compatible = "azoteq,iqs620a-pwm", 593 + }, 594 + { .name = "iqs620at-temp", }, 595 + }; 596 + 597 + static const struct mfd_cell iqs620a_sub_devs[] = { 598 + { 599 + .name = "iqs62x-keys", 600 + .of_compatible = "azoteq,iqs620a-keys", 601 + }, 602 + { 603 + .name = "iqs620a-pwm", 604 + .of_compatible = "azoteq,iqs620a-pwm", 605 + }, 606 + }; 607 + 608 + static const struct mfd_cell iqs621_sub_devs[] = { 609 + { 610 + .name = "iqs62x-keys", 611 + .of_compatible = "azoteq,iqs621-keys", 612 + }, 613 + { .name = "iqs621-als", }, 614 + }; 615 + 616 + static const struct mfd_cell iqs622_sub_devs[] = { 617 + { 618 + .name = "iqs62x-keys", 619 + .of_compatible = "azoteq,iqs622-keys", 620 + }, 621 + { .name = "iqs621-als", }, 622 + }; 623 + 624 + static const struct mfd_cell iqs624_sub_devs[] = { 625 + { 626 + .name = "iqs62x-keys", 627 + .of_compatible = "azoteq,iqs624-keys", 628 + }, 629 + { .name = "iqs624-pos", }, 630 + }; 631 + 632 + static const struct mfd_cell iqs625_sub_devs[] = { 633 + { 634 + .name = "iqs62x-keys", 635 + .of_compatible = "azoteq,iqs625-keys", 636 + }, 637 + { .name = "iqs624-pos", }, 638 + }; 639 + 640 + static const u8 iqs620at_cal_regs[] = { 641 + IQS620_TEMP_CAL_MULT, 642 + IQS620_TEMP_CAL_DIV, 643 + IQS620_TEMP_CAL_OFFS, 644 + }; 645 + 646 + static const u8 iqs621_cal_regs[] = { 647 + IQS621_ALS_CAL_DIV_LUX, 648 + IQS621_ALS_CAL_DIV_IR, 649 + }; 650 + 651 + static const enum iqs62x_event_reg iqs620a_event_regs[][IQS62X_EVENT_SIZE] = { 652 + [IQS62X_UI_PROX] = { 653 + IQS62X_EVENT_SYS, /* 0x10 */ 654 + IQS62X_EVENT_NONE, 655 + IQS62X_EVENT_PROX, /* 0x12 */ 656 + IQS62X_EVENT_HYST, /* 0x13 */ 657 + IQS62X_EVENT_NONE, 658 + IQS62X_EVENT_NONE, 659 + IQS62X_EVENT_HALL, /* 0x16 */ 660 + IQS62X_EVENT_NONE, 661 + IQS62X_EVENT_NONE, 662 + IQS62X_EVENT_NONE, 663 + }, 664 + [IQS62X_UI_SAR1] = { 665 + IQS62X_EVENT_SYS, /* 0x10 */ 666 + IQS62X_EVENT_NONE, 667 + IQS62X_EVENT_NONE, 668 + IQS62X_EVENT_HYST, /* 0x13 */ 669 + IQS62X_EVENT_NONE, 670 + IQS62X_EVENT_NONE, 671 + IQS62X_EVENT_HALL, /* 0x16 */ 672 + IQS62X_EVENT_NONE, 673 + IQS62X_EVENT_NONE, 674 + IQS62X_EVENT_NONE, 675 + }, 676 + }; 677 + 678 + static const enum iqs62x_event_reg iqs621_event_regs[][IQS62X_EVENT_SIZE] = { 679 + [IQS62X_UI_PROX] = { 680 + IQS62X_EVENT_SYS, /* 0x10 */ 681 + IQS62X_EVENT_NONE, 682 + IQS62X_EVENT_PROX, /* 0x12 */ 683 + IQS62X_EVENT_HYST, /* 0x13 */ 684 + IQS62X_EVENT_NONE, 685 + IQS62X_EVENT_NONE, 686 + IQS62X_EVENT_ALS, /* 0x16 */ 687 + IQS62X_EVENT_UI_LO, /* 0x17 */ 688 + IQS62X_EVENT_UI_HI, /* 0x18 */ 689 + IQS62X_EVENT_HALL, /* 0x19 */ 690 + }, 691 + }; 692 + 693 + static const enum iqs62x_event_reg iqs622_event_regs[][IQS62X_EVENT_SIZE] = { 694 + [IQS62X_UI_PROX] = { 695 + IQS62X_EVENT_SYS, /* 0x10 */ 696 + IQS62X_EVENT_NONE, 697 + IQS62X_EVENT_PROX, /* 0x12 */ 698 + IQS62X_EVENT_NONE, 699 + IQS62X_EVENT_ALS, /* 0x14 */ 700 + IQS62X_EVENT_NONE, 701 + IQS62X_EVENT_IR, /* 0x16 */ 702 + IQS62X_EVENT_UI_LO, /* 0x17 */ 703 + IQS62X_EVENT_UI_HI, /* 0x18 */ 704 + IQS62X_EVENT_HALL, /* 0x19 */ 705 + }, 706 + [IQS62X_UI_SAR1] = { 707 + IQS62X_EVENT_SYS, /* 0x10 */ 708 + IQS62X_EVENT_NONE, 709 + IQS62X_EVENT_NONE, 710 + IQS62X_EVENT_HYST, /* 0x13 */ 711 + IQS62X_EVENT_ALS, /* 0x14 */ 712 + IQS62X_EVENT_NONE, 713 + IQS62X_EVENT_IR, /* 0x16 */ 714 + IQS62X_EVENT_UI_LO, /* 0x17 */ 715 + IQS62X_EVENT_UI_HI, /* 0x18 */ 716 + IQS62X_EVENT_HALL, /* 0x19 */ 717 + }, 718 + }; 719 + 720 + static const enum iqs62x_event_reg iqs624_event_regs[][IQS62X_EVENT_SIZE] = { 721 + [IQS62X_UI_PROX] = { 722 + IQS62X_EVENT_SYS, /* 0x10 */ 723 + IQS62X_EVENT_NONE, 724 + IQS62X_EVENT_PROX, /* 0x12 */ 725 + IQS62X_EVENT_NONE, 726 + IQS62X_EVENT_WHEEL, /* 0x14 */ 727 + IQS62X_EVENT_NONE, 728 + IQS62X_EVENT_UI_LO, /* 0x16 */ 729 + IQS62X_EVENT_UI_HI, /* 0x17 */ 730 + IQS62X_EVENT_INTER, /* 0x18 */ 731 + IQS62X_EVENT_NONE, 732 + }, 733 + }; 734 + 735 + static const enum iqs62x_event_reg iqs625_event_regs[][IQS62X_EVENT_SIZE] = { 736 + [IQS62X_UI_PROX] = { 737 + IQS62X_EVENT_SYS, /* 0x10 */ 738 + IQS62X_EVENT_PROX, /* 0x11 */ 739 + IQS62X_EVENT_INTER, /* 0x12 */ 740 + IQS62X_EVENT_NONE, 741 + IQS62X_EVENT_NONE, 742 + IQS62X_EVENT_NONE, 743 + IQS62X_EVENT_NONE, 744 + IQS62X_EVENT_NONE, 745 + IQS62X_EVENT_NONE, 746 + IQS62X_EVENT_NONE, 747 + }, 748 + }; 749 + 750 + static const struct iqs62x_dev_desc iqs62x_devs[] = { 751 + { 752 + .dev_name = "iqs620at", 753 + .sub_devs = iqs620at_sub_devs, 754 + .num_sub_devs = ARRAY_SIZE(iqs620at_sub_devs), 755 + 756 + .prod_num = IQS620_PROD_NUM, 757 + .sw_num = 0x08, 758 + .cal_regs = iqs620at_cal_regs, 759 + .num_cal_regs = ARRAY_SIZE(iqs620at_cal_regs), 760 + 761 + .prox_mask = BIT(0), 762 + .sar_mask = BIT(1) | BIT(7), 763 + .hall_mask = BIT(2), 764 + .hyst_mask = BIT(3), 765 + .temp_mask = BIT(4), 766 + 767 + .prox_settings = IQS620_PROX_SETTINGS_4, 768 + .hall_flags = IQS620_HALL_FLAGS, 769 + 770 + .clk_div = 4, 771 + .fw_name = "iqs620a.bin", 772 + .event_regs = &iqs620a_event_regs[IQS62X_UI_PROX], 773 + }, 774 + { 775 + .dev_name = "iqs620a", 776 + .sub_devs = iqs620a_sub_devs, 777 + .num_sub_devs = ARRAY_SIZE(iqs620a_sub_devs), 778 + 779 + .prod_num = IQS620_PROD_NUM, 780 + .sw_num = 0x08, 781 + 782 + .prox_mask = BIT(0), 783 + .sar_mask = BIT(1) | BIT(7), 784 + .hall_mask = BIT(2), 785 + .hyst_mask = BIT(3), 786 + .temp_mask = BIT(4), 787 + 788 + .prox_settings = IQS620_PROX_SETTINGS_4, 789 + .hall_flags = IQS620_HALL_FLAGS, 790 + 791 + .clk_div = 4, 792 + .fw_name = "iqs620a.bin", 793 + .event_regs = &iqs620a_event_regs[IQS62X_UI_PROX], 794 + }, 795 + { 796 + .dev_name = "iqs621", 797 + .sub_devs = iqs621_sub_devs, 798 + .num_sub_devs = ARRAY_SIZE(iqs621_sub_devs), 799 + 800 + .prod_num = IQS621_PROD_NUM, 801 + .sw_num = 0x09, 802 + .cal_regs = iqs621_cal_regs, 803 + .num_cal_regs = ARRAY_SIZE(iqs621_cal_regs), 804 + 805 + .prox_mask = BIT(0), 806 + .hall_mask = BIT(1), 807 + .als_mask = BIT(2), 808 + .hyst_mask = BIT(3), 809 + .temp_mask = BIT(4), 810 + 811 + .als_flags = IQS621_ALS_FLAGS, 812 + .hall_flags = IQS621_HALL_FLAGS, 813 + .hyst_shift = 5, 814 + 815 + .clk_div = 2, 816 + .fw_name = "iqs621.bin", 817 + .event_regs = &iqs621_event_regs[IQS62X_UI_PROX], 818 + }, 819 + { 820 + .dev_name = "iqs622", 821 + .sub_devs = iqs622_sub_devs, 822 + .num_sub_devs = ARRAY_SIZE(iqs622_sub_devs), 823 + 824 + .prod_num = IQS622_PROD_NUM, 825 + .sw_num = 0x06, 826 + 827 + .prox_mask = BIT(0), 828 + .sar_mask = BIT(1), 829 + .hall_mask = BIT(2), 830 + .als_mask = BIT(3), 831 + .ir_mask = BIT(4), 832 + 833 + .prox_settings = IQS622_PROX_SETTINGS_4, 834 + .als_flags = IQS622_ALS_FLAGS, 835 + .hall_flags = IQS622_HALL_FLAGS, 836 + 837 + .clk_div = 2, 838 + .fw_name = "iqs622.bin", 839 + .event_regs = &iqs622_event_regs[IQS62X_UI_PROX], 840 + }, 841 + { 842 + .dev_name = "iqs624", 843 + .sub_devs = iqs624_sub_devs, 844 + .num_sub_devs = ARRAY_SIZE(iqs624_sub_devs), 845 + 846 + .prod_num = IQS624_PROD_NUM, 847 + .sw_num = 0x0B, 848 + 849 + .interval = IQS624_INTERVAL_NUM, 850 + .interval_div = 3, 851 + 852 + .clk_div = 2, 853 + .fw_name = "iqs624.bin", 854 + .event_regs = &iqs624_event_regs[IQS62X_UI_PROX], 855 + }, 856 + { 857 + .dev_name = "iqs625", 858 + .sub_devs = iqs625_sub_devs, 859 + .num_sub_devs = ARRAY_SIZE(iqs625_sub_devs), 860 + 861 + .prod_num = IQS625_PROD_NUM, 862 + .sw_num = 0x0B, 863 + 864 + .interval = IQS625_INTERVAL_NUM, 865 + .interval_div = 10, 866 + 867 + .clk_div = 2, 868 + .fw_name = "iqs625.bin", 869 + .event_regs = &iqs625_event_regs[IQS62X_UI_PROX], 870 + }, 871 + }; 872 + 873 + static const struct regmap_config iqs62x_map_config = { 874 + .reg_bits = 8, 875 + .val_bits = 8, 876 + .max_register = IQS62X_MAX_REG, 877 + }; 878 + 879 + static int iqs62x_probe(struct i2c_client *client) 880 + { 881 + struct iqs62x_core *iqs62x; 882 + struct iqs62x_info info; 883 + unsigned int val; 884 + int ret, i, j; 885 + u8 sw_num = 0; 886 + const char *fw_name = NULL; 887 + 888 + iqs62x = devm_kzalloc(&client->dev, sizeof(*iqs62x), GFP_KERNEL); 889 + if (!iqs62x) 890 + return -ENOMEM; 891 + 892 + i2c_set_clientdata(client, iqs62x); 893 + iqs62x->client = client; 894 + 895 + BLOCKING_INIT_NOTIFIER_HEAD(&iqs62x->nh); 896 + INIT_LIST_HEAD(&iqs62x->fw_blk_head); 897 + init_completion(&iqs62x->fw_done); 898 + 899 + iqs62x->regmap = devm_regmap_init_i2c(client, &iqs62x_map_config); 900 + if (IS_ERR(iqs62x->regmap)) { 901 + ret = PTR_ERR(iqs62x->regmap); 902 + dev_err(&client->dev, "Failed to initialize register map: %d\n", 903 + ret); 904 + return ret; 905 + } 906 + 907 + ret = regmap_raw_read(iqs62x->regmap, IQS62X_PROD_NUM, &info, 908 + sizeof(info)); 909 + if (ret) 910 + return ret; 911 + 912 + /* 913 + * The following sequence validates the device's product and software 914 + * numbers. It then determines if the device is factory-calibrated by 915 + * checking for nonzero values in the device's designated calibration 916 + * registers (if applicable). Depending on the device, the absence of 917 + * calibration data indicates a reduced feature set or invalid device. 918 + * 919 + * For devices given in both calibrated and uncalibrated versions, the 920 + * calibrated version (e.g. IQS620AT) appears first in the iqs62x_devs 921 + * array. The uncalibrated version (e.g. IQS620A) appears next and has 922 + * the same product and software numbers, but no calibration registers 923 + * are specified. 924 + */ 925 + for (i = 0; i < ARRAY_SIZE(iqs62x_devs); i++) { 926 + if (info.prod_num != iqs62x_devs[i].prod_num) 927 + continue; 928 + 929 + iqs62x->dev_desc = &iqs62x_devs[i]; 930 + 931 + if (info.sw_num < iqs62x->dev_desc->sw_num) 932 + continue; 933 + 934 + sw_num = info.sw_num; 935 + 936 + /* 937 + * Read each of the device's designated calibration registers, 938 + * if any, and exit from the inner loop early if any are equal 939 + * to zero (indicating the device is uncalibrated). This could 940 + * be acceptable depending on the device (e.g. IQS620A instead 941 + * of IQS620AT). 942 + */ 943 + for (j = 0; j < iqs62x->dev_desc->num_cal_regs; j++) { 944 + ret = regmap_read(iqs62x->regmap, 945 + iqs62x->dev_desc->cal_regs[j], &val); 946 + if (ret) 947 + return ret; 948 + 949 + if (!val) 950 + break; 951 + } 952 + 953 + /* 954 + * If the number of nonzero values read from the device equals 955 + * the number of designated calibration registers (which could 956 + * be zero), exit from the outer loop early to signal that the 957 + * device's product and software numbers match a known device, 958 + * and the device is calibrated (if applicable). 959 + */ 960 + if (j == iqs62x->dev_desc->num_cal_regs) 961 + break; 962 + } 963 + 964 + if (!iqs62x->dev_desc) { 965 + dev_err(&client->dev, "Unrecognized product number: 0x%02X\n", 966 + info.prod_num); 967 + return -EINVAL; 968 + } 969 + 970 + if (!sw_num) { 971 + dev_err(&client->dev, "Unrecognized software number: 0x%02X\n", 972 + info.sw_num); 973 + return -EINVAL; 974 + } 975 + 976 + if (i == ARRAY_SIZE(iqs62x_devs)) { 977 + dev_err(&client->dev, "Uncalibrated device\n"); 978 + return -ENODATA; 979 + } 980 + 981 + device_property_read_string(&client->dev, "firmware-name", &fw_name); 982 + 983 + ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, 984 + fw_name ? : iqs62x->dev_desc->fw_name, 985 + &client->dev, GFP_KERNEL, iqs62x, 986 + iqs62x_firmware_load); 987 + if (ret) 988 + dev_err(&client->dev, "Failed to request firmware: %d\n", ret); 989 + 990 + return ret; 991 + } 992 + 993 + static int iqs62x_remove(struct i2c_client *client) 994 + { 995 + struct iqs62x_core *iqs62x = i2c_get_clientdata(client); 996 + 997 + wait_for_completion(&iqs62x->fw_done); 998 + 999 + return 0; 1000 + } 1001 + 1002 + static int __maybe_unused iqs62x_suspend(struct device *dev) 1003 + { 1004 + struct iqs62x_core *iqs62x = dev_get_drvdata(dev); 1005 + int ret; 1006 + 1007 + wait_for_completion(&iqs62x->fw_done); 1008 + 1009 + /* 1010 + * As per the datasheet, automatic mode switching must be disabled 1011 + * before the device is placed in or taken out of halt mode. 1012 + */ 1013 + ret = regmap_update_bits(iqs62x->regmap, IQS62X_PWR_SETTINGS, 1014 + IQS62X_PWR_SETTINGS_DIS_AUTO, 0xFF); 1015 + if (ret) 1016 + return ret; 1017 + 1018 + return regmap_update_bits(iqs62x->regmap, IQS62X_PWR_SETTINGS, 1019 + IQS62X_PWR_SETTINGS_PWR_MODE_MASK, 1020 + IQS62X_PWR_SETTINGS_PWR_MODE_HALT); 1021 + } 1022 + 1023 + static int __maybe_unused iqs62x_resume(struct device *dev) 1024 + { 1025 + struct iqs62x_core *iqs62x = dev_get_drvdata(dev); 1026 + int ret; 1027 + 1028 + ret = regmap_update_bits(iqs62x->regmap, IQS62X_PWR_SETTINGS, 1029 + IQS62X_PWR_SETTINGS_PWR_MODE_MASK, 1030 + IQS62X_PWR_SETTINGS_PWR_MODE_NORM); 1031 + if (ret) 1032 + return ret; 1033 + 1034 + return regmap_update_bits(iqs62x->regmap, IQS62X_PWR_SETTINGS, 1035 + IQS62X_PWR_SETTINGS_DIS_AUTO, 0); 1036 + } 1037 + 1038 + static SIMPLE_DEV_PM_OPS(iqs62x_pm, iqs62x_suspend, iqs62x_resume); 1039 + 1040 + static const struct of_device_id iqs62x_of_match[] = { 1041 + { .compatible = "azoteq,iqs620a" }, 1042 + { .compatible = "azoteq,iqs621" }, 1043 + { .compatible = "azoteq,iqs622" }, 1044 + { .compatible = "azoteq,iqs624" }, 1045 + { .compatible = "azoteq,iqs625" }, 1046 + { } 1047 + }; 1048 + MODULE_DEVICE_TABLE(of, iqs62x_of_match); 1049 + 1050 + static struct i2c_driver iqs62x_i2c_driver = { 1051 + .driver = { 1052 + .name = "iqs62x", 1053 + .of_match_table = iqs62x_of_match, 1054 + .pm = &iqs62x_pm, 1055 + }, 1056 + .probe_new = iqs62x_probe, 1057 + .remove = iqs62x_remove, 1058 + }; 1059 + module_i2c_driver(iqs62x_i2c_driver); 1060 + 1061 + MODULE_AUTHOR("Jeff LaBundy <jeff@labundy.com>"); 1062 + MODULE_DESCRIPTION("Azoteq IQS620A/621/622/624/625 Multi-Function Sensors"); 1063 + MODULE_LICENSE("GPL");
+1 -1
drivers/mfd/omap-usb-host.c
··· 840 840 841 841 static struct platform_driver usbhs_omap_driver = { 842 842 .driver = { 843 - .name = (char *)usbhs_driver_name, 843 + .name = usbhs_driver_name, 844 844 .pm = &usbhsomap_dev_pm_ops, 845 845 .of_match_table = usbhs_omap_dt_ids, 846 846 },
+2 -2
drivers/mfd/omap-usb-tll.c
··· 99 99 struct usbtll_omap { 100 100 void __iomem *base; 101 101 int nch; /* num. of channels */ 102 - struct clk *ch_clk[0]; /* must be the last member */ 102 + struct clk *ch_clk[]; /* must be the last member */ 103 103 }; 104 104 105 105 /*-------------------------------------------------------------------------*/ ··· 304 304 305 305 static struct platform_driver usbtll_omap_driver = { 306 306 .driver = { 307 - .name = (char *)usbtll_driver_name, 307 + .name = usbtll_driver_name, 308 308 .of_match_table = usbtll_omap_dt_ids, 309 309 }, 310 310 .probe = usbtll_omap_probe,
+1 -1
drivers/mfd/qcom-pm8xxx.c
··· 76 76 unsigned int num_masters; 77 77 const struct pm_irq_data *pm_irq_data; 78 78 /* MUST BE AT THE END OF THIS STRUCT */ 79 - u8 config[0]; 79 + u8 config[]; 80 80 }; 81 81 82 82 static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, unsigned int bp,
+48 -91
drivers/mfd/rk808.c
··· 19 19 #include <linux/module.h> 20 20 #include <linux/of_device.h> 21 21 #include <linux/regmap.h> 22 - #include <linux/syscore_ops.h> 23 22 24 23 struct rk808_reg_data { 25 24 int addr; ··· 185 186 {RK805_BUCK4_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK, 186 187 RK805_BUCK4_ILMAX_3500MA}, 187 188 {RK805_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_400MA}, 188 - {RK805_GPIO_IO_POL_REG, SLP_SD_MSK, SLEEP_FUN}, 189 189 {RK805_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP115C}, 190 190 }; 191 191 ··· 447 449 448 450 static struct i2c_client *rk808_i2c_client; 449 451 450 - static void rk805_device_shutdown(void) 452 + static void rk808_pm_power_off(void) 451 453 { 452 454 int ret; 455 + unsigned int reg, bit; 453 456 struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); 454 457 455 - if (!rk808) 458 + switch (rk808->variant) { 459 + case RK805_ID: 460 + reg = RK805_DEV_CTRL_REG; 461 + bit = DEV_OFF; 462 + break; 463 + case RK808_ID: 464 + reg = RK808_DEVCTRL_REG, 465 + bit = DEV_OFF_RST; 466 + break; 467 + case RK818_ID: 468 + reg = RK818_DEVCTRL_REG; 469 + bit = DEV_OFF; 470 + break; 471 + default: 456 472 return; 457 - 458 - ret = regmap_update_bits(rk808->regmap, 459 - RK805_DEV_CTRL_REG, 460 - DEV_OFF, DEV_OFF); 473 + } 474 + ret = regmap_update_bits(rk808->regmap, reg, bit, bit); 461 475 if (ret) 462 476 dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n"); 463 477 } 464 478 465 - static void rk805_device_shutdown_prepare(void) 479 + static void rk8xx_shutdown(struct i2c_client *client) 466 480 { 467 - int ret; 468 - struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); 469 - 470 - if (!rk808) 471 - return; 472 - 473 - ret = regmap_update_bits(rk808->regmap, 474 - RK805_GPIO_IO_POL_REG, 475 - SLP_SD_MSK, SHUTDOWN_FUN); 476 - if (ret) 477 - dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n"); 478 - } 479 - 480 - static void rk808_device_shutdown(void) 481 - { 482 - int ret; 483 - struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); 484 - 485 - if (!rk808) 486 - return; 487 - 488 - ret = regmap_update_bits(rk808->regmap, 489 - RK808_DEVCTRL_REG, 490 - DEV_OFF_RST, DEV_OFF_RST); 491 - if (ret) 492 - dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n"); 493 - } 494 - 495 - static void rk818_device_shutdown(void) 496 - { 497 - int ret; 498 - struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); 499 - 500 - if (!rk808) 501 - return; 502 - 503 - ret = regmap_update_bits(rk808->regmap, 504 - RK818_DEVCTRL_REG, 505 - DEV_OFF, DEV_OFF); 506 - if (ret) 507 - dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n"); 508 - } 509 - 510 - static void rk8xx_syscore_shutdown(void) 511 - { 512 - struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); 481 + struct rk808 *rk808 = i2c_get_clientdata(client); 513 482 int ret; 514 483 515 - if (system_state == SYSTEM_POWER_OFF && 516 - (rk808->variant == RK809_ID || rk808->variant == RK817_ID)) { 484 + switch (rk808->variant) { 485 + case RK805_ID: 486 + ret = regmap_update_bits(rk808->regmap, 487 + RK805_GPIO_IO_POL_REG, 488 + SLP_SD_MSK, 489 + SHUTDOWN_FUN); 490 + break; 491 + case RK809_ID: 492 + case RK817_ID: 517 493 ret = regmap_update_bits(rk808->regmap, 518 494 RK817_SYS_CFG(3), 519 495 RK817_SLPPIN_FUNC_MSK, 520 496 SLPPIN_DN_FUN); 521 - if (ret) { 522 - dev_warn(&rk808_i2c_client->dev, 523 - "Cannot switch to power down function\n"); 524 - } 497 + break; 498 + default: 499 + return; 525 500 } 501 + if (ret) 502 + dev_warn(&client->dev, 503 + "Cannot switch to power down function\n"); 526 504 } 527 - 528 - static struct syscore_ops rk808_syscore_ops = { 529 - .shutdown = rk8xx_syscore_shutdown, 530 - }; 531 505 532 506 static const struct of_device_id rk808_of_match[] = { 533 507 { .compatible = "rockchip,rk805" }, ··· 520 550 const struct mfd_cell *cells; 521 551 int nr_pre_init_regs; 522 552 int nr_cells; 523 - int pm_off = 0, msb, lsb; 553 + int msb, lsb; 524 554 unsigned char pmic_id_msb, pmic_id_lsb; 525 555 int ret; 526 556 int i; ··· 564 594 nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg); 565 595 cells = rk805s; 566 596 nr_cells = ARRAY_SIZE(rk805s); 567 - rk808->pm_pwroff_fn = rk805_device_shutdown; 568 - rk808->pm_pwroff_prep_fn = rk805_device_shutdown_prepare; 569 597 break; 570 598 case RK808_ID: 571 599 rk808->regmap_cfg = &rk808_regmap_config; ··· 572 604 nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg); 573 605 cells = rk808s; 574 606 nr_cells = ARRAY_SIZE(rk808s); 575 - rk808->pm_pwroff_fn = rk808_device_shutdown; 576 607 break; 577 608 case RK818_ID: 578 609 rk808->regmap_cfg = &rk818_regmap_config; ··· 580 613 nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg); 581 614 cells = rk818s; 582 615 nr_cells = ARRAY_SIZE(rk818s); 583 - rk808->pm_pwroff_fn = rk818_device_shutdown; 584 616 break; 585 617 case RK809_ID: 586 618 case RK817_ID: ··· 589 623 nr_pre_init_regs = ARRAY_SIZE(rk817_pre_init_reg); 590 624 cells = rk817s; 591 625 nr_cells = ARRAY_SIZE(rk817s); 592 - register_syscore_ops(&rk808_syscore_ops); 593 626 break; 594 627 default: 595 628 dev_err(&client->dev, "Unsupported RK8XX ID %lu\n", ··· 639 674 goto err_irq; 640 675 } 641 676 642 - pm_off = of_property_read_bool(np, 643 - "rockchip,system-power-controller"); 644 - if (pm_off && !pm_power_off) { 677 + if (of_property_read_bool(np, "rockchip,system-power-controller")) { 645 678 rk808_i2c_client = client; 646 - pm_power_off = rk808->pm_pwroff_fn; 647 - } 648 - 649 - if (pm_off && !pm_power_off_prepare) { 650 - if (!rk808_i2c_client) 651 - rk808_i2c_client = client; 652 - pm_power_off_prepare = rk808->pm_pwroff_prep_fn; 679 + pm_power_off = rk808_pm_power_off; 653 680 } 654 681 655 682 return 0; ··· 661 704 * pm_power_off may points to a function from another module. 662 705 * Check if the pointer is set by us and only then overwrite it. 663 706 */ 664 - if (rk808->pm_pwroff_fn && pm_power_off == rk808->pm_pwroff_fn) 707 + if (pm_power_off == rk808_pm_power_off) 665 708 pm_power_off = NULL; 666 - 667 - /** 668 - * As above, check if the pointer is set by us before overwrite. 669 - */ 670 - if (rk808->pm_pwroff_prep_fn && 671 - pm_power_off_prepare == rk808->pm_pwroff_prep_fn) 672 - pm_power_off_prepare = NULL; 673 709 674 710 return 0; 675 711 } 676 712 677 713 static int __maybe_unused rk8xx_suspend(struct device *dev) 678 714 { 679 - struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); 715 + struct rk808 *rk808 = i2c_get_clientdata(to_i2c_client(dev)); 680 716 int ret = 0; 681 717 682 718 switch (rk808->variant) { 719 + case RK805_ID: 720 + ret = regmap_update_bits(rk808->regmap, 721 + RK805_GPIO_IO_POL_REG, 722 + SLP_SD_MSK, 723 + SLEEP_FUN); 724 + break; 683 725 case RK809_ID: 684 726 case RK817_ID: 685 727 ret = regmap_update_bits(rk808->regmap, ··· 695 739 696 740 static int __maybe_unused rk8xx_resume(struct device *dev) 697 741 { 698 - struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); 742 + struct rk808 *rk808 = i2c_get_clientdata(to_i2c_client(dev)); 699 743 int ret = 0; 700 744 701 745 switch (rk808->variant) { ··· 722 766 }, 723 767 .probe = rk808_probe, 724 768 .remove = rk808_remove, 769 + .shutdown = rk8xx_shutdown, 725 770 }; 726 771 727 772 module_i2c_driver(rk808_i2c_driver);
+98 -11
drivers/mfd/rn5t618.c
··· 8 8 9 9 #include <linux/delay.h> 10 10 #include <linux/i2c.h> 11 + #include <linux/interrupt.h> 12 + #include <linux/irq.h> 11 13 #include <linux/mfd/core.h> 12 14 #include <linux/mfd/rn5t618.h> 13 15 #include <linux/module.h> 14 16 #include <linux/of_device.h> 17 + #include <linux/platform_device.h> 15 18 #include <linux/reboot.h> 16 19 #include <linux/regmap.h> 17 20 18 21 static const struct mfd_cell rn5t618_cells[] = { 19 22 { .name = "rn5t618-regulator" }, 23 + { .name = "rn5t618-wdt" }, 24 + }; 25 + 26 + static const struct mfd_cell rc5t619_cells[] = { 27 + { .name = "rn5t618-adc" }, 28 + { .name = "rn5t618-regulator" }, 29 + { .name = "rc5t619-rtc" }, 20 30 { .name = "rn5t618-wdt" }, 21 31 }; 22 32 ··· 42 32 case RN5T618_IR_GPF: 43 33 case RN5T618_MON_IOIN: 44 34 case RN5T618_INTMON: 35 + case RN5T618_RTC_CTRL1 ... RN5T618_RTC_CTRL2: 36 + case RN5T618_RTC_SECONDS ... RN5T618_RTC_YEAR: 45 37 return true; 46 38 default: 47 39 return false; ··· 58 46 .cache_type = REGCACHE_RBTREE, 59 47 }; 60 48 49 + static const struct regmap_irq rc5t619_irqs[] = { 50 + REGMAP_IRQ_REG(RN5T618_IRQ_SYS, 0, BIT(0)), 51 + REGMAP_IRQ_REG(RN5T618_IRQ_DCDC, 0, BIT(1)), 52 + REGMAP_IRQ_REG(RN5T618_IRQ_RTC, 0, BIT(2)), 53 + REGMAP_IRQ_REG(RN5T618_IRQ_ADC, 0, BIT(3)), 54 + REGMAP_IRQ_REG(RN5T618_IRQ_GPIO, 0, BIT(4)), 55 + REGMAP_IRQ_REG(RN5T618_IRQ_CHG, 0, BIT(6)), 56 + }; 57 + 58 + static const struct regmap_irq_chip rc5t619_irq_chip = { 59 + .name = "rc5t619", 60 + .irqs = rc5t619_irqs, 61 + .num_irqs = ARRAY_SIZE(rc5t619_irqs), 62 + .num_regs = 1, 63 + .status_base = RN5T618_INTMON, 64 + .mask_base = RN5T618_INTEN, 65 + .mask_invert = true, 66 + }; 67 + 61 68 static struct rn5t618 *rn5t618_pm_power_off; 62 69 static struct notifier_block rn5t618_restart_handler; 70 + 71 + static int rn5t618_irq_init(struct rn5t618 *rn5t618) 72 + { 73 + const struct regmap_irq_chip *irq_chip = NULL; 74 + int ret; 75 + 76 + if (!rn5t618->irq) 77 + return 0; 78 + 79 + switch (rn5t618->variant) { 80 + case RC5T619: 81 + irq_chip = &rc5t619_irq_chip; 82 + break; 83 + default: 84 + dev_err(rn5t618->dev, "Currently no IRQ support for variant %d\n", 85 + (int)rn5t618->variant); 86 + return -ENOENT; 87 + } 88 + 89 + ret = devm_regmap_add_irq_chip(rn5t618->dev, rn5t618->regmap, 90 + rn5t618->irq, 91 + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 92 + 0, irq_chip, &rn5t618->irq_data); 93 + if (ret) 94 + dev_err(rn5t618->dev, "Failed to register IRQ chip\n"); 95 + 96 + return ret; 97 + } 63 98 64 99 static void rn5t618_trigger_poweroff_sequence(bool repower) 65 100 { ··· 146 87 }; 147 88 MODULE_DEVICE_TABLE(of, rn5t618_of_match); 148 89 149 - static int rn5t618_i2c_probe(struct i2c_client *i2c, 150 - const struct i2c_device_id *id) 90 + static int rn5t618_i2c_probe(struct i2c_client *i2c) 151 91 { 152 92 const struct of_device_id *of_id; 153 93 struct rn5t618 *priv; ··· 164 106 165 107 i2c_set_clientdata(i2c, priv); 166 108 priv->variant = (long)of_id->data; 109 + priv->irq = i2c->irq; 110 + priv->dev = &i2c->dev; 167 111 168 112 priv->regmap = devm_regmap_init_i2c(i2c, &rn5t618_regmap_config); 169 113 if (IS_ERR(priv->regmap)) { ··· 174 114 return ret; 175 115 } 176 116 177 - ret = devm_mfd_add_devices(&i2c->dev, -1, rn5t618_cells, 178 - ARRAY_SIZE(rn5t618_cells), NULL, 0, NULL); 117 + if (priv->variant == RC5T619) 118 + ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_NONE, 119 + rc5t619_cells, 120 + ARRAY_SIZE(rc5t619_cells), 121 + NULL, 0, NULL); 122 + else 123 + ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_NONE, 124 + rn5t618_cells, 125 + ARRAY_SIZE(rn5t618_cells), 126 + NULL, 0, NULL); 179 127 if (ret) { 180 128 dev_err(&i2c->dev, "failed to add sub-devices: %d\n", ret); 181 129 return ret; ··· 206 138 return ret; 207 139 } 208 140 209 - return 0; 141 + return rn5t618_irq_init(priv); 210 142 } 211 143 212 144 static int rn5t618_i2c_remove(struct i2c_client *i2c) ··· 223 155 return 0; 224 156 } 225 157 226 - static const struct i2c_device_id rn5t618_i2c_id[] = { 227 - { } 228 - }; 229 - MODULE_DEVICE_TABLE(i2c, rn5t618_i2c_id); 158 + static int __maybe_unused rn5t618_i2c_suspend(struct device *dev) 159 + { 160 + struct rn5t618 *priv = dev_get_drvdata(dev); 161 + 162 + if (priv->irq) 163 + disable_irq(priv->irq); 164 + 165 + return 0; 166 + } 167 + 168 + static int __maybe_unused rn5t618_i2c_resume(struct device *dev) 169 + { 170 + struct rn5t618 *priv = dev_get_drvdata(dev); 171 + 172 + if (priv->irq) 173 + enable_irq(priv->irq); 174 + 175 + return 0; 176 + } 177 + 178 + static SIMPLE_DEV_PM_OPS(rn5t618_i2c_dev_pm_ops, 179 + rn5t618_i2c_suspend, 180 + rn5t618_i2c_resume); 230 181 231 182 static struct i2c_driver rn5t618_i2c_driver = { 232 183 .driver = { 233 184 .name = "rn5t618", 234 185 .of_match_table = of_match_ptr(rn5t618_of_match), 186 + .pm = &rn5t618_i2c_dev_pm_ops, 235 187 }, 236 - .probe = rn5t618_i2c_probe, 188 + .probe_new = rn5t618_i2c_probe, 237 189 .remove = rn5t618_i2c_remove, 238 - .id_table = rn5t618_i2c_id, 239 190 }; 240 191 241 192 module_i2c_driver(rn5t618_i2c_driver);
+52
drivers/mfd/sprd-sc27xx-spi.c
··· 10 10 #include <linux/of_device.h> 11 11 #include <linux/regmap.h> 12 12 #include <linux/spi/spi.h> 13 + #include <uapi/linux/usb/charger.h> 13 14 14 15 #define SPRD_PMIC_INT_MASK_STATUS 0x0 15 16 #define SPRD_PMIC_INT_RAW_STATUS 0x4 ··· 18 17 19 18 #define SPRD_SC2731_IRQ_BASE 0x140 20 19 #define SPRD_SC2731_IRQ_NUMS 16 20 + #define SPRD_SC2731_CHG_DET 0xedc 21 + 22 + /* PMIC charger detection definition */ 23 + #define SPRD_PMIC_CHG_DET_DELAY_US 200000 24 + #define SPRD_PMIC_CHG_DET_TIMEOUT 2000000 25 + #define SPRD_PMIC_CHG_DET_DONE BIT(11) 26 + #define SPRD_PMIC_SDP_TYPE BIT(7) 27 + #define SPRD_PMIC_DCP_TYPE BIT(6) 28 + #define SPRD_PMIC_CDP_TYPE BIT(5) 29 + #define SPRD_PMIC_CHG_TYPE_MASK GENMASK(7, 5) 21 30 22 31 struct sprd_pmic { 23 32 struct regmap *regmap; ··· 35 24 struct regmap_irq *irqs; 36 25 struct regmap_irq_chip irq_chip; 37 26 struct regmap_irq_chip_data *irq_data; 27 + const struct sprd_pmic_data *pdata; 38 28 int irq; 39 29 }; 40 30 41 31 struct sprd_pmic_data { 42 32 u32 irq_base; 43 33 u32 num_irqs; 34 + u32 charger_det; 44 35 }; 45 36 46 37 /* ··· 53 40 static const struct sprd_pmic_data sc2731_data = { 54 41 .irq_base = SPRD_SC2731_IRQ_BASE, 55 42 .num_irqs = SPRD_SC2731_IRQ_NUMS, 43 + .charger_det = SPRD_SC2731_CHG_DET, 56 44 }; 45 + 46 + enum usb_charger_type sprd_pmic_detect_charger_type(struct device *dev) 47 + { 48 + struct spi_device *spi = to_spi_device(dev); 49 + struct sprd_pmic *ddata = spi_get_drvdata(spi); 50 + const struct sprd_pmic_data *pdata = ddata->pdata; 51 + enum usb_charger_type type; 52 + u32 val; 53 + int ret; 54 + 55 + ret = regmap_read_poll_timeout(ddata->regmap, pdata->charger_det, val, 56 + (val & SPRD_PMIC_CHG_DET_DONE), 57 + SPRD_PMIC_CHG_DET_DELAY_US, 58 + SPRD_PMIC_CHG_DET_TIMEOUT); 59 + if (ret) { 60 + dev_err(&spi->dev, "failed to detect charger type\n"); 61 + return UNKNOWN_TYPE; 62 + } 63 + 64 + switch (val & SPRD_PMIC_CHG_TYPE_MASK) { 65 + case SPRD_PMIC_CDP_TYPE: 66 + type = CDP_TYPE; 67 + break; 68 + case SPRD_PMIC_DCP_TYPE: 69 + type = DCP_TYPE; 70 + break; 71 + case SPRD_PMIC_SDP_TYPE: 72 + type = SDP_TYPE; 73 + break; 74 + default: 75 + type = UNKNOWN_TYPE; 76 + break; 77 + } 78 + 79 + return type; 80 + } 81 + EXPORT_SYMBOL_GPL(sprd_pmic_detect_charger_type); 57 82 58 83 static const struct mfd_cell sprd_pmic_devs[] = { 59 84 { ··· 232 181 spi_set_drvdata(spi, ddata); 233 182 ddata->dev = &spi->dev; 234 183 ddata->irq = spi->irq; 184 + ddata->pdata = pdata; 235 185 236 186 ddata->irq_chip.name = dev_name(&spi->dev); 237 187 ddata->irq_chip.status_base =
+10
drivers/rtc/Kconfig
··· 590 590 This driver can also be built as a module. If so, the module 591 591 will be called rtc-rc5t583. 592 592 593 + config RTC_DRV_RC5T619 594 + tristate "RICOH RC5T619 RTC driver" 595 + depends on MFD_RN5T618 596 + help 597 + If you say yes here you get support for the RTC on the 598 + RICOH RC5T619 chips. 599 + 600 + This driver can also be built as a module. If so, the module 601 + will be called rtc-rc5t619. 602 + 593 603 config RTC_DRV_S35390A 594 604 tristate "Seiko Instruments S-35390A" 595 605 select BITREVERSE
+1
drivers/rtc/Makefile
··· 133 133 obj-$(CONFIG_RTC_DRV_R7301) += rtc-r7301.o 134 134 obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o 135 135 obj-$(CONFIG_RTC_DRV_RC5T583) += rtc-rc5t583.o 136 + obj-$(CONFIG_RTC_DRV_RC5T619) += rtc-rc5t619.o 136 137 obj-$(CONFIG_RTC_DRV_RK808) += rtc-rk808.o 137 138 obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c01.o 138 139 obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o
+444
drivers/rtc/rtc-rc5t619.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * drivers/rtc/rtc-rc5t619.c 4 + * 5 + * Real time clock driver for RICOH RC5T619 power management chip. 6 + * 7 + * Copyright (C) 2019 Andreas Kemnade 8 + */ 9 + 10 + #include <linux/kernel.h> 11 + #include <linux/device.h> 12 + #include <linux/errno.h> 13 + #include <linux/init.h> 14 + #include <linux/module.h> 15 + #include <linux/mfd/rn5t618.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/regmap.h> 18 + #include <linux/bcd.h> 19 + #include <linux/rtc.h> 20 + #include <linux/slab.h> 21 + #include <linux/irqdomain.h> 22 + 23 + struct rc5t619_rtc { 24 + int irq; 25 + struct rtc_device *rtc; 26 + struct rn5t618 *rn5t618; 27 + }; 28 + 29 + #define CTRL1_ALARM_ENABLED 0x40 30 + #define CTRL1_24HR 0x20 31 + #define CTRL1_PERIODIC_MASK 0xf 32 + 33 + #define CTRL2_PON 0x10 34 + #define CTRL2_ALARM_STATUS 0x80 35 + #define CTRL2_CTFG 0x4 36 + #define CTRL2_CTC 0x1 37 + 38 + #define MONTH_CENTFLAG 0x80 39 + #define HOUR_PMFLAG 0x20 40 + #define MDAY_DAL_EXT 0x80 41 + 42 + static uint8_t rtc5t619_12hour_bcd2bin(uint8_t hour) 43 + { 44 + if (hour & HOUR_PMFLAG) { 45 + hour = bcd2bin(hour & ~HOUR_PMFLAG); 46 + return hour == 12 ? 12 : 12 + hour; 47 + } 48 + 49 + hour = bcd2bin(hour); 50 + return hour == 12 ? 0 : hour; 51 + } 52 + 53 + static uint8_t rtc5t619_12hour_bin2bcd(uint8_t hour) 54 + { 55 + if (!hour) 56 + return 0x12; 57 + 58 + if (hour < 12) 59 + return bin2bcd(hour); 60 + 61 + if (hour == 12) 62 + return 0x12 | HOUR_PMFLAG; 63 + 64 + return bin2bcd(hour - 12) | HOUR_PMFLAG; 65 + } 66 + 67 + static int rc5t619_rtc_periodic_disable(struct device *dev) 68 + { 69 + struct rc5t619_rtc *rtc = dev_get_drvdata(dev); 70 + int err; 71 + 72 + /* disable function */ 73 + err = regmap_update_bits(rtc->rn5t618->regmap, 74 + RN5T618_RTC_CTRL1, CTRL1_PERIODIC_MASK, 0); 75 + if (err < 0) 76 + return err; 77 + 78 + /* clear alarm flag and CTFG */ 79 + err = regmap_update_bits(rtc->rn5t618->regmap, RN5T618_RTC_CTRL2, 80 + CTRL2_ALARM_STATUS | CTRL2_CTFG | CTRL2_CTC, 81 + 0); 82 + if (err < 0) 83 + return err; 84 + 85 + return 0; 86 + } 87 + 88 + /* things to be done once after power on */ 89 + static int rc5t619_rtc_pon_setup(struct device *dev) 90 + { 91 + struct rc5t619_rtc *rtc = dev_get_drvdata(dev); 92 + int err; 93 + unsigned int reg_data; 94 + 95 + err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL2, &reg_data); 96 + if (err < 0) 97 + return err; 98 + 99 + /* clear VDET PON */ 100 + reg_data &= ~(CTRL2_PON | CTRL2_CTC | 0x4a); /* 0101-1011 */ 101 + reg_data |= 0x20; /* 0010-0000 */ 102 + err = regmap_write(rtc->rn5t618->regmap, RN5T618_RTC_CTRL2, reg_data); 103 + if (err < 0) 104 + return err; 105 + 106 + /* clearing RTC Adjust register */ 107 + err = regmap_write(rtc->rn5t618->regmap, RN5T618_RTC_ADJUST, 0); 108 + if (err) 109 + return err; 110 + 111 + return regmap_update_bits(rtc->rn5t618->regmap, 112 + RN5T618_RTC_CTRL1, 113 + CTRL1_24HR, CTRL1_24HR); 114 + } 115 + 116 + static int rc5t619_rtc_read_time(struct device *dev, struct rtc_time *tm) 117 + { 118 + struct rc5t619_rtc *rtc = dev_get_drvdata(dev); 119 + u8 buff[7]; 120 + int err; 121 + int cent_flag; 122 + unsigned int ctrl1; 123 + unsigned int ctrl2; 124 + 125 + err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL2, &ctrl2); 126 + if (err < 0) 127 + return err; 128 + 129 + if (ctrl2 & CTRL2_PON) 130 + return -EINVAL; 131 + 132 + err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL1, &ctrl1); 133 + if (err < 0) 134 + return err; 135 + 136 + err = regmap_bulk_read(rtc->rn5t618->regmap, RN5T618_RTC_SECONDS, 137 + buff, sizeof(buff)); 138 + if (err < 0) 139 + return err; 140 + 141 + if (buff[5] & MONTH_CENTFLAG) 142 + cent_flag = 1; 143 + else 144 + cent_flag = 0; 145 + 146 + tm->tm_sec = bcd2bin(buff[0]); 147 + tm->tm_min = bcd2bin(buff[1]); 148 + 149 + if (ctrl1 & CTRL1_24HR) 150 + tm->tm_hour = bcd2bin(buff[2]); 151 + else 152 + tm->tm_hour = rtc5t619_12hour_bcd2bin(buff[2]); 153 + 154 + tm->tm_wday = bcd2bin(buff[3]); 155 + tm->tm_mday = bcd2bin(buff[4]); 156 + tm->tm_mon = bcd2bin(buff[5] & 0x1f) - 1; /* back to system 0-11 */ 157 + tm->tm_year = bcd2bin(buff[6]) + 100 * cent_flag; 158 + 159 + return 0; 160 + } 161 + 162 + static int rc5t619_rtc_set_time(struct device *dev, struct rtc_time *tm) 163 + { 164 + struct rc5t619_rtc *rtc = dev_get_drvdata(dev); 165 + u8 buff[7]; 166 + int err; 167 + int cent_flag; 168 + unsigned int ctrl1; 169 + unsigned int ctrl2; 170 + 171 + err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL2, &ctrl2); 172 + if (err < 0) 173 + return err; 174 + 175 + if (ctrl2 & CTRL2_PON) 176 + rc5t619_rtc_pon_setup(dev); 177 + 178 + err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL1, &ctrl1); 179 + if (err < 0) 180 + return err; 181 + 182 + if (tm->tm_year >= 100) 183 + cent_flag = 1; 184 + else 185 + cent_flag = 0; 186 + 187 + buff[0] = bin2bcd(tm->tm_sec); 188 + buff[1] = bin2bcd(tm->tm_min); 189 + 190 + if (ctrl1 & CTRL1_24HR) 191 + buff[2] = bin2bcd(tm->tm_hour); 192 + else 193 + buff[2] = rtc5t619_12hour_bin2bcd(tm->tm_hour); 194 + 195 + buff[3] = bin2bcd(tm->tm_wday); 196 + buff[4] = bin2bcd(tm->tm_mday); 197 + buff[5] = bin2bcd(tm->tm_mon + 1); /* system set 0-11 */ 198 + buff[6] = bin2bcd(tm->tm_year - cent_flag * 100); 199 + 200 + if (cent_flag) 201 + buff[5] |= MONTH_CENTFLAG; 202 + 203 + err = regmap_bulk_write(rtc->rn5t618->regmap, RN5T618_RTC_SECONDS, 204 + buff, sizeof(buff)); 205 + if (err < 0) { 206 + dev_err(dev, "failed to program new time: %d\n", err); 207 + return err; 208 + } 209 + 210 + return 0; 211 + } 212 + 213 + /* 0-disable, 1-enable */ 214 + static int rc5t619_rtc_alarm_enable(struct device *dev, unsigned int enabled) 215 + { 216 + struct rc5t619_rtc *rtc = dev_get_drvdata(dev); 217 + 218 + return regmap_update_bits(rtc->rn5t618->regmap, 219 + RN5T618_RTC_CTRL1, 220 + CTRL1_ALARM_ENABLED, 221 + enabled ? CTRL1_ALARM_ENABLED : 0); 222 + } 223 + 224 + static int rc5t619_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) 225 + { 226 + struct rc5t619_rtc *rtc = dev_get_drvdata(dev); 227 + u8 buff[6]; 228 + unsigned int buff_cent; 229 + int err; 230 + int cent_flag; 231 + unsigned int ctrl1; 232 + 233 + err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL1, &ctrl1); 234 + if (err) 235 + return err; 236 + 237 + err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_MONTH, &buff_cent); 238 + if (err < 0) { 239 + dev_err(dev, "failed to read time: %d\n", err); 240 + return err; 241 + } 242 + 243 + if (buff_cent & MONTH_CENTFLAG) 244 + cent_flag = 1; 245 + else 246 + cent_flag = 0; 247 + 248 + err = regmap_bulk_read(rtc->rn5t618->regmap, RN5T618_RTC_ALARM_Y_SEC, 249 + buff, sizeof(buff)); 250 + if (err) 251 + return err; 252 + 253 + buff[3] = buff[3] & 0x3f; 254 + 255 + alrm->time.tm_sec = bcd2bin(buff[0]); 256 + alrm->time.tm_min = bcd2bin(buff[1]); 257 + 258 + if (ctrl1 & CTRL1_24HR) 259 + alrm->time.tm_hour = bcd2bin(buff[2]); 260 + else 261 + alrm->time.tm_hour = rtc5t619_12hour_bcd2bin(buff[2]); 262 + 263 + alrm->time.tm_mday = bcd2bin(buff[3]); 264 + alrm->time.tm_mon = bcd2bin(buff[4]) - 1; 265 + alrm->time.tm_year = bcd2bin(buff[5]) + 100 * cent_flag; 266 + alrm->enabled = !!(ctrl1 & CTRL1_ALARM_ENABLED); 267 + dev_dbg(dev, "read alarm: %ptR\n", &alrm->time); 268 + 269 + return 0; 270 + } 271 + 272 + static int rc5t619_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 273 + { 274 + struct rc5t619_rtc *rtc = dev_get_drvdata(dev); 275 + u8 buff[6]; 276 + int err; 277 + int cent_flag; 278 + unsigned int ctrl1; 279 + 280 + err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL1, &ctrl1); 281 + if (err) 282 + return err; 283 + 284 + err = rc5t619_rtc_alarm_enable(dev, 0); 285 + if (err < 0) 286 + return err; 287 + 288 + if (rtc->irq == -1) 289 + return -EINVAL; 290 + 291 + if (alrm->enabled == 0) 292 + return 0; 293 + 294 + if (alrm->time.tm_year >= 100) 295 + cent_flag = 1; 296 + else 297 + cent_flag = 0; 298 + 299 + alrm->time.tm_mon += 1; 300 + buff[0] = bin2bcd(alrm->time.tm_sec); 301 + buff[1] = bin2bcd(alrm->time.tm_min); 302 + 303 + if (ctrl1 & CTRL1_24HR) 304 + buff[2] = bin2bcd(alrm->time.tm_hour); 305 + else 306 + buff[2] = rtc5t619_12hour_bin2bcd(alrm->time.tm_hour); 307 + 308 + buff[3] = bin2bcd(alrm->time.tm_mday); 309 + buff[4] = bin2bcd(alrm->time.tm_mon); 310 + buff[5] = bin2bcd(alrm->time.tm_year - 100 * cent_flag); 311 + buff[3] |= MDAY_DAL_EXT; 312 + 313 + err = regmap_bulk_write(rtc->rn5t618->regmap, RN5T618_RTC_ALARM_Y_SEC, 314 + buff, sizeof(buff)); 315 + if (err < 0) 316 + return err; 317 + 318 + return rc5t619_rtc_alarm_enable(dev, alrm->enabled); 319 + } 320 + 321 + static const struct rtc_class_ops rc5t619_rtc_ops = { 322 + .read_time = rc5t619_rtc_read_time, 323 + .set_time = rc5t619_rtc_set_time, 324 + .set_alarm = rc5t619_rtc_set_alarm, 325 + .read_alarm = rc5t619_rtc_read_alarm, 326 + .alarm_irq_enable = rc5t619_rtc_alarm_enable, 327 + }; 328 + 329 + static int rc5t619_rtc_alarm_flag_clr(struct device *dev) 330 + { 331 + struct rc5t619_rtc *rtc = dev_get_drvdata(dev); 332 + 333 + /* clear alarm-D status bits.*/ 334 + return regmap_update_bits(rtc->rn5t618->regmap, 335 + RN5T618_RTC_CTRL2, 336 + CTRL2_ALARM_STATUS | CTRL2_CTC, 0); 337 + } 338 + 339 + static irqreturn_t rc5t619_rtc_irq(int irq, void *data) 340 + { 341 + struct device *dev = data; 342 + struct rc5t619_rtc *rtc = dev_get_drvdata(dev); 343 + 344 + rc5t619_rtc_alarm_flag_clr(dev); 345 + 346 + rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); 347 + return IRQ_HANDLED; 348 + } 349 + 350 + static int rc5t619_rtc_probe(struct platform_device *pdev) 351 + { 352 + struct device *dev = &pdev->dev; 353 + struct rn5t618 *rn5t618 = dev_get_drvdata(pdev->dev.parent); 354 + struct rc5t619_rtc *rtc; 355 + unsigned int ctrl2; 356 + int err; 357 + 358 + rtc = devm_kzalloc(dev, sizeof(*rtc), GFP_KERNEL); 359 + if (IS_ERR(rtc)) { 360 + err = PTR_ERR(rtc); 361 + return -ENOMEM; 362 + } 363 + 364 + rtc->rn5t618 = rn5t618; 365 + 366 + dev_set_drvdata(dev, rtc); 367 + rtc->irq = -1; 368 + 369 + if (rn5t618->irq_data) 370 + rtc->irq = regmap_irq_get_virq(rn5t618->irq_data, 371 + RN5T618_IRQ_RTC); 372 + 373 + if (rtc->irq < 0) 374 + rtc->irq = -1; 375 + 376 + err = regmap_read(rtc->rn5t618->regmap, RN5T618_RTC_CTRL2, &ctrl2); 377 + if (err < 0) 378 + return err; 379 + 380 + /* disable rtc periodic function */ 381 + err = rc5t619_rtc_periodic_disable(&pdev->dev); 382 + if (err) 383 + return err; 384 + 385 + if (ctrl2 & CTRL2_PON) { 386 + err = rc5t619_rtc_alarm_flag_clr(&pdev->dev); 387 + if (err) 388 + return err; 389 + } 390 + 391 + rtc->rtc = devm_rtc_allocate_device(&pdev->dev); 392 + if (IS_ERR(rtc->rtc)) { 393 + err = PTR_ERR(rtc->rtc); 394 + dev_err(dev, "RTC device register: err %d\n", err); 395 + return err; 396 + } 397 + 398 + rtc->rtc->ops = &rc5t619_rtc_ops; 399 + rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_1900; 400 + rtc->rtc->range_max = RTC_TIMESTAMP_END_2099; 401 + 402 + /* set interrupt and enable it */ 403 + if (rtc->irq != -1) { 404 + err = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, 405 + rc5t619_rtc_irq, 406 + IRQF_ONESHOT, 407 + "rtc-rc5t619", 408 + &pdev->dev); 409 + if (err < 0) { 410 + dev_err(&pdev->dev, "request IRQ:%d fail\n", rtc->irq); 411 + rtc->irq = -1; 412 + 413 + err = rc5t619_rtc_alarm_enable(&pdev->dev, 0); 414 + if (err) 415 + return err; 416 + 417 + } else { 418 + /* enable wake */ 419 + device_init_wakeup(&pdev->dev, 1); 420 + enable_irq_wake(rtc->irq); 421 + } 422 + } else { 423 + /* system don't want to using alarm interrupt, so close it */ 424 + err = rc5t619_rtc_alarm_enable(&pdev->dev, 0); 425 + if (err) 426 + return err; 427 + 428 + dev_warn(&pdev->dev, "rc5t619 interrupt is disabled\n"); 429 + } 430 + 431 + return rtc_register_device(rtc->rtc); 432 + } 433 + 434 + static struct platform_driver rc5t619_rtc_driver = { 435 + .driver = { 436 + .name = "rc5t619-rtc", 437 + }, 438 + .probe = rc5t619_rtc_probe, 439 + }; 440 + 441 + module_platform_driver(rc5t619_rtc_driver); 442 + MODULE_ALIAS("platform:rc5t619-rtc"); 443 + MODULE_DESCRIPTION("RICOH RC5T619 RTC driver"); 444 + MODULE_LICENSE("GPL");
+139
include/linux/mfd/iqs62x.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* 3 + * Azoteq IQS620A/621/622/624/625 Multi-Function Sensors 4 + * 5 + * Copyright (C) 2019 Jeff LaBundy <jeff@labundy.com> 6 + */ 7 + 8 + #ifndef __LINUX_MFD_IQS62X_H 9 + #define __LINUX_MFD_IQS62X_H 10 + 11 + #define IQS620_PROD_NUM 0x41 12 + #define IQS621_PROD_NUM 0x46 13 + #define IQS622_PROD_NUM 0x42 14 + #define IQS624_PROD_NUM 0x43 15 + #define IQS625_PROD_NUM 0x4E 16 + 17 + #define IQS621_ALS_FLAGS 0x16 18 + #define IQS622_ALS_FLAGS 0x14 19 + 20 + #define IQS624_HALL_UI 0x70 21 + #define IQS624_HALL_UI_WHL_EVENT BIT(4) 22 + #define IQS624_HALL_UI_INT_EVENT BIT(3) 23 + #define IQS624_HALL_UI_AUTO_CAL BIT(2) 24 + 25 + #define IQS624_INTERVAL_DIV 0x7D 26 + 27 + #define IQS620_GLBL_EVENT_MASK 0xD7 28 + #define IQS620_GLBL_EVENT_MASK_PMU BIT(6) 29 + 30 + #define IQS62X_NUM_KEYS 16 31 + #define IQS62X_NUM_EVENTS (IQS62X_NUM_KEYS + 5) 32 + 33 + #define IQS62X_EVENT_SIZE 10 34 + 35 + enum iqs62x_ui_sel { 36 + IQS62X_UI_PROX, 37 + IQS62X_UI_SAR1, 38 + }; 39 + 40 + enum iqs62x_event_reg { 41 + IQS62X_EVENT_NONE, 42 + IQS62X_EVENT_SYS, 43 + IQS62X_EVENT_PROX, 44 + IQS62X_EVENT_HYST, 45 + IQS62X_EVENT_HALL, 46 + IQS62X_EVENT_ALS, 47 + IQS62X_EVENT_IR, 48 + IQS62X_EVENT_WHEEL, 49 + IQS62X_EVENT_INTER, 50 + IQS62X_EVENT_UI_LO, 51 + IQS62X_EVENT_UI_HI, 52 + }; 53 + 54 + enum iqs62x_event_flag { 55 + /* keys */ 56 + IQS62X_EVENT_PROX_CH0_T, 57 + IQS62X_EVENT_PROX_CH0_P, 58 + IQS62X_EVENT_PROX_CH1_T, 59 + IQS62X_EVENT_PROX_CH1_P, 60 + IQS62X_EVENT_PROX_CH2_T, 61 + IQS62X_EVENT_PROX_CH2_P, 62 + IQS62X_EVENT_HYST_POS_T, 63 + IQS62X_EVENT_HYST_POS_P, 64 + IQS62X_EVENT_HYST_NEG_T, 65 + IQS62X_EVENT_HYST_NEG_P, 66 + IQS62X_EVENT_SAR1_ACT, 67 + IQS62X_EVENT_SAR1_QRD, 68 + IQS62X_EVENT_SAR1_MOVE, 69 + IQS62X_EVENT_SAR1_HALT, 70 + IQS62X_EVENT_WHEEL_UP, 71 + IQS62X_EVENT_WHEEL_DN, 72 + 73 + /* switches */ 74 + IQS62X_EVENT_HALL_N_T, 75 + IQS62X_EVENT_HALL_N_P, 76 + IQS62X_EVENT_HALL_S_T, 77 + IQS62X_EVENT_HALL_S_P, 78 + 79 + /* everything else */ 80 + IQS62X_EVENT_SYS_RESET, 81 + }; 82 + 83 + struct iqs62x_event_data { 84 + u16 ui_data; 85 + u8 als_flags; 86 + u8 ir_flags; 87 + u8 interval; 88 + }; 89 + 90 + struct iqs62x_event_desc { 91 + enum iqs62x_event_reg reg; 92 + u8 mask; 93 + u8 val; 94 + }; 95 + 96 + struct iqs62x_dev_desc { 97 + const char *dev_name; 98 + const struct mfd_cell *sub_devs; 99 + int num_sub_devs; 100 + 101 + u8 prod_num; 102 + u8 sw_num; 103 + const u8 *cal_regs; 104 + int num_cal_regs; 105 + 106 + u8 prox_mask; 107 + u8 sar_mask; 108 + u8 hall_mask; 109 + u8 hyst_mask; 110 + u8 temp_mask; 111 + u8 als_mask; 112 + u8 ir_mask; 113 + 114 + u8 prox_settings; 115 + u8 als_flags; 116 + u8 hall_flags; 117 + u8 hyst_shift; 118 + 119 + u8 interval; 120 + u8 interval_div; 121 + 122 + u8 clk_div; 123 + const char *fw_name; 124 + const enum iqs62x_event_reg (*event_regs)[IQS62X_EVENT_SIZE]; 125 + }; 126 + 127 + struct iqs62x_core { 128 + const struct iqs62x_dev_desc *dev_desc; 129 + struct i2c_client *client; 130 + struct regmap *regmap; 131 + struct blocking_notifier_head nh; 132 + struct list_head fw_blk_head; 133 + struct completion fw_done; 134 + enum iqs62x_ui_sel ui_sel; 135 + }; 136 + 137 + extern const struct iqs62x_event_desc iqs62x_events[IQS62X_NUM_EVENTS]; 138 + 139 + #endif /* __LINUX_MFD_IQS62X_H */
-2
include/linux/mfd/rk808.h
··· 620 620 long variant; 621 621 const struct regmap_config *regmap_cfg; 622 622 const struct regmap_irq_chip *regmap_irq_chip; 623 - void (*pm_pwroff_fn)(void); 624 - void (*pm_pwroff_prep_fn)(void); 625 623 }; 626 624 #endif /* __LINUX_REGULATOR_RK808_H */
+26
include/linux/mfd/rn5t618.h
··· 139 139 #define RN5T618_INTPOL 0x9c 140 140 #define RN5T618_INTEN 0x9d 141 141 #define RN5T618_INTMON 0x9e 142 + 143 + #define RN5T618_RTC_SECONDS 0xA0 144 + #define RN5T618_RTC_MDAY 0xA4 145 + #define RN5T618_RTC_MONTH 0xA5 146 + #define RN5T618_RTC_YEAR 0xA6 147 + #define RN5T618_RTC_ADJUST 0xA7 148 + #define RN5T618_RTC_ALARM_Y_SEC 0xA8 149 + #define RN5T618_RTC_DAL_MONTH 0xAC 150 + #define RN5T618_RTC_CTRL1 0xAE 151 + #define RN5T618_RTC_CTRL2 0xAF 152 + 142 153 #define RN5T618_PREVINDAC 0xb0 143 154 #define RN5T618_BATDAC 0xb1 144 155 #define RN5T618_CHGCTL1 0xb3 ··· 253 242 RC5T619, 254 243 }; 255 244 245 + /* RN5T618 IRQ definitions */ 246 + enum { 247 + RN5T618_IRQ_SYS = 0, 248 + RN5T618_IRQ_DCDC, 249 + RN5T618_IRQ_RTC, 250 + RN5T618_IRQ_ADC, 251 + RN5T618_IRQ_GPIO, 252 + RN5T618_IRQ_CHG, 253 + RN5T618_NR_IRQS, 254 + }; 255 + 256 256 struct rn5t618 { 257 257 struct regmap *regmap; 258 + struct device *dev; 258 259 long variant; 260 + 261 + int irq; 262 + struct regmap_irq_chip_data *irq_data; 259 263 }; 260 264 261 265 #endif /* __LINUX_MFD_RN5T618_H */
+7
include/linux/mfd/sc27xx-pmic.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef __LINUX_MFD_SC27XX_PMIC_H 3 + #define __LINUX_MFD_SC27XX_PMIC_H 4 + 5 + extern enum usb_charger_type sprd_pmic_detect_charger_type(struct device *dev); 6 + 7 + #endif /* __LINUX_MFD_SC27XX_PMIC_H */