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

Merge tag 'hwmon-for-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging

Pull hwmon updates from Guenter Roeck:
"New drivers:
- Amphenol ChipCap 2
- ASPEED g6 PWM/Fan tach
- Astera Labs PT5161L retimer
- ASUS ROG RYUJIN II 360 AIO cooler
- LTC4282
- Microsoft Surface devices
- MPS MPQ8785 Synchronous Step-Down Converter
- NZXT Kraken X and Z series AIO CPU coolers

Additional chip support in existing drivers:
- Ayaneo Air Plus 7320u (oxp-sensors)
- INA260 (ina2xx)
- XPS 9315 (dell-smm)
- MSI customer ID (nct6683)

Devicetree bindings updates:
- Common schema for hardware monitoring devices
- Common schema for fans
- Update chip descriptions to use common schema
- Document regulator properties in several drivers
- Explicit bindings for infineon buck converters

Other improvements:
- Replaced rbtree with maple tree register cache in several drivers
- Added support for humidity min/max alarm and volatage fault
attributes to hwmon core
- Dropped non-functional I2C_CLASS_HWMON support for drivers w/o
detect()
- Dropped obsolete and redundant entried from MAINTAINERS
- Cleaned up axi-fan-control and coretemp drivers
- Minor fixes and improvements in several other drivers"

* tag 'hwmon-for-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging: (70 commits)
hwmon: (dell-smm) Add XPS 9315 to fan control whitelist
hwmon: (aspeed-g6-pwm-tacho): Support for ASPEED g6 PWM/Fan tach
dt-bindings: hwmon: Support Aspeed g6 PWM TACH Control
dt-bindings: hwmon: fan: Add fan binding to schema
dt-bindings: hwmon: tda38640: Add interrupt & regulator properties
hwmon: (amc6821) add of_match table
dt-bindings: hwmon: lm75: use common hwmon schema
hwmon: (sis5595) drop unused DIV_TO_REG function
dt-bindings: hwmon: reference common hwmon schema
dt-bindings: hwmon: lltc,ltc4286: use common hwmon schema
dt-bindings: hwmon: adi,adm1275: use common hwmon schema
dt-bindings: hwmon: ti,ina2xx: use common hwmon schema
dt-bindings: hwmon: add common properties
hwmon: (pmbus/ir38064) Use PMBUS_REGULATOR_ONE to declare regulator
hwmon: (pmbus/lm25066) Use PMBUS_REGULATOR_ONE to declare regulator
hwmon: (pmbus/tda38640) Use PMBUS_REGULATOR_ONE to declare regulator
regulator: dt-bindings: promote infineon buck converters to their own binding
dt-bindings: hwmon/pmbus: ti,lm25066: document regulators
dt-bindings: hwmon: nuvoton,nct6775: Add compatible value for NCT6799
MAINTAINERS: Drop redundant hwmon entries
...

+7136 -335
+27
Documentation/ABI/testing/sysfs-class-hwmon
··· 149 149 150 150 RW 151 151 152 + What: /sys/class/hwmon/hwmonX/inY_fault 153 + Description: 154 + Reports a voltage hard failure (eg: shorted component) 155 + 156 + - 1: Failed 157 + - 0: Ok 158 + 159 + RO 160 + 152 161 What: /sys/class/hwmon/hwmonX/cpuY_vid 153 162 Description: 154 163 CPU core reference voltage. ··· 977 968 978 969 RW 979 970 971 + What: /sys/class/hwmon/hwmonX/humidityY_max_alarm 972 + Description: 973 + Maximum humidity detection 974 + 975 + - 0: OK 976 + - 1: Maximum humidity detected 977 + 978 + RO 979 + 980 980 What: /sys/class/hwmon/hwmonX/humidityY_max_hyst 981 981 Description: 982 982 Humidity hysteresis value for max limit. ··· 1004 986 Unit: milli-percent (per cent mille, pcm) 1005 987 1006 988 RW 989 + 990 + What: /sys/class/hwmon/hwmonX/humidityY_min_alarm 991 + Description: 992 + Minimum humidity detection 993 + 994 + - 0: OK 995 + - 1: Minimum humidity detected 996 + 997 + RO 1007 998 1008 999 What: /sys/class/hwmon/hwmonX/humidityY_min_hyst 1009 1000 Description:
+4 -1
Documentation/devicetree/bindings/hwmon/adi,adm1177.yaml
··· 46 46 - compatible 47 47 - reg 48 48 49 - additionalProperties: false 49 + allOf: 50 + - $ref: hwmon-common.yaml# 51 + 52 + unevaluatedProperties: false 50 53 51 54 examples: 52 55 - |
+2 -5
Documentation/devicetree/bindings/hwmon/adi,adm1275.yaml
··· 33 33 reg: 34 34 maxItems: 1 35 35 36 - shunt-resistor-micro-ohms: 37 - description: 38 - Shunt resistor value in micro-Ohm. 39 - 40 36 adi,volt-curr-sample-average: 41 37 description: | 42 38 Number of samples to be used to report voltage and current values. ··· 46 50 enum: [1, 2, 4, 8, 16, 32, 64, 128] 47 51 48 52 allOf: 53 + - $ref: hwmon-common.yaml# 49 54 - if: 50 55 properties: 51 56 compatible: ··· 104 107 - compatible 105 108 - reg 106 109 107 - additionalProperties: false 110 + unevaluatedProperties: false 108 111 109 112 examples: 110 113 - |
+4 -1
Documentation/devicetree/bindings/hwmon/adi,ltc2945.yaml
··· 31 31 - compatible 32 32 - reg 33 33 34 - additionalProperties: false 34 + allOf: 35 + - $ref: hwmon-common.yaml# 36 + 37 + unevaluatedProperties: false 35 38 36 39 examples: 37 40 - |
+159
Documentation/devicetree/bindings/hwmon/adi,ltc4282.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/hwmon/adi,ltc4282.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Analog Devices LTC4282 I2C High Current Hot Swap Controller over I2C 8 + 9 + maintainers: 10 + - Nuno Sa <nuno.sa@analog.com> 11 + 12 + description: | 13 + Analog Devices LTC4282 I2C High Current Hot Swap Controller over I2C. 14 + 15 + https://www.analog.com/media/en/technical-documentation/data-sheets/ltc4282.pdf 16 + 17 + properties: 18 + compatible: 19 + enum: 20 + - adi,ltc4282 21 + 22 + reg: 23 + maxItems: 1 24 + 25 + vdd-supply: true 26 + 27 + clocks: 28 + maxItems: 1 29 + 30 + '#clock-cells': 31 + const: 0 32 + 33 + adi,rsense-nano-ohms: 34 + description: Value of the sense resistor. 35 + 36 + adi,vin-mode-microvolt: 37 + description: 38 + Selects operating range for the Undervoltage, Overvoltage and Foldback 39 + pins. Also for the ADC. Should be set to the nominal input voltage. 40 + enum: [3300000, 5000000, 12000000, 24000000] 41 + default: 12000000 42 + 43 + adi,fet-bad-timeout-ms: 44 + description: 45 + From the moment a FET bad conditions is present, this property selects the 46 + wait time/timeout for a FET-bad fault to be signaled. Setting this to 0, 47 + disables FET bad faults to be reported. 48 + default: 255 49 + maximum: 255 50 + 51 + adi,overvoltage-dividers: 52 + description: | 53 + Select which dividers to use for VDD Overvoltage detection. Note that 54 + when the internal dividers are used the threshold is referenced to VDD. 55 + The percentages in the datasheet are misleading since the actual values 56 + to look for are in the "Absolute Maximum Ratings" table in the 57 + "Comparator Inputs" section. In there there's a line for each of the 5%, 58 + 10% and 15% settings with the actual min, typical and max tolerances. 59 + $ref: /schemas/types.yaml#/definitions/string 60 + enum: [external, vdd_5_percent, vdd_10_percent, vdd_15_percent] 61 + default: external 62 + 63 + adi,undervoltage-dividers: 64 + description: | 65 + Select which dividers to use for VDD Overvoltage detection. Note that 66 + when the internal dividers are used the threshold is referenced to VDD. 67 + The percentages in the datasheet are misleading since the actual values 68 + to look for are in the "Absolute Maximum Ratings" table in the 69 + "Comparator Inputs" section. In there there's a line for each of the 5%, 70 + 10% and 15% settings with the actual min, typical and max tolerances. 71 + $ref: /schemas/types.yaml#/definitions/string 72 + enum: [external, vdd_5_percent, vdd_10_percent, vdd_15_percent] 73 + default: external 74 + 75 + adi,current-limit-sense-microvolt: 76 + description: 77 + The current limit sense voltage of the chip is adjustable between 78 + 12.5mV and 34.4mV in 3.1mV steps. This effectively limits the current 79 + on the load. 80 + enum: [12500, 15625, 18750, 21875, 25000, 28125, 31250, 34375] 81 + default: 25000 82 + 83 + adi,overcurrent-retry: 84 + description: 85 + If set, enables the chip to auto-retry 256 timer cycles after an 86 + Overcurrent fault. 87 + type: boolean 88 + 89 + adi,overvoltage-retry-disable: 90 + description: 91 + If set, disables the chip to auto-retry 50ms after an Overvoltage fault. 92 + It's enabled by default. 93 + type: boolean 94 + 95 + adi,undervoltage-retry-disable: 96 + description: 97 + If set, disables the chip to auto-retry 50ms after an Undervoltage fault. 98 + It's enabled by default. 99 + type: boolean 100 + 101 + adi,fault-log-enable: 102 + description: 103 + If set, enables the FAULT_LOG and ADC_ALERT_LOG registers to be written 104 + to the EEPROM when a fault bit transitions high and hence, will be 105 + available after a power cycle (the chip loads the contents of 106 + the EE_FAULT_LOG register - the one in EEPROM - into FAULT_LOG at boot). 107 + type: boolean 108 + 109 + adi,gpio1-mode: 110 + description: Defines the function of the Pin. It can indicate that power is 111 + good (PULL the pin low when power is not good) or that power is bad (Go 112 + into high-z when power is not good). 113 + $ref: /schemas/types.yaml#/definitions/string 114 + enum: [power_bad, power_good] 115 + default: power_good 116 + 117 + adi,gpio2-mode: 118 + description: Defines the function of the Pin. It can be set as the input for 119 + the ADC or indicating that the MOSFET is in stress (dissipating power). 120 + $ref: /schemas/types.yaml#/definitions/string 121 + enum: [adc_input, stress_fet] 122 + default: adc_input 123 + 124 + adi,gpio3-monitor-enable: 125 + description: If set, gpio3 is set as input for the ADC instead of gpio2. 126 + type: boolean 127 + 128 + allOf: 129 + - if: 130 + required: 131 + - adi,gpio3-monitor-enable 132 + then: 133 + properties: 134 + adi,gpio2-mode: 135 + const: stress_fet 136 + 137 + required: 138 + - compatible 139 + - reg 140 + - adi,rsense-nano-ohms 141 + 142 + additionalProperties: false 143 + 144 + examples: 145 + - | 146 + i2c { 147 + #address-cells = <1>; 148 + #size-cells = <0>; 149 + 150 + hwmon@50 { 151 + compatible = "adi,ltc4282"; 152 + reg = <0x50>; 153 + adi,rsense-nano-ohms = <500>; 154 + 155 + adi,gpio1-mode = "power_good"; 156 + adi,gpio2-mode = "adc_input"; 157 + }; 158 + }; 159 + ...
+77
Documentation/devicetree/bindings/hwmon/amphenol,chipcap2.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/hwmon/amphenol,chipcap2.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: ChipCap 2 humidity and temperature iio sensor 8 + 9 + maintainers: 10 + - Javier Carrasco <javier.carrasco.cruz@gmail.com> 11 + 12 + description: | 13 + Relative humidity and temperature sensor on I2C bus. 14 + 15 + Datasheets: 16 + https://www.amphenol-sensors.com/en/telaire/humidity/527-humidity-sensors/3095-chipcap-2 17 + 18 + properties: 19 + compatible: 20 + oneOf: 21 + - const: amphenol,cc2d23 22 + - items: 23 + - enum: 24 + - amphenol,cc2d23s 25 + - amphenol,cc2d25 26 + - amphenol,cc2d25s 27 + - amphenol,cc2d33 28 + - amphenol,cc2d33s 29 + - amphenol,cc2d35 30 + - amphenol,cc2d35s 31 + - const: amphenol,cc2d23 32 + 33 + reg: 34 + maxItems: 1 35 + 36 + interrupts: 37 + items: 38 + - description: measurement ready indicator 39 + - description: low humidity alarm 40 + - description: high humidity alarm 41 + 42 + interrupt-names: 43 + items: 44 + - const: ready 45 + - const: low 46 + - const: high 47 + 48 + vdd-supply: 49 + description: 50 + Dedicated, controllable supply-regulator to reset the device and 51 + enter in command mode. 52 + 53 + required: 54 + - compatible 55 + - reg 56 + - vdd-supply 57 + 58 + additionalProperties: false 59 + 60 + examples: 61 + - | 62 + #include <dt-bindings/interrupt-controller/irq.h> 63 + i2c { 64 + #address-cells = <1>; 65 + #size-cells = <0>; 66 + 67 + humidity@28 { 68 + compatible = "amphenol,cc2d23s", "amphenol,cc2d23"; 69 + reg = <0x28>; 70 + interrupt-parent = <&gpio>; 71 + interrupts = <4 IRQ_TYPE_EDGE_RISING>, 72 + <5 IRQ_TYPE_EDGE_RISING>, 73 + <6 IRQ_TYPE_EDGE_RISING>; 74 + interrupt-names = "ready", "low", "high"; 75 + vdd-supply = <&reg_vdd>; 76 + }; 77 + };
+71
Documentation/devicetree/bindings/hwmon/aspeed,g6-pwm-tach.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + # Copyright (C) 2023 Aspeed, Inc. 3 + %YAML 1.2 4 + --- 5 + $id: http://devicetree.org/schemas/hwmon/aspeed,g6-pwm-tach.yaml# 6 + $schema: http://devicetree.org/meta-schemas/core.yaml# 7 + 8 + title: ASPEED G6 PWM and Fan Tach controller 9 + 10 + maintainers: 11 + - Billy Tsai <billy_tsai@aspeedtech.com> 12 + 13 + description: | 14 + The ASPEED PWM controller can support up to 16 PWM outputs. 15 + The ASPEED Fan Tacho controller can support up to 16 fan tach input. 16 + They are independent hardware blocks, which are different from the 17 + previous version of the ASPEED chip. 18 + 19 + properties: 20 + compatible: 21 + enum: 22 + - aspeed,ast2600-pwm-tach 23 + 24 + reg: 25 + maxItems: 1 26 + 27 + clocks: 28 + maxItems: 1 29 + 30 + resets: 31 + maxItems: 1 32 + 33 + "#pwm-cells": 34 + const: 3 35 + 36 + patternProperties: 37 + "^fan-[0-9]+$": 38 + $ref: fan-common.yaml# 39 + unevaluatedProperties: false 40 + required: 41 + - tach-ch 42 + 43 + required: 44 + - reg 45 + - clocks 46 + - resets 47 + - "#pwm-cells" 48 + - compatible 49 + 50 + additionalProperties: false 51 + 52 + examples: 53 + - | 54 + #include <dt-bindings/clock/aspeed-clock.h> 55 + pwm_tach: pwm-tach-controller@1e610000 { 56 + compatible = "aspeed,ast2600-pwm-tach"; 57 + reg = <0x1e610000 0x100>; 58 + clocks = <&syscon ASPEED_CLK_AHB>; 59 + resets = <&syscon ASPEED_RESET_PWM>; 60 + #pwm-cells = <3>; 61 + 62 + fan-0 { 63 + tach-ch = /bits/ 8 <0x0>; 64 + pwms = <&pwm_tach 0 40000 0>; 65 + }; 66 + 67 + fan-1 { 68 + tach-ch = /bits/ 8 <0x1 0x2>; 69 + pwms = <&pwm_tach 1 40000 0>; 70 + }; 71 + };
+79
Documentation/devicetree/bindings/hwmon/fan-common.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/hwmon/fan-common.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Common Fan Properties 8 + 9 + maintainers: 10 + - Naresh Solanki <naresh.solanki@9elements.com> 11 + - Billy Tsai <billy_tsai@aspeedtech.com> 12 + 13 + properties: 14 + max-rpm: 15 + description: 16 + Max RPM supported by fan. 17 + $ref: /schemas/types.yaml#/definitions/uint32 18 + maximum: 100000 19 + 20 + min-rpm: 21 + description: 22 + Min RPM supported by fan. 23 + $ref: /schemas/types.yaml#/definitions/uint32 24 + maximum: 1000 25 + 26 + pulses-per-revolution: 27 + description: 28 + The number of pulse from fan sensor per revolution. 29 + $ref: /schemas/types.yaml#/definitions/uint32 30 + maximum: 4 31 + 32 + tach-div: 33 + description: 34 + Divisor for the tach sampling clock, which determines the sensitivity of the tach pin. 35 + $ref: /schemas/types.yaml#/definitions/uint32 36 + 37 + target-rpm: 38 + description: 39 + The default desired fan speed in RPM. 40 + $ref: /schemas/types.yaml#/definitions/uint32 41 + 42 + fan-driving-mode: 43 + description: 44 + Select the driving mode of the fan.(DC, PWM and so on) 45 + $ref: /schemas/types.yaml#/definitions/string 46 + enum: [ dc, pwm ] 47 + 48 + pwms: 49 + description: 50 + PWM provider. 51 + maxItems: 1 52 + 53 + "#cooling-cells": 54 + const: 2 55 + 56 + cooling-levels: 57 + description: 58 + The control value which correspond to thermal cooling states. 59 + $ref: /schemas/types.yaml#/definitions/uint32-array 60 + 61 + tach-ch: 62 + description: 63 + The tach channel used for the fan. 64 + $ref: /schemas/types.yaml#/definitions/uint8-array 65 + 66 + label: 67 + description: 68 + Optional fan label 69 + 70 + fan-supply: 71 + description: 72 + Power supply for fan. 73 + 74 + reg: 75 + maxItems: 1 76 + 77 + additionalProperties: true 78 + 79 + ...
+19
Documentation/devicetree/bindings/hwmon/hwmon-common.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/hwmon/hwmon-common.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Hardware Monitoring Devices Common Properties 8 + 9 + maintainers: 10 + - Guenter Roeck <linux@roeck-us.net> 11 + 12 + properties: 13 + label: 14 + description: A descriptive name for this device. 15 + 16 + shunt-resistor-micro-ohms: 17 + description: The value of current sense resistor. 18 + 19 + additionalProperties: true
+4 -1
Documentation/devicetree/bindings/hwmon/lltc,ltc4151.yaml
··· 25 25 - compatible 26 26 - reg 27 27 28 - additionalProperties: false 28 + allOf: 29 + - $ref: hwmon-common.yaml# 30 + 31 + unevaluatedProperties: false 29 32 30 33 examples: 31 34 - |
+4 -5
Documentation/devicetree/bindings/hwmon/lltc,ltc4286.yaml
··· 25 25 The default is 102.4 volts. 26 26 type: boolean 27 27 28 - shunt-resistor-micro-ohms: 29 - description: 30 - Resistor value micro-ohms. 31 - 32 28 required: 33 29 - compatible 34 30 - reg 35 31 36 - additionalProperties: false 32 + allOf: 33 + - $ref: hwmon-common.yaml# 34 + 35 + unevaluatedProperties: false 37 36 38 37 examples: 39 38 - |
+2 -1
Documentation/devicetree/bindings/hwmon/lm75.yaml
··· 57 57 - reg 58 58 59 59 allOf: 60 + - $ref: hwmon-common.yaml# 60 61 - if: 61 62 not: 62 63 properties: ··· 72 71 properties: 73 72 interrupts: false 74 73 75 - additionalProperties: false 74 + unevaluatedProperties: false 76 75 77 76 examples: 78 77 - |
+1
Documentation/devicetree/bindings/hwmon/nuvoton,nct6775.yaml
··· 25 25 - nuvoton,nct6796 26 26 - nuvoton,nct6797 27 27 - nuvoton,nct6798 28 + - nuvoton,nct6799 28 29 29 30 reg: 30 31 maxItems: 1
+28
Documentation/devicetree/bindings/hwmon/pmbus/infineon,tda38640.yaml
··· 30 30 unconnected(has internal pull-down). 31 31 type: boolean 32 32 33 + interrupts: 34 + maxItems: 1 35 + 36 + regulators: 37 + type: object 38 + description: 39 + list of regulators provided by this controller. 40 + 41 + properties: 42 + vout: 43 + $ref: /schemas/regulator/regulator.yaml# 44 + type: object 45 + 46 + unevaluatedProperties: false 47 + 48 + additionalProperties: false 49 + 33 50 required: 34 51 - compatible 35 52 - reg ··· 55 38 56 39 examples: 57 40 - | 41 + #include <dt-bindings/interrupt-controller/irq.h> 58 42 i2c { 59 43 #address-cells = <1>; 60 44 #size-cells = <0>; ··· 63 45 tda38640@40 { 64 46 compatible = "infineon,tda38640"; 65 47 reg = <0x40>; 48 + 49 + interrupt-parent = <&smb_pex_cpu0_event>; 50 + interrupts = <10 IRQ_TYPE_LEVEL_LOW>; 51 + 52 + regulators { 53 + pvnn_main_cpu0: vout { 54 + regulator-name = "pvnn_main_cpu0"; 55 + regulator-enable-ramp-delay = <200>; 56 + }; 57 + }; 66 58 }; 67 59 };
+16 -1
Documentation/devicetree/bindings/hwmon/pmbus/ti,lm25066.yaml
··· 34 34 Shunt (sense) resistor value in micro-Ohms 35 35 default: 1000 36 36 37 + regulators: 38 + type: object 39 + 40 + properties: 41 + vout: 42 + $ref: /schemas/regulator/regulator.yaml# 43 + type: object 44 + 45 + unevaluatedProperties: false 46 + 47 + additionalProperties: false 48 + 37 49 required: 38 50 - compatible 39 51 - reg 40 52 41 - additionalProperties: false 53 + allOf: 54 + - $ref: /schemas/hwmon/hwmon-common.yaml# 55 + 56 + unevaluatedProperties: false 42 57 43 58 examples: 44 59 - |
+10 -1
Documentation/devicetree/bindings/hwmon/ti,ina2xx.yaml
··· 28 28 - ti,ina231 29 29 - ti,ina237 30 30 - ti,ina238 31 + - ti,ina260 31 32 32 33 reg: 33 34 maxItems: 1 35 + 36 + "#io-channel-cells": 37 + const: 1 34 38 35 39 shunt-resistor: 36 40 description: ··· 70 66 - compatible 71 67 - reg 72 68 73 - additionalProperties: false 69 + allOf: 70 + - $ref: hwmon-common.yaml# 71 + 72 + unevaluatedProperties: false 74 73 75 74 examples: 76 75 - | ··· 84 77 power-sensor@44 { 85 78 compatible = "ti,ina220"; 86 79 reg = <0x44>; 80 + #io-channel-cells = <1>; 81 + label = "vdd_3v0"; 87 82 shunt-resistor = <1000>; 88 83 vs-supply = <&vdd_3v0>; 89 84 };
+4 -1
Documentation/devicetree/bindings/hwmon/ti,tmp513.yaml
··· 72 72 - compatible 73 73 - reg 74 74 75 - additionalProperties: false 75 + allOf: 76 + - $ref: hwmon-common.yaml# 77 + 78 + unevaluatedProperties: false 76 79 77 80 examples: 78 81 - |
+4 -1
Documentation/devicetree/bindings/hwmon/ti,tps23861.yaml
··· 35 35 - compatible 36 36 - reg 37 37 38 - additionalProperties: false 38 + allOf: 39 + - $ref: hwmon-common.yaml# 40 + 41 + unevaluatedProperties: false 39 42 40 43 examples: 41 44 - |
+45
Documentation/devicetree/bindings/regulator/infineon,ir38060.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/infineon,ir38060.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Infineon Buck Regulators with PMBUS interfaces 8 + 9 + maintainers: 10 + - Not Me. 11 + 12 + allOf: 13 + - $ref: regulator.yaml# 14 + 15 + properties: 16 + compatible: 17 + enum: 18 + - infineon,ir38060 19 + - infineon,ir38064 20 + - infineon,ir38164 21 + - infineon,ir38263 22 + 23 + reg: 24 + maxItems: 1 25 + 26 + required: 27 + - compatible 28 + - reg 29 + 30 + unevaluatedProperties: false 31 + 32 + examples: 33 + - | 34 + i2c { 35 + #address-cells = <1>; 36 + #size-cells = <0>; 37 + 38 + regulator@34 { 39 + compatible = "infineon,ir38060"; 40 + reg = <0x34>; 41 + 42 + regulator-min-microvolt = <437500>; 43 + regulator-max-microvolt = <1387500>; 44 + }; 45 + };
+4 -8
Documentation/devicetree/bindings/trivial-devices.yaml
··· 47 47 - adi,lt7182s 48 48 # AMS iAQ-Core VOC Sensor 49 49 - ams,iaq-core 50 + # Temperature monitoring of Astera Labs PT5161L PCIe retimer 51 + - asteralabs,pt5161l 50 52 # i2c serial eeprom (24cxx) 51 53 - at,24c08 52 54 # ATSHA204 - i2c h/w symmetric crypto module ··· 131 129 - mps,mp2975 132 130 # Monolithic Power Systems Inc. multi-phase hot-swap controller mp5990 133 131 - mps,mp5990 132 + # Monolithic Power Systems Inc. synchronous step-down converter mpq8785 133 + - mps,mpq8785 134 134 # Honeywell Humidicon HIH-6130 humidity/temperature sensor 135 135 - honeywell,hi6130 136 136 # IBM Common Form Factor Power Supply Versions (all versions) ··· 143 139 - ibm,cffps2 144 140 # Infineon IR36021 digital POL buck controller 145 141 - infineon,ir36021 146 - # Infineon IR38060 Voltage Regulator 147 - - infineon,ir38060 148 - # Infineon IR38064 Voltage Regulator 149 - - infineon,ir38064 150 - # Infineon IR38164 Voltage Regulator 151 - - infineon,ir38164 152 - # Infineon IR38263 Voltage Regulator 153 - - infineon,ir38263 154 142 # Infineon IRPS5401 Voltage Regulator (PMIC) 155 143 - infineon,irps5401 156 144 # Infineon TLV493D-A1B6 I2C 3D Magnetic Sensor
+4
Documentation/devicetree/bindings/vendor-prefixes.yaml
··· 109 109 description: Amlogic, Inc. 110 110 "^ampere,.*": 111 111 description: Ampere Computing LLC 112 + "^amphenol,.*": 113 + description: Amphenol Advanced Sensors 112 114 "^ampire,.*": 113 115 description: Ampire Co., Ltd. 114 116 "^ams,.*": ··· 163 161 description: ASPEED Technology Inc. 164 162 "^asrock,.*": 165 163 description: ASRock Inc. 164 + "^asteralabs,.*": 165 + description: Astera Labs, Inc. 166 166 "^asus,.*": 167 167 description: AsusTek Computer Inc. 168 168 "^atheros,.*":
+26
Documentation/hwmon/aspeed-g6-pwm-tach.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + Kernel driver aspeed-g6-pwm-tach 4 + ================================= 5 + 6 + Supported chips: 7 + ASPEED AST2600 8 + 9 + Authors: 10 + <billy_tsai@aspeedtech.com> 11 + 12 + Description: 13 + ------------ 14 + This driver implements support for ASPEED AST2600 Fan Tacho controller. 15 + The controller supports up to 16 tachometer inputs. 16 + 17 + The driver provides the following sensor accesses in sysfs: 18 + 19 + =============== ======= ====================================================== 20 + fanX_input ro provide current fan rotation value in RPM as reported 21 + by the fan to the device. 22 + fanX_div rw Fan divisor: Supported value are power of 4 (1, 4, 16 23 + 64, ... 4194304) 24 + The larger divisor, the less rpm accuracy and the less 25 + affected by fan signal glitch. 26 + =============== ======= ======================================================
+47
Documentation/hwmon/asus_rog_ryujin.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + Kernel driver asus_rog_ryujin 4 + ============================= 5 + 6 + Supported devices: 7 + 8 + * ASUS ROG RYUJIN II 360 9 + 10 + Author: Aleksa Savic 11 + 12 + Description 13 + ----------- 14 + 15 + This driver enables hardware monitoring support for the listed ASUS ROG RYUJIN 16 + all-in-one CPU liquid coolers. Available sensors are pump, internal and external 17 + (controller) fan speed in RPM, their duties in PWM, as well as coolant temperature. 18 + 19 + Attaching external fans to the controller is optional and allows them to be 20 + controlled from the device. If not connected, the fan-related sensors will 21 + report zeroes. The controller is a separate hardware unit that comes bundled 22 + with the AIO and connects to it to allow fan control. 23 + 24 + The addressable LCD screen is not supported in this driver and should 25 + be controlled through userspace tools. 26 + 27 + Usage notes 28 + ----------- 29 + 30 + As these are USB HIDs, the driver can be loaded automatically by the kernel and 31 + supports hot swapping. 32 + 33 + Sysfs entries 34 + ------------- 35 + 36 + =========== ============================================= 37 + fan1_input Pump speed (in rpm) 38 + fan2_input Internal fan speed (in rpm) 39 + fan3_input External (controller) fan 1 speed (in rpm) 40 + fan4_input External (controller) fan 2 speed (in rpm) 41 + fan5_input External (controller) fan 3 speed (in rpm) 42 + fan6_input External (controller) fan 4 speed (in rpm) 43 + temp1_input Coolant temperature (in millidegrees Celsius) 44 + pwm1 Pump duty 45 + pwm2 Internal fan duty 46 + pwm3 External (controller) fan duty 47 + =========== =============================================
+73
Documentation/hwmon/chipcap2.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + Kernel driver ChipCap2 4 + ====================== 5 + 6 + Supported chips: 7 + 8 + * Amphenol CC2D23, CC2D23S, CC2D25, CC2D25S, CC2D33, CC2D33S, CC2D35, CC2D35S 9 + 10 + Prefix: 'chipcap2' 11 + 12 + Addresses scanned: - 13 + 14 + Datasheet: https://www.amphenol-sensors.com/en/telaire/humidity/527-humidity-sensors/3095-chipcap-2 15 + 16 + Author: 17 + 18 + - Javier Carrasco <javier.carrasco.cruz@gmail.com> 19 + 20 + Description 21 + ----------- 22 + 23 + This driver implements support for the Amphenol ChipCap 2, a humidity and 24 + temperature chip family. Temperature is measured in milli degrees celsius, 25 + relative humidity is expressed as a per cent mille. The measurement ranges 26 + are the following: 27 + 28 + - Relative humidity: 0 to 100000 pcm (14-bit resolution) 29 + - Temperature: -40000 to +125000 m°C (14-bit resolution) 30 + 31 + The device communicates with the I2C protocol and uses the I2C address 0x28 32 + by default. 33 + 34 + Depending on the hardware configuration, up to two humidity alarms to control 35 + minimum and maximum values are provided. Their thresholds and hystersis can be 36 + configured via sysfs. 37 + 38 + Thresholds and hysteris must be provided as a per cent mille. These values 39 + might be truncated to match the 14-bit device resolution (6.1 pcm/LSB) 40 + 41 + Known Issues 42 + ------------ 43 + 44 + The driver does not support I2C address and command window length modification. 45 + 46 + sysfs-Interface 47 + --------------- 48 + 49 + The following list includes the sysfs attributes that the driver always provides, 50 + their permissions and a short description: 51 + 52 + =============================== ======= ======================================== 53 + Name Perm Description 54 + =============================== ======= ======================================== 55 + temp1_input: RO temperature input 56 + humidity1_input: RO humidity input 57 + =============================== ======= ======================================== 58 + 59 + The following list includes the sysfs attributes that the driver may provide 60 + depending on the hardware configuration: 61 + 62 + =============================== ======= ======================================== 63 + Name Perm Description 64 + =============================== ======= ======================================== 65 + humidity1_min: RW humidity low limit. Measurements under 66 + this limit trigger a humidity low alarm 67 + humidity1_max: RW humidity high limit. Measurements above 68 + this limit trigger a humidity high alarm 69 + humidity1_min_hyst: RW humidity low hystersis 70 + humidity1_max_hyst: RW humidity high hystersis 71 + humidity1_min_alarm: RO humidity low alarm indicator 72 + humidity1_max_alarm: RO humidity high alarm indicator 73 + =============================== ======= ========================================
-1
Documentation/hwmon/emc2305.rst
··· 6 6 Supported chips: 7 7 Microchip EMC2305, EMC2303, EMC2302, EMC2301 8 8 9 - Addresses scanned: I2C 0x27, 0x2c, 0x2d, 0x2e, 0x2f, 0x4c, 0x4d 10 9 Prefixes: 'emc2305' 11 10 12 11 Datasheet: Publicly available at the Microchip website :
+8
Documentation/hwmon/index.rst
··· 44 44 aquacomputer_d5next 45 45 asb100 46 46 asc7621 47 + aspeed-g6-pwm-tach 47 48 aspeed-pwm-tacho 48 49 asus_ec_sensors 50 + asus_rog_ryujin 49 51 asus_wmi_sensors 50 52 bcm54140 51 53 bel-pfe 52 54 bpa-rs600 53 55 bt1-pvt 56 + chipcap2 54 57 coretemp 55 58 corsair-cpro 56 59 corsair-psu ··· 132 129 ltc4245 133 130 ltc4260 134 131 ltc4261 132 + ltc4282 135 133 ltc4286 136 134 max127 137 135 max15301 ··· 167 163 mp2975 168 164 mp5023 169 165 mp5990 166 + mpq8785 170 167 nct6683 171 168 nct6775 172 169 nct7802 ··· 176 171 nsa320 177 172 ntc_thermistor 178 173 nzxt-kraken2 174 + nzxt-kraken3 179 175 nzxt-smart2 180 176 occ 181 177 oxp-sensors ··· 191 185 pmbus 192 186 powerz 193 187 powr1220 188 + pt5161l 194 189 pxe1610 195 190 pwm-fan 196 191 q54sj108a2 ··· 215 208 smsc47m1 216 209 sparx5-temp 217 210 stpddc60 211 + surface_fan 218 212 sy7636a-hwmon 219 213 tc654 220 214 tc74
+133
Documentation/hwmon/ltc4282.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0-only 2 + 3 + Kernel drivers ltc4282 4 + ========================================== 5 + 6 + Supported chips: 7 + 8 + * Analog Devices LTC4282 9 + 10 + Prefix: 'ltc4282' 11 + 12 + Addresses scanned: - I2C 0x40 - 0x5A (7-bit) 13 + Addresses scanned: - I2C 0x80 - 0xB4 with a step of 2 (8-bit) 14 + 15 + Datasheet: 16 + 17 + https://www.analog.com/media/en/technical-documentation/data-sheets/ltc4282.pdf 18 + 19 + Author: Nuno Sá <nuno.sa@analog.com> 20 + 21 + Description 22 + ___________ 23 + 24 + The LTC4282 hot swap controller allows a board to be safely inserted and removed 25 + from a live backplane. Using one or more external N-channel pass transistors, 26 + board supply voltage and inrush current are ramped up at an adjustable rate. An 27 + I2C interface and onboard ADC allows for monitoring of board current, voltage, 28 + power, energy and fault status. The device features analog foldback current 29 + limiting and supply monitoring for applications from 2.9V to 33V. Dual 12V gate 30 + drive allows high power applications to either share safe operating area across 31 + parallel MOSFETs or support a 2-stage start-up that first charges the load 32 + capacitance followed by enabling a low on-resistance path to the load. The 33 + LTC4282 is well suited to high power applications because the precise monitoring 34 + capability and accurate current limiting reduce the extremes in which both loads 35 + and power supplies must safely operate. Non-volatile configuration allows for 36 + flexibility in the autonomous generation of alerts and response to faults. 37 + 38 + Sysfs entries 39 + _____________ 40 + 41 + The following attributes are supported. Limits are read-write and all the other 42 + attributes are read-only. Note that in0 and in1 are mutually exclusive. Enabling 43 + one disables the other and disabling one enables the other. 44 + 45 + ======================= ========================================== 46 + in0_input Output voltage (mV). 47 + in0_min Undervoltage threshold 48 + in0_max Overvoltage threshold 49 + in0_lowest Lowest measured voltage 50 + in0_highest Highest measured voltage 51 + in0_reset_history Write 1 to reset in0 history. 52 + Also clears fet bad and short fault logs. 53 + in0_min_alarm Undervoltage alarm 54 + in0_max_alarm Overvoltage alarm 55 + in0_enable Enable/Disable VSOURCE monitoring 56 + in0_fault Failure in the MOSFETs. Either bad or shorted FET. 57 + in0_label Channel label (VSOURCE) 58 + 59 + in1_input Input voltage (mV). 60 + in1_min Undervoltage threshold 61 + in1_max Overvoltage threshold 62 + in1_lowest Lowest measured voltage 63 + in1_highest Highest measured voltage 64 + in1_reset_history Write 1 to reset in1 history. 65 + Also clears over/undervoltage fault logs. 66 + in1_min_alarm Undervoltage alarm 67 + in1_max_alarm Overvoltage alarm 68 + in1_lcrit_alarm Critical Undervoltage alarm 69 + in1_crit_alarm Critical Overvoltage alarm 70 + in1_enable Enable/Disable VDD monitoring 71 + in1_label Channel label (VDD) 72 + 73 + in2_input GPIO voltage (mV) 74 + in2_min Undervoltage threshold 75 + in2_max Overvoltage threshold 76 + in2_lowest Lowest measured voltage 77 + in2_highest Highest measured voltage 78 + in2_reset_history Write 1 to reset in2 history 79 + in2_min_alarm Undervoltage alarm 80 + in2_max_alarm Overvoltage alarm 81 + in2_label Channel label (VGPIO) 82 + 83 + curr1_input Sense current (mA) 84 + curr1_min Undercurrent threshold 85 + curr1_max Overcurrent threshold 86 + curr1_lowest Lowest measured current 87 + curr1_highest Highest measured current 88 + curr1_reset_history Write 1 to reset curr1 history. 89 + Also clears overcurrent fault logs. 90 + curr1_min_alarm Undercurrent alarm 91 + curr1_max_alarm Overcurrent alarm 92 + curr1_crit_alarm Critical Overcurrent alarm 93 + curr1_label Channel label (ISENSE) 94 + 95 + power1_input Power (in uW) 96 + power1_min Low power threshold 97 + power1_max High power threshold 98 + power1_input_lowest Historical minimum power use 99 + power1_input_highest Historical maximum power use 100 + power1_reset_history Write 1 to reset power1 history. 101 + Also clears power bad fault logs. 102 + power1_min_alarm Low power alarm 103 + power1_max_alarm High power alarm 104 + power1_label Channel label (Power) 105 + 106 + energy1_input Measured energy over time (in microJoule) 107 + energy1_enable Enable/Disable Energy accumulation 108 + ======================= ========================================== 109 + 110 + DebugFs entries 111 + _______________ 112 + 113 + The chip also has a fault log register where failures can be logged. Hence, 114 + as these are logging events, we give access to them in debugfs. Note that 115 + even if some failure is detected in these logs, it does necessarily mean 116 + that the failure is still present. As mentioned in the proper Sysfs entries, 117 + these logs can be cleared by writing in the proper reset_history attribute. 118 + 119 + .. warning:: The debugfs interface is subject to change without notice 120 + and is only available when the kernel is compiled with 121 + ``CONFIG_DEBUG_FS`` defined. 122 + 123 + ``/sys/kernel/debug/ltc4282-hwmon[X]/`` 124 + contains the following attributes: 125 + 126 + ======================= ========================================== 127 + power1_bad_fault_log Set to 1 by a power1 bad fault occurring. 128 + in0_fet_short_fault_log Set to 1 when the ADC detects a FET-short fault. 129 + in0_fet_bad_fault_log Set to 1 when a FET-BAD fault occurs. 130 + in1_crit_fault_log Set to 1 by a VDD overvoltage fault occurring. 131 + in1_lcrit_fault_log Set to 1 by a VDD undervoltage fault occurring. 132 + curr1_crit_fault_log Set to 1 by an overcurrent fault occurring. 133 + ======================= ==========================================
+1 -1
Documentation/hwmon/max6620.rst
··· 11 11 12 12 Addresses scanned: none 13 13 14 - Datasheet: http://pdfserv.maxim-ic.com/en/ds/MAX6620.pdf 14 + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max6620.pdf 15 15 16 16 Authors: 17 17 - L\. Grunenberg <contact@lgrunenberg.de>
+94
Documentation/hwmon/mpq8785.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0-only 2 + 3 + Kernel driver mpq8785 4 + ======================= 5 + 6 + Supported chips: 7 + 8 + * MPS MPQ8785 9 + 10 + Prefix: 'mpq8785' 11 + 12 + Author: Charles Hsu <ythsu0511@gmail.com> 13 + 14 + Description 15 + ----------- 16 + 17 + The MPQ8785 is a fully integrated, PMBus-compatible, high-frequency, synchronous 18 + buck converter. The MPQ8785 offers a very compact solution that achieves up to 19 + 40A output current per phase, with excellent load and line regulation over a 20 + wide input supply range. The MPQ8785 operates at high efficiency over a wide 21 + output current load range. 22 + 23 + The PMBus interface provides converter configurations and key parameters 24 + monitoring. 25 + 26 + The MPQ8785 adopts MPS's proprietary multi-phase digital constant-on-time (MCOT) 27 + control, which provides fast transient response and eases loop stabilization. 28 + The MCOT scheme also allows multiple MPQ8785 devices to be connected in parallel 29 + with excellent current sharing and phase interleaving for high-current 30 + applications. 31 + 32 + Fully integrated protection features include over-current protection (OCP), 33 + over-voltage protection (OVP), under-voltage protection (UVP), and 34 + over-temperature protection (OTP). 35 + 36 + The MPQ8785 requires a minimal number of readily available, standard external 37 + components, and is available in a TLGA (5mmx6mm) package. 38 + 39 + Device compliant with: 40 + 41 + - PMBus rev 1.3 interface. 42 + 43 + The driver exports the following attributes via the 'sysfs' files 44 + for input voltage: 45 + 46 + **in1_input** 47 + 48 + **in1_label** 49 + 50 + **in1_max** 51 + 52 + **in1_max_alarm** 53 + 54 + **in1_min** 55 + 56 + **in1_min_alarm** 57 + 58 + **in1_crit** 59 + 60 + **in1_crit_alarm** 61 + 62 + The driver provides the following attributes for output voltage: 63 + 64 + **in2_input** 65 + 66 + **in2_label** 67 + 68 + **in2_alarm** 69 + 70 + The driver provides the following attributes for output current: 71 + 72 + **curr1_input** 73 + 74 + **curr1_label** 75 + 76 + **curr1_max** 77 + 78 + **curr1_max_alarm** 79 + 80 + **curr1_crit** 81 + 82 + **curr1_crit_alarm** 83 + 84 + The driver provides the following attributes for temperature: 85 + 86 + **temp1_input** 87 + 88 + **temp1_max** 89 + 90 + **temp1_max_alarm** 91 + 92 + **temp1_crit** 93 + 94 + **temp1_crit_alarm**
+1
Documentation/hwmon/nct6683.rst
··· 64 64 ASRock X570 NCT6683D EC firmware version 1.0 build 06/28/19 65 65 ASRock X670E NCT6686D EC firmware version 1.0 build 05/19/22 66 66 MSI B550 NCT6687D EC firmware version 1.0 build 05/07/20 67 + MSI X670-P NCT6687D EC firmware version 0.0 build 09/27/22 67 68 =============== ===============================================
+74
Documentation/hwmon/nzxt-kraken3.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + Kernel driver nzxt-kraken3 4 + ========================== 5 + 6 + Supported devices: 7 + 8 + * NZXT Kraken X53 9 + * NZXT Kraken X63 10 + * NZXT Kraken X73 11 + * NZXT Kraken Z53 12 + * NZXT Kraken Z63 13 + * NZXT Kraken Z73 14 + 15 + Author: Jonas Malaco, Aleksa Savic 16 + 17 + Description 18 + ----------- 19 + 20 + This driver enables hardware monitoring support for NZXT Kraken X53/X63/X73 and 21 + Z53/Z63/Z73 all-in-one CPU liquid coolers. All models expose liquid temperature 22 + and pump speed (in RPM), as well as PWM control (either as a fixed value 23 + or through a temp-PWM curve). The Z-series models additionally expose the speed 24 + and duty of an optionally connected fan, with the same PWM control capabilities. 25 + 26 + Pump and fan duty control mode can be set through pwm[1-2]_enable, where 1 is 27 + for the manual control mode and 2 is for the liquid temp to PWM curve mode. 28 + Writing a 0 disables control of the channel through the driver after setting its 29 + duty to 100%. 30 + 31 + The temperature of the curves relates to the fixed [20-59] range, correlating to 32 + the detected liquid temperature. Only PWM values (ranging from 0-255) can be set. 33 + If in curve mode, setting point values should be done in moderation - the devices 34 + require complete curves to be sent for each change; they can lock up or discard 35 + the changes if they are too numerous at once. Suggestion is to set them while 36 + in an another mode, and then apply them by switching to curve. 37 + 38 + The devices can report if they are faulty. The driver supports that situation 39 + and will issue a warning. This can also happen when the USB cable is connected, 40 + but SATA power is not. 41 + 42 + The addressable RGB LEDs and LCD screen (only on Z-series models) are not 43 + supported in this driver, but can be controlled through existing userspace tools, 44 + such as `liquidctl`_. 45 + 46 + .. _liquidctl: https://github.com/liquidctl/liquidctl 47 + 48 + Usage Notes 49 + ----------- 50 + 51 + As these are USB HIDs, the driver can be loaded automatically by the kernel and 52 + supports hot swapping. 53 + 54 + Possible pwm_enable values are: 55 + 56 + ====== ========================================================================== 57 + 0 Set fan to 100% 58 + 1 Direct PWM mode (applies value in corresponding PWM entry) 59 + 2 Curve control mode (applies the temp-PWM duty curve based on coolant temp) 60 + ====== ========================================================================== 61 + 62 + Sysfs entries 63 + ------------- 64 + 65 + ============================== ================================================================ 66 + fan1_input Pump speed (in rpm) 67 + fan2_input Fan speed (in rpm) 68 + temp1_input Coolant temperature (in millidegrees Celsius) 69 + pwm1 Pump duty (value between 0-255) 70 + pwm1_enable Pump duty control mode (0: disabled, 1: manual, 2: curve) 71 + pwm2 Fan duty (value between 0-255) 72 + pwm2_enable Fan duty control mode (0: disabled, 1: manual, 2: curve) 73 + temp[1-2]_auto_point[1-40]_pwm Temp-PWM duty curves (for pump and fan), related to coolant temp 74 + ============================== ================================================================
+1
Documentation/hwmon/oxp-sensors.rst
··· 33 33 - AOK ZOE A1 PRO 34 34 - Aya Neo 2 35 35 - Aya Neo AIR 36 + - Aya Neo AIR Plus (Mendocino) 36 37 - Aya Neo AIR Pro 37 38 - Aya Neo Geek 38 39 - OneXPlayer AMD
+42
Documentation/hwmon/pt5161l.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + Kernel driver pt5161l 4 + ===================== 5 + 6 + Supported chips: 7 + 8 + * Astera Labs PT5161L 9 + 10 + Prefix: 'pt5161l' 11 + 12 + Addresses scanned: I2C 0x20 - 0x27 13 + 14 + Datasheet: Not publicly available. 15 + 16 + Authors: Cosmo Chou <cosmo.chou@quantatw.com> 17 + 18 + Description 19 + ----------- 20 + 21 + This driver implements support for temperature monitoring of Astera Labs 22 + PT5161L series PCIe retimer chips. 23 + 24 + This driver implementation originates from the CSDK available at 25 + https://github.com/facebook/openbmc/tree/helium/common/recipes-lib/retimer-v2.14 26 + The communication protocol utilized is based on the I2C/SMBus standard. 27 + 28 + Sysfs entries 29 + ---------------- 30 + 31 + ================ ============================================== 32 + temp1_input Measured temperature (in millidegrees Celsius) 33 + ================ ============================================== 34 + 35 + Debugfs entries 36 + ---------------- 37 + 38 + ================ =============================== 39 + fw_load_status Firmware load status 40 + fw_ver Firmware version of the retimer 41 + heartbeat_status Heartbeat status 42 + ================ ===============================
+11
Documentation/hwmon/sht3x.rst
··· 65 65 values, the alert bit is set to 0 and the alert pin on the sensor is set to 66 66 low. 67 67 68 + The serial number exposed to debugfs allows for unique identification of the 69 + sensors. For sts32, sts33 and sht33, the manufacturer provides calibration 70 + certificates through an API. 71 + 68 72 sysfs-Interface 69 73 --------------- 70 74 ··· 102 98 - 0: low repeatability 103 99 - 1: medium repeatability 104 100 - 2: high repeatability 101 + =================== ============================================================ 102 + 103 + debugfs-Interface 104 + ----------------- 105 + 106 + =================== ============================================================ 107 + serial_number: unique serial number of the sensor in decimal 105 108 =================== ============================================================
+25
Documentation/hwmon/surface_fan.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + Kernel driver surface_fan 4 + ========================= 5 + 6 + Supported Devices: 7 + 8 + * Microsoft Surface Pro 9 9 + 10 + Author: Ivor Wanders <ivor@iwanders.net> 11 + 12 + Description 13 + ----------- 14 + 15 + This provides monitoring of the fan found in some Microsoft Surface Pro devices, 16 + like the Surface Pro 9. The fan is always controlled by the onboard controller. 17 + 18 + Sysfs interface 19 + --------------- 20 + 21 + ======================= ======= ========================================= 22 + Name Perm Description 23 + ======================= ======= ========================================= 24 + ``fan1_input`` RO Current fan speed in RPM. 25 + ======================= ======= =========================================
+43 -124
MAINTAINERS
··· 1104 1104 F: drivers/perf/amlogic/ 1105 1105 F: include/soc/amlogic/ 1106 1106 1107 + AMPHENOL CHIPCAP 2 HUMIDITY-TEMPERATURE IIO DRIVER 1108 + M: Javier Carrasco <javier.carrasco.cruz@gmail.com> 1109 + L: linux-hwmon@vger.kernel.org 1110 + S: Maintained 1111 + F: Documentation/devicetree/bindings/hwmon/amphenol,chipcap2.yaml 1112 + F: Documentation/hwmon/chipcap2.rst 1113 + F: drivers/hwmon/chipcap2.c 1114 + 1107 1115 AMPHION VPU CODEC V4L2 DRIVER 1108 1116 M: Ming Qian <ming.qian@nxp.com> 1109 1117 M: Zhou Peng <eagle.zhou@nxp.com> ··· 1397 1389 F: drivers/iio/amplifiers/hmc425a.c 1398 1390 F: drivers/staging/iio/*/ad* 1399 1391 X: drivers/iio/*/adjd* 1400 - 1401 - ANALOG DEVICES INC MAX31760 DRIVER 1402 - M: Ibrahim Tilki <Ibrahim.Tilki@analog.com> 1403 - S: Maintained 1404 - W: http://wiki.analog.com/ 1405 - W: https://ez.analog.com/linux-software-drivers 1406 - F: Documentation/devicetree/bindings/hwmon/adi,max31760.yaml 1407 - F: Documentation/hwmon/max31760.rst 1408 - F: drivers/hwmon/max31760.c 1409 1392 1410 1393 ANALOGBITS PLL LIBRARIES 1411 1394 M: Paul Walmsley <paul.walmsley@sifive.com> ··· 3188 3189 S: Maintained 3189 3190 T: git git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git 3190 3191 F: drivers/platform/x86/asus-tf103c-dock.c 3192 + 3193 + ASUS ROG RYUJIN AIO HARDWARE MONITOR DRIVER 3194 + M: Aleksa Savic <savicaleksa83@gmail.com> 3195 + L: linux-hwmon@vger.kernel.org 3196 + S: Maintained 3197 + F: drivers/hwmon/asus_rog_ryujin.c 3191 3198 3192 3199 ASUS WIRELESS RADIO CONTROL DRIVER 3193 3200 M: João Paulo Rechi Vita <jprvita@gmail.com> ··· 10536 10531 S: Orphan 10537 10532 F: drivers/video/fbdev/imsttfb.c 10538 10533 10539 - INA209 HARDWARE MONITOR DRIVER 10540 - M: Guenter Roeck <linux@roeck-us.net> 10541 - L: linux-hwmon@vger.kernel.org 10542 - S: Maintained 10543 - F: Documentation/devicetree/bindings/hwmon/ti,ina2xx.yaml 10544 - F: Documentation/hwmon/ina209.rst 10545 - F: drivers/hwmon/ina209.c 10546 - 10547 - INA2XX HARDWARE MONITOR DRIVER 10548 - M: Guenter Roeck <linux@roeck-us.net> 10549 - L: linux-hwmon@vger.kernel.org 10550 - S: Maintained 10551 - F: Documentation/hwmon/ina2xx.rst 10552 - F: drivers/hwmon/ina2xx.c 10553 - F: include/linux/platform_data/ina2xx.h 10554 - 10555 10534 INDEX OF FURTHER KERNEL DOCUMENTATION 10556 10535 M: Carlos Bilbao <carlos.bilbao@amd.com> 10557 10536 S: Maintained ··· 11519 11530 S: Maintained 11520 11531 F: arch/x86/include/asm/jailhouse_para.h 11521 11532 F: arch/x86/kernel/jailhouse.c 11522 - 11523 - JC42.4 TEMPERATURE SENSOR DRIVER 11524 - M: Guenter Roeck <linux@roeck-us.net> 11525 - L: linux-hwmon@vger.kernel.org 11526 - S: Maintained 11527 - F: Documentation/devicetree/bindings/hwmon/jedec,jc42.yaml 11528 - F: Documentation/hwmon/jc42.rst 11529 - F: drivers/hwmon/jc42.c 11530 11533 11531 11534 JFS FILESYSTEM 11532 11535 M: Dave Kleikamp <shaggy@kernel.org> ··· 12584 12603 F: drivers/hwmon/lm90.c 12585 12604 F: include/dt-bindings/thermal/lm90.h 12586 12605 12587 - LM95234 HARDWARE MONITOR DRIVER 12588 - M: Guenter Roeck <linux@roeck-us.net> 12589 - L: linux-hwmon@vger.kernel.org 12590 - S: Maintained 12591 - F: Documentation/hwmon/lm95234.rst 12592 - F: drivers/hwmon/lm95234.c 12593 - 12594 12606 LME2510 MEDIA DRIVER 12595 12607 M: Malcolm Priestley <tvboxspy@gmail.com> 12596 12608 L: linux-media@vger.kernel.org ··· 12787 12813 F: Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml 12788 12814 F: drivers/iio/temperature/ltc2983.c 12789 12815 12790 - LTC4261 HARDWARE MONITOR DRIVER 12791 - M: Guenter Roeck <linux@roeck-us.net> 12816 + LTC4282 HARDWARE MONITOR DRIVER 12817 + M: Nuno Sa <nuno.sa@analog.com> 12792 12818 L: linux-hwmon@vger.kernel.org 12793 - S: Maintained 12794 - F: Documentation/hwmon/ltc4261.rst 12795 - F: drivers/hwmon/ltc4261.c 12819 + S: Supported 12820 + F: Documentation/devicetree/bindings/hwmon/adi,ltc4282.yaml 12821 + F: Documentation/hwmon/ltc4282.rst 12822 + F: drivers/hwmon/ltc4282.c 12796 12823 12797 12824 LTC4286 HARDWARE MONITOR DRIVER 12798 12825 M: Delphine CC Chiu <Delphine_CC_Chiu@Wiwynn.com> ··· 13151 13176 F: Documentation/hwmon/max15301.rst 13152 13177 F: drivers/hwmon/pmbus/max15301.c 13153 13178 13154 - MAX16065 HARDWARE MONITOR DRIVER 13155 - M: Guenter Roeck <linux@roeck-us.net> 13156 - L: linux-hwmon@vger.kernel.org 13157 - S: Maintained 13158 - F: Documentation/hwmon/max16065.rst 13159 - F: drivers/hwmon/max16065.c 13160 - 13161 13179 MAX2175 SDR TUNER DRIVER 13162 13180 M: Ramesh Shanmugasundaram <rashanmu@gmail.com> 13163 13181 L: linux-media@vger.kernel.org ··· 13160 13192 F: Documentation/userspace-api/media/drivers/max2175.rst 13161 13193 F: drivers/media/i2c/max2175* 13162 13194 F: include/uapi/linux/max2175.h 13163 - 13164 - MAX31827 TEMPERATURE SWITCH DRIVER 13165 - M: Daniel Matyas <daniel.matyas@analog.com> 13166 - L: linux-hwmon@vger.kernel.org 13167 - S: Supported 13168 - W: https://ez.analog.com/linux-software-drivers 13169 - F: Documentation/devicetree/bindings/hwmon/adi,max31827.yaml 13170 - F: Documentation/hwmon/max31827.rst 13171 - F: drivers/hwmon/max31827.c 13172 13195 13173 13196 MAX31335 RTC DRIVER 13174 13197 M: Antoniu Miclaus <antoniu.miclaus@analog.com> ··· 13174 13215 S: Orphan 13175 13216 F: Documentation/hwmon/max6650.rst 13176 13217 F: drivers/hwmon/max6650.c 13177 - 13178 - MAX6697 HARDWARE MONITOR DRIVER 13179 - M: Guenter Roeck <linux@roeck-us.net> 13180 - L: linux-hwmon@vger.kernel.org 13181 - S: Maintained 13182 - F: Documentation/devicetree/bindings/hwmon/max6697.txt 13183 - F: Documentation/hwmon/max6697.rst 13184 - F: drivers/hwmon/max6697.c 13185 - F: include/linux/platform_data/max6697.h 13186 13218 13187 13219 MAX9286 QUAD GMSL DESERIALIZER DRIVER 13188 13220 M: Jacopo Mondi <jacopo+renesas@jmondi.org> ··· 14580 14630 F: drivers/platform/surface/surface_dtx.c 14581 14631 F: include/uapi/linux/surface_aggregator/dtx.h 14582 14632 14633 + MICROSOFT SURFACE SENSOR FAN DRIVER 14634 + M: Maximilian Luz <luzmaximilian@gmail.com> 14635 + M: Ivor Wanders <ivor@iwanders.net> 14636 + L: linux-hwmon@vger.kernel.org 14637 + S: Maintained 14638 + F: Documentation/hwmon/surface_fan.rst 14639 + F: drivers/hwmon/surface_fan.c 14640 + 14583 14641 MICROSOFT SURFACE GPE LID SUPPORT DRIVER 14584 14642 M: Maximilian Luz <luzmaximilian@gmail.com> 14585 14643 L: platform-driver-x86@vger.kernel.org ··· 15091 15133 M: Samuel Mendoza-Jonas <sam@mendozajonas.com> 15092 15134 S: Maintained 15093 15135 F: net/ncsi/ 15094 - 15095 - NCT6775 HARDWARE MONITOR DRIVER - CORE & PLATFORM DRIVER 15096 - M: Guenter Roeck <linux@roeck-us.net> 15097 - L: linux-hwmon@vger.kernel.org 15098 - S: Maintained 15099 - F: Documentation/hwmon/nct6775.rst 15100 - F: drivers/hwmon/nct6775-core.c 15101 - F: drivers/hwmon/nct6775-platform.c 15102 - F: drivers/hwmon/nct6775.h 15103 15136 15104 15137 NCT6775 HARDWARE MONITOR DRIVER - I2C DRIVER 15105 15138 M: Zev Weiss <zev@bewilderbeest.net> ··· 15846 15897 S: Maintained 15847 15898 F: Documentation/hwmon/nzxt-kraken2.rst 15848 15899 F: drivers/hwmon/nzxt-kraken2.c 15900 + 15901 + NZXT-KRAKEN3 HARDWARE MONITORING DRIVER 15902 + M: Jonas Malaco <jonas@protocubo.io> 15903 + M: Aleksa Savic <savicaleksa83@gmail.com> 15904 + L: linux-hwmon@vger.kernel.org 15905 + S: Maintained 15906 + F: Documentation/hwmon/nzxt-kraken3.rst 15907 + F: drivers/hwmon/nzxt-kraken3.c 15849 15908 15850 15909 NZXT-SMART2 HARDWARE MONITORING DRIVER 15851 15910 M: Aleksandr Mezin <mezin.alexander@gmail.com> ··· 17447 17490 F: Documentation/hwmon/pm6764tr.rst 17448 17491 F: drivers/hwmon/pmbus/pm6764tr.c 17449 17492 17450 - PMBUS HARDWARE MONITORING DRIVERS 17451 - M: Guenter Roeck <linux@roeck-us.net> 17452 - L: linux-hwmon@vger.kernel.org 17453 - S: Maintained 17454 - W: http://hwmon.wiki.kernel.org/ 17455 - W: http://www.roeck-us.net/linux/drivers/ 17456 - T: git git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git 17457 - F: Documentation/devicetree/bindings/hwmon/ltc2978.txt 17458 - F: Documentation/devicetree/bindings/hwmon/max31785.txt 17459 - F: Documentation/hwmon/adm1275.rst 17460 - F: Documentation/hwmon/ibm-cffps.rst 17461 - F: Documentation/hwmon/ir35221.rst 17462 - F: Documentation/hwmon/lm25066.rst 17463 - F: Documentation/hwmon/ltc2978.rst 17464 - F: Documentation/hwmon/ltc3815.rst 17465 - F: Documentation/hwmon/max16064.rst 17466 - F: Documentation/hwmon/max20751.rst 17467 - F: Documentation/hwmon/max31785.rst 17468 - F: Documentation/hwmon/max34440.rst 17469 - F: Documentation/hwmon/max8688.rst 17470 - F: Documentation/hwmon/pmbus-core.rst 17471 - F: Documentation/hwmon/pmbus.rst 17472 - F: Documentation/hwmon/tps40422.rst 17473 - F: Documentation/hwmon/ucd9000.rst 17474 - F: Documentation/hwmon/ucd9200.rst 17475 - F: Documentation/hwmon/zl6100.rst 17476 - F: drivers/hwmon/pmbus/ 17477 - F: include/linux/pmbus.h 17478 - 17479 17493 PMC SIERRA MaxRAID DRIVER 17480 17494 L: linux-scsi@vger.kernel.org 17481 17495 S: Orphan ··· 17667 17739 F: fs/pstore/ 17668 17740 F: include/linux/pstore* 17669 17741 K: \b(pstore|ramoops) 17742 + 17743 + PT5161L HARDWARE MONITOR DRIVER 17744 + M: Cosmo Chou <cosmo.chou@quantatw.com> 17745 + L: linux-hwmon@vger.kernel.org 17746 + S: Maintained 17747 + F: Documentation/hwmon/pt5161l.rst 17748 + F: drivers/hwmon/pt5161l.c 17670 17749 17671 17750 PTP HARDWARE CLOCK SUPPORT 17672 17751 M: Richard Cochran <richardcochran@gmail.com> ··· 22161 22226 F: drivers/mmc/host/renesas_sdhi* 22162 22227 F: drivers/mmc/host/tmio_mmc* 22163 22228 F: include/linux/mfd/tmio.h 22164 - 22165 - TMP401 HARDWARE MONITOR DRIVER 22166 - M: Guenter Roeck <linux@roeck-us.net> 22167 - L: linux-hwmon@vger.kernel.org 22168 - S: Maintained 22169 - F: Documentation/devicetree/bindings/hwmon/ti,tmp401.yaml 22170 - F: Documentation/hwmon/tmp401.rst 22171 - F: drivers/hwmon/tmp401.c 22172 - 22173 - TMP464 HARDWARE MONITOR DRIVER 22174 - M: Guenter Roeck <linux@roeck-us.net> 22175 - L: linux-hwmon@vger.kernel.org 22176 - S: Maintained 22177 - F: Documentation/devicetree/bindings/hwmon/ti,tmp464.yaml 22178 - F: Documentation/hwmon/tmp464.rst 22179 - F: drivers/hwmon/tmp464.c 22180 22229 22181 22230 TMP513 HARDWARE MONITOR DRIVER 22182 22231 M: Eric Tremblay <etremblay@distech-controls.com>
+76
drivers/hwmon/Kconfig
··· 301 301 This driver can also be built as a module. If so, the module 302 302 will be called asc7621. 303 303 304 + config SENSORS_ASUS_ROG_RYUJIN 305 + tristate "ASUS ROG RYUJIN II 360 hardware monitoring driver" 306 + depends on HID 307 + help 308 + If you say yes here you get support for the fans and sensors of 309 + the ASUS ROG RYUJIN II 360 AIO CPU liquid cooler. 310 + 311 + This driver can also be built as a module. If so, the module 312 + will be called asus_rog_ryujin. 313 + 304 314 config SENSORS_AXI_FAN_CONTROL 305 315 tristate "Analog Devices FAN Control HDL Core driver" 306 316 help ··· 422 412 This driver can also be built as a module. If so, the module 423 413 will be called aspeed_pwm_tacho. 424 414 415 + config SENSORS_ASPEED_G6 416 + tristate "ASPEED g6 PWM and Fan tach driver" 417 + depends on ARCH_ASPEED || COMPILE_TEST 418 + depends on PWM 419 + help 420 + This driver provides support for ASPEED G6 PWM and Fan Tach 421 + controllers. 422 + 423 + This driver can also be built as a module. If so, the module 424 + will be called aspeed_pwm_tacho. 425 + 425 426 config SENSORS_ATXP1 426 427 tristate "Attansic ATXP1 VID controller" 427 428 depends on I2C ··· 472 451 performed on demand from the user-space. If this config is enabled 473 452 the data conversion will be periodically performed and the data will be 474 453 saved in the internal driver cache. 454 + 455 + config SENSORS_CHIPCAP2 456 + tristate "Amphenol ChipCap 2 relative humidity and temperature sensor" 457 + depends on I2C 458 + help 459 + Say yes here to build support for the Amphenol ChipCap 2 460 + relative humidity and temperature sensor. 461 + 462 + To compile this driver as a module, choose M here: the module 463 + will be called chipcap2. 475 464 476 465 config SENSORS_CORSAIR_CPRO 477 466 tristate "Corsair Commander Pro controller" ··· 1068 1037 1069 1038 This driver can also be built as a module. If so, the module will 1070 1039 be called ltc4261. 1040 + 1041 + config SENSORS_LTC4282 1042 + tristate "Analog Devices LTC4282" 1043 + depends on I2C 1044 + select REGMAP_I2C 1045 + help 1046 + If you say yes here you get support for Analog Devices LTC4282 1047 + High Current Hot Swap Controller I2C interface. 1048 + 1049 + This driver can also be built as a module. If so, the module will 1050 + be called ltc4282. 1071 1051 1072 1052 config SENSORS_LTQ_CPUTEMP 1073 1053 bool "Lantiq cpu temperature sensor driver" ··· 1716 1674 This driver can also be built as a module. If so, the module 1717 1675 will be called nzxt-kraken2. 1718 1676 1677 + config SENSORS_NZXT_KRAKEN3 1678 + tristate "NZXT Kraken X53/X63/X73, Z53/Z63/Z73 coolers" 1679 + depends on USB_HID 1680 + help 1681 + If you say yes here you get support for hardware monitoring for the 1682 + NZXT Kraken X53/X63/X73, Z53/Z63/Z73 all-in-one CPU liquid coolers. 1683 + 1684 + This driver can also be built as a module. If so, the module 1685 + will be called nzxt-kraken3. 1686 + 1719 1687 config SENSORS_NZXT_SMART2 1720 1688 tristate "NZXT RGB & Fan Controller/Smart Device v2" 1721 1689 depends on USB_HID ··· 1765 1713 source "drivers/hwmon/peci/Kconfig" 1766 1714 1767 1715 source "drivers/hwmon/pmbus/Kconfig" 1716 + 1717 + config SENSORS_PT5161L 1718 + tristate "Astera Labs PT5161L PCIe retimer hardware monitoring" 1719 + depends on I2C 1720 + help 1721 + If you say yes here you get support for temperature monitoring 1722 + on the Astera Labs PT5161L PCIe retimer. 1723 + 1724 + This driver can also be built as a module. If so, the module 1725 + will be called pt5161l. 1768 1726 1769 1727 config SENSORS_PWM_FAN 1770 1728 tristate "PWM fan" ··· 2055 1993 2056 1994 This driver can also be built as a module. If so, the module 2057 1995 will be called sfctemp. 1996 + 1997 + config SENSORS_SURFACE_FAN 1998 + tristate "Surface Fan Driver" 1999 + depends on SURFACE_AGGREGATOR 2000 + depends on SURFACE_AGGREGATOR_BUS 2001 + help 2002 + Driver that provides monitoring of the fan on Surface Pro devices that 2003 + have a fan, like the Surface Pro 9. 2004 + 2005 + This makes the fan's current speed accessible through the hwmon 2006 + system. It does not provide control over the fan, the firmware is 2007 + responsible for that, this driver merely provides monitoring. 2008 + 2009 + Select M or Y here, if you want to be able to read the fan's speed. 2058 2010 2059 2011 config SENSORS_ADC128D818 2060 2012 tristate "Texas Instruments ADC128D818"
+7
drivers/hwmon/Makefile
··· 55 55 obj-$(CONFIG_SENSORS_AS370) += as370-hwmon.o 56 56 obj-$(CONFIG_SENSORS_ASC7621) += asc7621.o 57 57 obj-$(CONFIG_SENSORS_ASPEED) += aspeed-pwm-tacho.o 58 + obj-$(CONFIG_SENSORS_ASPEED_G6) += aspeed-g6-pwm-tach.o 59 + obj-$(CONFIG_SENSORS_ASUS_ROG_RYUJIN) += asus_rog_ryujin.o 58 60 obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o 59 61 obj-$(CONFIG_SENSORS_AXI_FAN_CONTROL) += axi-fan-control.o 60 62 obj-$(CONFIG_SENSORS_BT1_PVT) += bt1-pvt.o 63 + obj-$(CONFIG_SENSORS_CHIPCAP2) += chipcap2.o 61 64 obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o 62 65 obj-$(CONFIG_SENSORS_CORSAIR_CPRO) += corsair-cpro.o 63 66 obj-$(CONFIG_SENSORS_CORSAIR_PSU) += corsair-psu.o ··· 139 136 obj-$(CONFIG_SENSORS_LTC4245) += ltc4245.o 140 137 obj-$(CONFIG_SENSORS_LTC4260) += ltc4260.o 141 138 obj-$(CONFIG_SENSORS_LTC4261) += ltc4261.o 139 + obj-$(CONFIG_SENSORS_LTC4282) += ltc4282.o 142 140 obj-$(CONFIG_SENSORS_LTQ_CPUTEMP) += ltq-cputemp.o 143 141 obj-$(CONFIG_SENSORS_MAX1111) += max1111.o 144 142 obj-$(CONFIG_SENSORS_MAX127) += max127.o ··· 177 173 obj-$(CONFIG_SENSORS_NSA320) += nsa320-hwmon.o 178 174 obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o 179 175 obj-$(CONFIG_SENSORS_NZXT_KRAKEN2) += nzxt-kraken2.o 176 + obj-$(CONFIG_SENSORS_NZXT_KRAKEN3) += nzxt-kraken3.o 180 177 obj-$(CONFIG_SENSORS_NZXT_SMART2) += nzxt-smart2.o 181 178 obj-$(CONFIG_SENSORS_OXP) += oxp-sensors.o 182 179 obj-$(CONFIG_SENSORS_PC87360) += pc87360.o ··· 185 180 obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o 186 181 obj-$(CONFIG_SENSORS_POWERZ) += powerz.o 187 182 obj-$(CONFIG_SENSORS_POWR1220) += powr1220.o 183 + obj-$(CONFIG_SENSORS_PT5161L) += pt5161l.o 188 184 obj-$(CONFIG_SENSORS_PWM_FAN) += pwm-fan.o 189 185 obj-$(CONFIG_SENSORS_RASPBERRYPI_HWMON) += raspberrypi-hwmon.o 190 186 obj-$(CONFIG_SENSORS_SBTSI) += sbtsi_temp.o ··· 207 201 obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o 208 202 obj-$(CONFIG_SENSORS_SPARX5) += sparx5-temp.o 209 203 obj-$(CONFIG_SENSORS_STTS751) += stts751.o 204 + obj-$(CONFIG_SENSORS_SURFACE_FAN)+= surface_fan.o 210 205 obj-$(CONFIG_SENSORS_SY7636A) += sy7636a-hwmon.o 211 206 obj-$(CONFIG_SENSORS_AMC6821) += amc6821.o 212 207 obj-$(CONFIG_SENSORS_TC74) += tc74.o
-1
drivers/hwmon/adm1177.c
··· 250 250 MODULE_DEVICE_TABLE(of, adm1177_dt_ids); 251 251 252 252 static struct i2c_driver adm1177_driver = { 253 - .class = I2C_CLASS_HWMON, 254 253 .driver = { 255 254 .name = "adm1177", 256 255 .of_match_table = adm1177_dt_ids,
+1 -1
drivers/hwmon/adt7310.c
··· 124 124 static const struct regmap_config adt7310_regmap_config = { 125 125 .reg_bits = 8, 126 126 .val_bits = 16, 127 - .cache_type = REGCACHE_RBTREE, 127 + .cache_type = REGCACHE_MAPLE, 128 128 .volatile_reg = adt7310_regmap_is_volatile, 129 129 .reg_read = adt7310_reg_read, 130 130 .reg_write = adt7310_reg_write,
+1 -3
drivers/hwmon/adt7410.c
··· 69 69 .reg_bits = 8, 70 70 .val_bits = 16, 71 71 .max_register = ADT7X10_ID, 72 - .cache_type = REGCACHE_RBTREE, 72 + .cache_type = REGCACHE_MAPLE, 73 73 .volatile_reg = adt7410_regmap_is_volatile, 74 74 .reg_read = adt7410_reg_read, 75 75 .reg_write = adt7410_reg_write, ··· 95 95 MODULE_DEVICE_TABLE(i2c, adt7410_ids); 96 96 97 97 static struct i2c_driver adt7410_driver = { 98 - .class = I2C_CLASS_HWMON, 99 98 .driver = { 100 99 .name = "adt7410", 101 100 .pm = pm_sleep_ptr(&adt7x10_dev_pm_ops), 102 101 }, 103 102 .probe = adt7410_i2c_probe, 104 103 .id_table = adt7410_ids, 105 - .address_list = I2C_ADDRS(0x48, 0x49, 0x4a, 0x4b), 106 104 }; 107 105 module_i2c_driver(adt7410_driver); 108 106
+11
drivers/hwmon/amc6821.c
··· 934 934 935 935 MODULE_DEVICE_TABLE(i2c, amc6821_id); 936 936 937 + static const struct of_device_id __maybe_unused amc6821_of_match[] = { 938 + { 939 + .compatible = "ti,amc6821", 940 + .data = (void *)amc6821, 941 + }, 942 + { } 943 + }; 944 + 945 + MODULE_DEVICE_TABLE(of, amc6821_of_match); 946 + 937 947 static struct i2c_driver amc6821_driver = { 938 948 .class = I2C_CLASS_HWMON, 939 949 .driver = { 940 950 .name = "amc6821", 951 + .of_match_table = of_match_ptr(amc6821_of_match), 941 952 }, 942 953 .probe = amc6821_probe, 943 954 .id_table = amc6821_id,
+549
drivers/hwmon/aspeed-g6-pwm-tach.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Copyright (C) 2021 Aspeed Technology Inc. 4 + * 5 + * PWM/TACH controller driver for Aspeed ast2600 SoCs. 6 + * This drivers doesn't support earlier version of the IP. 7 + * 8 + * The hardware operates in time quantities of length 9 + * Q := (DIV_L + 1) << DIV_H / input-clk 10 + * The length of a PWM period is (DUTY_CYCLE_PERIOD + 1) * Q. 11 + * The maximal value for DUTY_CYCLE_PERIOD is used here to provide 12 + * a fine grained selection for the duty cycle. 13 + * 14 + * This driver uses DUTY_CYCLE_RISING_POINT = 0, so from the start of a 15 + * period the output is active until DUTY_CYCLE_FALLING_POINT * Q. Note 16 + * that if DUTY_CYCLE_RISING_POINT = DUTY_CYCLE_FALLING_POINT the output is 17 + * always active. 18 + * 19 + * Register usage: 20 + * PIN_ENABLE: When it is unset the pwm controller will emit inactive level to the external. 21 + * Use to determine whether the PWM channel is enabled or disabled 22 + * CLK_ENABLE: When it is unset the pwm controller will assert the duty counter reset and 23 + * emit inactive level to the PIN_ENABLE mux after that the driver can still change the pwm period 24 + * and duty and the value will apply when CLK_ENABLE be set again. 25 + * Use to determine whether duty_cycle bigger than 0. 26 + * PWM_ASPEED_CTRL_INVERSE: When it is toggled the output value will inverse immediately. 27 + * PWM_ASPEED_DUTY_CYCLE_FALLING_POINT/PWM_ASPEED_DUTY_CYCLE_RISING_POINT: When these two 28 + * values are equal it means the duty cycle = 100%. 29 + * 30 + * The glitch may generate at: 31 + * - Enabled changing when the duty_cycle bigger than 0% and less than 100%. 32 + * - Polarity changing when the duty_cycle bigger than 0% and less than 100%. 33 + * 34 + * Limitations: 35 + * - When changing both duty cycle and period, we cannot prevent in 36 + * software that the output might produce a period with mixed 37 + * settings. 38 + * - Disabling the PWM doesn't complete the current period. 39 + * 40 + * Improvements: 41 + * - When only changing one of duty cycle or period, our pwm controller will not 42 + * generate the glitch, the configure will change at next cycle of pwm. 43 + * This improvement can disable/enable through PWM_ASPEED_CTRL_DUTY_SYNC_DISABLE. 44 + */ 45 + 46 + #include <linux/bitfield.h> 47 + #include <linux/clk.h> 48 + #include <linux/delay.h> 49 + #include <linux/errno.h> 50 + #include <linux/hwmon.h> 51 + #include <linux/io.h> 52 + #include <linux/kernel.h> 53 + #include <linux/math64.h> 54 + #include <linux/module.h> 55 + #include <linux/of_device.h> 56 + #include <linux/of_platform.h> 57 + #include <linux/platform_device.h> 58 + #include <linux/pwm.h> 59 + #include <linux/reset.h> 60 + #include <linux/sysfs.h> 61 + 62 + /* The channel number of Aspeed pwm controller */ 63 + #define PWM_ASPEED_NR_PWMS 16 64 + /* PWM Control Register */ 65 + #define PWM_ASPEED_CTRL(ch) ((ch) * 0x10 + 0x00) 66 + #define PWM_ASPEED_CTRL_LOAD_SEL_RISING_AS_WDT BIT(19) 67 + #define PWM_ASPEED_CTRL_DUTY_LOAD_AS_WDT_ENABLE BIT(18) 68 + #define PWM_ASPEED_CTRL_DUTY_SYNC_DISABLE BIT(17) 69 + #define PWM_ASPEED_CTRL_CLK_ENABLE BIT(16) 70 + #define PWM_ASPEED_CTRL_LEVEL_OUTPUT BIT(15) 71 + #define PWM_ASPEED_CTRL_INVERSE BIT(14) 72 + #define PWM_ASPEED_CTRL_OPEN_DRAIN_ENABLE BIT(13) 73 + #define PWM_ASPEED_CTRL_PIN_ENABLE BIT(12) 74 + #define PWM_ASPEED_CTRL_CLK_DIV_H GENMASK(11, 8) 75 + #define PWM_ASPEED_CTRL_CLK_DIV_L GENMASK(7, 0) 76 + 77 + /* PWM Duty Cycle Register */ 78 + #define PWM_ASPEED_DUTY_CYCLE(ch) ((ch) * 0x10 + 0x04) 79 + #define PWM_ASPEED_DUTY_CYCLE_PERIOD GENMASK(31, 24) 80 + #define PWM_ASPEED_DUTY_CYCLE_POINT_AS_WDT GENMASK(23, 16) 81 + #define PWM_ASPEED_DUTY_CYCLE_FALLING_POINT GENMASK(15, 8) 82 + #define PWM_ASPEED_DUTY_CYCLE_RISING_POINT GENMASK(7, 0) 83 + 84 + /* PWM fixed value */ 85 + #define PWM_ASPEED_FIXED_PERIOD FIELD_MAX(PWM_ASPEED_DUTY_CYCLE_PERIOD) 86 + 87 + /* The channel number of Aspeed tach controller */ 88 + #define TACH_ASPEED_NR_TACHS 16 89 + /* TACH Control Register */ 90 + #define TACH_ASPEED_CTRL(ch) (((ch) * 0x10) + 0x08) 91 + #define TACH_ASPEED_IER BIT(31) 92 + #define TACH_ASPEED_INVERS_LIMIT BIT(30) 93 + #define TACH_ASPEED_LOOPBACK BIT(29) 94 + #define TACH_ASPEED_ENABLE BIT(28) 95 + #define TACH_ASPEED_DEBOUNCE_MASK GENMASK(27, 26) 96 + #define TACH_ASPEED_DEBOUNCE_BIT 26 97 + #define TACH_ASPEED_IO_EDGE_MASK GENMASK(25, 24) 98 + #define TACH_ASPEED_IO_EDGE_BIT 24 99 + #define TACH_ASPEED_CLK_DIV_T_MASK GENMASK(23, 20) 100 + #define TACH_ASPEED_CLK_DIV_BIT 20 101 + #define TACH_ASPEED_THRESHOLD_MASK GENMASK(19, 0) 102 + /* [27:26] */ 103 + #define DEBOUNCE_3_CLK 0x00 104 + #define DEBOUNCE_2_CLK 0x01 105 + #define DEBOUNCE_1_CLK 0x02 106 + #define DEBOUNCE_0_CLK 0x03 107 + /* [25:24] */ 108 + #define F2F_EDGES 0x00 109 + #define R2R_EDGES 0x01 110 + #define BOTH_EDGES 0x02 111 + /* [23:20] */ 112 + /* divisor = 4 to the nth power, n = register value */ 113 + #define DEFAULT_TACH_DIV 1024 114 + #define DIV_TO_REG(divisor) (ilog2(divisor) >> 1) 115 + 116 + /* TACH Status Register */ 117 + #define TACH_ASPEED_STS(ch) (((ch) * 0x10) + 0x0C) 118 + 119 + /*PWM_TACH_STS */ 120 + #define TACH_ASPEED_ISR BIT(31) 121 + #define TACH_ASPEED_PWM_OUT BIT(25) 122 + #define TACH_ASPEED_PWM_OEN BIT(24) 123 + #define TACH_ASPEED_DEB_INPUT BIT(23) 124 + #define TACH_ASPEED_RAW_INPUT BIT(22) 125 + #define TACH_ASPEED_VALUE_UPDATE BIT(21) 126 + #define TACH_ASPEED_FULL_MEASUREMENT BIT(20) 127 + #define TACH_ASPEED_VALUE_MASK GENMASK(19, 0) 128 + /********************************************************** 129 + * Software setting 130 + *********************************************************/ 131 + #define DEFAULT_FAN_PULSE_PR 2 132 + 133 + struct aspeed_pwm_tach_data { 134 + struct device *dev; 135 + void __iomem *base; 136 + struct clk *clk; 137 + struct reset_control *reset; 138 + unsigned long clk_rate; 139 + struct pwm_chip chip; 140 + bool tach_present[TACH_ASPEED_NR_TACHS]; 141 + u32 tach_divisor; 142 + }; 143 + 144 + static inline struct aspeed_pwm_tach_data * 145 + aspeed_pwm_chip_to_data(struct pwm_chip *chip) 146 + { 147 + return container_of(chip, struct aspeed_pwm_tach_data, chip); 148 + } 149 + 150 + static int aspeed_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, 151 + struct pwm_state *state) 152 + { 153 + struct aspeed_pwm_tach_data *priv = aspeed_pwm_chip_to_data(chip); 154 + u32 hwpwm = pwm->hwpwm; 155 + bool polarity, pin_en, clk_en; 156 + u32 duty_pt, val; 157 + u64 div_h, div_l, duty_cycle_period, dividend; 158 + 159 + val = readl(priv->base + PWM_ASPEED_CTRL(hwpwm)); 160 + polarity = FIELD_GET(PWM_ASPEED_CTRL_INVERSE, val); 161 + pin_en = FIELD_GET(PWM_ASPEED_CTRL_PIN_ENABLE, val); 162 + clk_en = FIELD_GET(PWM_ASPEED_CTRL_CLK_ENABLE, val); 163 + div_h = FIELD_GET(PWM_ASPEED_CTRL_CLK_DIV_H, val); 164 + div_l = FIELD_GET(PWM_ASPEED_CTRL_CLK_DIV_L, val); 165 + val = readl(priv->base + PWM_ASPEED_DUTY_CYCLE(hwpwm)); 166 + duty_pt = FIELD_GET(PWM_ASPEED_DUTY_CYCLE_FALLING_POINT, val); 167 + duty_cycle_period = FIELD_GET(PWM_ASPEED_DUTY_CYCLE_PERIOD, val); 168 + /* 169 + * This multiplication doesn't overflow, the upper bound is 170 + * 1000000000 * 256 * 256 << 15 = 0x1dcd650000000000 171 + */ 172 + dividend = (u64)NSEC_PER_SEC * (div_l + 1) * (duty_cycle_period + 1) 173 + << div_h; 174 + state->period = DIV_ROUND_UP_ULL(dividend, priv->clk_rate); 175 + 176 + if (clk_en && duty_pt) { 177 + dividend = (u64)NSEC_PER_SEC * (div_l + 1) * duty_pt 178 + << div_h; 179 + state->duty_cycle = DIV_ROUND_UP_ULL(dividend, priv->clk_rate); 180 + } else { 181 + state->duty_cycle = clk_en ? state->period : 0; 182 + } 183 + state->polarity = polarity ? PWM_POLARITY_INVERSED : PWM_POLARITY_NORMAL; 184 + state->enabled = pin_en; 185 + return 0; 186 + } 187 + 188 + static int aspeed_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, 189 + const struct pwm_state *state) 190 + { 191 + struct aspeed_pwm_tach_data *priv = aspeed_pwm_chip_to_data(chip); 192 + u32 hwpwm = pwm->hwpwm, duty_pt, val; 193 + u64 div_h, div_l, divisor, expect_period; 194 + bool clk_en; 195 + 196 + expect_period = div64_u64(ULLONG_MAX, (u64)priv->clk_rate); 197 + expect_period = min(expect_period, state->period); 198 + dev_dbg(chip->dev, "expect period: %lldns, duty_cycle: %lldns", 199 + expect_period, state->duty_cycle); 200 + /* 201 + * Pick the smallest value for div_h so that div_l can be the biggest 202 + * which results in a finer resolution near the target period value. 203 + */ 204 + divisor = (u64)NSEC_PER_SEC * (PWM_ASPEED_FIXED_PERIOD + 1) * 205 + (FIELD_MAX(PWM_ASPEED_CTRL_CLK_DIV_L) + 1); 206 + div_h = order_base_2(DIV64_U64_ROUND_UP(priv->clk_rate * expect_period, divisor)); 207 + if (div_h > 0xf) 208 + div_h = 0xf; 209 + 210 + divisor = ((u64)NSEC_PER_SEC * (PWM_ASPEED_FIXED_PERIOD + 1)) << div_h; 211 + div_l = div64_u64(priv->clk_rate * expect_period, divisor); 212 + 213 + if (div_l == 0) 214 + return -ERANGE; 215 + 216 + div_l -= 1; 217 + 218 + if (div_l > 255) 219 + div_l = 255; 220 + 221 + dev_dbg(chip->dev, "clk source: %ld div_h %lld, div_l : %lld\n", 222 + priv->clk_rate, div_h, div_l); 223 + /* duty_pt = duty_cycle * (PERIOD + 1) / period */ 224 + duty_pt = div64_u64(state->duty_cycle * priv->clk_rate, 225 + (u64)NSEC_PER_SEC * (div_l + 1) << div_h); 226 + dev_dbg(chip->dev, "duty_cycle = %lld, duty_pt = %d\n", 227 + state->duty_cycle, duty_pt); 228 + 229 + /* 230 + * Fixed DUTY_CYCLE_PERIOD to its max value to get a 231 + * fine-grained resolution for duty_cycle at the expense of a 232 + * coarser period resolution. 233 + */ 234 + val = readl(priv->base + PWM_ASPEED_DUTY_CYCLE(hwpwm)); 235 + val &= ~PWM_ASPEED_DUTY_CYCLE_PERIOD; 236 + val |= FIELD_PREP(PWM_ASPEED_DUTY_CYCLE_PERIOD, 237 + PWM_ASPEED_FIXED_PERIOD); 238 + writel(val, priv->base + PWM_ASPEED_DUTY_CYCLE(hwpwm)); 239 + 240 + if (duty_pt == 0) { 241 + /* emit inactive level and assert the duty counter reset */ 242 + clk_en = 0; 243 + } else { 244 + clk_en = 1; 245 + if (duty_pt >= (PWM_ASPEED_FIXED_PERIOD + 1)) 246 + duty_pt = 0; 247 + val = readl(priv->base + PWM_ASPEED_DUTY_CYCLE(hwpwm)); 248 + val &= ~(PWM_ASPEED_DUTY_CYCLE_RISING_POINT | 249 + PWM_ASPEED_DUTY_CYCLE_FALLING_POINT); 250 + val |= FIELD_PREP(PWM_ASPEED_DUTY_CYCLE_FALLING_POINT, duty_pt); 251 + writel(val, priv->base + PWM_ASPEED_DUTY_CYCLE(hwpwm)); 252 + } 253 + 254 + val = readl(priv->base + PWM_ASPEED_CTRL(hwpwm)); 255 + val &= ~(PWM_ASPEED_CTRL_CLK_DIV_H | PWM_ASPEED_CTRL_CLK_DIV_L | 256 + PWM_ASPEED_CTRL_PIN_ENABLE | PWM_ASPEED_CTRL_CLK_ENABLE | 257 + PWM_ASPEED_CTRL_INVERSE); 258 + val |= FIELD_PREP(PWM_ASPEED_CTRL_CLK_DIV_H, div_h) | 259 + FIELD_PREP(PWM_ASPEED_CTRL_CLK_DIV_L, div_l) | 260 + FIELD_PREP(PWM_ASPEED_CTRL_PIN_ENABLE, state->enabled) | 261 + FIELD_PREP(PWM_ASPEED_CTRL_CLK_ENABLE, clk_en) | 262 + FIELD_PREP(PWM_ASPEED_CTRL_INVERSE, state->polarity); 263 + writel(val, priv->base + PWM_ASPEED_CTRL(hwpwm)); 264 + 265 + return 0; 266 + } 267 + 268 + static const struct pwm_ops aspeed_pwm_ops = { 269 + .apply = aspeed_pwm_apply, 270 + .get_state = aspeed_pwm_get_state, 271 + }; 272 + 273 + static void aspeed_tach_ch_enable(struct aspeed_pwm_tach_data *priv, u8 tach_ch, 274 + bool enable) 275 + { 276 + if (enable) 277 + writel(readl(priv->base + TACH_ASPEED_CTRL(tach_ch)) | 278 + TACH_ASPEED_ENABLE, 279 + priv->base + TACH_ASPEED_CTRL(tach_ch)); 280 + else 281 + writel(readl(priv->base + TACH_ASPEED_CTRL(tach_ch)) & 282 + ~TACH_ASPEED_ENABLE, 283 + priv->base + TACH_ASPEED_CTRL(tach_ch)); 284 + } 285 + 286 + static int aspeed_tach_val_to_rpm(struct aspeed_pwm_tach_data *priv, u32 tach_val) 287 + { 288 + u64 rpm; 289 + u32 tach_div; 290 + 291 + tach_div = tach_val * priv->tach_divisor * DEFAULT_FAN_PULSE_PR; 292 + 293 + dev_dbg(priv->dev, "clk %ld, tach_val %d , tach_div %d\n", 294 + priv->clk_rate, tach_val, tach_div); 295 + 296 + rpm = (u64)priv->clk_rate * 60; 297 + do_div(rpm, tach_div); 298 + 299 + return (int)rpm; 300 + } 301 + 302 + static int aspeed_get_fan_tach_ch_rpm(struct aspeed_pwm_tach_data *priv, 303 + u8 fan_tach_ch) 304 + { 305 + u32 val; 306 + 307 + val = readl(priv->base + TACH_ASPEED_STS(fan_tach_ch)); 308 + 309 + if (!(val & TACH_ASPEED_FULL_MEASUREMENT)) 310 + return 0; 311 + val = FIELD_GET(TACH_ASPEED_VALUE_MASK, val); 312 + return aspeed_tach_val_to_rpm(priv, val); 313 + } 314 + 315 + static int aspeed_tach_hwmon_read(struct device *dev, 316 + enum hwmon_sensor_types type, u32 attr, 317 + int channel, long *val) 318 + { 319 + struct aspeed_pwm_tach_data *priv = dev_get_drvdata(dev); 320 + u32 reg_val; 321 + 322 + switch (attr) { 323 + case hwmon_fan_input: 324 + *val = aspeed_get_fan_tach_ch_rpm(priv, channel); 325 + break; 326 + case hwmon_fan_div: 327 + reg_val = readl(priv->base + TACH_ASPEED_CTRL(channel)); 328 + reg_val = FIELD_GET(TACH_ASPEED_CLK_DIV_T_MASK, reg_val); 329 + *val = BIT(reg_val << 1); 330 + break; 331 + default: 332 + return -EOPNOTSUPP; 333 + } 334 + return 0; 335 + } 336 + 337 + static int aspeed_tach_hwmon_write(struct device *dev, 338 + enum hwmon_sensor_types type, u32 attr, 339 + int channel, long val) 340 + { 341 + struct aspeed_pwm_tach_data *priv = dev_get_drvdata(dev); 342 + u32 reg_val; 343 + 344 + switch (attr) { 345 + case hwmon_fan_div: 346 + if (!is_power_of_2(val) || (ilog2(val) % 2) || 347 + DIV_TO_REG(val) > 0xb) 348 + return -EINVAL; 349 + priv->tach_divisor = val; 350 + reg_val = readl(priv->base + TACH_ASPEED_CTRL(channel)); 351 + reg_val &= ~TACH_ASPEED_CLK_DIV_T_MASK; 352 + reg_val |= FIELD_PREP(TACH_ASPEED_CLK_DIV_T_MASK, 353 + DIV_TO_REG(priv->tach_divisor)); 354 + writel(reg_val, priv->base + TACH_ASPEED_CTRL(channel)); 355 + break; 356 + default: 357 + return -EOPNOTSUPP; 358 + } 359 + 360 + return 0; 361 + } 362 + 363 + static umode_t aspeed_tach_dev_is_visible(const void *drvdata, 364 + enum hwmon_sensor_types type, 365 + u32 attr, int channel) 366 + { 367 + const struct aspeed_pwm_tach_data *priv = drvdata; 368 + 369 + if (!priv->tach_present[channel]) 370 + return 0; 371 + switch (attr) { 372 + case hwmon_fan_input: 373 + return 0444; 374 + case hwmon_fan_div: 375 + return 0644; 376 + } 377 + return 0; 378 + } 379 + 380 + static const struct hwmon_ops aspeed_tach_ops = { 381 + .is_visible = aspeed_tach_dev_is_visible, 382 + .read = aspeed_tach_hwmon_read, 383 + .write = aspeed_tach_hwmon_write, 384 + }; 385 + 386 + static const struct hwmon_channel_info *aspeed_tach_info[] = { 387 + HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT | HWMON_F_DIV, HWMON_F_INPUT | HWMON_F_DIV, 388 + HWMON_F_INPUT | HWMON_F_DIV, HWMON_F_INPUT | HWMON_F_DIV, 389 + HWMON_F_INPUT | HWMON_F_DIV, HWMON_F_INPUT | HWMON_F_DIV, 390 + HWMON_F_INPUT | HWMON_F_DIV, HWMON_F_INPUT | HWMON_F_DIV, 391 + HWMON_F_INPUT | HWMON_F_DIV, HWMON_F_INPUT | HWMON_F_DIV, 392 + HWMON_F_INPUT | HWMON_F_DIV, HWMON_F_INPUT | HWMON_F_DIV, 393 + HWMON_F_INPUT | HWMON_F_DIV, HWMON_F_INPUT | HWMON_F_DIV, 394 + HWMON_F_INPUT | HWMON_F_DIV, HWMON_F_INPUT | HWMON_F_DIV), 395 + NULL 396 + }; 397 + 398 + static const struct hwmon_chip_info aspeed_tach_chip_info = { 399 + .ops = &aspeed_tach_ops, 400 + .info = aspeed_tach_info, 401 + }; 402 + 403 + static void aspeed_present_fan_tach(struct aspeed_pwm_tach_data *priv, u8 *tach_ch, int count) 404 + { 405 + u8 ch, index; 406 + u32 val; 407 + 408 + for (index = 0; index < count; index++) { 409 + ch = tach_ch[index]; 410 + priv->tach_present[ch] = true; 411 + priv->tach_divisor = DEFAULT_TACH_DIV; 412 + 413 + val = readl(priv->base + TACH_ASPEED_CTRL(ch)); 414 + val &= ~(TACH_ASPEED_INVERS_LIMIT | TACH_ASPEED_DEBOUNCE_MASK | 415 + TACH_ASPEED_IO_EDGE_MASK | TACH_ASPEED_CLK_DIV_T_MASK | 416 + TACH_ASPEED_THRESHOLD_MASK); 417 + val |= (DEBOUNCE_3_CLK << TACH_ASPEED_DEBOUNCE_BIT) | 418 + F2F_EDGES | 419 + FIELD_PREP(TACH_ASPEED_CLK_DIV_T_MASK, 420 + DIV_TO_REG(priv->tach_divisor)); 421 + writel(val, priv->base + TACH_ASPEED_CTRL(ch)); 422 + 423 + aspeed_tach_ch_enable(priv, ch, true); 424 + } 425 + } 426 + 427 + static int aspeed_create_fan_monitor(struct device *dev, 428 + struct device_node *child, 429 + struct aspeed_pwm_tach_data *priv) 430 + { 431 + int ret, count; 432 + u8 *tach_ch; 433 + 434 + count = of_property_count_u8_elems(child, "tach-ch"); 435 + if (count < 1) 436 + return -EINVAL; 437 + tach_ch = devm_kcalloc(dev, count, sizeof(*tach_ch), GFP_KERNEL); 438 + if (!tach_ch) 439 + return -ENOMEM; 440 + ret = of_property_read_u8_array(child, "tach-ch", tach_ch, count); 441 + if (ret) 442 + return ret; 443 + 444 + aspeed_present_fan_tach(priv, tach_ch, count); 445 + 446 + return 0; 447 + } 448 + 449 + static void aspeed_pwm_tach_reset_assert(void *data) 450 + { 451 + struct reset_control *rst = data; 452 + 453 + reset_control_assert(rst); 454 + } 455 + 456 + static int aspeed_pwm_tach_probe(struct platform_device *pdev) 457 + { 458 + struct device *dev = &pdev->dev, *hwmon; 459 + int ret; 460 + struct device_node *child; 461 + struct aspeed_pwm_tach_data *priv; 462 + 463 + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 464 + if (!priv) 465 + return -ENOMEM; 466 + priv->dev = dev; 467 + priv->base = devm_platform_ioremap_resource(pdev, 0); 468 + if (IS_ERR(priv->base)) 469 + return PTR_ERR(priv->base); 470 + 471 + priv->clk = devm_clk_get_enabled(dev, NULL); 472 + if (IS_ERR(priv->clk)) 473 + return dev_err_probe(dev, PTR_ERR(priv->clk), 474 + "Couldn't get clock\n"); 475 + priv->clk_rate = clk_get_rate(priv->clk); 476 + priv->reset = devm_reset_control_get_exclusive(dev, NULL); 477 + if (IS_ERR(priv->reset)) 478 + return dev_err_probe(dev, PTR_ERR(priv->reset), 479 + "Couldn't get reset control\n"); 480 + 481 + ret = reset_control_deassert(priv->reset); 482 + if (ret) 483 + return dev_err_probe(dev, ret, 484 + "Couldn't deassert reset control\n"); 485 + ret = devm_add_action_or_reset(dev, aspeed_pwm_tach_reset_assert, 486 + priv->reset); 487 + if (ret) 488 + return ret; 489 + 490 + priv->chip.dev = dev; 491 + priv->chip.ops = &aspeed_pwm_ops; 492 + priv->chip.npwm = PWM_ASPEED_NR_PWMS; 493 + 494 + ret = devm_pwmchip_add(dev, &priv->chip); 495 + if (ret) 496 + return dev_err_probe(dev, ret, "Failed to add PWM chip\n"); 497 + 498 + for_each_child_of_node(dev->of_node, child) { 499 + ret = aspeed_create_fan_monitor(dev, child, priv); 500 + if (ret) { 501 + of_node_put(child); 502 + dev_warn(dev, "Failed to create fan %d", ret); 503 + return 0; 504 + } 505 + } 506 + 507 + hwmon = devm_hwmon_device_register_with_info(dev, "aspeed_tach", priv, 508 + &aspeed_tach_chip_info, NULL); 509 + ret = PTR_ERR_OR_ZERO(hwmon); 510 + if (ret) 511 + return dev_err_probe(dev, ret, 512 + "Failed to register hwmon device\n"); 513 + 514 + of_platform_populate(dev->of_node, NULL, NULL, dev); 515 + 516 + return 0; 517 + } 518 + 519 + static int aspeed_pwm_tach_remove(struct platform_device *pdev) 520 + { 521 + struct aspeed_pwm_tach_data *priv = platform_get_drvdata(pdev); 522 + 523 + reset_control_assert(priv->reset); 524 + 525 + return 0; 526 + } 527 + 528 + static const struct of_device_id aspeed_pwm_tach_match[] = { 529 + { 530 + .compatible = "aspeed,ast2600-pwm-tach", 531 + }, 532 + {}, 533 + }; 534 + MODULE_DEVICE_TABLE(of, aspeed_pwm_tach_match); 535 + 536 + static struct platform_driver aspeed_pwm_tach_driver = { 537 + .probe = aspeed_pwm_tach_probe, 538 + .remove = aspeed_pwm_tach_remove, 539 + .driver = { 540 + .name = "aspeed-g6-pwm-tach", 541 + .of_match_table = aspeed_pwm_tach_match, 542 + }, 543 + }; 544 + 545 + module_platform_driver(aspeed_pwm_tach_driver); 546 + 547 + MODULE_AUTHOR("Billy Tsai <billy_tsai@aspeedtech.com>"); 548 + MODULE_DESCRIPTION("Aspeed ast2600 PWM and Fan Tach device driver"); 549 + MODULE_LICENSE("GPL");
+609
drivers/hwmon/asus_rog_ryujin.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * hwmon driver for Asus ROG Ryujin II 360 AIO cooler. 4 + * 5 + * Copyright 2024 Aleksa Savic <savicaleksa83@gmail.com> 6 + */ 7 + 8 + #include <linux/debugfs.h> 9 + #include <linux/hid.h> 10 + #include <linux/hwmon.h> 11 + #include <linux/jiffies.h> 12 + #include <linux/module.h> 13 + #include <linux/spinlock.h> 14 + #include <asm/unaligned.h> 15 + 16 + #define DRIVER_NAME "asus_rog_ryujin" 17 + 18 + #define USB_VENDOR_ID_ASUS_ROG 0x0b05 19 + #define USB_PRODUCT_ID_RYUJIN_AIO 0x1988 /* ASUS ROG RYUJIN II 360 */ 20 + 21 + #define STATUS_VALIDITY 1500 /* ms */ 22 + #define MAX_REPORT_LENGTH 65 23 + 24 + /* Cooler status report offsets */ 25 + #define RYUJIN_TEMP_SENSOR_1 3 26 + #define RYUJIN_TEMP_SENSOR_2 4 27 + #define RYUJIN_PUMP_SPEED 5 28 + #define RYUJIN_INTERNAL_FAN_SPEED 7 29 + 30 + /* Cooler duty report offsets */ 31 + #define RYUJIN_PUMP_DUTY 4 32 + #define RYUJIN_INTERNAL_FAN_DUTY 5 33 + 34 + /* Controller status (speeds) report offsets */ 35 + #define RYUJIN_CONTROLLER_SPEED_1 5 36 + #define RYUJIN_CONTROLLER_SPEED_2 7 37 + #define RYUJIN_CONTROLLER_SPEED_3 9 38 + #define RYUJIN_CONTROLLER_SPEED_4 3 39 + 40 + /* Controller duty report offsets */ 41 + #define RYUJIN_CONTROLLER_DUTY 4 42 + 43 + /* Control commands and their inner offsets */ 44 + #define RYUJIN_CMD_PREFIX 0xEC 45 + 46 + static const u8 get_cooler_status_cmd[] = { RYUJIN_CMD_PREFIX, 0x99 }; 47 + static const u8 get_cooler_duty_cmd[] = { RYUJIN_CMD_PREFIX, 0x9A }; 48 + static const u8 get_controller_speed_cmd[] = { RYUJIN_CMD_PREFIX, 0xA0 }; 49 + static const u8 get_controller_duty_cmd[] = { RYUJIN_CMD_PREFIX, 0xA1 }; 50 + 51 + #define RYUJIN_SET_COOLER_PUMP_DUTY_OFFSET 3 52 + #define RYUJIN_SET_COOLER_FAN_DUTY_OFFSET 4 53 + static const u8 set_cooler_duty_cmd[] = { RYUJIN_CMD_PREFIX, 0x1A, 0x00, 0x00, 0x00 }; 54 + 55 + #define RYUJIN_SET_CONTROLLER_FAN_DUTY_OFFSET 4 56 + static const u8 set_controller_duty_cmd[] = { RYUJIN_CMD_PREFIX, 0x21, 0x00, 0x00, 0x00 }; 57 + 58 + /* Command lengths */ 59 + #define GET_CMD_LENGTH 2 /* Same length for all get commands */ 60 + #define SET_CMD_LENGTH 5 /* Same length for all set commands */ 61 + 62 + /* Command response headers */ 63 + #define RYUJIN_GET_COOLER_STATUS_CMD_RESPONSE 0x19 64 + #define RYUJIN_GET_COOLER_DUTY_CMD_RESPONSE 0x1A 65 + #define RYUJIN_GET_CONTROLLER_SPEED_CMD_RESPONSE 0x20 66 + #define RYUJIN_GET_CONTROLLER_DUTY_CMD_RESPONSE 0x21 67 + 68 + static const char *const rog_ryujin_temp_label[] = { 69 + "Coolant temp" 70 + }; 71 + 72 + static const char *const rog_ryujin_speed_label[] = { 73 + "Pump speed", 74 + "Internal fan speed", 75 + "Controller fan 1 speed", 76 + "Controller fan 2 speed", 77 + "Controller fan 3 speed", 78 + "Controller fan 4 speed", 79 + }; 80 + 81 + struct rog_ryujin_data { 82 + struct hid_device *hdev; 83 + struct device *hwmon_dev; 84 + /* For locking access to buffer */ 85 + struct mutex buffer_lock; 86 + /* For queueing multiple readers */ 87 + struct mutex status_report_request_mutex; 88 + /* For reinitializing the completions below */ 89 + spinlock_t status_report_request_lock; 90 + struct completion cooler_status_received; 91 + struct completion controller_status_received; 92 + struct completion cooler_duty_received; 93 + struct completion controller_duty_received; 94 + struct completion cooler_duty_set; 95 + struct completion controller_duty_set; 96 + 97 + /* Sensor data */ 98 + s32 temp_input[1]; 99 + u16 speed_input[6]; /* Pump, internal fan and four controller fan speeds in RPM */ 100 + u8 duty_input[3]; /* Pump, internal fan and controller fan duty in PWM */ 101 + 102 + u8 *buffer; 103 + unsigned long updated; /* jiffies */ 104 + }; 105 + 106 + static int rog_ryujin_percent_to_pwm(u16 val) 107 + { 108 + return DIV_ROUND_CLOSEST(val * 255, 100); 109 + } 110 + 111 + static int rog_ryujin_pwm_to_percent(long val) 112 + { 113 + return DIV_ROUND_CLOSEST(val * 100, 255); 114 + } 115 + 116 + static umode_t rog_ryujin_is_visible(const void *data, 117 + enum hwmon_sensor_types type, u32 attr, int channel) 118 + { 119 + switch (type) { 120 + case hwmon_temp: 121 + switch (attr) { 122 + case hwmon_temp_label: 123 + case hwmon_temp_input: 124 + return 0444; 125 + default: 126 + break; 127 + } 128 + break; 129 + case hwmon_fan: 130 + switch (attr) { 131 + case hwmon_fan_label: 132 + case hwmon_fan_input: 133 + return 0444; 134 + default: 135 + break; 136 + } 137 + break; 138 + case hwmon_pwm: 139 + switch (attr) { 140 + case hwmon_pwm_input: 141 + return 0644; 142 + default: 143 + break; 144 + } 145 + break; 146 + default: 147 + break; 148 + } 149 + 150 + return 0; 151 + } 152 + 153 + /* Writes the command to the device with the rest of the report filled with zeroes */ 154 + static int rog_ryujin_write_expanded(struct rog_ryujin_data *priv, const u8 *cmd, int cmd_length) 155 + { 156 + int ret; 157 + 158 + mutex_lock(&priv->buffer_lock); 159 + 160 + memcpy_and_pad(priv->buffer, MAX_REPORT_LENGTH, cmd, cmd_length, 0x00); 161 + ret = hid_hw_output_report(priv->hdev, priv->buffer, MAX_REPORT_LENGTH); 162 + 163 + mutex_unlock(&priv->buffer_lock); 164 + return ret; 165 + } 166 + 167 + /* Assumes priv->status_report_request_mutex is locked */ 168 + static int rog_ryujin_execute_cmd(struct rog_ryujin_data *priv, const u8 *cmd, int cmd_length, 169 + struct completion *status_completion) 170 + { 171 + int ret; 172 + 173 + /* 174 + * Disable raw event parsing for a moment to safely reinitialize the 175 + * completion. Reinit is done because hidraw could have triggered 176 + * the raw event parsing and marked the passed in completion as done. 177 + */ 178 + spin_lock_bh(&priv->status_report_request_lock); 179 + reinit_completion(status_completion); 180 + spin_unlock_bh(&priv->status_report_request_lock); 181 + 182 + /* Send command for getting data */ 183 + ret = rog_ryujin_write_expanded(priv, cmd, cmd_length); 184 + if (ret < 0) 185 + return ret; 186 + 187 + ret = wait_for_completion_interruptible_timeout(status_completion, 188 + msecs_to_jiffies(STATUS_VALIDITY)); 189 + if (ret == 0) 190 + return -ETIMEDOUT; 191 + else if (ret < 0) 192 + return ret; 193 + 194 + return 0; 195 + } 196 + 197 + static int rog_ryujin_get_status(struct rog_ryujin_data *priv) 198 + { 199 + int ret = mutex_lock_interruptible(&priv->status_report_request_mutex); 200 + 201 + if (ret < 0) 202 + return ret; 203 + 204 + if (!time_after(jiffies, priv->updated + msecs_to_jiffies(STATUS_VALIDITY))) { 205 + /* Data is up to date */ 206 + goto unlock_and_return; 207 + } 208 + 209 + /* Retrieve cooler status */ 210 + ret = 211 + rog_ryujin_execute_cmd(priv, get_cooler_status_cmd, GET_CMD_LENGTH, 212 + &priv->cooler_status_received); 213 + if (ret < 0) 214 + goto unlock_and_return; 215 + 216 + /* Retrieve controller status (speeds) */ 217 + ret = 218 + rog_ryujin_execute_cmd(priv, get_controller_speed_cmd, GET_CMD_LENGTH, 219 + &priv->controller_status_received); 220 + if (ret < 0) 221 + goto unlock_and_return; 222 + 223 + /* Retrieve cooler duty */ 224 + ret = 225 + rog_ryujin_execute_cmd(priv, get_cooler_duty_cmd, GET_CMD_LENGTH, 226 + &priv->cooler_duty_received); 227 + if (ret < 0) 228 + goto unlock_and_return; 229 + 230 + /* Retrieve controller duty */ 231 + ret = 232 + rog_ryujin_execute_cmd(priv, get_controller_duty_cmd, GET_CMD_LENGTH, 233 + &priv->controller_duty_received); 234 + if (ret < 0) 235 + goto unlock_and_return; 236 + 237 + priv->updated = jiffies; 238 + 239 + unlock_and_return: 240 + mutex_unlock(&priv->status_report_request_mutex); 241 + if (ret < 0) 242 + return ret; 243 + 244 + return 0; 245 + } 246 + 247 + static int rog_ryujin_read(struct device *dev, enum hwmon_sensor_types type, 248 + u32 attr, int channel, long *val) 249 + { 250 + struct rog_ryujin_data *priv = dev_get_drvdata(dev); 251 + int ret = rog_ryujin_get_status(priv); 252 + 253 + if (ret < 0) 254 + return ret; 255 + 256 + switch (type) { 257 + case hwmon_temp: 258 + *val = priv->temp_input[channel]; 259 + break; 260 + case hwmon_fan: 261 + *val = priv->speed_input[channel]; 262 + break; 263 + case hwmon_pwm: 264 + switch (attr) { 265 + case hwmon_pwm_input: 266 + *val = priv->duty_input[channel]; 267 + break; 268 + default: 269 + return -EOPNOTSUPP; 270 + } 271 + break; 272 + default: 273 + return -EOPNOTSUPP; /* unreachable */ 274 + } 275 + 276 + return 0; 277 + } 278 + 279 + static int rog_ryujin_read_string(struct device *dev, enum hwmon_sensor_types type, 280 + u32 attr, int channel, const char **str) 281 + { 282 + switch (type) { 283 + case hwmon_temp: 284 + *str = rog_ryujin_temp_label[channel]; 285 + break; 286 + case hwmon_fan: 287 + *str = rog_ryujin_speed_label[channel]; 288 + break; 289 + default: 290 + return -EOPNOTSUPP; /* unreachable */ 291 + } 292 + 293 + return 0; 294 + } 295 + 296 + static int rog_ryujin_write_fixed_duty(struct rog_ryujin_data *priv, int channel, int val) 297 + { 298 + u8 set_cmd[SET_CMD_LENGTH]; 299 + int ret; 300 + 301 + if (channel < 2) { 302 + /* 303 + * Retrieve cooler duty since both pump and internal fan are set 304 + * together, then write back with one of them modified. 305 + */ 306 + ret = mutex_lock_interruptible(&priv->status_report_request_mutex); 307 + if (ret < 0) 308 + return ret; 309 + ret = 310 + rog_ryujin_execute_cmd(priv, get_cooler_duty_cmd, GET_CMD_LENGTH, 311 + &priv->cooler_duty_received); 312 + if (ret < 0) 313 + goto unlock_and_return; 314 + 315 + memcpy(set_cmd, set_cooler_duty_cmd, SET_CMD_LENGTH); 316 + 317 + /* Cooler duties are set as 0-100% */ 318 + val = rog_ryujin_pwm_to_percent(val); 319 + 320 + if (channel == 0) { 321 + /* Cooler pump duty */ 322 + set_cmd[RYUJIN_SET_COOLER_PUMP_DUTY_OFFSET] = val; 323 + set_cmd[RYUJIN_SET_COOLER_FAN_DUTY_OFFSET] = 324 + rog_ryujin_pwm_to_percent(priv->duty_input[1]); 325 + } else if (channel == 1) { 326 + /* Cooler internal fan duty */ 327 + set_cmd[RYUJIN_SET_COOLER_PUMP_DUTY_OFFSET] = 328 + rog_ryujin_pwm_to_percent(priv->duty_input[0]); 329 + set_cmd[RYUJIN_SET_COOLER_FAN_DUTY_OFFSET] = val; 330 + } 331 + 332 + ret = rog_ryujin_execute_cmd(priv, set_cmd, SET_CMD_LENGTH, &priv->cooler_duty_set); 333 + unlock_and_return: 334 + mutex_unlock(&priv->status_report_request_mutex); 335 + if (ret < 0) 336 + return ret; 337 + } else { 338 + /* 339 + * Controller fan duty (channel == 2). No need to retrieve current 340 + * duty, so just send the command. 341 + */ 342 + memcpy(set_cmd, set_controller_duty_cmd, SET_CMD_LENGTH); 343 + set_cmd[RYUJIN_SET_CONTROLLER_FAN_DUTY_OFFSET] = val; 344 + 345 + ret = 346 + rog_ryujin_execute_cmd(priv, set_cmd, SET_CMD_LENGTH, 347 + &priv->controller_duty_set); 348 + if (ret < 0) 349 + return ret; 350 + } 351 + 352 + /* Lock onto this value until next refresh cycle */ 353 + priv->duty_input[channel] = val; 354 + 355 + return 0; 356 + } 357 + 358 + static int rog_ryujin_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, 359 + long val) 360 + { 361 + struct rog_ryujin_data *priv = dev_get_drvdata(dev); 362 + int ret; 363 + 364 + switch (type) { 365 + case hwmon_pwm: 366 + switch (attr) { 367 + case hwmon_pwm_input: 368 + if (val < 0 || val > 255) 369 + return -EINVAL; 370 + 371 + ret = rog_ryujin_write_fixed_duty(priv, channel, val); 372 + if (ret < 0) 373 + return ret; 374 + break; 375 + default: 376 + return -EOPNOTSUPP; 377 + } 378 + break; 379 + default: 380 + return -EOPNOTSUPP; 381 + } 382 + 383 + return 0; 384 + } 385 + 386 + static const struct hwmon_ops rog_ryujin_hwmon_ops = { 387 + .is_visible = rog_ryujin_is_visible, 388 + .read = rog_ryujin_read, 389 + .read_string = rog_ryujin_read_string, 390 + .write = rog_ryujin_write 391 + }; 392 + 393 + static const struct hwmon_channel_info *rog_ryujin_info[] = { 394 + HWMON_CHANNEL_INFO(temp, 395 + HWMON_T_INPUT | HWMON_T_LABEL), 396 + HWMON_CHANNEL_INFO(fan, 397 + HWMON_F_INPUT | HWMON_F_LABEL, 398 + HWMON_F_INPUT | HWMON_F_LABEL, 399 + HWMON_F_INPUT | HWMON_F_LABEL, 400 + HWMON_F_INPUT | HWMON_F_LABEL, 401 + HWMON_F_INPUT | HWMON_F_LABEL, 402 + HWMON_F_INPUT | HWMON_F_LABEL), 403 + HWMON_CHANNEL_INFO(pwm, 404 + HWMON_PWM_INPUT, 405 + HWMON_PWM_INPUT, 406 + HWMON_PWM_INPUT), 407 + NULL 408 + }; 409 + 410 + static const struct hwmon_chip_info rog_ryujin_chip_info = { 411 + .ops = &rog_ryujin_hwmon_ops, 412 + .info = rog_ryujin_info, 413 + }; 414 + 415 + static int rog_ryujin_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data, 416 + int size) 417 + { 418 + struct rog_ryujin_data *priv = hid_get_drvdata(hdev); 419 + 420 + if (data[0] != RYUJIN_CMD_PREFIX) 421 + return 0; 422 + 423 + if (data[1] == RYUJIN_GET_COOLER_STATUS_CMD_RESPONSE) { 424 + /* Received coolant temp and speeds of pump and internal fan */ 425 + priv->temp_input[0] = 426 + data[RYUJIN_TEMP_SENSOR_1] * 1000 + data[RYUJIN_TEMP_SENSOR_2] * 100; 427 + priv->speed_input[0] = get_unaligned_le16(data + RYUJIN_PUMP_SPEED); 428 + priv->speed_input[1] = get_unaligned_le16(data + RYUJIN_INTERNAL_FAN_SPEED); 429 + 430 + if (!completion_done(&priv->cooler_status_received)) 431 + complete_all(&priv->cooler_status_received); 432 + } else if (data[1] == RYUJIN_GET_CONTROLLER_SPEED_CMD_RESPONSE) { 433 + /* Received speeds of four fans attached to the controller */ 434 + priv->speed_input[2] = get_unaligned_le16(data + RYUJIN_CONTROLLER_SPEED_1); 435 + priv->speed_input[3] = get_unaligned_le16(data + RYUJIN_CONTROLLER_SPEED_2); 436 + priv->speed_input[4] = get_unaligned_le16(data + RYUJIN_CONTROLLER_SPEED_3); 437 + priv->speed_input[5] = get_unaligned_le16(data + RYUJIN_CONTROLLER_SPEED_4); 438 + 439 + if (!completion_done(&priv->controller_status_received)) 440 + complete_all(&priv->controller_status_received); 441 + } else if (data[1] == RYUJIN_GET_COOLER_DUTY_CMD_RESPONSE) { 442 + /* Received report for pump and internal fan duties (in %) */ 443 + if (data[RYUJIN_PUMP_DUTY] == 0 && data[RYUJIN_INTERNAL_FAN_DUTY] == 0) { 444 + /* 445 + * We received a report with zeroes for duty in both places. 446 + * The device returns this as a confirmation that setting values 447 + * is successful. If we initiated a write, mark it as complete. 448 + */ 449 + if (!completion_done(&priv->cooler_duty_set)) 450 + complete_all(&priv->cooler_duty_set); 451 + else if (!completion_done(&priv->cooler_duty_received)) 452 + /* 453 + * We didn't initiate a write, but received both zeroes. 454 + * This means that either both duties are actually zero, 455 + * or that we received a success report caused by userspace. 456 + * We're expecting a report, so parse it. 457 + */ 458 + goto read_cooler_duty; 459 + return 0; 460 + } 461 + read_cooler_duty: 462 + priv->duty_input[0] = rog_ryujin_percent_to_pwm(data[RYUJIN_PUMP_DUTY]); 463 + priv->duty_input[1] = rog_ryujin_percent_to_pwm(data[RYUJIN_INTERNAL_FAN_DUTY]); 464 + 465 + if (!completion_done(&priv->cooler_duty_received)) 466 + complete_all(&priv->cooler_duty_received); 467 + } else if (data[1] == RYUJIN_GET_CONTROLLER_DUTY_CMD_RESPONSE) { 468 + /* Received report for controller duty for fans (in PWM) */ 469 + if (data[RYUJIN_CONTROLLER_DUTY] == 0) { 470 + /* 471 + * We received a report with a zero for duty. The device returns this as 472 + * a confirmation that setting the controller duty value was successful. 473 + * If we initiated a write, mark it as complete. 474 + */ 475 + if (!completion_done(&priv->controller_duty_set)) 476 + complete_all(&priv->controller_duty_set); 477 + else if (!completion_done(&priv->controller_duty_received)) 478 + /* 479 + * We didn't initiate a write, but received a zero for duty. 480 + * This means that either the duty is actually zero, or that 481 + * we received a success report caused by userspace. 482 + * We're expecting a report, so parse it. 483 + */ 484 + goto read_controller_duty; 485 + return 0; 486 + } 487 + read_controller_duty: 488 + priv->duty_input[2] = data[RYUJIN_CONTROLLER_DUTY]; 489 + 490 + if (!completion_done(&priv->controller_duty_received)) 491 + complete_all(&priv->controller_duty_received); 492 + } 493 + 494 + return 0; 495 + } 496 + 497 + static int rog_ryujin_probe(struct hid_device *hdev, const struct hid_device_id *id) 498 + { 499 + struct rog_ryujin_data *priv; 500 + int ret; 501 + 502 + priv = devm_kzalloc(&hdev->dev, sizeof(*priv), GFP_KERNEL); 503 + if (!priv) 504 + return -ENOMEM; 505 + 506 + priv->hdev = hdev; 507 + hid_set_drvdata(hdev, priv); 508 + 509 + /* 510 + * Initialize priv->updated to STATUS_VALIDITY seconds in the past, making 511 + * the initial empty data invalid for rog_ryujin_read() without the need for 512 + * a special case there. 513 + */ 514 + priv->updated = jiffies - msecs_to_jiffies(STATUS_VALIDITY); 515 + 516 + ret = hid_parse(hdev); 517 + if (ret) { 518 + hid_err(hdev, "hid parse failed with %d\n", ret); 519 + return ret; 520 + } 521 + 522 + /* Enable hidraw so existing user-space tools can continue to work */ 523 + ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW); 524 + if (ret) { 525 + hid_err(hdev, "hid hw start failed with %d\n", ret); 526 + return ret; 527 + } 528 + 529 + ret = hid_hw_open(hdev); 530 + if (ret) { 531 + hid_err(hdev, "hid hw open failed with %d\n", ret); 532 + goto fail_and_stop; 533 + } 534 + 535 + priv->buffer = devm_kzalloc(&hdev->dev, MAX_REPORT_LENGTH, GFP_KERNEL); 536 + if (!priv->buffer) { 537 + ret = -ENOMEM; 538 + goto fail_and_close; 539 + } 540 + 541 + mutex_init(&priv->status_report_request_mutex); 542 + mutex_init(&priv->buffer_lock); 543 + spin_lock_init(&priv->status_report_request_lock); 544 + init_completion(&priv->cooler_status_received); 545 + init_completion(&priv->controller_status_received); 546 + init_completion(&priv->cooler_duty_received); 547 + init_completion(&priv->controller_duty_received); 548 + init_completion(&priv->cooler_duty_set); 549 + init_completion(&priv->controller_duty_set); 550 + 551 + priv->hwmon_dev = hwmon_device_register_with_info(&hdev->dev, "rog_ryujin", 552 + priv, &rog_ryujin_chip_info, NULL); 553 + if (IS_ERR(priv->hwmon_dev)) { 554 + ret = PTR_ERR(priv->hwmon_dev); 555 + hid_err(hdev, "hwmon registration failed with %d\n", ret); 556 + goto fail_and_close; 557 + } 558 + 559 + return 0; 560 + 561 + fail_and_close: 562 + hid_hw_close(hdev); 563 + fail_and_stop: 564 + hid_hw_stop(hdev); 565 + return ret; 566 + } 567 + 568 + static void rog_ryujin_remove(struct hid_device *hdev) 569 + { 570 + struct rog_ryujin_data *priv = hid_get_drvdata(hdev); 571 + 572 + hwmon_device_unregister(priv->hwmon_dev); 573 + 574 + hid_hw_close(hdev); 575 + hid_hw_stop(hdev); 576 + } 577 + 578 + static const struct hid_device_id rog_ryujin_table[] = { 579 + { HID_USB_DEVICE(USB_VENDOR_ID_ASUS_ROG, USB_PRODUCT_ID_RYUJIN_AIO) }, 580 + { } 581 + }; 582 + 583 + MODULE_DEVICE_TABLE(hid, rog_ryujin_table); 584 + 585 + static struct hid_driver rog_ryujin_driver = { 586 + .name = "rog_ryujin", 587 + .id_table = rog_ryujin_table, 588 + .probe = rog_ryujin_probe, 589 + .remove = rog_ryujin_remove, 590 + .raw_event = rog_ryujin_raw_event, 591 + }; 592 + 593 + static int __init rog_ryujin_init(void) 594 + { 595 + return hid_register_driver(&rog_ryujin_driver); 596 + } 597 + 598 + static void __exit rog_ryujin_exit(void) 599 + { 600 + hid_unregister_driver(&rog_ryujin_driver); 601 + } 602 + 603 + /* When compiled into the kernel, initialize after the HID bus */ 604 + late_initcall(rog_ryujin_init); 605 + module_exit(rog_ryujin_exit); 606 + 607 + MODULE_LICENSE("GPL"); 608 + MODULE_AUTHOR("Aleksa Savic <savicaleksa83@gmail.com>"); 609 + MODULE_DESCRIPTION("Hwmon driver for Asus ROG Ryujin II 360 AIO cooler");
+35 -38
drivers/hwmon/axi-fan-control.c
··· 13 13 #include <linux/io.h> 14 14 #include <linux/kernel.h> 15 15 #include <linux/module.h> 16 - #include <linux/of.h> 16 + #include <linux/mod_devicetable.h> 17 17 #include <linux/platform_device.h> 18 + #include <linux/property.h> 18 19 19 20 /* register map */ 20 21 #define ADI_REG_RSTN 0x0080 ··· 84 83 85 84 temp = DIV_ROUND_CLOSEST_ULL(temp * 509314ULL, 65535) - 280230; 86 85 87 - return sprintf(buf, "%u\n", temp); 86 + return sysfs_emit(buf, "%u\n", temp); 88 87 } 89 88 90 89 static ssize_t axi_fan_control_store(struct device *dev, struct device_attribute *da, ··· 369 368 } 370 369 371 370 static int axi_fan_control_init(struct axi_fan_control_data *ctl, 372 - const struct device_node *np) 371 + const struct device *dev) 373 372 { 374 373 int ret; 375 374 376 375 /* get fan pulses per revolution */ 377 - ret = of_property_read_u32(np, "pulses-per-revolution", &ctl->ppr); 376 + ret = device_property_read_u32(dev, "pulses-per-revolution", &ctl->ppr); 378 377 if (ret) 379 378 return ret; 380 379 ··· 444 443 }; 445 444 ATTRIBUTE_GROUPS(axi_fan_control); 446 445 447 - static const u32 version_1_0_0 = ADI_AXI_PCORE_VER(1, 0, 'a'); 448 - 449 - static const struct of_device_id axi_fan_control_of_match[] = { 450 - { .compatible = "adi,axi-fan-control-1.00.a", 451 - .data = (void *)&version_1_0_0}, 452 - {}, 453 - }; 454 - MODULE_DEVICE_TABLE(of, axi_fan_control_of_match); 455 - 456 446 static int axi_fan_control_probe(struct platform_device *pdev) 457 447 { 458 448 struct axi_fan_control_data *ctl; 459 449 struct clk *clk; 460 - const struct of_device_id *id; 450 + const unsigned int *id; 461 451 const char *name = "axi_fan_control"; 462 452 u32 version; 463 453 int ret; 464 454 465 - id = of_match_node(axi_fan_control_of_match, pdev->dev.of_node); 455 + id = device_get_match_data(&pdev->dev); 466 456 if (!id) 467 457 return -EINVAL; 468 458 ··· 466 474 return PTR_ERR(ctl->base); 467 475 468 476 clk = devm_clk_get_enabled(&pdev->dev, NULL); 469 - if (IS_ERR(clk)) { 470 - dev_err(&pdev->dev, "clk_get failed with %ld\n", PTR_ERR(clk)); 471 - return PTR_ERR(clk); 472 - } 477 + if (IS_ERR(clk)) 478 + return dev_err_probe(&pdev->dev, PTR_ERR(clk), 479 + "clk_get failed\n"); 473 480 474 481 ctl->clk_rate = clk_get_rate(clk); 475 482 if (!ctl->clk_rate) ··· 476 485 477 486 version = axi_ioread(ADI_AXI_REG_VERSION, ctl); 478 487 if (ADI_AXI_PCORE_VER_MAJOR(version) != 479 - ADI_AXI_PCORE_VER_MAJOR((*(u32 *)id->data))) { 480 - dev_err(&pdev->dev, "Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n", 481 - ADI_AXI_PCORE_VER_MAJOR((*(u32 *)id->data)), 482 - ADI_AXI_PCORE_VER_MINOR((*(u32 *)id->data)), 483 - ADI_AXI_PCORE_VER_PATCH((*(u32 *)id->data)), 484 - ADI_AXI_PCORE_VER_MAJOR(version), 485 - ADI_AXI_PCORE_VER_MINOR(version), 486 - ADI_AXI_PCORE_VER_PATCH(version)); 487 - return -ENODEV; 488 - } 488 + ADI_AXI_PCORE_VER_MAJOR((*id))) 489 + return dev_err_probe(&pdev->dev, -ENODEV, 490 + "Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n", 491 + ADI_AXI_PCORE_VER_MAJOR(*id), 492 + ADI_AXI_PCORE_VER_MINOR(*id), 493 + ADI_AXI_PCORE_VER_PATCH(*id), 494 + ADI_AXI_PCORE_VER_MAJOR(version), 495 + ADI_AXI_PCORE_VER_MINOR(version), 496 + ADI_AXI_PCORE_VER_PATCH(version)); 489 497 490 - ret = axi_fan_control_init(ctl, pdev->dev.of_node); 491 - if (ret) { 492 - dev_err(&pdev->dev, "Failed to initialize device\n"); 493 - return ret; 494 - } 498 + ret = axi_fan_control_init(ctl, &pdev->dev); 499 + if (ret) 500 + return dev_err_probe(&pdev->dev, ret, 501 + "Failed to initialize device\n"); 495 502 496 503 ctl->hdev = devm_hwmon_device_register_with_info(&pdev->dev, 497 504 name, ··· 508 519 axi_fan_control_irq_handler, 509 520 IRQF_ONESHOT | IRQF_TRIGGER_HIGH, 510 521 pdev->driver_override, ctl); 511 - if (ret) { 512 - dev_err(&pdev->dev, "failed to request an irq, %d", ret); 513 - return ret; 514 - } 522 + if (ret) 523 + return dev_err_probe(&pdev->dev, ret, 524 + "failed to request an irq\n"); 515 525 516 526 return 0; 517 527 } 528 + 529 + static const u32 version_1_0_0 = ADI_AXI_PCORE_VER(1, 0, 'a'); 530 + 531 + static const struct of_device_id axi_fan_control_of_match[] = { 532 + { .compatible = "adi,axi-fan-control-1.00.a", 533 + .data = (void *)&version_1_0_0}, 534 + {}, 535 + }; 536 + MODULE_DEVICE_TABLE(of, axi_fan_control_of_match); 518 537 519 538 static struct platform_driver axi_fan_control_driver = { 520 539 .driver = {
+822
drivers/hwmon/chipcap2.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * cc2.c - Support for the Amphenol ChipCap 2 relative humidity, temperature sensor 4 + * 5 + * Part numbers supported: 6 + * CC2D23, CC2D23S, CC2D25, CC2D25S, CC2D33, CC2D33S, CC2D35, CC2D35S 7 + * 8 + * Author: Javier Carrasco <javier.carrasco.cruz@gmail.com> 9 + * 10 + * Datasheet and application notes: 11 + * https://www.amphenol-sensors.com/en/telaire/humidity/527-humidity-sensors/3095-chipcap-2 12 + */ 13 + 14 + #include <linux/bitfield.h> 15 + #include <linux/bits.h> 16 + #include <linux/completion.h> 17 + #include <linux/delay.h> 18 + #include <linux/hwmon.h> 19 + #include <linux/i2c.h> 20 + #include <linux/interrupt.h> 21 + #include <linux/irq.h> 22 + #include <linux/module.h> 23 + #include <linux/regulator/consumer.h> 24 + 25 + #define CC2_START_CM 0xA0 26 + #define CC2_START_NOM 0x80 27 + #define CC2_R_ALARM_H_ON 0x18 28 + #define CC2_R_ALARM_H_OFF 0x19 29 + #define CC2_R_ALARM_L_ON 0x1A 30 + #define CC2_R_ALARM_L_OFF 0x1B 31 + #define CC2_RW_OFFSET 0x40 32 + #define CC2_W_ALARM_H_ON (CC2_R_ALARM_H_ON + CC2_RW_OFFSET) 33 + #define CC2_W_ALARM_H_OFF (CC2_R_ALARM_H_OFF + CC2_RW_OFFSET) 34 + #define CC2_W_ALARM_L_ON (CC2_R_ALARM_L_ON + CC2_RW_OFFSET) 35 + #define CC2_W_ALARM_L_OFF (CC2_R_ALARM_L_OFF + CC2_RW_OFFSET) 36 + 37 + #define CC2_STATUS_FIELD GENMASK(7, 6) 38 + #define CC2_STATUS_VALID_DATA 0x00 39 + #define CC2_STATUS_STALE_DATA 0x01 40 + #define CC2_STATUS_CMD_MODE 0x02 41 + 42 + #define CC2_RESPONSE_FIELD GENMASK(1, 0) 43 + #define CC2_RESPONSE_BUSY 0x00 44 + #define CC2_RESPONSE_ACK 0x01 45 + #define CC2_RESPONSE_NACK 0x02 46 + 47 + #define CC2_ERR_CORR_EEPROM BIT(2) 48 + #define CC2_ERR_UNCORR_EEPROM BIT(3) 49 + #define CC2_ERR_RAM_PARITY BIT(4) 50 + #define CC2_ERR_CONFIG_LOAD BIT(5) 51 + 52 + #define CC2_EEPROM_SIZE 10 53 + #define CC2_EEPROM_DATA_LEN 3 54 + #define CC2_MEASUREMENT_DATA_LEN 4 55 + 56 + #define CC2_RH_DATA_FIELD GENMASK(13, 0) 57 + 58 + /* ensure clean off -> on transitions */ 59 + #define CC2_POWER_CYCLE_MS 80 60 + 61 + #define CC2_STARTUP_TO_DATA_MS 55 62 + #define CC2_RESP_START_CM_US 100 63 + #define CC2_RESP_EEPROM_R_US 100 64 + #define CC2_RESP_EEPROM_W_MS 12 65 + #define CC2_STARTUP_TIME_US 1250 66 + 67 + #define CC2_RH_MAX (100 * 1000U) 68 + 69 + #define CC2_CM_RETRIES 5 70 + 71 + struct cc2_rh_alarm_info { 72 + bool low_alarm; 73 + bool high_alarm; 74 + bool low_alarm_visible; 75 + bool high_alarm_visible; 76 + }; 77 + 78 + struct cc2_data { 79 + struct cc2_rh_alarm_info rh_alarm; 80 + struct completion complete; 81 + struct device *hwmon; 82 + struct i2c_client *client; 83 + struct mutex dev_access_lock; /* device access lock */ 84 + struct regulator *regulator; 85 + const char *name; 86 + int irq_ready; 87 + int irq_low; 88 + int irq_high; 89 + bool process_irqs; 90 + }; 91 + 92 + enum cc2_chan_addr { 93 + CC2_CHAN_TEMP = 0, 94 + CC2_CHAN_HUMIDITY, 95 + }; 96 + 97 + /* %RH as a per cent mille from a register value */ 98 + static long cc2_rh_convert(u16 data) 99 + { 100 + unsigned long tmp = (data & CC2_RH_DATA_FIELD) * CC2_RH_MAX; 101 + 102 + return tmp / ((1 << 14) - 1); 103 + } 104 + 105 + /* convert %RH to a register value */ 106 + static u16 cc2_rh_to_reg(long data) 107 + { 108 + return data * ((1 << 14) - 1) / CC2_RH_MAX; 109 + } 110 + 111 + /* temperature in milli degrees celsius from a register value */ 112 + static long cc2_temp_convert(u16 data) 113 + { 114 + unsigned long tmp = ((data >> 2) * 165 * 1000U) / ((1 << 14) - 1); 115 + 116 + return tmp - 40 * 1000U; 117 + } 118 + 119 + static int cc2_enable(struct cc2_data *data) 120 + { 121 + int ret; 122 + 123 + /* exclusive regulator, check in case a disable failed */ 124 + if (regulator_is_enabled(data->regulator)) 125 + return 0; 126 + 127 + /* clear any pending completion */ 128 + try_wait_for_completion(&data->complete); 129 + 130 + ret = regulator_enable(data->regulator); 131 + if (ret < 0) 132 + return ret; 133 + 134 + usleep_range(CC2_STARTUP_TIME_US, CC2_STARTUP_TIME_US + 125); 135 + 136 + data->process_irqs = true; 137 + 138 + return 0; 139 + } 140 + 141 + static void cc2_disable(struct cc2_data *data) 142 + { 143 + int err; 144 + 145 + /* ignore alarms triggered by voltage toggling when powering up */ 146 + data->process_irqs = false; 147 + 148 + /* exclusive regulator, check in case an enable failed */ 149 + if (regulator_is_enabled(data->regulator)) { 150 + err = regulator_disable(data->regulator); 151 + if (err) 152 + dev_dbg(&data->client->dev, "Failed to disable device"); 153 + } 154 + } 155 + 156 + static int cc2_cmd_response_diagnostic(struct device *dev, u8 status) 157 + { 158 + int resp; 159 + 160 + if (FIELD_GET(CC2_STATUS_FIELD, status) != CC2_STATUS_CMD_MODE) { 161 + dev_dbg(dev, "Command sent out of command window\n"); 162 + return -ETIMEDOUT; 163 + } 164 + 165 + resp = FIELD_GET(CC2_RESPONSE_FIELD, status); 166 + switch (resp) { 167 + case CC2_RESPONSE_ACK: 168 + return 0; 169 + case CC2_RESPONSE_BUSY: 170 + return -EBUSY; 171 + case CC2_RESPONSE_NACK: 172 + if (resp & CC2_ERR_CORR_EEPROM) 173 + dev_dbg(dev, "Command failed: corrected EEPROM\n"); 174 + if (resp & CC2_ERR_UNCORR_EEPROM) 175 + dev_dbg(dev, "Command failed: uncorrected EEPROM\n"); 176 + if (resp & CC2_ERR_RAM_PARITY) 177 + dev_dbg(dev, "Command failed: RAM parity\n"); 178 + if (resp & CC2_ERR_RAM_PARITY) 179 + dev_dbg(dev, "Command failed: configuration error\n"); 180 + return -ENODATA; 181 + default: 182 + dev_dbg(dev, "Unknown command reply\n"); 183 + return -EINVAL; 184 + } 185 + } 186 + 187 + static int cc2_read_command_status(struct i2c_client *client) 188 + { 189 + u8 status; 190 + int ret; 191 + 192 + ret = i2c_master_recv(client, &status, 1); 193 + if (ret != 1) { 194 + ret = ret < 0 ? ret : -EIO; 195 + return ret; 196 + } 197 + 198 + return cc2_cmd_response_diagnostic(&client->dev, status); 199 + } 200 + 201 + /* 202 + * The command mode is only accessible after sending the START_CM command in the 203 + * first 10 ms after power-up. Only in case the command window is missed, 204 + * CC2_CM_RETRIES retries are attempted before giving up and returning an error. 205 + */ 206 + static int cc2_command_mode_start(struct cc2_data *data) 207 + { 208 + unsigned long timeout; 209 + int i, ret; 210 + 211 + for (i = 0; i < CC2_CM_RETRIES; i++) { 212 + ret = cc2_enable(data); 213 + if (ret < 0) 214 + return ret; 215 + 216 + ret = i2c_smbus_write_word_data(data->client, CC2_START_CM, 0); 217 + if (ret < 0) 218 + return ret; 219 + 220 + if (data->irq_ready > 0) { 221 + timeout = usecs_to_jiffies(2 * CC2_RESP_START_CM_US); 222 + ret = wait_for_completion_timeout(&data->complete, 223 + timeout); 224 + if (!ret) 225 + return -ETIMEDOUT; 226 + } else { 227 + usleep_range(CC2_RESP_START_CM_US, 228 + 2 * CC2_RESP_START_CM_US); 229 + } 230 + ret = cc2_read_command_status(data->client); 231 + if (ret != -ETIMEDOUT || i == CC2_CM_RETRIES) 232 + break; 233 + 234 + /* command window missed, prepare for a retry */ 235 + cc2_disable(data); 236 + msleep(CC2_POWER_CYCLE_MS); 237 + } 238 + 239 + return ret; 240 + } 241 + 242 + /* Sending a Start_NOM command finishes the command mode immediately with no 243 + * reply and the device enters normal operation mode 244 + */ 245 + static int cc2_command_mode_finish(struct cc2_data *data) 246 + { 247 + int ret; 248 + 249 + ret = i2c_smbus_write_word_data(data->client, CC2_START_NOM, 0); 250 + if (ret < 0) 251 + return ret; 252 + 253 + return 0; 254 + } 255 + 256 + static int cc2_write_reg(struct cc2_data *data, u8 reg, u16 val) 257 + { 258 + unsigned long timeout; 259 + int ret; 260 + 261 + ret = cc2_command_mode_start(data); 262 + if (ret < 0) 263 + goto disable; 264 + 265 + cpu_to_be16s(&val); 266 + ret = i2c_smbus_write_word_data(data->client, reg, val); 267 + if (ret < 0) 268 + goto disable; 269 + 270 + if (data->irq_ready > 0) { 271 + timeout = msecs_to_jiffies(2 * CC2_RESP_EEPROM_W_MS); 272 + ret = wait_for_completion_timeout(&data->complete, timeout); 273 + if (!ret) { 274 + ret = -ETIMEDOUT; 275 + goto disable; 276 + } 277 + } else { 278 + msleep(CC2_RESP_EEPROM_W_MS); 279 + } 280 + 281 + ret = cc2_read_command_status(data->client); 282 + 283 + disable: 284 + cc2_disable(data); 285 + 286 + return ret; 287 + } 288 + 289 + static int cc2_read_reg(struct cc2_data *data, u8 reg, u16 *val) 290 + { 291 + u8 buf[CC2_EEPROM_DATA_LEN]; 292 + unsigned long timeout; 293 + int ret; 294 + 295 + ret = cc2_command_mode_start(data); 296 + if (ret < 0) 297 + return ret; 298 + 299 + ret = i2c_smbus_write_word_data(data->client, reg, 0); 300 + if (ret < 0) 301 + return ret; 302 + 303 + if (data->irq_ready > 0) { 304 + timeout = usecs_to_jiffies(2 * CC2_RESP_EEPROM_R_US); 305 + ret = wait_for_completion_timeout(&data->complete, timeout); 306 + if (!ret) 307 + return -ETIMEDOUT; 308 + 309 + } else { 310 + usleep_range(CC2_RESP_EEPROM_R_US, CC2_RESP_EEPROM_R_US + 10); 311 + } 312 + ret = i2c_master_recv(data->client, buf, CC2_EEPROM_DATA_LEN); 313 + if (ret != CC2_EEPROM_DATA_LEN) 314 + return ret < 0 ? ret : -EIO; 315 + 316 + *val = be16_to_cpup((__be16 *)&buf[1]); 317 + 318 + return cc2_read_command_status(data->client); 319 + } 320 + 321 + static int cc2_get_reg_val(struct cc2_data *data, u8 reg, long *val) 322 + { 323 + u16 reg_val; 324 + int ret; 325 + 326 + ret = cc2_read_reg(data, reg, &reg_val); 327 + if (!ret) 328 + *val = cc2_rh_convert(reg_val); 329 + 330 + cc2_disable(data); 331 + 332 + return ret; 333 + } 334 + 335 + static int cc2_data_fetch(struct i2c_client *client, 336 + enum hwmon_sensor_types type, long *val) 337 + { 338 + u8 data[CC2_MEASUREMENT_DATA_LEN]; 339 + u8 status; 340 + int ret; 341 + 342 + ret = i2c_master_recv(client, data, CC2_MEASUREMENT_DATA_LEN); 343 + if (ret != CC2_MEASUREMENT_DATA_LEN) { 344 + ret = ret < 0 ? ret : -EIO; 345 + return ret; 346 + } 347 + status = FIELD_GET(CC2_STATUS_FIELD, data[0]); 348 + if (status == CC2_STATUS_STALE_DATA) 349 + return -EBUSY; 350 + 351 + if (status != CC2_STATUS_VALID_DATA) 352 + return -EIO; 353 + 354 + switch (type) { 355 + case hwmon_humidity: 356 + *val = cc2_rh_convert(be16_to_cpup((__be16 *)&data[0])); 357 + break; 358 + case hwmon_temp: 359 + *val = cc2_temp_convert(be16_to_cpup((__be16 *)&data[2])); 360 + break; 361 + default: 362 + return -EINVAL; 363 + } 364 + 365 + return 0; 366 + } 367 + 368 + static int cc2_read_measurement(struct cc2_data *data, 369 + enum hwmon_sensor_types type, long *val) 370 + { 371 + unsigned long timeout; 372 + int ret; 373 + 374 + if (data->irq_ready > 0) { 375 + timeout = msecs_to_jiffies(CC2_STARTUP_TO_DATA_MS * 2); 376 + ret = wait_for_completion_timeout(&data->complete, timeout); 377 + if (!ret) 378 + return -ETIMEDOUT; 379 + 380 + } else { 381 + msleep(CC2_STARTUP_TO_DATA_MS); 382 + } 383 + 384 + ret = cc2_data_fetch(data->client, type, val); 385 + 386 + return ret; 387 + } 388 + 389 + /* 390 + * A measurement requires enabling the device, waiting for the automatic 391 + * measurement to finish, reading the measurement data and disabling the device 392 + * again. 393 + */ 394 + static int cc2_measurement(struct cc2_data *data, enum hwmon_sensor_types type, 395 + long *val) 396 + { 397 + int ret; 398 + 399 + ret = cc2_enable(data); 400 + if (ret) 401 + return ret; 402 + 403 + ret = cc2_read_measurement(data, type, val); 404 + 405 + cc2_disable(data); 406 + 407 + return ret; 408 + } 409 + 410 + /* 411 + * In order to check alarm status, the corresponding ALARM_OFF (hysteresis) 412 + * register must be read and a new measurement must be carried out to trigger 413 + * the alarm signals. Given that the device carries out a measurement after 414 + * exiting the command mode, there is no need to force two power-up sequences. 415 + * Instead, a NOM command is sent and the device is disabled after the 416 + * measurement is read. 417 + */ 418 + static int cc2_read_hyst_and_measure(struct cc2_data *data, u8 reg, 419 + long *hyst, long *measurement) 420 + { 421 + u16 reg_val; 422 + int ret; 423 + 424 + ret = cc2_read_reg(data, reg, &reg_val); 425 + if (ret) 426 + goto disable; 427 + 428 + *hyst = cc2_rh_convert(reg_val); 429 + 430 + ret = cc2_command_mode_finish(data); 431 + if (ret) 432 + goto disable; 433 + 434 + ret = cc2_read_measurement(data, hwmon_humidity, measurement); 435 + 436 + disable: 437 + cc2_disable(data); 438 + 439 + return ret; 440 + } 441 + 442 + static umode_t cc2_is_visible(const void *data, enum hwmon_sensor_types type, 443 + u32 attr, int channel) 444 + { 445 + const struct cc2_data *cc2 = data; 446 + 447 + switch (type) { 448 + case hwmon_humidity: 449 + switch (attr) { 450 + case hwmon_humidity_input: 451 + return 0444; 452 + case hwmon_humidity_min_alarm: 453 + return cc2->rh_alarm.low_alarm_visible ? 0444 : 0; 454 + case hwmon_humidity_max_alarm: 455 + return cc2->rh_alarm.high_alarm_visible ? 0444 : 0; 456 + case hwmon_humidity_min: 457 + case hwmon_humidity_min_hyst: 458 + return cc2->rh_alarm.low_alarm_visible ? 0644 : 0; 459 + case hwmon_humidity_max: 460 + case hwmon_humidity_max_hyst: 461 + return cc2->rh_alarm.high_alarm_visible ? 0644 : 0; 462 + default: 463 + return 0; 464 + } 465 + case hwmon_temp: 466 + switch (attr) { 467 + case hwmon_temp_input: 468 + return 0444; 469 + default: 470 + return 0; 471 + } 472 + default: 473 + break; 474 + } 475 + 476 + return 0; 477 + } 478 + 479 + static irqreturn_t cc2_ready_interrupt(int irq, void *data) 480 + { 481 + struct cc2_data *cc2 = data; 482 + 483 + if (cc2->process_irqs) 484 + complete(&cc2->complete); 485 + 486 + return IRQ_HANDLED; 487 + } 488 + 489 + static irqreturn_t cc2_low_interrupt(int irq, void *data) 490 + { 491 + struct cc2_data *cc2 = data; 492 + 493 + if (cc2->process_irqs) { 494 + hwmon_notify_event(cc2->hwmon, hwmon_humidity, 495 + hwmon_humidity_min_alarm, CC2_CHAN_HUMIDITY); 496 + cc2->rh_alarm.low_alarm = true; 497 + } 498 + 499 + return IRQ_HANDLED; 500 + } 501 + 502 + static irqreturn_t cc2_high_interrupt(int irq, void *data) 503 + { 504 + struct cc2_data *cc2 = data; 505 + 506 + if (cc2->process_irqs) { 507 + hwmon_notify_event(cc2->hwmon, hwmon_humidity, 508 + hwmon_humidity_max_alarm, CC2_CHAN_HUMIDITY); 509 + cc2->rh_alarm.high_alarm = true; 510 + } 511 + 512 + return IRQ_HANDLED; 513 + } 514 + 515 + static int cc2_humidity_min_alarm_status(struct cc2_data *data, long *val) 516 + { 517 + long measurement, min_hyst; 518 + int ret; 519 + 520 + ret = cc2_read_hyst_and_measure(data, CC2_R_ALARM_L_OFF, &min_hyst, 521 + &measurement); 522 + if (ret < 0) 523 + return ret; 524 + 525 + if (data->rh_alarm.low_alarm) { 526 + *val = (measurement < min_hyst) ? 1 : 0; 527 + data->rh_alarm.low_alarm = *val; 528 + } else { 529 + *val = 0; 530 + } 531 + 532 + return 0; 533 + } 534 + 535 + static int cc2_humidity_max_alarm_status(struct cc2_data *data, long *val) 536 + { 537 + long measurement, max_hyst; 538 + int ret; 539 + 540 + ret = cc2_read_hyst_and_measure(data, CC2_R_ALARM_H_OFF, &max_hyst, 541 + &measurement); 542 + if (ret < 0) 543 + return ret; 544 + 545 + if (data->rh_alarm.high_alarm) { 546 + *val = (measurement > max_hyst) ? 1 : 0; 547 + data->rh_alarm.high_alarm = *val; 548 + } else { 549 + *val = 0; 550 + } 551 + 552 + return 0; 553 + } 554 + 555 + static int cc2_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, 556 + int channel, long *val) 557 + { 558 + struct cc2_data *data = dev_get_drvdata(dev); 559 + int ret = 0; 560 + 561 + mutex_lock(&data->dev_access_lock); 562 + 563 + switch (type) { 564 + case hwmon_temp: 565 + ret = cc2_measurement(data, type, val); 566 + break; 567 + case hwmon_humidity: 568 + switch (attr) { 569 + case hwmon_humidity_input: 570 + ret = cc2_measurement(data, type, val); 571 + break; 572 + case hwmon_humidity_min: 573 + ret = cc2_get_reg_val(data, CC2_R_ALARM_L_ON, val); 574 + break; 575 + case hwmon_humidity_min_hyst: 576 + ret = cc2_get_reg_val(data, CC2_R_ALARM_L_OFF, val); 577 + break; 578 + case hwmon_humidity_max: 579 + ret = cc2_get_reg_val(data, CC2_R_ALARM_H_ON, val); 580 + break; 581 + case hwmon_humidity_max_hyst: 582 + ret = cc2_get_reg_val(data, CC2_R_ALARM_H_OFF, val); 583 + break; 584 + case hwmon_humidity_min_alarm: 585 + ret = cc2_humidity_min_alarm_status(data, val); 586 + break; 587 + case hwmon_humidity_max_alarm: 588 + ret = cc2_humidity_max_alarm_status(data, val); 589 + break; 590 + default: 591 + ret = -EOPNOTSUPP; 592 + } 593 + break; 594 + default: 595 + ret = -EOPNOTSUPP; 596 + } 597 + 598 + mutex_unlock(&data->dev_access_lock); 599 + 600 + return ret; 601 + } 602 + 603 + static int cc2_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, 604 + int channel, long val) 605 + { 606 + struct cc2_data *data = dev_get_drvdata(dev); 607 + int ret; 608 + u16 arg; 609 + u8 cmd; 610 + 611 + if (type != hwmon_humidity) 612 + return -EOPNOTSUPP; 613 + 614 + if (val < 0 || val > CC2_RH_MAX) 615 + return -EINVAL; 616 + 617 + mutex_lock(&data->dev_access_lock); 618 + 619 + switch (attr) { 620 + case hwmon_humidity_min: 621 + cmd = CC2_W_ALARM_L_ON; 622 + arg = cc2_rh_to_reg(val); 623 + ret = cc2_write_reg(data, cmd, arg); 624 + break; 625 + 626 + case hwmon_humidity_min_hyst: 627 + cmd = CC2_W_ALARM_L_OFF; 628 + arg = cc2_rh_to_reg(val); 629 + ret = cc2_write_reg(data, cmd, arg); 630 + break; 631 + 632 + case hwmon_humidity_max: 633 + cmd = CC2_W_ALARM_H_ON; 634 + arg = cc2_rh_to_reg(val); 635 + ret = cc2_write_reg(data, cmd, arg); 636 + break; 637 + 638 + case hwmon_humidity_max_hyst: 639 + cmd = CC2_W_ALARM_H_OFF; 640 + arg = cc2_rh_to_reg(val); 641 + ret = cc2_write_reg(data, cmd, arg); 642 + break; 643 + 644 + default: 645 + ret = -EOPNOTSUPP; 646 + break; 647 + } 648 + 649 + mutex_unlock(&data->dev_access_lock); 650 + 651 + return ret; 652 + } 653 + 654 + static int cc2_request_ready_irq(struct cc2_data *data, struct device *dev) 655 + { 656 + int ret = 0; 657 + 658 + data->irq_ready = fwnode_irq_get_byname(dev_fwnode(dev), "ready"); 659 + if (data->irq_ready > 0) { 660 + init_completion(&data->complete); 661 + ret = devm_request_threaded_irq(dev, data->irq_ready, NULL, 662 + cc2_ready_interrupt, 663 + IRQF_ONESHOT | 664 + IRQF_TRIGGER_RISING, 665 + dev_name(dev), data); 666 + } 667 + 668 + return ret; 669 + } 670 + 671 + static int cc2_request_alarm_irqs(struct cc2_data *data, struct device *dev) 672 + { 673 + int ret = 0; 674 + 675 + data->irq_low = fwnode_irq_get_byname(dev_fwnode(dev), "low"); 676 + if (data->irq_low > 0) { 677 + ret = devm_request_threaded_irq(dev, data->irq_low, NULL, 678 + cc2_low_interrupt, 679 + IRQF_ONESHOT | 680 + IRQF_TRIGGER_RISING, 681 + dev_name(dev), data); 682 + if (ret) 683 + return ret; 684 + 685 + data->rh_alarm.low_alarm_visible = true; 686 + } 687 + 688 + data->irq_high = fwnode_irq_get_byname(dev_fwnode(dev), "high"); 689 + if (data->irq_high > 0) { 690 + ret = devm_request_threaded_irq(dev, data->irq_high, NULL, 691 + cc2_high_interrupt, 692 + IRQF_ONESHOT | 693 + IRQF_TRIGGER_RISING, 694 + dev_name(dev), data); 695 + if (ret) 696 + return ret; 697 + 698 + data->rh_alarm.high_alarm_visible = true; 699 + } 700 + 701 + return ret; 702 + } 703 + 704 + static const struct hwmon_channel_info *cc2_info[] = { 705 + HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT), 706 + HWMON_CHANNEL_INFO(humidity, HWMON_H_INPUT | HWMON_H_MIN | HWMON_H_MAX | 707 + HWMON_H_MIN_HYST | HWMON_H_MAX_HYST | 708 + HWMON_H_MIN_ALARM | HWMON_H_MAX_ALARM), 709 + NULL 710 + }; 711 + 712 + static const struct hwmon_ops cc2_hwmon_ops = { 713 + .is_visible = cc2_is_visible, 714 + .read = cc2_read, 715 + .write = cc2_write, 716 + }; 717 + 718 + static const struct hwmon_chip_info cc2_chip_info = { 719 + .ops = &cc2_hwmon_ops, 720 + .info = cc2_info, 721 + }; 722 + 723 + static int cc2_probe(struct i2c_client *client) 724 + { 725 + struct cc2_data *data; 726 + struct device *dev = &client->dev; 727 + int ret; 728 + 729 + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 730 + return -EOPNOTSUPP; 731 + 732 + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 733 + if (!data) 734 + return -ENOMEM; 735 + 736 + i2c_set_clientdata(client, data); 737 + 738 + mutex_init(&data->dev_access_lock); 739 + 740 + data->client = client; 741 + 742 + data->regulator = devm_regulator_get_exclusive(dev, "vdd"); 743 + if (IS_ERR(data->regulator)) { 744 + dev_err_probe(dev, PTR_ERR(data->regulator), 745 + "Failed to get regulator\n"); 746 + return PTR_ERR(data->regulator); 747 + } 748 + 749 + ret = cc2_request_ready_irq(data, dev); 750 + if (ret) { 751 + dev_err_probe(dev, ret, "Failed to request ready irq\n"); 752 + return ret; 753 + } 754 + 755 + ret = cc2_request_alarm_irqs(data, dev); 756 + if (ret) { 757 + dev_err_probe(dev, ret, "Failed to request alarm irqs\n"); 758 + goto disable; 759 + } 760 + 761 + data->hwmon = devm_hwmon_device_register_with_info(dev, client->name, 762 + data, &cc2_chip_info, 763 + NULL); 764 + if (IS_ERR(data->hwmon)) { 765 + dev_err_probe(dev, PTR_ERR(data->hwmon), 766 + "Failed to register hwmon device\n"); 767 + ret = PTR_ERR(data->hwmon); 768 + } 769 + 770 + disable: 771 + cc2_disable(data); 772 + 773 + return ret; 774 + } 775 + 776 + static void cc2_remove(struct i2c_client *client) 777 + { 778 + struct cc2_data *data = i2c_get_clientdata(client); 779 + 780 + cc2_disable(data); 781 + } 782 + 783 + static const struct i2c_device_id cc2_id[] = { 784 + { "cc2d23" }, 785 + { "cc2d23s" }, 786 + { "cc2d25" }, 787 + { "cc2d25s" }, 788 + { "cc2d33" }, 789 + { "cc2d33s" }, 790 + { "cc2d35" }, 791 + { "cc2d35s" }, 792 + { } 793 + }; 794 + MODULE_DEVICE_TABLE(i2c, cc2_id); 795 + 796 + static const struct of_device_id cc2_of_match[] = { 797 + { .compatible = "amphenol,cc2d23" }, 798 + { .compatible = "amphenol,cc2d23s" }, 799 + { .compatible = "amphenol,cc2d25" }, 800 + { .compatible = "amphenol,cc2d25s" }, 801 + { .compatible = "amphenol,cc2d33" }, 802 + { .compatible = "amphenol,cc2d33s" }, 803 + { .compatible = "amphenol,cc2d35" }, 804 + { .compatible = "amphenol,cc2d35s" }, 805 + { }, 806 + }; 807 + MODULE_DEVICE_TABLE(of, cc2_of_match); 808 + 809 + static struct i2c_driver cc2_driver = { 810 + .driver = { 811 + .name = "cc2d23", 812 + .of_match_table = cc2_of_match, 813 + }, 814 + .probe = cc2_probe, 815 + .remove = cc2_remove, 816 + .id_table = cc2_id, 817 + }; 818 + module_i2c_driver(cc2_driver); 819 + 820 + MODULE_AUTHOR("Javier Carrasco <javier.carrasco.cruz@gamil.com>"); 821 + MODULE_DESCRIPTION("Amphenol ChipCap 2 humidity and temperature sensor driver"); 822 + MODULE_LICENSE("GPL");
+110 -94
drivers/hwmon/coretemp.c
··· 39 39 module_param_named(tjmax, force_tjmax, int, 0444); 40 40 MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius"); 41 41 42 - #define PKG_SYSFS_ATTR_NO 1 /* Sysfs attribute for package temp */ 43 - #define BASE_SYSFS_ATTR_NO 2 /* Sysfs Base attr no for coretemp */ 44 42 #define NUM_REAL_CORES 512 /* Number of Real cores per cpu */ 45 43 #define CORETEMP_NAME_LENGTH 28 /* String Length of attrs */ 46 - #define MAX_CORE_ATTRS 4 /* Maximum no of basic attrs */ 47 - #define TOTAL_ATTRS (MAX_CORE_ATTRS + 1) 48 - #define MAX_CORE_DATA (NUM_REAL_CORES + BASE_SYSFS_ATTR_NO) 44 + 45 + enum coretemp_attr_index { 46 + ATTR_LABEL, 47 + ATTR_CRIT_ALARM, 48 + ATTR_TEMP, 49 + ATTR_TJMAX, 50 + ATTR_TTARGET, 51 + MAX_CORE_ATTRS = ATTR_TJMAX + 1, /* Maximum no of basic attrs */ 52 + TOTAL_ATTRS = ATTR_TTARGET + 1 /* Maximum no of possible attrs */ 53 + }; 49 54 50 55 #ifdef CONFIG_SMP 51 56 #define for_each_sibling(i, cpu) \ ··· 70 65 * @status_reg: One of IA32_THERM_STATUS or IA32_PACKAGE_THERM_STATUS, 71 66 * from where the temperature values should be read. 72 67 * @attr_size: Total number of pre-core attrs displayed in the sysfs. 73 - * @is_pkg_data: If this is 1, the temp_data holds pkgtemp data. 74 - * Otherwise, temp_data holds coretemp data. 75 68 */ 76 69 struct temp_data { 77 70 int temp; 78 71 int tjmax; 79 72 unsigned long last_updated; 80 73 unsigned int cpu; 74 + int index; 81 75 u32 cpu_core_id; 82 76 u32 status_reg; 83 77 int attr_size; 84 - bool is_pkg_data; 85 - struct sensor_device_attribute sd_attrs[TOTAL_ATTRS]; 78 + struct device_attribute sd_attrs[TOTAL_ATTRS]; 86 79 char attr_name[TOTAL_ATTRS][CORETEMP_NAME_LENGTH]; 87 80 struct attribute *attrs[TOTAL_ATTRS + 1]; 88 81 struct attribute_group attr_group; ··· 91 88 struct platform_data { 92 89 struct device *hwmon_dev; 93 90 u16 pkg_id; 94 - u16 cpu_map[NUM_REAL_CORES]; 91 + int nr_cores; 95 92 struct ida ida; 96 93 struct cpumask cpumask; 97 - struct temp_data *core_data[MAX_CORE_DATA]; 94 + struct temp_data *pkg_data; 95 + struct temp_data **core_data; 98 96 struct device_attribute name_attr; 99 97 }; 100 98 ··· 146 142 * PCI table 147 143 */ 148 144 }; 145 + 146 + static bool is_pkg_temp_data(struct temp_data *tdata) 147 + { 148 + return tdata->index < 0; 149 + } 149 150 150 151 static int adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) 151 152 { ··· 341 332 static ssize_t show_label(struct device *dev, 342 333 struct device_attribute *devattr, char *buf) 343 334 { 344 - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 345 335 struct platform_data *pdata = dev_get_drvdata(dev); 346 - struct temp_data *tdata = pdata->core_data[attr->index]; 336 + struct temp_data *tdata = container_of(devattr, struct temp_data, sd_attrs[ATTR_LABEL]); 347 337 348 - if (tdata->is_pkg_data) 338 + if (is_pkg_temp_data(tdata)) 349 339 return sprintf(buf, "Package id %u\n", pdata->pkg_id); 350 340 351 341 return sprintf(buf, "Core %u\n", tdata->cpu_core_id); ··· 354 346 struct device_attribute *devattr, char *buf) 355 347 { 356 348 u32 eax, edx; 357 - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 358 - struct platform_data *pdata = dev_get_drvdata(dev); 359 - struct temp_data *tdata = pdata->core_data[attr->index]; 349 + struct temp_data *tdata = container_of(devattr, struct temp_data, 350 + sd_attrs[ATTR_CRIT_ALARM]); 360 351 361 352 mutex_lock(&tdata->update_lock); 362 353 rdmsr_on_cpu(tdata->cpu, tdata->status_reg, &eax, &edx); ··· 367 360 static ssize_t show_tjmax(struct device *dev, 368 361 struct device_attribute *devattr, char *buf) 369 362 { 370 - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 371 - struct platform_data *pdata = dev_get_drvdata(dev); 372 - struct temp_data *tdata = pdata->core_data[attr->index]; 363 + struct temp_data *tdata = container_of(devattr, struct temp_data, sd_attrs[ATTR_TJMAX]); 373 364 int tjmax; 374 365 375 366 mutex_lock(&tdata->update_lock); ··· 380 375 static ssize_t show_ttarget(struct device *dev, 381 376 struct device_attribute *devattr, char *buf) 382 377 { 383 - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 384 - struct platform_data *pdata = dev_get_drvdata(dev); 385 - struct temp_data *tdata = pdata->core_data[attr->index]; 378 + struct temp_data *tdata = container_of(devattr, struct temp_data, sd_attrs[ATTR_TTARGET]); 386 379 int ttarget; 387 380 388 381 mutex_lock(&tdata->update_lock); ··· 396 393 struct device_attribute *devattr, char *buf) 397 394 { 398 395 u32 eax, edx; 399 - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 400 - struct platform_data *pdata = dev_get_drvdata(dev); 401 - struct temp_data *tdata = pdata->core_data[attr->index]; 396 + struct temp_data *tdata = container_of(devattr, struct temp_data, sd_attrs[ATTR_TEMP]); 402 397 int tjmax; 403 398 404 399 mutex_lock(&tdata->update_lock); ··· 419 418 return sprintf(buf, "%d\n", tdata->temp); 420 419 } 421 420 422 - static int create_core_attrs(struct temp_data *tdata, struct device *dev, 423 - int index) 421 + static int create_core_attrs(struct temp_data *tdata, struct device *dev) 424 422 { 425 423 int i; 426 424 static ssize_t (*const rd_ptr[TOTAL_ATTRS]) (struct device *dev, ··· 436 436 * The attr number is always core id + 2 437 437 * The Pkgtemp will always show up as temp1_*, if available 438 438 */ 439 - int attr_no = tdata->is_pkg_data ? 1 : tdata->cpu_core_id + 2; 439 + int attr_no = is_pkg_temp_data(tdata) ? 1 : tdata->cpu_core_id + 2; 440 440 441 441 snprintf(tdata->attr_name[i], CORETEMP_NAME_LENGTH, 442 442 "temp%d_%s", attr_no, suffixes[i]); 443 - sysfs_attr_init(&tdata->sd_attrs[i].dev_attr.attr); 444 - tdata->sd_attrs[i].dev_attr.attr.name = tdata->attr_name[i]; 445 - tdata->sd_attrs[i].dev_attr.attr.mode = 0444; 446 - tdata->sd_attrs[i].dev_attr.show = rd_ptr[i]; 447 - tdata->sd_attrs[i].index = index; 448 - tdata->attrs[i] = &tdata->sd_attrs[i].dev_attr.attr; 443 + sysfs_attr_init(&tdata->sd_attrs[i].attr); 444 + tdata->sd_attrs[i].attr.name = tdata->attr_name[i]; 445 + tdata->sd_attrs[i].attr.mode = 0444; 446 + tdata->sd_attrs[i].show = rd_ptr[i]; 447 + tdata->attrs[i] = &tdata->sd_attrs[i].attr; 449 448 } 450 449 tdata->attr_group.attrs = tdata->attrs; 451 450 return sysfs_create_group(&dev->kobj, &tdata->attr_group); ··· 476 477 return NULL; 477 478 } 478 479 479 - static struct temp_data *init_temp_data(unsigned int cpu, int pkg_flag) 480 + static struct temp_data * 481 + init_temp_data(struct platform_data *pdata, unsigned int cpu, int pkg_flag) 480 482 { 481 483 struct temp_data *tdata; 484 + 485 + if (!pdata->core_data) { 486 + /* 487 + * TODO: 488 + * The information of actual possible cores in a package is broken for now. 489 + * Will replace hardcoded NUM_REAL_CORES with actual per package core count 490 + * when this information becomes available. 491 + */ 492 + pdata->nr_cores = NUM_REAL_CORES; 493 + pdata->core_data = kcalloc(pdata->nr_cores, sizeof(struct temp_data *), 494 + GFP_KERNEL); 495 + if (!pdata->core_data) 496 + return NULL; 497 + } 482 498 483 499 tdata = kzalloc(sizeof(struct temp_data), GFP_KERNEL); 484 500 if (!tdata) 485 501 return NULL; 486 502 503 + if (pkg_flag) { 504 + pdata->pkg_data = tdata; 505 + /* Use tdata->index as indicator of package temp data */ 506 + tdata->index = -1; 507 + } else { 508 + tdata->index = ida_alloc_max(&pdata->ida, pdata->nr_cores - 1, GFP_KERNEL); 509 + if (tdata->index < 0) { 510 + kfree(tdata); 511 + return NULL; 512 + } 513 + pdata->core_data[tdata->index] = tdata; 514 + } 515 + 487 516 tdata->status_reg = pkg_flag ? MSR_IA32_PACKAGE_THERM_STATUS : 488 517 MSR_IA32_THERM_STATUS; 489 - tdata->is_pkg_data = pkg_flag; 490 518 tdata->cpu = cpu; 491 519 tdata->cpu_core_id = topology_core_id(cpu); 492 520 tdata->attr_size = MAX_CORE_ATTRS; 493 521 mutex_init(&tdata->update_lock); 494 522 return tdata; 523 + } 524 + 525 + static void destroy_temp_data(struct platform_data *pdata, struct temp_data *tdata) 526 + { 527 + if (is_pkg_temp_data(tdata)) { 528 + pdata->pkg_data = NULL; 529 + kfree(pdata->core_data); 530 + pdata->core_data = NULL; 531 + pdata->nr_cores = 0; 532 + } else { 533 + pdata->core_data[tdata->index] = NULL; 534 + ida_free(&pdata->ida, tdata->index); 535 + } 536 + kfree(tdata); 537 + } 538 + 539 + static struct temp_data *get_temp_data(struct platform_data *pdata, int cpu) 540 + { 541 + int i; 542 + 543 + /* cpu < 0 means get pkg temp_data */ 544 + if (cpu < 0) 545 + return pdata->pkg_data; 546 + 547 + for (i = 0; i < pdata->nr_cores; i++) { 548 + if (pdata->core_data[i] && 549 + pdata->core_data[i]->cpu_core_id == topology_core_id(cpu)) 550 + return pdata->core_data[i]; 551 + } 552 + return NULL; 495 553 } 496 554 497 555 static int create_core_data(struct platform_device *pdev, unsigned int cpu, ··· 558 502 struct platform_data *pdata = platform_get_drvdata(pdev); 559 503 struct cpuinfo_x86 *c = &cpu_data(cpu); 560 504 u32 eax, edx; 561 - int err, index; 505 + int err; 562 506 563 507 if (!housekeeping_cpu(cpu, HK_TYPE_MISC)) 564 508 return 0; 565 509 566 - /* 567 - * Get the index of tdata in pdata->core_data[] 568 - * tdata for package: pdata->core_data[1] 569 - * tdata for core: pdata->core_data[2] .. pdata->core_data[NUM_REAL_CORES + 1] 570 - */ 571 - if (pkg_flag) { 572 - index = PKG_SYSFS_ATTR_NO; 573 - } else { 574 - index = ida_alloc_max(&pdata->ida, NUM_REAL_CORES - 1, GFP_KERNEL); 575 - if (index < 0) 576 - return index; 577 - 578 - pdata->cpu_map[index] = topology_core_id(cpu); 579 - index += BASE_SYSFS_ATTR_NO; 580 - } 581 - 582 - tdata = init_temp_data(cpu, pkg_flag); 583 - if (!tdata) { 584 - err = -ENOMEM; 585 - goto ida_free; 586 - } 510 + tdata = init_temp_data(pdata, cpu, pkg_flag); 511 + if (!tdata) 512 + return -ENOMEM; 587 513 588 514 /* Test if we can access the status register */ 589 515 err = rdmsr_safe_on_cpu(cpu, tdata->status_reg, &eax, &edx); 590 516 if (err) 591 - goto exit_free; 517 + goto err; 592 518 593 519 /* Make sure tdata->tjmax is a valid indicator for dynamic/static tjmax */ 594 520 get_tjmax(tdata, &pdev->dev); ··· 584 546 if (get_ttarget(tdata, &pdev->dev) >= 0) 585 547 tdata->attr_size++; 586 548 587 - pdata->core_data[index] = tdata; 588 - 589 549 /* Create sysfs interfaces */ 590 - err = create_core_attrs(tdata, pdata->hwmon_dev, index); 550 + err = create_core_attrs(tdata, pdata->hwmon_dev); 591 551 if (err) 592 - goto exit_free; 552 + goto err; 593 553 594 554 return 0; 595 - exit_free: 596 - pdata->core_data[index] = NULL; 597 - kfree(tdata); 598 - ida_free: 599 - if (!pkg_flag) 600 - ida_free(&pdata->ida, index - BASE_SYSFS_ATTR_NO); 555 + 556 + err: 557 + destroy_temp_data(pdata, tdata); 601 558 return err; 602 559 } 603 560 ··· 603 570 dev_err(&pdev->dev, "Adding Core %u failed\n", cpu); 604 571 } 605 572 606 - static void coretemp_remove_core(struct platform_data *pdata, int indx) 573 + static void coretemp_remove_core(struct platform_data *pdata, struct temp_data *tdata) 607 574 { 608 - struct temp_data *tdata = pdata->core_data[indx]; 609 - 610 575 /* if we errored on add then this is already gone */ 611 576 if (!tdata) 612 577 return; ··· 612 581 /* Remove the sysfs attributes */ 613 582 sysfs_remove_group(&pdata->hwmon_dev->kobj, &tdata->attr_group); 614 583 615 - kfree(pdata->core_data[indx]); 616 - pdata->core_data[indx] = NULL; 617 - 618 - if (indx >= BASE_SYSFS_ATTR_NO) 619 - ida_free(&pdata->ida, indx - BASE_SYSFS_ATTR_NO); 584 + destroy_temp_data(pdata, tdata); 620 585 } 621 586 622 587 static int coretemp_device_add(int zoneid) ··· 725 698 struct platform_device *pdev = coretemp_get_pdev(cpu); 726 699 struct platform_data *pd; 727 700 struct temp_data *tdata; 728 - int i, indx = -1, target; 701 + int target; 729 702 730 703 /* No need to tear down any interfaces for suspend */ 731 704 if (cpuhp_tasks_frozen) ··· 736 709 if (!pd->hwmon_dev) 737 710 return 0; 738 711 739 - for (i = 0; i < NUM_REAL_CORES; i++) { 740 - if (pd->cpu_map[i] == topology_core_id(cpu)) { 741 - indx = i + BASE_SYSFS_ATTR_NO; 742 - break; 743 - } 744 - } 745 - 746 - /* Too many cores and this core is not populated, just return */ 747 - if (indx < 0) 748 - return 0; 749 - 750 - tdata = pd->core_data[indx]; 712 + tdata = get_temp_data(pd, cpu); 751 713 752 714 cpumask_clear_cpu(cpu, &pd->cpumask); 753 715 ··· 747 731 */ 748 732 target = cpumask_any_and(&pd->cpumask, topology_sibling_cpumask(cpu)); 749 733 if (target >= nr_cpu_ids) { 750 - coretemp_remove_core(pd, indx); 734 + coretemp_remove_core(pd, tdata); 751 735 } else if (tdata && tdata->cpu == cpu) { 752 736 mutex_lock(&tdata->update_lock); 753 737 tdata->cpu = target; ··· 757 741 /* 758 742 * If all cores in this pkg are offline, remove the interface. 759 743 */ 760 - tdata = pd->core_data[PKG_SYSFS_ATTR_NO]; 744 + tdata = get_temp_data(pd, -1); 761 745 if (cpumask_empty(&pd->cpumask)) { 762 746 if (tdata) 763 - coretemp_remove_core(pd, PKG_SYSFS_ATTR_NO); 747 + coretemp_remove_core(pd, tdata); 764 748 hwmon_device_unregister(pd->hwmon_dev); 765 749 pd->hwmon_dev = NULL; 766 750 return 0;
+13
drivers/hwmon/dell-smm-hwmon.c
··· 1450 1450 }; 1451 1451 1452 1452 enum i8k_fan_controls { 1453 + I8K_FAN_30A3_31A3, 1453 1454 I8K_FAN_34A3_35A3, 1454 1455 }; 1455 1456 1456 1457 static const struct i8k_fan_control_data i8k_fan_control_data[] __initconst = { 1458 + [I8K_FAN_30A3_31A3] = { 1459 + .manual_fan = 0x30a3, 1460 + .auto_fan = 0x31a3, 1461 + }, 1457 1462 [I8K_FAN_34A3_35A3] = { 1458 1463 .manual_fan = 0x34a3, 1459 1464 .auto_fan = 0x35a3, ··· 1521 1516 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "OptiPlex 7000"), 1522 1517 }, 1523 1518 .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3], 1519 + }, 1520 + { 1521 + .ident = "Dell XPS 9315", 1522 + .matches = { 1523 + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 1524 + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "XPS 9315"), 1525 + }, 1526 + .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_30A3_31A3], 1524 1527 }, 1525 1528 { } 1526 1529 };
-1
drivers/hwmon/ds1621.c
··· 380 380 381 381 /* This is the driver that will be inserted */ 382 382 static struct i2c_driver ds1621_driver = { 383 - .class = I2C_CLASS_HWMON, 384 383 .driver = { 385 384 .name = "ds1621", 386 385 },
-1
drivers/hwmon/ds620.c
··· 241 241 242 242 /* This is the driver that will be inserted */ 243 243 static struct i2c_driver ds620_driver = { 244 - .class = I2C_CLASS_HWMON, 245 244 .driver = { 246 245 .name = "ds620", 247 246 },
+1 -1
drivers/hwmon/emc1403.c
··· 385 385 static const struct regmap_config emc1403_regmap_config = { 386 386 .reg_bits = 8, 387 387 .val_bits = 8, 388 - .cache_type = REGCACHE_RBTREE, 388 + .cache_type = REGCACHE_MAPLE, 389 389 .volatile_reg = emc1403_regmap_is_volatile, 390 390 }; 391 391
-5
drivers/hwmon/emc2305.c
··· 12 12 #include <linux/platform_data/emc2305.h> 13 13 #include <linux/thermal.h> 14 14 15 - static const unsigned short 16 - emc2305_normal_i2c[] = { 0x27, 0x2c, 0x2d, 0x2e, 0x2f, 0x4c, 0x4d, I2C_CLIENT_END }; 17 - 18 15 #define EMC2305_REG_DRIVE_FAIL_STATUS 0x27 19 16 #define EMC2305_REG_VENDOR 0xfe 20 17 #define EMC2305_FAN_MAX 0xff ··· 608 611 } 609 612 610 613 static struct i2c_driver emc2305_driver = { 611 - .class = I2C_CLASS_HWMON, 612 614 .driver = { 613 615 .name = "emc2305", 614 616 }, 615 617 .probe = emc2305_probe, 616 618 .remove = emc2305_remove, 617 619 .id_table = emc2305_ids, 618 - .address_list = emc2305_normal_i2c, 619 620 }; 620 621 621 622 module_i2c_driver(emc2305_driver);
+3
drivers/hwmon/hwmon.c
··· 510 510 [hwmon_in_rated_min] = "in%d_rated_min", 511 511 [hwmon_in_rated_max] = "in%d_rated_max", 512 512 [hwmon_in_beep] = "in%d_beep", 513 + [hwmon_in_fault] = "in%d_fault", 513 514 }; 514 515 515 516 static const char * const hwmon_curr_attr_templates[] = { ··· 587 586 [hwmon_humidity_fault] = "humidity%d_fault", 588 587 [hwmon_humidity_rated_min] = "humidity%d_rated_min", 589 588 [hwmon_humidity_rated_max] = "humidity%d_rated_max", 589 + [hwmon_humidity_min_alarm] = "humidity%d_min_alarm", 590 + [hwmon_humidity_max_alarm] = "humidity%d_max_alarm", 590 591 }; 591 592 592 593 static const char * const hwmon_fan_attr_templates[] = {
-1
drivers/hwmon/ina209.c
··· 589 589 590 590 /* This is the driver that will be inserted */ 591 591 static struct i2c_driver ina209_driver = { 592 - .class = I2C_CLASS_HWMON, 593 592 .driver = { 594 593 .name = "ina209", 595 594 .of_match_table = of_match_ptr(ina209_of_match),
-1
drivers/hwmon/ina238.c
··· 629 629 MODULE_DEVICE_TABLE(of, ina238_of_match); 630 630 631 631 static struct i2c_driver ina238_driver = { 632 - .class = I2C_CLASS_HWMON, 633 632 .driver = { 634 633 .name = "ina238", 635 634 .of_match_table = of_match_ptr(ina238_of_match),
+1 -1
drivers/hwmon/ina3221.c
··· 762 762 .reg_bits = 8, 763 763 .val_bits = 16, 764 764 765 - .cache_type = REGCACHE_RBTREE, 765 + .cache_type = REGCACHE_MAPLE, 766 766 .volatile_table = &ina3221_volatile_table, 767 767 }; 768 768
+1 -1
drivers/hwmon/jc42.c
··· 497 497 .writeable_reg = jc42_writable_reg, 498 498 .readable_reg = jc42_readable_reg, 499 499 .volatile_reg = jc42_volatile_reg, 500 - .cache_type = REGCACHE_RBTREE, 500 + .cache_type = REGCACHE_MAPLE, 501 501 }; 502 502 503 503 static int jc42_probe(struct i2c_client *client)
+1 -1
drivers/hwmon/lm83.c
··· 165 165 static const struct regmap_config lm83_regmap_config = { 166 166 .reg_bits = 8, 167 167 .val_bits = 8, 168 - .cache_type = REGCACHE_RBTREE, 168 + .cache_type = REGCACHE_MAPLE, 169 169 .volatile_reg = lm83_regmap_is_volatile, 170 170 .reg_read = lm83_regmap_reg_read, 171 171 .reg_write = lm83_regmap_reg_write,
+1782
drivers/hwmon/ltc4282.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Analog Devices LTC4282 I2C High Current Hot Swap Controller over I2C 4 + * 5 + * Copyright 2023 Analog Devices Inc. 6 + */ 7 + #include <linux/bitfield.h> 8 + #include <linux/cleanup.h> 9 + #include <linux/clk.h> 10 + #include <linux/clk-provider.h> 11 + #include <linux/debugfs.h> 12 + #include <linux/delay.h> 13 + #include <linux/device.h> 14 + #include <linux/hwmon.h> 15 + #include <linux/hwmon-sysfs.h> 16 + #include <linux/i2c.h> 17 + #include <linux/math.h> 18 + #include <linux/minmax.h> 19 + #include <linux/module.h> 20 + #include <linux/mod_devicetable.h> 21 + #include <linux/mutex.h> 22 + #include <linux/regmap.h> 23 + #include <linux/property.h> 24 + #include <linux/string.h> 25 + #include <linux/units.h> 26 + #include <linux/util_macros.h> 27 + 28 + #define LTC4282_CTRL_LSB 0x00 29 + #define LTC4282_CTRL_OV_RETRY_MASK BIT(0) 30 + #define LTC4282_CTRL_UV_RETRY_MASK BIT(1) 31 + #define LTC4282_CTRL_OC_RETRY_MASK BIT(2) 32 + #define LTC4282_CTRL_ON_ACTIVE_LOW_MASK BIT(5) 33 + #define LTC4282_CTRL_ON_DELAY_MASK BIT(6) 34 + #define LTC4282_CTRL_MSB 0x01 35 + #define LTC4282_CTRL_VIN_MODE_MASK GENMASK(1, 0) 36 + #define LTC4282_CTRL_OV_MODE_MASK GENMASK(3, 2) 37 + #define LTC4282_CTRL_UV_MODE_MASK GENMASK(5, 4) 38 + #define LTC4282_FAULT_LOG 0x04 39 + #define LTC4282_OV_FAULT_MASK BIT(0) 40 + #define LTC4282_UV_FAULT_MASK BIT(1) 41 + #define LTC4282_VDD_FAULT_MASK \ 42 + (LTC4282_OV_FAULT_MASK | LTC4282_UV_FAULT_MASK) 43 + #define LTC4282_OC_FAULT_MASK BIT(2) 44 + #define LTC4282_POWER_BAD_FAULT_MASK BIT(3) 45 + #define LTC4282_FET_SHORT_FAULT_MASK BIT(5) 46 + #define LTC4282_FET_BAD_FAULT_MASK BIT(6) 47 + #define LTC4282_FET_FAILURE_FAULT_MASK \ 48 + (LTC4282_FET_SHORT_FAULT_MASK | LTC4282_FET_BAD_FAULT_MASK) 49 + #define LTC4282_ADC_ALERT_LOG 0x05 50 + #define LTC4282_GPIO_ALARM_L_MASK BIT(0) 51 + #define LTC4282_GPIO_ALARM_H_MASK BIT(1) 52 + #define LTC4282_VSOURCE_ALARM_L_MASK BIT(2) 53 + #define LTC4282_VSOURCE_ALARM_H_MASK BIT(3) 54 + #define LTC4282_VSENSE_ALARM_L_MASK BIT(4) 55 + #define LTC4282_VSENSE_ALARM_H_MASK BIT(5) 56 + #define LTC4282_POWER_ALARM_L_MASK BIT(6) 57 + #define LTC4282_POWER_ALARM_H_MASK BIT(7) 58 + #define LTC4282_FET_BAD_FAULT_TIMEOUT 0x06 59 + #define LTC4282_FET_BAD_MAX_TIMEOUT 255 60 + #define LTC4282_GPIO_CONFIG 0x07 61 + #define LTC4282_GPIO_2_FET_STRESS_MASK BIT(1) 62 + #define LTC4282_GPIO_1_CONFIG_MASK GENMASK(5, 4) 63 + #define LTC4282_VGPIO_MIN 0x08 64 + #define LTC4282_VGPIO_MAX 0x09 65 + #define LTC4282_VSOURCE_MIN 0x0a 66 + #define LTC4282_VSOURCE_MAX 0x0b 67 + #define LTC4282_VSENSE_MIN 0x0c 68 + #define LTC4282_VSENSE_MAX 0x0d 69 + #define LTC4282_POWER_MIN 0x0e 70 + #define LTC4282_POWER_MAX 0x0f 71 + #define LTC4282_CLK_DIV 0x10 72 + #define LTC4282_CLK_DIV_MASK GENMASK(4, 0) 73 + #define LTC4282_CLKOUT_MASK GENMASK(6, 5) 74 + #define LTC4282_ILIM_ADJUST 0x11 75 + #define LTC4282_GPIO_MODE_MASK BIT(1) 76 + #define LTC4282_VDD_MONITOR_MASK BIT(2) 77 + #define LTC4282_FOLDBACK_MODE_MASK GENMASK(4, 3) 78 + #define LTC4282_ILIM_ADJUST_MASK GENMASK(7, 5) 79 + #define LTC4282_ENERGY 0x12 80 + #define LTC4282_TIME_COUNTER 0x18 81 + #define LTC4282_ALERT_CTRL 0x1c 82 + #define LTC4282_ALERT_OUT_MASK BIT(6) 83 + #define LTC4282_ADC_CTRL 0x1d 84 + #define LTC4282_FAULT_LOG_EN_MASK BIT(2) 85 + #define LTC4282_METER_HALT_MASK BIT(5) 86 + #define LTC4282_METER_RESET_MASK BIT(6) 87 + #define LTC4282_RESET_MASK BIT(7) 88 + #define LTC4282_STATUS_LSB 0x1e 89 + #define LTC4282_OV_STATUS_MASK BIT(0) 90 + #define LTC4282_UV_STATUS_MASK BIT(1) 91 + #define LTC4282_VDD_STATUS_MASK \ 92 + (LTC4282_OV_STATUS_MASK | LTC4282_UV_STATUS_MASK) 93 + #define LTC4282_OC_STATUS_MASK BIT(2) 94 + #define LTC4282_POWER_GOOD_MASK BIT(3) 95 + #define LTC4282_FET_FAILURE_MASK GENMASK(6, 5) 96 + #define LTC4282_STATUS_MSB 0x1f 97 + #define LTC4282_RESERVED_1 0x32 98 + #define LTC4282_RESERVED_2 0x33 99 + #define LTC4282_VGPIO 0x34 100 + #define LTC4282_VGPIO_LOWEST 0x36 101 + #define LTC4282_VGPIO_HIGHEST 0x38 102 + #define LTC4282_VSOURCE 0x3a 103 + #define LTC4282_VSOURCE_LOWEST 0x3c 104 + #define LTC4282_VSOURCE_HIGHEST 0x3e 105 + #define LTC4282_VSENSE 0x40 106 + #define LTC4282_VSENSE_LOWEST 0x42 107 + #define LTC4282_VSENSE_HIGHEST 0x44 108 + #define LTC4282_POWER 0x46 109 + #define LTC4282_POWER_LOWEST 0x48 110 + #define LTC4282_POWER_HIGHEST 0x4a 111 + #define LTC4282_RESERVED_3 0x50 112 + 113 + #define LTC4282_CLKIN_MIN (250 * KILO) 114 + #define LTC4282_CLKIN_MAX (15500 * KILO) 115 + #define LTC4282_CLKIN_RANGE (LTC4282_CLKIN_MAX - LTC4282_CLKIN_MIN + 1) 116 + #define LTC4282_CLKOUT_SYSTEM (250 * KILO) 117 + #define LTC4282_CLKOUT_CNV 15 118 + 119 + enum { 120 + LTC4282_CHAN_VSOURCE, 121 + LTC4282_CHAN_VDD, 122 + LTC4282_CHAN_VGPIO, 123 + }; 124 + 125 + struct ltc4282_cache { 126 + u32 in_max_raw; 127 + u32 in_min_raw; 128 + long in_highest; 129 + long in_lowest; 130 + bool en; 131 + }; 132 + 133 + struct ltc4282_state { 134 + struct regmap *map; 135 + /* Protect against multiple accesses to the device registers */ 136 + struct mutex lock; 137 + struct clk_hw clk_hw; 138 + /* 139 + * Used to cache values for VDD/VSOURCE depending which will be used 140 + * when hwmon is not enabled for that channel. Needed because they share 141 + * the same registers. 142 + */ 143 + struct ltc4282_cache in0_1_cache[LTC4282_CHAN_VGPIO]; 144 + u32 vsense_max; 145 + long power_max; 146 + u32 rsense; 147 + u16 vdd; 148 + u16 vfs_out; 149 + bool energy_en; 150 + }; 151 + 152 + enum { 153 + LTC4282_CLKOUT_NONE, 154 + LTC4282_CLKOUT_INT, 155 + LTC4282_CLKOUT_TICK, 156 + }; 157 + 158 + static int ltc4282_set_rate(struct clk_hw *hw, 159 + unsigned long rate, unsigned long parent_rate) 160 + { 161 + struct ltc4282_state *st = container_of(hw, struct ltc4282_state, 162 + clk_hw); 163 + u32 val = LTC4282_CLKOUT_INT; 164 + 165 + if (rate == LTC4282_CLKOUT_CNV) 166 + val = LTC4282_CLKOUT_TICK; 167 + 168 + return regmap_update_bits(st->map, LTC4282_CLK_DIV, LTC4282_CLKOUT_MASK, 169 + FIELD_PREP(LTC4282_CLKOUT_MASK, val)); 170 + } 171 + 172 + /* 173 + * Note the 15HZ conversion rate assumes 12bit ADC which is what we are 174 + * supporting for now. 175 + */ 176 + static const unsigned int ltc4282_out_rates[] = { 177 + LTC4282_CLKOUT_CNV, LTC4282_CLKOUT_SYSTEM 178 + }; 179 + 180 + static long ltc4282_round_rate(struct clk_hw *hw, unsigned long rate, 181 + unsigned long *parent_rate) 182 + { 183 + int idx = find_closest(rate, ltc4282_out_rates, 184 + ARRAY_SIZE(ltc4282_out_rates)); 185 + 186 + return ltc4282_out_rates[idx]; 187 + } 188 + 189 + static unsigned long ltc4282_recalc_rate(struct clk_hw *hw, 190 + unsigned long parent) 191 + { 192 + struct ltc4282_state *st = container_of(hw, struct ltc4282_state, 193 + clk_hw); 194 + u32 clkdiv; 195 + int ret; 196 + 197 + ret = regmap_read(st->map, LTC4282_CLK_DIV, &clkdiv); 198 + if (ret) 199 + return 0; 200 + 201 + clkdiv = FIELD_GET(LTC4282_CLKOUT_MASK, clkdiv); 202 + if (!clkdiv) 203 + return 0; 204 + if (clkdiv == LTC4282_CLKOUT_INT) 205 + return LTC4282_CLKOUT_SYSTEM; 206 + 207 + return LTC4282_CLKOUT_CNV; 208 + } 209 + 210 + static void ltc4282_disable(struct clk_hw *clk_hw) 211 + { 212 + struct ltc4282_state *st = container_of(clk_hw, struct ltc4282_state, 213 + clk_hw); 214 + 215 + regmap_clear_bits(st->map, LTC4282_CLK_DIV, LTC4282_CLKOUT_MASK); 216 + } 217 + 218 + static int ltc4282_read_voltage_word(const struct ltc4282_state *st, u32 reg, 219 + u32 fs, long *val) 220 + { 221 + __be16 in; 222 + int ret; 223 + 224 + ret = regmap_bulk_read(st->map, reg, &in, sizeof(in)); 225 + if (ret) 226 + return ret; 227 + 228 + /* 229 + * This is also used to calculate current in which case fs comes in 230 + * 10 * uV. Hence the ULL usage. 231 + */ 232 + *val = DIV_ROUND_CLOSEST_ULL(be16_to_cpu(in) * (u64)fs, U16_MAX); 233 + return 0; 234 + } 235 + 236 + static int ltc4282_read_voltage_byte_cached(const struct ltc4282_state *st, 237 + u32 reg, u32 fs, long *val, 238 + u32 *cached_raw) 239 + { 240 + int ret; 241 + u32 in; 242 + 243 + if (cached_raw) { 244 + in = *cached_raw; 245 + } else { 246 + ret = regmap_read(st->map, reg, &in); 247 + if (ret) 248 + return ret; 249 + } 250 + 251 + *val = DIV_ROUND_CLOSEST(in * fs, U8_MAX); 252 + return 0; 253 + } 254 + 255 + static int ltc4282_read_voltage_byte(const struct ltc4282_state *st, u32 reg, 256 + u32 fs, long *val) 257 + { 258 + return ltc4282_read_voltage_byte_cached(st, reg, fs, val, NULL); 259 + } 260 + 261 + static int __ltc4282_read_alarm(struct ltc4282_state *st, u32 reg, u32 mask, 262 + long *val) 263 + { 264 + u32 alarm; 265 + int ret; 266 + 267 + ret = regmap_read(st->map, reg, &alarm); 268 + if (ret) 269 + return ret; 270 + 271 + *val = !!(alarm & mask); 272 + 273 + /* if not status/fault logs, clear the alarm after reading it */ 274 + if (reg != LTC4282_STATUS_LSB && reg != LTC4282_FAULT_LOG) 275 + return regmap_clear_bits(st->map, reg, mask); 276 + 277 + return 0; 278 + } 279 + 280 + static int ltc4282_read_alarm(struct ltc4282_state *st, u32 reg, u32 mask, 281 + long *val) 282 + { 283 + guard(mutex)(&st->lock); 284 + return __ltc4282_read_alarm(st, reg, mask, val); 285 + } 286 + 287 + static int ltc4282_vdd_source_read_in(struct ltc4282_state *st, u32 channel, 288 + long *val) 289 + { 290 + guard(mutex)(&st->lock); 291 + if (!st->in0_1_cache[channel].en) 292 + return -ENODATA; 293 + 294 + return ltc4282_read_voltage_word(st, LTC4282_VSOURCE, st->vfs_out, val); 295 + } 296 + 297 + static int ltc4282_vdd_source_read_hist(struct ltc4282_state *st, u32 reg, 298 + u32 channel, long *cached, long *val) 299 + { 300 + int ret; 301 + 302 + guard(mutex)(&st->lock); 303 + if (!st->in0_1_cache[channel].en) { 304 + *val = *cached; 305 + return 0; 306 + } 307 + 308 + ret = ltc4282_read_voltage_word(st, reg, st->vfs_out, val); 309 + if (ret) 310 + return ret; 311 + 312 + *cached = *val; 313 + return 0; 314 + } 315 + 316 + static int ltc4282_vdd_source_read_lim(struct ltc4282_state *st, u32 reg, 317 + u32 channel, u32 *cached, long *val) 318 + { 319 + guard(mutex)(&st->lock); 320 + if (!st->in0_1_cache[channel].en) 321 + return ltc4282_read_voltage_byte_cached(st, reg, st->vfs_out, 322 + val, cached); 323 + 324 + return ltc4282_read_voltage_byte(st, reg, st->vfs_out, val); 325 + } 326 + 327 + static int ltc4282_vdd_source_read_alm(struct ltc4282_state *st, u32 mask, 328 + u32 channel, long *val) 329 + { 330 + guard(mutex)(&st->lock); 331 + if (!st->in0_1_cache[channel].en) { 332 + /* 333 + * Do this otherwise alarms can get confused because we clear 334 + * them after reading them. So, if someone mistakenly reads 335 + * VSOURCE right before VDD (or the other way around), we might 336 + * get no alarm just because it was cleared when reading VSOURCE 337 + * and had no time for a new conversion and thus having the 338 + * alarm again. 339 + */ 340 + *val = 0; 341 + return 0; 342 + } 343 + 344 + return __ltc4282_read_alarm(st, LTC4282_ADC_ALERT_LOG, mask, val); 345 + } 346 + 347 + static int ltc4282_read_in(struct ltc4282_state *st, u32 attr, long *val, 348 + u32 channel) 349 + { 350 + switch (attr) { 351 + case hwmon_in_input: 352 + if (channel == LTC4282_CHAN_VGPIO) 353 + return ltc4282_read_voltage_word(st, LTC4282_VGPIO, 354 + 1280, val); 355 + 356 + return ltc4282_vdd_source_read_in(st, channel, val); 357 + case hwmon_in_highest: 358 + if (channel == LTC4282_CHAN_VGPIO) 359 + return ltc4282_read_voltage_word(st, 360 + LTC4282_VGPIO_HIGHEST, 361 + 1280, val); 362 + 363 + return ltc4282_vdd_source_read_hist(st, LTC4282_VSOURCE_HIGHEST, 364 + channel, 365 + &st->in0_1_cache[channel].in_highest, val); 366 + case hwmon_in_lowest: 367 + if (channel == LTC4282_CHAN_VGPIO) 368 + return ltc4282_read_voltage_word(st, LTC4282_VGPIO_LOWEST, 369 + 1280, val); 370 + 371 + return ltc4282_vdd_source_read_hist(st, LTC4282_VSOURCE_LOWEST, 372 + channel, 373 + &st->in0_1_cache[channel].in_lowest, val); 374 + case hwmon_in_max_alarm: 375 + if (channel == LTC4282_CHAN_VGPIO) 376 + return ltc4282_read_alarm(st, LTC4282_ADC_ALERT_LOG, 377 + LTC4282_GPIO_ALARM_H_MASK, 378 + val); 379 + 380 + return ltc4282_vdd_source_read_alm(st, 381 + LTC4282_VSOURCE_ALARM_H_MASK, 382 + channel, val); 383 + case hwmon_in_min_alarm: 384 + if (channel == LTC4282_CHAN_VGPIO) 385 + ltc4282_read_alarm(st, LTC4282_ADC_ALERT_LOG, 386 + LTC4282_GPIO_ALARM_L_MASK, val); 387 + 388 + return ltc4282_vdd_source_read_alm(st, 389 + LTC4282_VSOURCE_ALARM_L_MASK, 390 + channel, val); 391 + case hwmon_in_crit_alarm: 392 + return ltc4282_read_alarm(st, LTC4282_STATUS_LSB, 393 + LTC4282_OV_STATUS_MASK, val); 394 + case hwmon_in_lcrit_alarm: 395 + return ltc4282_read_alarm(st, LTC4282_STATUS_LSB, 396 + LTC4282_UV_STATUS_MASK, val); 397 + case hwmon_in_max: 398 + if (channel == LTC4282_CHAN_VGPIO) 399 + return ltc4282_read_voltage_byte(st, LTC4282_VGPIO_MAX, 400 + 1280, val); 401 + 402 + return ltc4282_vdd_source_read_lim(st, LTC4282_VSOURCE_MAX, 403 + channel, 404 + &st->in0_1_cache[channel].in_max_raw, val); 405 + case hwmon_in_min: 406 + if (channel == LTC4282_CHAN_VGPIO) 407 + return ltc4282_read_voltage_byte(st, LTC4282_VGPIO_MIN, 408 + 1280, val); 409 + 410 + return ltc4282_vdd_source_read_lim(st, LTC4282_VSOURCE_MIN, 411 + channel, 412 + &st->in0_1_cache[channel].in_min_raw, val); 413 + case hwmon_in_enable: 414 + scoped_guard(mutex, &st->lock) { 415 + *val = st->in0_1_cache[channel].en; 416 + } 417 + return 0; 418 + case hwmon_in_fault: 419 + /* 420 + * We report failure if we detect either a fer_bad or a 421 + * fet_short in the status register. 422 + */ 423 + return ltc4282_read_alarm(st, LTC4282_STATUS_LSB, 424 + LTC4282_FET_FAILURE_MASK, val); 425 + default: 426 + return -EOPNOTSUPP; 427 + } 428 + } 429 + 430 + static int ltc4282_read_current_word(const struct ltc4282_state *st, u32 reg, 431 + long *val) 432 + { 433 + long in; 434 + int ret; 435 + 436 + /* 437 + * We pass in full scale in 10 * micro (note that 40 is already 438 + * millivolt) so we have better approximations to calculate current. 439 + */ 440 + ret = ltc4282_read_voltage_word(st, reg, DECA * 40 * MILLI, &in); 441 + if (ret) 442 + return ret; 443 + 444 + *val = DIV_ROUND_CLOSEST(in * MILLI, st->rsense); 445 + 446 + return 0; 447 + } 448 + 449 + static int ltc4282_read_current_byte(const struct ltc4282_state *st, u32 reg, 450 + long *val) 451 + { 452 + long in; 453 + int ret; 454 + 455 + ret = ltc4282_read_voltage_byte(st, reg, DECA * 40 * MILLI, &in); 456 + if (ret) 457 + return ret; 458 + 459 + *val = DIV_ROUND_CLOSEST(in * MILLI, st->rsense); 460 + 461 + return 0; 462 + } 463 + 464 + static int ltc4282_read_curr(struct ltc4282_state *st, const u32 attr, 465 + long *val) 466 + { 467 + switch (attr) { 468 + case hwmon_curr_input: 469 + return ltc4282_read_current_word(st, LTC4282_VSENSE, val); 470 + case hwmon_curr_highest: 471 + return ltc4282_read_current_word(st, LTC4282_VSENSE_HIGHEST, 472 + val); 473 + case hwmon_curr_lowest: 474 + return ltc4282_read_current_word(st, LTC4282_VSENSE_LOWEST, 475 + val); 476 + case hwmon_curr_max: 477 + return ltc4282_read_current_byte(st, LTC4282_VSENSE_MAX, val); 478 + case hwmon_curr_min: 479 + return ltc4282_read_current_byte(st, LTC4282_VSENSE_MIN, val); 480 + case hwmon_curr_max_alarm: 481 + return ltc4282_read_alarm(st, LTC4282_ADC_ALERT_LOG, 482 + LTC4282_VSENSE_ALARM_H_MASK, val); 483 + case hwmon_curr_min_alarm: 484 + return ltc4282_read_alarm(st, LTC4282_ADC_ALERT_LOG, 485 + LTC4282_VSENSE_ALARM_L_MASK, val); 486 + case hwmon_curr_crit_alarm: 487 + return ltc4282_read_alarm(st, LTC4282_STATUS_LSB, 488 + LTC4282_OC_STATUS_MASK, val); 489 + default: 490 + return -EOPNOTSUPP; 491 + } 492 + } 493 + 494 + static int ltc4282_read_power_word(const struct ltc4282_state *st, u32 reg, 495 + long *val) 496 + { 497 + u64 temp = DECA * 40ULL * st->vfs_out * BIT(16), temp_2; 498 + __be16 raw; 499 + u16 power; 500 + int ret; 501 + 502 + ret = regmap_bulk_read(st->map, reg, &raw, sizeof(raw)); 503 + if (ret) 504 + return ret; 505 + 506 + power = be16_to_cpu(raw); 507 + /* 508 + * Power is given by: 509 + * P = CODE(16b) * 0.040 * Vfs(out) * 2^16 / ((2^16 - 1)^2 * Rsense) 510 + */ 511 + if (check_mul_overflow(power * temp, MICRO, &temp_2)) { 512 + temp = DIV_ROUND_CLOSEST_ULL(power * temp, U16_MAX); 513 + *val = DIV64_U64_ROUND_CLOSEST(temp * MICRO, 514 + U16_MAX * (u64)st->rsense); 515 + return 0; 516 + } 517 + 518 + *val = DIV64_U64_ROUND_CLOSEST(temp_2, 519 + st->rsense * int_pow(U16_MAX, 2)); 520 + 521 + return 0; 522 + } 523 + 524 + static int ltc4282_read_power_byte(const struct ltc4282_state *st, u32 reg, 525 + long *val) 526 + { 527 + u32 power; 528 + u64 temp; 529 + int ret; 530 + 531 + ret = regmap_read(st->map, reg, &power); 532 + if (ret) 533 + return ret; 534 + 535 + temp = power * 40 * DECA * st->vfs_out * BIT_ULL(8); 536 + *val = DIV64_U64_ROUND_CLOSEST(temp * MICRO, 537 + int_pow(U8_MAX, 2) * st->rsense); 538 + 539 + return 0; 540 + } 541 + 542 + static int ltc4282_read_energy(const struct ltc4282_state *st, u64 *val) 543 + { 544 + u64 temp, energy; 545 + __be64 raw; 546 + int ret; 547 + 548 + ret = regmap_bulk_read(st->map, LTC4282_ENERGY, &raw, 6); 549 + if (ret) 550 + return ret; 551 + 552 + energy = be64_to_cpu(raw) >> 16; 553 + /* 554 + * The formula for energy is given by: 555 + * E = CODE(48b) * 0.040 * Vfs(out) * Tconv * 256 / 556 + * ((2^16 - 1)^2 * Rsense) 557 + * 558 + * Since we only support 12bit ADC, Tconv = 0.065535s. Passing Vfs(out) 559 + * and 0.040 to mV and Tconv to us, we can simplify the formula to: 560 + * E = CODE(48b) * 40 * Vfs(out) * 256 / (U16_MAX * Rsense) 561 + * 562 + * As Rsense can have tenths of micro-ohm resolution, we need to 563 + * multiply by DECA to get microujoule. 564 + */ 565 + if (check_mul_overflow(DECA * st->vfs_out * 40 * BIT(8), energy, &temp)) { 566 + temp = DIV_ROUND_CLOSEST(DECA * st->vfs_out * 40 * BIT(8), U16_MAX); 567 + *val = DIV_ROUND_CLOSEST_ULL(temp * energy, st->rsense); 568 + return 0; 569 + } 570 + 571 + *val = DIV64_U64_ROUND_CLOSEST(temp, U16_MAX * (u64)st->rsense); 572 + 573 + return 0; 574 + } 575 + 576 + static int ltc4282_read_power(struct ltc4282_state *st, const u32 attr, 577 + long *val) 578 + { 579 + switch (attr) { 580 + case hwmon_power_input: 581 + return ltc4282_read_power_word(st, LTC4282_POWER, val); 582 + case hwmon_power_input_highest: 583 + return ltc4282_read_power_word(st, LTC4282_POWER_HIGHEST, val); 584 + case hwmon_power_input_lowest: 585 + return ltc4282_read_power_word(st, LTC4282_POWER_LOWEST, val); 586 + case hwmon_power_max_alarm: 587 + return ltc4282_read_alarm(st, LTC4282_ADC_ALERT_LOG, 588 + LTC4282_POWER_ALARM_H_MASK, val); 589 + case hwmon_power_min_alarm: 590 + return ltc4282_read_alarm(st, LTC4282_ADC_ALERT_LOG, 591 + LTC4282_POWER_ALARM_L_MASK, val); 592 + case hwmon_power_max: 593 + return ltc4282_read_power_byte(st, LTC4282_POWER_MAX, val); 594 + case hwmon_power_min: 595 + return ltc4282_read_power_byte(st, LTC4282_POWER_MIN, val); 596 + default: 597 + return -EOPNOTSUPP; 598 + } 599 + } 600 + 601 + static int ltc4282_read(struct device *dev, enum hwmon_sensor_types type, 602 + u32 attr, int channel, long *val) 603 + { 604 + struct ltc4282_state *st = dev_get_drvdata(dev); 605 + 606 + switch (type) { 607 + case hwmon_in: 608 + return ltc4282_read_in(st, attr, val, channel); 609 + case hwmon_curr: 610 + return ltc4282_read_curr(st, attr, val); 611 + case hwmon_power: 612 + return ltc4282_read_power(st, attr, val); 613 + case hwmon_energy: 614 + scoped_guard(mutex, &st->lock) { 615 + *val = st->energy_en; 616 + } 617 + return 0; 618 + default: 619 + return -EOPNOTSUPP; 620 + } 621 + } 622 + 623 + static int ltc4282_write_power_byte(const struct ltc4282_state *st, u32 reg, 624 + long val) 625 + { 626 + u32 power; 627 + u64 temp; 628 + 629 + if (val > st->power_max) 630 + val = st->power_max; 631 + 632 + temp = val * int_pow(U8_MAX, 2) * st->rsense; 633 + power = DIV64_U64_ROUND_CLOSEST(temp, 634 + MICRO * DECA * 256ULL * st->vfs_out * 40); 635 + 636 + return regmap_write(st->map, reg, power); 637 + } 638 + 639 + static int ltc4282_write_power_word(const struct ltc4282_state *st, u32 reg, 640 + long val) 641 + { 642 + u64 temp = int_pow(U16_MAX, 2) * st->rsense, temp_2; 643 + __be16 __raw; 644 + u16 code; 645 + 646 + if (check_mul_overflow(temp, val, &temp_2)) { 647 + temp = DIV_ROUND_CLOSEST_ULL(temp, DECA * MICRO); 648 + code = DIV64_U64_ROUND_CLOSEST(temp * val, 649 + 40ULL * BIT(16) * st->vfs_out); 650 + } else { 651 + temp = DECA * MICRO * 40ULL * BIT(16) * st->vfs_out; 652 + code = DIV64_U64_ROUND_CLOSEST(temp_2, temp); 653 + } 654 + 655 + __raw = cpu_to_be16(code); 656 + return regmap_bulk_write(st->map, reg, &__raw, sizeof(__raw)); 657 + } 658 + 659 + static int __ltc4282_in_write_history(const struct ltc4282_state *st, u32 reg, 660 + long lowest, long highest, u32 fs) 661 + { 662 + __be16 __raw; 663 + u16 tmp; 664 + int ret; 665 + 666 + tmp = DIV_ROUND_CLOSEST(U16_MAX * lowest, fs); 667 + 668 + __raw = cpu_to_be16(tmp); 669 + 670 + ret = regmap_bulk_write(st->map, reg, &__raw, 2); 671 + if (ret) 672 + return ret; 673 + 674 + tmp = DIV_ROUND_CLOSEST(U16_MAX * highest, fs); 675 + 676 + __raw = cpu_to_be16(tmp); 677 + 678 + return regmap_bulk_write(st->map, reg + 2, &__raw, 2); 679 + } 680 + 681 + static int ltc4282_in_write_history(struct ltc4282_state *st, u32 reg, 682 + long lowest, long highest, u32 fs) 683 + { 684 + guard(mutex)(&st->lock); 685 + return __ltc4282_in_write_history(st, reg, lowest, highest, fs); 686 + } 687 + 688 + static int ltc4282_power_reset_hist(struct ltc4282_state *st) 689 + { 690 + int ret; 691 + 692 + guard(mutex)(&st->lock); 693 + 694 + ret = ltc4282_write_power_word(st, LTC4282_POWER_LOWEST, 695 + st->power_max); 696 + if (ret) 697 + return ret; 698 + 699 + ret = ltc4282_write_power_word(st, LTC4282_POWER_HIGHEST, 0); 700 + if (ret) 701 + return ret; 702 + 703 + /* now, let's also clear possible power_bad fault logs */ 704 + return regmap_clear_bits(st->map, LTC4282_FAULT_LOG, 705 + LTC4282_POWER_BAD_FAULT_MASK); 706 + } 707 + 708 + static int ltc4282_write_power(struct ltc4282_state *st, u32 attr, 709 + long val) 710 + { 711 + switch (attr) { 712 + case hwmon_power_max: 713 + return ltc4282_write_power_byte(st, LTC4282_POWER_MAX, val); 714 + case hwmon_power_min: 715 + return ltc4282_write_power_byte(st, LTC4282_POWER_MIN, val); 716 + case hwmon_power_reset_history: 717 + return ltc4282_power_reset_hist(st); 718 + default: 719 + return -EOPNOTSUPP; 720 + } 721 + } 722 + 723 + static int ltc4282_write_voltage_byte_cached(const struct ltc4282_state *st, 724 + u32 reg, u32 fs, long val, 725 + u32 *cache_raw) 726 + { 727 + u32 in; 728 + 729 + val = clamp_val(val, 0, fs); 730 + in = DIV_ROUND_CLOSEST(val * U8_MAX, fs); 731 + 732 + if (cache_raw) { 733 + *cache_raw = in; 734 + return 0; 735 + } 736 + 737 + return regmap_write(st->map, reg, in); 738 + } 739 + 740 + static int ltc4282_write_voltage_byte(const struct ltc4282_state *st, u32 reg, 741 + u32 fs, long val) 742 + { 743 + return ltc4282_write_voltage_byte_cached(st, reg, fs, val, NULL); 744 + } 745 + 746 + static int ltc4282_cache_history(struct ltc4282_state *st, u32 channel) 747 + { 748 + long val; 749 + int ret; 750 + 751 + ret = ltc4282_read_voltage_word(st, LTC4282_VSOURCE_LOWEST, st->vfs_out, 752 + &val); 753 + if (ret) 754 + return ret; 755 + 756 + st->in0_1_cache[channel].in_lowest = val; 757 + 758 + ret = ltc4282_read_voltage_word(st, LTC4282_VSOURCE_HIGHEST, 759 + st->vfs_out, &val); 760 + if (ret) 761 + return ret; 762 + 763 + st->in0_1_cache[channel].in_highest = val; 764 + 765 + ret = regmap_read(st->map, LTC4282_VSOURCE_MIN, 766 + &st->in0_1_cache[channel].in_min_raw); 767 + if (ret) 768 + return ret; 769 + 770 + return regmap_read(st->map, LTC4282_VSOURCE_MAX, 771 + &st->in0_1_cache[channel].in_max_raw); 772 + } 773 + 774 + static int ltc4282_cache_sync(struct ltc4282_state *st, u32 channel) 775 + { 776 + int ret; 777 + 778 + ret = __ltc4282_in_write_history(st, LTC4282_VSOURCE_LOWEST, 779 + st->in0_1_cache[channel].in_lowest, 780 + st->in0_1_cache[channel].in_highest, 781 + st->vfs_out); 782 + if (ret) 783 + return ret; 784 + 785 + ret = regmap_write(st->map, LTC4282_VSOURCE_MIN, 786 + st->in0_1_cache[channel].in_min_raw); 787 + if (ret) 788 + return ret; 789 + 790 + return regmap_write(st->map, LTC4282_VSOURCE_MAX, 791 + st->in0_1_cache[channel].in_max_raw); 792 + } 793 + 794 + static int ltc4282_vdd_source_write_lim(struct ltc4282_state *st, u32 reg, 795 + int channel, u32 *cache, long val) 796 + { 797 + int ret; 798 + 799 + guard(mutex)(&st->lock); 800 + if (st->in0_1_cache[channel].en) 801 + ret = ltc4282_write_voltage_byte(st, reg, st->vfs_out, val); 802 + else 803 + ret = ltc4282_write_voltage_byte_cached(st, reg, st->vfs_out, 804 + val, cache); 805 + 806 + return ret; 807 + } 808 + 809 + static int ltc4282_vdd_source_reset_hist(struct ltc4282_state *st, int channel) 810 + { 811 + long lowest = st->vfs_out; 812 + int ret; 813 + 814 + if (channel == LTC4282_CHAN_VDD) 815 + lowest = st->vdd; 816 + 817 + guard(mutex)(&st->lock); 818 + if (st->in0_1_cache[channel].en) { 819 + ret = __ltc4282_in_write_history(st, LTC4282_VSOURCE_LOWEST, 820 + lowest, 0, st->vfs_out); 821 + if (ret) 822 + return ret; 823 + } 824 + 825 + st->in0_1_cache[channel].in_lowest = lowest; 826 + st->in0_1_cache[channel].in_highest = 0; 827 + 828 + /* 829 + * We are also clearing possible fault logs in reset_history. Clearing 830 + * the logs might be important when the auto retry bits are not enabled 831 + * as the chip only enables the output again after having these logs 832 + * cleared. As some of these logs are related to limits, it makes sense 833 + * to clear them in here. For VDD, we need to clear under/over voltage 834 + * events. For VSOURCE, fet_short and fet_bad... 835 + */ 836 + if (channel == LTC4282_CHAN_VSOURCE) 837 + return regmap_clear_bits(st->map, LTC4282_FAULT_LOG, 838 + LTC4282_FET_FAILURE_FAULT_MASK); 839 + 840 + return regmap_clear_bits(st->map, LTC4282_FAULT_LOG, 841 + LTC4282_VDD_FAULT_MASK); 842 + } 843 + 844 + /* 845 + * We need to mux between VSOURCE and VDD which means they are mutually 846 + * exclusive. Moreover, we can't really disable both VDD and VSOURCE as the ADC 847 + * is continuously running (we cannot independently halt it without also 848 + * stopping VGPIO). Hence, the logic is that disabling or enabling VDD will 849 + * automatically have the reverse effect on VSOURCE and vice-versa. 850 + */ 851 + static int ltc4282_vdd_source_enable(struct ltc4282_state *st, int channel, 852 + long val) 853 + { 854 + int ret, other_chan = ~channel & 0x1; 855 + u8 __val = val; 856 + 857 + guard(mutex)(&st->lock); 858 + if (st->in0_1_cache[channel].en == !!val) 859 + return 0; 860 + 861 + /* clearing the bit makes the ADC to monitor VDD */ 862 + if (channel == LTC4282_CHAN_VDD) 863 + __val = !__val; 864 + 865 + ret = regmap_update_bits(st->map, LTC4282_ILIM_ADJUST, 866 + LTC4282_VDD_MONITOR_MASK, 867 + FIELD_PREP(LTC4282_VDD_MONITOR_MASK, !!__val)); 868 + if (ret) 869 + return ret; 870 + 871 + st->in0_1_cache[channel].en = !!val; 872 + st->in0_1_cache[other_chan].en = !val; 873 + 874 + if (st->in0_1_cache[channel].en) { 875 + /* 876 + * Then, we are disabling @other_chan. Let's save it's current 877 + * history. 878 + */ 879 + ret = ltc4282_cache_history(st, other_chan); 880 + if (ret) 881 + return ret; 882 + 883 + return ltc4282_cache_sync(st, channel); 884 + } 885 + /* 886 + * Then, we are enabling @other_chan. We need to do the opposite from 887 + * above. 888 + */ 889 + ret = ltc4282_cache_history(st, channel); 890 + if (ret) 891 + return ret; 892 + 893 + return ltc4282_cache_sync(st, other_chan); 894 + } 895 + 896 + static int ltc4282_write_in(struct ltc4282_state *st, u32 attr, long val, 897 + int channel) 898 + { 899 + switch (attr) { 900 + case hwmon_in_max: 901 + if (channel == LTC4282_CHAN_VGPIO) 902 + return ltc4282_write_voltage_byte(st, LTC4282_VGPIO_MAX, 903 + 1280, val); 904 + 905 + return ltc4282_vdd_source_write_lim(st, LTC4282_VSOURCE_MAX, 906 + channel, 907 + &st->in0_1_cache[channel].in_max_raw, val); 908 + case hwmon_in_min: 909 + if (channel == LTC4282_CHAN_VGPIO) 910 + return ltc4282_write_voltage_byte(st, LTC4282_VGPIO_MIN, 911 + 1280, val); 912 + 913 + return ltc4282_vdd_source_write_lim(st, LTC4282_VSOURCE_MIN, 914 + channel, 915 + &st->in0_1_cache[channel].in_min_raw, val); 916 + case hwmon_in_reset_history: 917 + if (channel == LTC4282_CHAN_VGPIO) 918 + return ltc4282_in_write_history(st, 919 + LTC4282_VGPIO_LOWEST, 920 + 1280, 0, 1280); 921 + 922 + return ltc4282_vdd_source_reset_hist(st, channel); 923 + case hwmon_in_enable: 924 + return ltc4282_vdd_source_enable(st, channel, val); 925 + default: 926 + return -EOPNOTSUPP; 927 + } 928 + } 929 + 930 + static int ltc4282_curr_reset_hist(struct ltc4282_state *st) 931 + { 932 + int ret; 933 + 934 + guard(mutex)(&st->lock); 935 + 936 + ret = __ltc4282_in_write_history(st, LTC4282_VSENSE_LOWEST, 937 + st->vsense_max, 0, 40 * MILLI); 938 + if (ret) 939 + return ret; 940 + 941 + /* now, let's also clear possible overcurrent fault logs */ 942 + return regmap_clear_bits(st->map, LTC4282_FAULT_LOG, 943 + LTC4282_OC_FAULT_MASK); 944 + } 945 + 946 + static int ltc4282_write_curr(struct ltc4282_state *st, u32 attr, 947 + long val) 948 + { 949 + /* need to pass it in millivolt */ 950 + u32 in = DIV_ROUND_CLOSEST_ULL((u64)val * st->rsense, DECA * MICRO); 951 + 952 + switch (attr) { 953 + case hwmon_curr_max: 954 + return ltc4282_write_voltage_byte(st, LTC4282_VSENSE_MAX, 40, 955 + in); 956 + case hwmon_curr_min: 957 + return ltc4282_write_voltage_byte(st, LTC4282_VSENSE_MIN, 40, 958 + in); 959 + case hwmon_curr_reset_history: 960 + return ltc4282_curr_reset_hist(st); 961 + default: 962 + return -EOPNOTSUPP; 963 + } 964 + } 965 + 966 + static int ltc4282_energy_enable_set(struct ltc4282_state *st, long val) 967 + { 968 + int ret; 969 + 970 + guard(mutex)(&st->lock); 971 + /* setting the bit halts the meter */ 972 + ret = regmap_update_bits(st->map, LTC4282_ADC_CTRL, 973 + LTC4282_METER_HALT_MASK, 974 + FIELD_PREP(LTC4282_METER_HALT_MASK, !val)); 975 + if (ret) 976 + return ret; 977 + 978 + st->energy_en = !!val; 979 + 980 + return 0; 981 + } 982 + 983 + static int ltc4282_write(struct device *dev, 984 + enum hwmon_sensor_types type, 985 + u32 attr, int channel, long val) 986 + { 987 + struct ltc4282_state *st = dev_get_drvdata(dev); 988 + 989 + switch (type) { 990 + case hwmon_power: 991 + return ltc4282_write_power(st, attr, val); 992 + case hwmon_in: 993 + return ltc4282_write_in(st, attr, val, channel); 994 + case hwmon_curr: 995 + return ltc4282_write_curr(st, attr, val); 996 + case hwmon_energy: 997 + return ltc4282_energy_enable_set(st, val); 998 + default: 999 + return -EOPNOTSUPP; 1000 + } 1001 + } 1002 + 1003 + static umode_t ltc4282_in_is_visible(const struct ltc4282_state *st, u32 attr) 1004 + { 1005 + switch (attr) { 1006 + case hwmon_in_input: 1007 + case hwmon_in_highest: 1008 + case hwmon_in_lowest: 1009 + case hwmon_in_max_alarm: 1010 + case hwmon_in_min_alarm: 1011 + case hwmon_in_label: 1012 + case hwmon_in_lcrit_alarm: 1013 + case hwmon_in_crit_alarm: 1014 + case hwmon_in_fault: 1015 + return 0444; 1016 + case hwmon_in_max: 1017 + case hwmon_in_min: 1018 + case hwmon_in_enable: 1019 + case hwmon_in_reset_history: 1020 + return 0644; 1021 + default: 1022 + return 0; 1023 + } 1024 + } 1025 + 1026 + static umode_t ltc4282_curr_is_visible(u32 attr) 1027 + { 1028 + switch (attr) { 1029 + case hwmon_curr_input: 1030 + case hwmon_curr_highest: 1031 + case hwmon_curr_lowest: 1032 + case hwmon_curr_max_alarm: 1033 + case hwmon_curr_min_alarm: 1034 + case hwmon_curr_crit_alarm: 1035 + case hwmon_curr_label: 1036 + return 0444; 1037 + case hwmon_curr_max: 1038 + case hwmon_curr_min: 1039 + case hwmon_curr_reset_history: 1040 + return 0644; 1041 + default: 1042 + return 0; 1043 + } 1044 + } 1045 + 1046 + static umode_t ltc4282_power_is_visible(u32 attr) 1047 + { 1048 + switch (attr) { 1049 + case hwmon_power_input: 1050 + case hwmon_power_input_highest: 1051 + case hwmon_power_input_lowest: 1052 + case hwmon_power_label: 1053 + case hwmon_power_max_alarm: 1054 + case hwmon_power_min_alarm: 1055 + return 0444; 1056 + case hwmon_power_max: 1057 + case hwmon_power_min: 1058 + case hwmon_power_reset_history: 1059 + return 0644; 1060 + default: 1061 + return 0; 1062 + } 1063 + } 1064 + 1065 + static umode_t ltc4282_is_visible(const void *data, 1066 + enum hwmon_sensor_types type, 1067 + u32 attr, int channel) 1068 + { 1069 + switch (type) { 1070 + case hwmon_in: 1071 + return ltc4282_in_is_visible(data, attr); 1072 + case hwmon_curr: 1073 + return ltc4282_curr_is_visible(attr); 1074 + case hwmon_power: 1075 + return ltc4282_power_is_visible(attr); 1076 + case hwmon_energy: 1077 + /* hwmon_energy_enable */ 1078 + return 0644; 1079 + default: 1080 + return 0; 1081 + } 1082 + } 1083 + 1084 + static const char * const ltc4282_in_strs[] = { 1085 + "VSOURCE", "VDD", "VGPIO" 1086 + }; 1087 + 1088 + static int ltc4282_read_labels(struct device *dev, 1089 + enum hwmon_sensor_types type, 1090 + u32 attr, int channel, const char **str) 1091 + { 1092 + switch (type) { 1093 + case hwmon_in: 1094 + *str = ltc4282_in_strs[channel]; 1095 + return 0; 1096 + case hwmon_curr: 1097 + *str = "ISENSE"; 1098 + return 0; 1099 + case hwmon_power: 1100 + *str = "Power"; 1101 + return 0; 1102 + default: 1103 + return -EOPNOTSUPP; 1104 + } 1105 + } 1106 + 1107 + static ssize_t ltc4282_energy_show(struct device *dev, 1108 + struct device_attribute *da, char *buf) 1109 + { 1110 + struct ltc4282_state *st = dev_get_drvdata(dev); 1111 + u64 energy; 1112 + int ret; 1113 + 1114 + guard(mutex)(&st->lock); 1115 + if (!st->energy_en) 1116 + return -ENODATA; 1117 + 1118 + ret = ltc4282_read_energy(st, &energy); 1119 + if (ret < 0) 1120 + return ret; 1121 + 1122 + return sysfs_emit(buf, "%llu\n", energy); 1123 + } 1124 + 1125 + static const struct clk_ops ltc4282_ops = { 1126 + .recalc_rate = ltc4282_recalc_rate, 1127 + .round_rate = ltc4282_round_rate, 1128 + .set_rate = ltc4282_set_rate, 1129 + .disable = ltc4282_disable, 1130 + }; 1131 + 1132 + static int ltc428_clk_provider_setup(struct ltc4282_state *st, 1133 + struct device *dev) 1134 + { 1135 + struct clk_init_data init; 1136 + int ret; 1137 + 1138 + if (!IS_ENABLED(CONFIG_COMMON_CLK)) 1139 + return 0; 1140 + 1141 + init.name = devm_kasprintf(dev, GFP_KERNEL, "%s-clk", 1142 + fwnode_get_name(dev_fwnode(dev))); 1143 + if (!init.name) 1144 + return -ENOMEM; 1145 + 1146 + init.ops = &ltc4282_ops; 1147 + init.flags = CLK_GET_RATE_NOCACHE; 1148 + st->clk_hw.init = &init; 1149 + 1150 + ret = devm_clk_hw_register(dev, &st->clk_hw); 1151 + if (ret) 1152 + return ret; 1153 + 1154 + return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, 1155 + &st->clk_hw); 1156 + } 1157 + 1158 + static int ltc428_clks_setup(struct ltc4282_state *st, struct device *dev) 1159 + { 1160 + unsigned long rate; 1161 + struct clk *clkin; 1162 + u32 val; 1163 + int ret; 1164 + 1165 + ret = ltc428_clk_provider_setup(st, dev); 1166 + if (ret) 1167 + return ret; 1168 + 1169 + clkin = devm_clk_get_optional_enabled(dev, NULL); 1170 + if (IS_ERR(clkin)) 1171 + return dev_err_probe(dev, PTR_ERR(clkin), 1172 + "Failed to get clkin"); 1173 + if (!clkin) 1174 + return 0; 1175 + 1176 + rate = clk_get_rate(clkin); 1177 + if (!in_range(rate, LTC4282_CLKIN_MIN, LTC4282_CLKIN_RANGE)) 1178 + return dev_err_probe(dev, -EINVAL, 1179 + "Invalid clkin range(%lu) [%lu %lu]\n", 1180 + rate, LTC4282_CLKIN_MIN, 1181 + LTC4282_CLKIN_MAX); 1182 + 1183 + /* 1184 + * Clocks faster than 250KHZ should be reduced to 250KHZ. The clock 1185 + * frequency is divided by twice the value in the register. 1186 + */ 1187 + val = rate / (2 * LTC4282_CLKIN_MIN); 1188 + 1189 + return regmap_update_bits(st->map, LTC4282_CLK_DIV, 1190 + LTC4282_CLK_DIV_MASK, 1191 + FIELD_PREP(LTC4282_CLK_DIV_MASK, val)); 1192 + } 1193 + 1194 + static const int ltc4282_curr_lim_uv[] = { 1195 + 12500, 15625, 18750, 21875, 25000, 28125, 31250, 34375 1196 + }; 1197 + 1198 + static int ltc4282_get_defaults(struct ltc4282_state *st, u32 *vin_mode) 1199 + { 1200 + u32 reg_val, ilm_adjust; 1201 + int ret; 1202 + 1203 + ret = regmap_read(st->map, LTC4282_ADC_CTRL, &reg_val); 1204 + if (ret) 1205 + return ret; 1206 + 1207 + st->energy_en = !FIELD_GET(LTC4282_METER_HALT_MASK, reg_val); 1208 + 1209 + ret = regmap_read(st->map, LTC4282_CTRL_MSB, &reg_val); 1210 + if (ret) 1211 + return ret; 1212 + 1213 + *vin_mode = FIELD_GET(LTC4282_CTRL_VIN_MODE_MASK, reg_val); 1214 + 1215 + ret = regmap_read(st->map, LTC4282_ILIM_ADJUST, &reg_val); 1216 + if (ret) 1217 + return ret; 1218 + 1219 + ilm_adjust = FIELD_GET(LTC4282_ILIM_ADJUST_MASK, reg_val); 1220 + st->vsense_max = ltc4282_curr_lim_uv[ilm_adjust]; 1221 + 1222 + st->in0_1_cache[LTC4282_CHAN_VSOURCE].en = FIELD_GET(LTC4282_VDD_MONITOR_MASK, 1223 + ilm_adjust); 1224 + if (!st->in0_1_cache[LTC4282_CHAN_VSOURCE].en) { 1225 + st->in0_1_cache[LTC4282_CHAN_VDD].en = true; 1226 + return regmap_read(st->map, LTC4282_VSOURCE_MAX, 1227 + &st->in0_1_cache[LTC4282_CHAN_VSOURCE].in_max_raw); 1228 + } 1229 + 1230 + return regmap_read(st->map, LTC4282_VSOURCE_MAX, 1231 + &st->in0_1_cache[LTC4282_CHAN_VDD].in_max_raw); 1232 + } 1233 + 1234 + /* 1235 + * Set max limits for ISENSE and Power as that depends on the max voltage on 1236 + * rsense that is defined in ILIM_ADJUST. This is specially important for power 1237 + * because for some rsense and vfsout values, if we allow the default raw 255 1238 + * value, that would overflow long in 32bit archs when reading back the max 1239 + * power limit. 1240 + * 1241 + * Also set meaningful historic values for VDD and VSOURCE 1242 + * (0 would not mean much). 1243 + */ 1244 + static int ltc4282_set_max_limits(struct ltc4282_state *st) 1245 + { 1246 + int ret; 1247 + 1248 + ret = ltc4282_write_voltage_byte(st, LTC4282_VSENSE_MAX, 40 * MILLI, 1249 + st->vsense_max); 1250 + if (ret) 1251 + return ret; 1252 + 1253 + /* Power is given by ISENSE * Vout. */ 1254 + st->power_max = DIV_ROUND_CLOSEST(st->vsense_max * DECA * MILLI, st->rsense) * st->vfs_out; 1255 + ret = ltc4282_write_power_byte(st, LTC4282_POWER_MAX, st->power_max); 1256 + if (ret) 1257 + return ret; 1258 + 1259 + if (st->in0_1_cache[LTC4282_CHAN_VDD].en) { 1260 + st->in0_1_cache[LTC4282_CHAN_VSOURCE].in_lowest = st->vfs_out; 1261 + return __ltc4282_in_write_history(st, LTC4282_VSOURCE_LOWEST, 1262 + st->vdd, 0, st->vfs_out); 1263 + } 1264 + 1265 + st->in0_1_cache[LTC4282_CHAN_VDD].in_lowest = st->vdd; 1266 + return __ltc4282_in_write_history(st, LTC4282_VSOURCE_LOWEST, 1267 + st->vfs_out, 0, st->vfs_out); 1268 + } 1269 + 1270 + static const char * const ltc4282_gpio1_modes[] = { 1271 + "power_bad", "power_good" 1272 + }; 1273 + 1274 + static const char * const ltc4282_gpio2_modes[] = { 1275 + "adc_input", "stress_fet" 1276 + }; 1277 + 1278 + static int ltc4282_gpio_setup(struct ltc4282_state *st, struct device *dev) 1279 + { 1280 + const char *func = NULL; 1281 + int ret; 1282 + 1283 + ret = device_property_read_string(dev, "adi,gpio1-mode", &func); 1284 + if (!ret) { 1285 + ret = match_string(ltc4282_gpio1_modes, 1286 + ARRAY_SIZE(ltc4282_gpio1_modes), func); 1287 + if (ret < 0) 1288 + return dev_err_probe(dev, ret, 1289 + "Invalid func(%s) for gpio1\n", 1290 + func); 1291 + 1292 + ret = regmap_update_bits(st->map, LTC4282_GPIO_CONFIG, 1293 + LTC4282_GPIO_1_CONFIG_MASK, 1294 + FIELD_PREP(LTC4282_GPIO_1_CONFIG_MASK, ret)); 1295 + if (ret) 1296 + return ret; 1297 + } 1298 + 1299 + ret = device_property_read_string(dev, "adi,gpio2-mode", &func); 1300 + if (!ret) { 1301 + ret = match_string(ltc4282_gpio2_modes, 1302 + ARRAY_SIZE(ltc4282_gpio2_modes), func); 1303 + if (ret < 0) 1304 + return dev_err_probe(dev, ret, 1305 + "Invalid func(%s) for gpio2\n", 1306 + func); 1307 + if (!ret) { 1308 + /* setting the bit to 1 so the ADC to monitors GPIO2 */ 1309 + ret = regmap_set_bits(st->map, LTC4282_ILIM_ADJUST, 1310 + LTC4282_GPIO_MODE_MASK); 1311 + } else { 1312 + ret = regmap_update_bits(st->map, LTC4282_GPIO_CONFIG, 1313 + LTC4282_GPIO_2_FET_STRESS_MASK, 1314 + FIELD_PREP(LTC4282_GPIO_2_FET_STRESS_MASK, 1)); 1315 + } 1316 + 1317 + if (ret) 1318 + return ret; 1319 + } 1320 + 1321 + if (!device_property_read_bool(dev, "adi,gpio3-monitor-enable")) 1322 + return 0; 1323 + 1324 + if (func && !strcmp(func, "adc_input")) 1325 + return dev_err_probe(dev, -EINVAL, 1326 + "Cannot have both gpio2 and gpio3 muxed into the ADC"); 1327 + 1328 + return regmap_clear_bits(st->map, LTC4282_ILIM_ADJUST, 1329 + LTC4282_GPIO_MODE_MASK); 1330 + } 1331 + 1332 + static const char * const ltc4282_dividers[] = { 1333 + "external", "vdd_5_percent", "vdd_10_percent", "vdd_15_percent" 1334 + }; 1335 + 1336 + /* This maps the Vout full scale for the given Vin mode */ 1337 + static const u16 ltc4282_vfs_milli[] = { 5540, 8320, 16640, 33280 }; 1338 + 1339 + static const u16 ltc4282_vdd_milli[] = { 3300, 5000, 12000, 24000 }; 1340 + 1341 + enum { 1342 + LTC4282_VIN_3_3V, 1343 + LTC4282_VIN_5V, 1344 + LTC4282_VIN_12V, 1345 + LTC4282_VIN_24V, 1346 + }; 1347 + 1348 + static int ltc4282_setup(struct ltc4282_state *st, struct device *dev) 1349 + { 1350 + const char *divider; 1351 + u32 val, vin_mode; 1352 + int ret; 1353 + 1354 + /* The part has an eeprom so let's get the needed defaults from it */ 1355 + ret = ltc4282_get_defaults(st, &vin_mode); 1356 + if (ret) 1357 + return ret; 1358 + 1359 + ret = device_property_read_u32(dev, "adi,rsense-nano-ohms", 1360 + &st->rsense); 1361 + if (ret) 1362 + return dev_err_probe(dev, ret, 1363 + "Failed to read adi,rsense-nano-ohms\n"); 1364 + if (st->rsense < CENTI) 1365 + return dev_err_probe(dev, -EINVAL, 1366 + "adi,rsense-nano-ohms too small (< %lu)\n", 1367 + CENTI); 1368 + 1369 + /* 1370 + * The resolution for rsense is tenths of micro (eg: 62.5 uOhm) which 1371 + * means we need nano in the bindings. However, to make things easier to 1372 + * handle (with respect to overflows) we divide it by 100 as we don't 1373 + * really need the last two digits. 1374 + */ 1375 + st->rsense /= CENTI; 1376 + 1377 + val = vin_mode; 1378 + ret = device_property_read_u32(dev, "adi,vin-mode-microvolt", &val); 1379 + if (!ret) { 1380 + switch (val) { 1381 + case 3300000: 1382 + val = LTC4282_VIN_3_3V; 1383 + break; 1384 + case 5000000: 1385 + val = LTC4282_VIN_5V; 1386 + break; 1387 + case 12000000: 1388 + val = LTC4282_VIN_12V; 1389 + break; 1390 + case 24000000: 1391 + val = LTC4282_VIN_24V; 1392 + break; 1393 + default: 1394 + return dev_err_probe(dev, -EINVAL, 1395 + "Invalid val(%u) for vin-mode-microvolt\n", 1396 + val); 1397 + } 1398 + 1399 + ret = regmap_update_bits(st->map, LTC4282_CTRL_MSB, 1400 + LTC4282_CTRL_VIN_MODE_MASK, 1401 + FIELD_PREP(LTC4282_CTRL_VIN_MODE_MASK, val)); 1402 + if (ret) 1403 + return ret; 1404 + 1405 + /* Foldback mode should also be set to the input voltage */ 1406 + ret = regmap_update_bits(st->map, LTC4282_ILIM_ADJUST, 1407 + LTC4282_FOLDBACK_MODE_MASK, 1408 + FIELD_PREP(LTC4282_FOLDBACK_MODE_MASK, val)); 1409 + if (ret) 1410 + return ret; 1411 + } 1412 + 1413 + st->vfs_out = ltc4282_vfs_milli[val]; 1414 + st->vdd = ltc4282_vdd_milli[val]; 1415 + 1416 + ret = device_property_read_u32(dev, "adi,current-limit-sense-microvolt", 1417 + &st->vsense_max); 1418 + if (!ret) { 1419 + int reg_val; 1420 + 1421 + switch (val) { 1422 + case 12500: 1423 + reg_val = 0; 1424 + break; 1425 + case 15625: 1426 + reg_val = 1; 1427 + break; 1428 + case 18750: 1429 + reg_val = 2; 1430 + break; 1431 + case 21875: 1432 + reg_val = 3; 1433 + break; 1434 + case 25000: 1435 + reg_val = 4; 1436 + break; 1437 + case 28125: 1438 + reg_val = 5; 1439 + break; 1440 + case 31250: 1441 + reg_val = 6; 1442 + break; 1443 + case 34375: 1444 + reg_val = 7; 1445 + break; 1446 + default: 1447 + return dev_err_probe(dev, -EINVAL, 1448 + "Invalid val(%u) for adi,current-limit-microvolt\n", 1449 + st->vsense_max); 1450 + } 1451 + 1452 + ret = regmap_update_bits(st->map, LTC4282_ILIM_ADJUST, 1453 + LTC4282_ILIM_ADJUST_MASK, 1454 + FIELD_PREP(LTC4282_ILIM_ADJUST_MASK, reg_val)); 1455 + if (ret) 1456 + return ret; 1457 + } 1458 + 1459 + ret = ltc4282_set_max_limits(st); 1460 + if (ret) 1461 + return ret; 1462 + 1463 + ret = device_property_read_string(dev, "adi,overvoltage-dividers", 1464 + &divider); 1465 + if (!ret) { 1466 + int div = match_string(ltc4282_dividers, 1467 + ARRAY_SIZE(ltc4282_dividers), divider); 1468 + if (div < 0) 1469 + return dev_err_probe(dev, -EINVAL, 1470 + "Invalid val(%s) for adi,overvoltage-divider\n", 1471 + divider); 1472 + 1473 + ret = regmap_update_bits(st->map, LTC4282_CTRL_MSB, 1474 + LTC4282_CTRL_OV_MODE_MASK, 1475 + FIELD_PREP(LTC4282_CTRL_OV_MODE_MASK, div)); 1476 + } 1477 + 1478 + ret = device_property_read_string(dev, "adi,undervoltage-dividers", 1479 + &divider); 1480 + if (!ret) { 1481 + int div = match_string(ltc4282_dividers, 1482 + ARRAY_SIZE(ltc4282_dividers), divider); 1483 + if (div < 0) 1484 + return dev_err_probe(dev, -EINVAL, 1485 + "Invalid val(%s) for adi,undervoltage-divider\n", 1486 + divider); 1487 + 1488 + ret = regmap_update_bits(st->map, LTC4282_CTRL_MSB, 1489 + LTC4282_CTRL_UV_MODE_MASK, 1490 + FIELD_PREP(LTC4282_CTRL_UV_MODE_MASK, div)); 1491 + } 1492 + 1493 + if (device_property_read_bool(dev, "adi,overcurrent-retry")) { 1494 + ret = regmap_set_bits(st->map, LTC4282_CTRL_LSB, 1495 + LTC4282_CTRL_OC_RETRY_MASK); 1496 + if (ret) 1497 + return ret; 1498 + } 1499 + 1500 + if (device_property_read_bool(dev, "adi,overvoltage-retry-disable")) { 1501 + ret = regmap_clear_bits(st->map, LTC4282_CTRL_LSB, 1502 + LTC4282_CTRL_OV_RETRY_MASK); 1503 + if (ret) 1504 + return ret; 1505 + } 1506 + 1507 + if (device_property_read_bool(dev, "adi,undervoltage-retry-disable")) { 1508 + ret = regmap_clear_bits(st->map, LTC4282_CTRL_LSB, 1509 + LTC4282_CTRL_UV_RETRY_MASK); 1510 + if (ret) 1511 + return ret; 1512 + } 1513 + 1514 + if (device_property_read_bool(dev, "adi,fault-log-enable")) { 1515 + ret = regmap_set_bits(st->map, LTC4282_ADC_CTRL, 1516 + LTC4282_FAULT_LOG_EN_MASK); 1517 + if (ret) 1518 + return ret; 1519 + } 1520 + 1521 + if (device_property_read_bool(dev, "adi,fault-log-enable")) { 1522 + ret = regmap_set_bits(st->map, LTC4282_ADC_CTRL, LTC4282_FAULT_LOG_EN_MASK); 1523 + if (ret) 1524 + return ret; 1525 + } 1526 + 1527 + ret = device_property_read_u32(dev, "adi,fet-bad-timeout-ms", &val); 1528 + if (!ret) { 1529 + if (val > LTC4282_FET_BAD_MAX_TIMEOUT) 1530 + return dev_err_probe(dev, -EINVAL, 1531 + "Invalid value(%u) for adi,fet-bad-timeout-ms", 1532 + val); 1533 + 1534 + ret = regmap_write(st->map, LTC4282_FET_BAD_FAULT_TIMEOUT, val); 1535 + if (ret) 1536 + return ret; 1537 + } 1538 + 1539 + return ltc4282_gpio_setup(st, dev); 1540 + } 1541 + 1542 + static bool ltc4282_readable_reg(struct device *dev, unsigned int reg) 1543 + { 1544 + if (reg == LTC4282_RESERVED_1 || reg == LTC4282_RESERVED_2) 1545 + return false; 1546 + 1547 + return true; 1548 + } 1549 + 1550 + static bool ltc4282_writable_reg(struct device *dev, unsigned int reg) 1551 + { 1552 + if (reg == LTC4282_STATUS_LSB || reg == LTC4282_STATUS_MSB) 1553 + return false; 1554 + if (reg == LTC4282_RESERVED_1 || reg == LTC4282_RESERVED_2) 1555 + return false; 1556 + 1557 + return true; 1558 + } 1559 + 1560 + static const struct regmap_config ltc4282_regmap_config = { 1561 + .reg_bits = 8, 1562 + .val_bits = 8, 1563 + .max_register = LTC4282_RESERVED_3, 1564 + .readable_reg = ltc4282_readable_reg, 1565 + .writeable_reg = ltc4282_writable_reg, 1566 + }; 1567 + 1568 + static const struct hwmon_channel_info * const ltc4282_info[] = { 1569 + HWMON_CHANNEL_INFO(in, 1570 + HWMON_I_INPUT | HWMON_I_LOWEST | HWMON_I_HIGHEST | 1571 + HWMON_I_MAX | HWMON_I_MIN | HWMON_I_MIN_ALARM | 1572 + HWMON_I_MAX_ALARM | HWMON_I_ENABLE | 1573 + HWMON_I_RESET_HISTORY | HWMON_I_FAULT | 1574 + HWMON_I_LABEL, 1575 + HWMON_I_INPUT | HWMON_I_LOWEST | HWMON_I_HIGHEST | 1576 + HWMON_I_MAX | HWMON_I_MIN | HWMON_I_MIN_ALARM | 1577 + HWMON_I_MAX_ALARM | HWMON_I_LCRIT_ALARM | 1578 + HWMON_I_CRIT_ALARM | HWMON_I_ENABLE | 1579 + HWMON_I_RESET_HISTORY | HWMON_I_LABEL, 1580 + HWMON_I_INPUT | HWMON_I_LOWEST | HWMON_I_HIGHEST | 1581 + HWMON_I_MAX | HWMON_I_MIN | HWMON_I_MIN_ALARM | 1582 + HWMON_I_RESET_HISTORY | HWMON_I_MAX_ALARM | 1583 + HWMON_I_LABEL), 1584 + HWMON_CHANNEL_INFO(curr, 1585 + HWMON_C_INPUT | HWMON_C_LOWEST | HWMON_C_HIGHEST | 1586 + HWMON_C_MAX | HWMON_C_MIN | HWMON_C_MIN_ALARM | 1587 + HWMON_C_MAX_ALARM | HWMON_C_CRIT_ALARM | 1588 + HWMON_C_RESET_HISTORY | HWMON_C_LABEL), 1589 + HWMON_CHANNEL_INFO(power, 1590 + HWMON_P_INPUT | HWMON_P_INPUT_LOWEST | 1591 + HWMON_P_INPUT_HIGHEST | HWMON_P_MAX | HWMON_P_MIN | 1592 + HWMON_P_MAX_ALARM | HWMON_P_MIN_ALARM | 1593 + HWMON_P_RESET_HISTORY | HWMON_P_LABEL), 1594 + HWMON_CHANNEL_INFO(energy, 1595 + HWMON_E_ENABLE), 1596 + NULL 1597 + }; 1598 + 1599 + static const struct hwmon_ops ltc4282_hwmon_ops = { 1600 + .read = ltc4282_read, 1601 + .write = ltc4282_write, 1602 + .is_visible = ltc4282_is_visible, 1603 + .read_string = ltc4282_read_labels, 1604 + }; 1605 + 1606 + static const struct hwmon_chip_info ltc2947_chip_info = { 1607 + .ops = &ltc4282_hwmon_ops, 1608 + .info = ltc4282_info, 1609 + }; 1610 + 1611 + /* energy attributes are 6bytes wide so we need u64 */ 1612 + static SENSOR_DEVICE_ATTR_RO(energy1_input, ltc4282_energy, 0); 1613 + 1614 + static struct attribute *ltc4282_attrs[] = { 1615 + &sensor_dev_attr_energy1_input.dev_attr.attr, 1616 + NULL 1617 + }; 1618 + ATTRIBUTE_GROUPS(ltc4282); 1619 + 1620 + static int ltc4282_show_fault_log(void *arg, u64 *val, u32 mask) 1621 + { 1622 + struct ltc4282_state *st = arg; 1623 + long alarm; 1624 + int ret; 1625 + 1626 + ret = ltc4282_read_alarm(st, LTC4282_FAULT_LOG, mask, &alarm); 1627 + if (ret) 1628 + return ret; 1629 + 1630 + *val = alarm; 1631 + 1632 + return 0; 1633 + } 1634 + 1635 + static int ltc4282_show_curr1_crit_fault_log(void *arg, u64 *val) 1636 + { 1637 + return ltc4282_show_fault_log(arg, val, LTC4282_OC_FAULT_MASK); 1638 + } 1639 + DEFINE_DEBUGFS_ATTRIBUTE(ltc4282_curr1_crit_fault_log, 1640 + ltc4282_show_curr1_crit_fault_log, NULL, "%llu\n"); 1641 + 1642 + static int ltc4282_show_in1_lcrit_fault_log(void *arg, u64 *val) 1643 + { 1644 + return ltc4282_show_fault_log(arg, val, LTC4282_UV_FAULT_MASK); 1645 + } 1646 + DEFINE_DEBUGFS_ATTRIBUTE(ltc4282_in1_lcrit_fault_log, 1647 + ltc4282_show_in1_lcrit_fault_log, NULL, "%llu\n"); 1648 + 1649 + static int ltc4282_show_in1_crit_fault_log(void *arg, u64 *val) 1650 + { 1651 + return ltc4282_show_fault_log(arg, val, LTC4282_OV_FAULT_MASK); 1652 + } 1653 + DEFINE_DEBUGFS_ATTRIBUTE(ltc4282_in1_crit_fault_log, 1654 + ltc4282_show_in1_crit_fault_log, NULL, "%llu\n"); 1655 + 1656 + static int ltc4282_show_fet_bad_fault_log(void *arg, u64 *val) 1657 + { 1658 + return ltc4282_show_fault_log(arg, val, LTC4282_FET_BAD_FAULT_MASK); 1659 + } 1660 + DEFINE_DEBUGFS_ATTRIBUTE(ltc4282_fet_bad_fault_log, 1661 + ltc4282_show_fet_bad_fault_log, NULL, "%llu\n"); 1662 + 1663 + static int ltc4282_show_fet_short_fault_log(void *arg, u64 *val) 1664 + { 1665 + return ltc4282_show_fault_log(arg, val, LTC4282_FET_SHORT_FAULT_MASK); 1666 + } 1667 + DEFINE_DEBUGFS_ATTRIBUTE(ltc4282_fet_short_fault_log, 1668 + ltc4282_show_fet_short_fault_log, NULL, "%llu\n"); 1669 + 1670 + static int ltc4282_show_power1_bad_fault_log(void *arg, u64 *val) 1671 + { 1672 + return ltc4282_show_fault_log(arg, val, LTC4282_POWER_BAD_FAULT_MASK); 1673 + } 1674 + DEFINE_DEBUGFS_ATTRIBUTE(ltc4282_power1_bad_fault_log, 1675 + ltc4282_show_power1_bad_fault_log, NULL, "%llu\n"); 1676 + 1677 + static void ltc4282_debugfs_remove(void *dir) 1678 + { 1679 + debugfs_remove_recursive(dir); 1680 + } 1681 + 1682 + static void ltc4282_debugfs_init(struct ltc4282_state *st, 1683 + struct i2c_client *i2c, 1684 + const struct device *hwmon) 1685 + { 1686 + const char *debugfs_name; 1687 + struct dentry *dentry; 1688 + int ret; 1689 + 1690 + if (!IS_ENABLED(CONFIG_DEBUG_FS)) 1691 + return; 1692 + 1693 + debugfs_name = devm_kasprintf(&i2c->dev, GFP_KERNEL, "ltc4282-%s", 1694 + dev_name(hwmon)); 1695 + if (!debugfs_name) 1696 + return; 1697 + 1698 + dentry = debugfs_create_dir(debugfs_name, NULL); 1699 + if (IS_ERR(dentry)) 1700 + return; 1701 + 1702 + ret = devm_add_action_or_reset(&i2c->dev, ltc4282_debugfs_remove, 1703 + dentry); 1704 + if (ret) 1705 + return; 1706 + 1707 + debugfs_create_file_unsafe("power1_bad_fault_log", 0400, dentry, st, 1708 + &ltc4282_power1_bad_fault_log); 1709 + debugfs_create_file_unsafe("in0_fet_short_fault_log", 0400, dentry, st, 1710 + &ltc4282_fet_short_fault_log); 1711 + debugfs_create_file_unsafe("in0_fet_bad_fault_log", 0400, dentry, st, 1712 + &ltc4282_fet_bad_fault_log); 1713 + debugfs_create_file_unsafe("in1_crit_fault_log", 0400, dentry, st, 1714 + &ltc4282_in1_crit_fault_log); 1715 + debugfs_create_file_unsafe("in1_lcrit_fault_log", 0400, dentry, st, 1716 + &ltc4282_in1_lcrit_fault_log); 1717 + debugfs_create_file_unsafe("curr1_crit_fault_log", 0400, dentry, st, 1718 + &ltc4282_curr1_crit_fault_log); 1719 + } 1720 + 1721 + static int ltc4282_probe(struct i2c_client *i2c) 1722 + { 1723 + struct device *dev = &i2c->dev, *hwmon; 1724 + struct ltc4282_state *st; 1725 + int ret; 1726 + 1727 + st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL); 1728 + if (!st) 1729 + return dev_err_probe(dev, -ENOMEM, 1730 + "Failed to allocate memory\n"); 1731 + 1732 + st->map = devm_regmap_init_i2c(i2c, &ltc4282_regmap_config); 1733 + if (IS_ERR(st->map)) 1734 + return dev_err_probe(dev, PTR_ERR(st->map), 1735 + "failed regmap init\n"); 1736 + 1737 + /* Soft reset */ 1738 + ret = regmap_set_bits(st->map, LTC4282_ADC_CTRL, LTC4282_RESET_MASK); 1739 + if (ret) 1740 + return ret; 1741 + 1742 + /* Yes, it's big but it is as specified in the datasheet */ 1743 + msleep(3200); 1744 + 1745 + ret = ltc428_clks_setup(st, dev); 1746 + if (ret) 1747 + return ret; 1748 + 1749 + ret = ltc4282_setup(st, dev); 1750 + if (ret) 1751 + return ret; 1752 + 1753 + mutex_init(&st->lock); 1754 + hwmon = devm_hwmon_device_register_with_info(dev, "ltc4282", st, 1755 + &ltc2947_chip_info, 1756 + ltc4282_groups); 1757 + if (IS_ERR(hwmon)) 1758 + return PTR_ERR(hwmon); 1759 + 1760 + ltc4282_debugfs_init(st, i2c, hwmon); 1761 + 1762 + return 0; 1763 + } 1764 + 1765 + static const struct of_device_id ltc4282_of_match[] = { 1766 + { .compatible = "adi,ltc4282" }, 1767 + {} 1768 + }; 1769 + MODULE_DEVICE_TABLE(of, ltc4282_of_match); 1770 + 1771 + static struct i2c_driver ltc4282_driver = { 1772 + .driver = { 1773 + .name = "ltc4282", 1774 + .of_match_table = ltc4282_of_match, 1775 + }, 1776 + .probe = ltc4282_probe, 1777 + }; 1778 + module_i2c_driver(ltc4282_driver); 1779 + 1780 + MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>"); 1781 + MODULE_DESCRIPTION("LTC4282 I2C High Current Hot Swap Controller"); 1782 + MODULE_LICENSE("GPL");
-1
drivers/hwmon/max127.c
··· 335 335 MODULE_DEVICE_TABLE(i2c, max127_id); 336 336 337 337 static struct i2c_driver max127_driver = { 338 - .class = I2C_CLASS_HWMON, 339 338 .driver = { 340 339 .name = "max127", 341 340 },
+1 -2
drivers/hwmon/max31760.c
··· 60 60 .reg_bits = 8, 61 61 .val_bits = 8, 62 62 .max_register = 0x5B, 63 - .cache_type = REGCACHE_RBTREE, 63 + .cache_type = REGCACHE_MAPLE, 64 64 .volatile_reg = max31760_volatile_reg, 65 65 }; 66 66 ··· 578 578 max31760_resume); 579 579 580 580 static struct i2c_driver max31760_driver = { 581 - .class = I2C_CLASS_HWMON, 582 581 .driver = { 583 582 .name = "max31760", 584 583 .of_match_table = max31760_of_match,
-1
drivers/hwmon/max31790.c
··· 543 543 MODULE_DEVICE_TABLE(i2c, max31790_id); 544 544 545 545 static struct i2c_driver max31790_driver = { 546 - .class = I2C_CLASS_HWMON, 547 546 .probe = max31790_probe, 548 547 .driver = { 549 548 .name = "max31790",
-1
drivers/hwmon/max31827.c
··· 652 652 MODULE_DEVICE_TABLE(of, max31827_of_match); 653 653 654 654 static struct i2c_driver max31827_driver = { 655 - .class = I2C_CLASS_HWMON, 656 655 .driver = { 657 656 .name = "max31827", 658 657 .of_match_table = max31827_of_match,
-1
drivers/hwmon/max6621.c
··· 549 549 MODULE_DEVICE_TABLE(of, max6621_of_match); 550 550 551 551 static struct i2c_driver max6621_driver = { 552 - .class = I2C_CLASS_HWMON, 553 552 .driver = { 554 553 .name = MAX6621_DRV_NAME, 555 554 .of_match_table = of_match_ptr(max6621_of_match),
-1
drivers/hwmon/max6697.c
··· 780 780 MODULE_DEVICE_TABLE(of, max6697_of_match); 781 781 782 782 static struct i2c_driver max6697_driver = { 783 - .class = I2C_CLASS_HWMON, 784 783 .driver = { 785 784 .name = "max6697", 786 785 .of_match_table = of_match_ptr(max6697_of_match),
+3
drivers/hwmon/nct6683.c
··· 174 174 #define NCT6683_CUSTOMER_ID_MITAC 0xa0e 175 175 #define NCT6683_CUSTOMER_ID_MSI 0x201 176 176 #define NCT6683_CUSTOMER_ID_MSI2 0x200 177 + #define NCT6683_CUSTOMER_ID_MSI3 0x207 177 178 #define NCT6683_CUSTOMER_ID_ASROCK 0xe2c 178 179 #define NCT6683_CUSTOMER_ID_ASROCK2 0xe1b 179 180 #define NCT6683_CUSTOMER_ID_ASROCK3 0x1631 ··· 1224 1223 case NCT6683_CUSTOMER_ID_MSI: 1225 1224 break; 1226 1225 case NCT6683_CUSTOMER_ID_MSI2: 1226 + break; 1227 + case NCT6683_CUSTOMER_ID_MSI3: 1227 1228 break; 1228 1229 case NCT6683_CUSTOMER_ID_ASROCK: 1229 1230 break;
+1 -1
drivers/hwmon/nct7802.c
··· 1051 1051 static const struct regmap_config nct7802_regmap_config = { 1052 1052 .reg_bits = 8, 1053 1053 .val_bits = 8, 1054 - .cache_type = REGCACHE_RBTREE, 1054 + .cache_type = REGCACHE_MAPLE, 1055 1055 .volatile_reg = nct7802_regmap_is_volatile, 1056 1056 }; 1057 1057
+1008
drivers/hwmon/nzxt-kraken3.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * hwmon driver for NZXT Kraken X53/X63/X73 and Z53/Z63/Z73 all in one coolers. 4 + * X53 and Z53 in code refer to all models in their respective series (shortened 5 + * for brevity). 6 + * 7 + * Copyright 2021 Jonas Malaco <jonas@protocubo.io> 8 + * Copyright 2022 Aleksa Savic <savicaleksa83@gmail.com> 9 + */ 10 + 11 + #include <linux/debugfs.h> 12 + #include <linux/hid.h> 13 + #include <linux/hwmon.h> 14 + #include <linux/hwmon-sysfs.h> 15 + #include <linux/jiffies.h> 16 + #include <linux/module.h> 17 + #include <linux/mutex.h> 18 + #include <linux/spinlock.h> 19 + #include <linux/wait.h> 20 + #include <asm/unaligned.h> 21 + 22 + #define USB_VENDOR_ID_NZXT 0x1e71 23 + #define USB_PRODUCT_ID_X53 0x2007 24 + #define USB_PRODUCT_ID_X53_SECOND 0x2014 25 + #define USB_PRODUCT_ID_Z53 0x3008 26 + 27 + enum kinds { X53, Z53 } __packed; 28 + enum pwm_enable { off, manual, curve } __packed; 29 + 30 + static const char *const kraken3_device_names[] = { 31 + [X53] = "x53", 32 + [Z53] = "z53", 33 + }; 34 + 35 + #define DRIVER_NAME "nzxt_kraken3" 36 + #define STATUS_REPORT_ID 0x75 37 + #define FIRMWARE_REPORT_ID 0x11 38 + #define STATUS_VALIDITY 2000 /* In ms, equivalent to period of four status reports */ 39 + #define CUSTOM_CURVE_POINTS 40 /* For temps from 20C to 59C (critical temp) */ 40 + #define PUMP_DUTY_MIN 20 /* In percent */ 41 + 42 + /* Sensor report offsets for Kraken X53 and Z53 */ 43 + #define TEMP_SENSOR_START_OFFSET 15 44 + #define TEMP_SENSOR_END_OFFSET 16 45 + #define PUMP_SPEED_OFFSET 17 46 + #define PUMP_DUTY_OFFSET 19 47 + 48 + /* Firmware version report offset for Kraken X53 and Z53 */ 49 + #define FIRMWARE_VERSION_OFFSET 17 50 + 51 + /* Sensor report offsets for Kraken Z53 */ 52 + #define Z53_FAN_SPEED_OFFSET 23 53 + #define Z53_FAN_DUTY_OFFSET 25 54 + 55 + /* Report offsets for control commands for Kraken X53 and Z53 */ 56 + #define SET_DUTY_ID_OFFSET 1 57 + 58 + /* Control commands and their lengths for Kraken X53 and Z53 */ 59 + 60 + /* Last byte sets the report interval at 0.5s */ 61 + static const u8 set_interval_cmd[] = { 0x70, 0x02, 0x01, 0xB8, 1 }; 62 + static const u8 finish_init_cmd[] = { 0x70, 0x01 }; 63 + static const u8 __maybe_unused get_fw_version_cmd[] = { 0x10, 0x01 }; 64 + static const u8 set_pump_duty_cmd_header[] = { 0x72, 0x00, 0x00, 0x00 }; 65 + static const u8 z53_get_status_cmd[] = { 0x74, 0x01 }; 66 + 67 + #define SET_INTERVAL_CMD_LENGTH 5 68 + #define FINISH_INIT_CMD_LENGTH 2 69 + #define GET_FW_VERSION_CMD_LENGTH 2 70 + #define MAX_REPORT_LENGTH 64 71 + #define MIN_REPORT_LENGTH 20 72 + #define SET_CURVE_DUTY_CMD_HEADER_LENGTH 4 73 + /* 4 byte header and 40 duty offsets */ 74 + #define SET_CURVE_DUTY_CMD_LENGTH (4 + 40) 75 + #define Z53_GET_STATUS_CMD_LENGTH 2 76 + 77 + static const char *const kraken3_temp_label[] = { 78 + "Coolant temp", 79 + }; 80 + 81 + static const char *const kraken3_fan_label[] = { 82 + "Pump speed", 83 + "Fan speed" 84 + }; 85 + 86 + struct kraken3_channel_info { 87 + enum pwm_enable mode; 88 + 89 + /* Both values are PWM */ 90 + u16 reported_duty; 91 + u16 fixed_duty; /* Manually set fixed duty */ 92 + 93 + u8 pwm_points[CUSTOM_CURVE_POINTS]; 94 + }; 95 + 96 + struct kraken3_data { 97 + struct hid_device *hdev; 98 + struct device *hwmon_dev; 99 + struct dentry *debugfs; 100 + struct mutex buffer_lock; /* For locking access to buffer */ 101 + struct mutex z53_status_request_lock; 102 + struct completion fw_version_processed; 103 + /* 104 + * For X53 devices, tracks whether an initial (one) sensor report was received to 105 + * make fancontrol not bail outright. For Z53 devices, whether a status report 106 + * was processed after requesting one. 107 + */ 108 + struct completion status_report_processed; 109 + /* For locking the above completion */ 110 + spinlock_t status_completion_lock; 111 + 112 + u8 *buffer; 113 + struct kraken3_channel_info channel_info[2]; /* Pump and fan */ 114 + bool is_device_faulty; 115 + 116 + /* Sensor values */ 117 + s32 temp_input[1]; 118 + u16 fan_input[2]; 119 + 120 + enum kinds kind; 121 + u8 firmware_version[3]; 122 + 123 + unsigned long updated; /* jiffies */ 124 + }; 125 + 126 + static umode_t kraken3_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr, 127 + int channel) 128 + { 129 + const struct kraken3_data *priv = data; 130 + 131 + switch (type) { 132 + case hwmon_temp: 133 + if (channel < 1) 134 + return 0444; 135 + break; 136 + case hwmon_fan: 137 + switch (priv->kind) { 138 + case X53: 139 + /* Just the pump */ 140 + if (channel < 1) 141 + return 0444; 142 + break; 143 + case Z53: 144 + /* Pump and fan */ 145 + if (channel < 2) 146 + return 0444; 147 + break; 148 + default: 149 + break; 150 + } 151 + break; 152 + case hwmon_pwm: 153 + switch (attr) { 154 + case hwmon_pwm_enable: 155 + case hwmon_pwm_input: 156 + switch (priv->kind) { 157 + case X53: 158 + /* Just the pump */ 159 + if (channel < 1) 160 + return 0644; 161 + break; 162 + case Z53: 163 + /* Pump and fan */ 164 + if (channel < 2) 165 + return 0644; 166 + break; 167 + default: 168 + break; 169 + } 170 + break; 171 + default: 172 + break; 173 + } 174 + break; 175 + default: 176 + break; 177 + } 178 + 179 + return 0; 180 + } 181 + 182 + /* 183 + * Writes the command to the device with the rest of the report (up to 64 bytes) filled 184 + * with zeroes. 185 + */ 186 + static int kraken3_write_expanded(struct kraken3_data *priv, const u8 *cmd, int cmd_length) 187 + { 188 + int ret; 189 + 190 + mutex_lock(&priv->buffer_lock); 191 + 192 + memcpy_and_pad(priv->buffer, MAX_REPORT_LENGTH, cmd, cmd_length, 0x00); 193 + ret = hid_hw_output_report(priv->hdev, priv->buffer, MAX_REPORT_LENGTH); 194 + 195 + mutex_unlock(&priv->buffer_lock); 196 + return ret; 197 + } 198 + 199 + static int kraken3_percent_to_pwm(long val) 200 + { 201 + return DIV_ROUND_CLOSEST(val * 255, 100); 202 + } 203 + 204 + static int kraken3_pwm_to_percent(long val, int channel) 205 + { 206 + int percent_value; 207 + 208 + if (val < 0 || val > 255) 209 + return -EINVAL; 210 + 211 + percent_value = DIV_ROUND_CLOSEST(val * 100, 255); 212 + 213 + /* Bring up pump duty to min value if needed */ 214 + if (channel == 0 && percent_value < PUMP_DUTY_MIN) 215 + percent_value = PUMP_DUTY_MIN; 216 + 217 + return percent_value; 218 + } 219 + 220 + static int kraken3_read_x53(struct kraken3_data *priv) 221 + { 222 + int ret; 223 + 224 + if (completion_done(&priv->status_report_processed)) 225 + /* 226 + * We're here because data is stale. This means that sensor reports haven't 227 + * been received for some time in kraken3_raw_event(). On X-series sensor data 228 + * can't be manually requested, so return an error. 229 + */ 230 + return -ENODATA; 231 + 232 + /* 233 + * Data needs to be read, but a sensor report wasn't yet received. It's usually 234 + * fancontrol that requests data this early and it exits if it reads an error code. 235 + * So, wait for the first report to be parsed (but up to STATUS_VALIDITY). 236 + * This does not concern the Z series devices, because they send a sensor report 237 + * only when requested. 238 + */ 239 + ret = wait_for_completion_interruptible_timeout(&priv->status_report_processed, 240 + msecs_to_jiffies(STATUS_VALIDITY)); 241 + if (ret == 0) 242 + return -ETIMEDOUT; 243 + else if (ret < 0) 244 + return ret; 245 + 246 + /* The first sensor report was parsed on time and reading can continue */ 247 + return 0; 248 + } 249 + 250 + static int kraken3_read_z53(struct kraken3_data *priv) 251 + { 252 + int ret = mutex_lock_interruptible(&priv->z53_status_request_lock); 253 + 254 + if (ret < 0) 255 + return ret; 256 + 257 + if (!time_after(jiffies, priv->updated + msecs_to_jiffies(STATUS_VALIDITY))) { 258 + /* Data is up to date */ 259 + goto unlock_and_return; 260 + } 261 + 262 + /* 263 + * Disable interrupts for a moment to safely reinit the completion, 264 + * as hidraw calls could have allowed one or more readers to complete. 265 + */ 266 + spin_lock_bh(&priv->status_completion_lock); 267 + reinit_completion(&priv->status_report_processed); 268 + spin_unlock_bh(&priv->status_completion_lock); 269 + 270 + /* Send command for getting status */ 271 + ret = kraken3_write_expanded(priv, z53_get_status_cmd, Z53_GET_STATUS_CMD_LENGTH); 272 + if (ret < 0) 273 + goto unlock_and_return; 274 + 275 + /* Wait for completion from kraken3_raw_event() */ 276 + ret = wait_for_completion_interruptible_timeout(&priv->status_report_processed, 277 + msecs_to_jiffies(STATUS_VALIDITY)); 278 + if (ret == 0) 279 + ret = -ETIMEDOUT; 280 + 281 + unlock_and_return: 282 + mutex_unlock(&priv->z53_status_request_lock); 283 + if (ret < 0) 284 + return ret; 285 + 286 + return 0; 287 + } 288 + 289 + static int kraken3_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, 290 + long *val) 291 + { 292 + struct kraken3_data *priv = dev_get_drvdata(dev); 293 + int ret; 294 + 295 + if (time_after(jiffies, priv->updated + msecs_to_jiffies(STATUS_VALIDITY))) { 296 + if (priv->kind == X53) 297 + ret = kraken3_read_x53(priv); 298 + else 299 + ret = kraken3_read_z53(priv); 300 + 301 + if (ret < 0) 302 + return ret; 303 + 304 + if (priv->is_device_faulty) 305 + return -ENODATA; 306 + } 307 + 308 + switch (type) { 309 + case hwmon_temp: 310 + *val = priv->temp_input[channel]; 311 + break; 312 + case hwmon_fan: 313 + *val = priv->fan_input[channel]; 314 + break; 315 + case hwmon_pwm: 316 + switch (attr) { 317 + case hwmon_pwm_enable: 318 + *val = priv->channel_info[channel].mode; 319 + break; 320 + case hwmon_pwm_input: 321 + *val = priv->channel_info[channel].reported_duty; 322 + break; 323 + default: 324 + return -EOPNOTSUPP; 325 + } 326 + break; 327 + default: 328 + return -EOPNOTSUPP; 329 + } 330 + 331 + return 0; 332 + } 333 + 334 + static int kraken3_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr, 335 + int channel, const char **str) 336 + { 337 + switch (type) { 338 + case hwmon_temp: 339 + *str = kraken3_temp_label[channel]; 340 + break; 341 + case hwmon_fan: 342 + *str = kraken3_fan_label[channel]; 343 + break; 344 + default: 345 + return -EOPNOTSUPP; 346 + } 347 + 348 + return 0; 349 + } 350 + 351 + /* Writes custom curve to device */ 352 + static int kraken3_write_curve(struct kraken3_data *priv, u8 *curve_array, int channel) 353 + { 354 + u8 fixed_duty_cmd[SET_CURVE_DUTY_CMD_LENGTH]; 355 + int ret; 356 + 357 + /* Copy command header */ 358 + memcpy(fixed_duty_cmd, set_pump_duty_cmd_header, SET_CURVE_DUTY_CMD_HEADER_LENGTH); 359 + 360 + /* Set the correct ID for writing pump/fan duty (0x01 or 0x02, respectively) */ 361 + fixed_duty_cmd[SET_DUTY_ID_OFFSET] = channel + 1; 362 + 363 + /* Copy curve to command */ 364 + memcpy(fixed_duty_cmd + SET_CURVE_DUTY_CMD_HEADER_LENGTH, curve_array, CUSTOM_CURVE_POINTS); 365 + 366 + ret = kraken3_write_expanded(priv, fixed_duty_cmd, SET_CURVE_DUTY_CMD_LENGTH); 367 + return ret; 368 + } 369 + 370 + static int kraken3_write_fixed_duty(struct kraken3_data *priv, long val, int channel) 371 + { 372 + u8 fixed_curve_points[CUSTOM_CURVE_POINTS]; 373 + int ret, percent_val, i; 374 + 375 + percent_val = kraken3_pwm_to_percent(val, channel); 376 + if (percent_val < 0) 377 + return percent_val; 378 + 379 + /* 380 + * The devices can only control the duty through a curve. 381 + * Since we're setting a fixed duty here, fill the whole curve 382 + * (ranging from 20C to 59C) with the same duty, except for 383 + * the last point, the critical temperature, where it's maxed 384 + * out for safety. 385 + */ 386 + 387 + /* Fill the custom curve with the fixed value we're setting */ 388 + for (i = 0; i < CUSTOM_CURVE_POINTS - 1; i++) 389 + fixed_curve_points[i] = percent_val; 390 + 391 + /* Force duty to 100% at critical temp */ 392 + fixed_curve_points[CUSTOM_CURVE_POINTS - 1] = 100; 393 + 394 + /* Write the fixed duty curve to the device */ 395 + ret = kraken3_write_curve(priv, fixed_curve_points, channel); 396 + return ret; 397 + } 398 + 399 + static int kraken3_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, 400 + long val) 401 + { 402 + struct kraken3_data *priv = dev_get_drvdata(dev); 403 + int ret; 404 + 405 + switch (type) { 406 + case hwmon_pwm: 407 + switch (attr) { 408 + case hwmon_pwm_input: 409 + /* Remember the last set fixed duty for channel */ 410 + priv->channel_info[channel].fixed_duty = val; 411 + 412 + if (priv->channel_info[channel].mode == manual) { 413 + ret = kraken3_write_fixed_duty(priv, val, channel); 414 + if (ret < 0) 415 + return ret; 416 + 417 + /* 418 + * Lock onto this value and report it until next interrupt status 419 + * report is received, so userspace tools can continue to work. 420 + */ 421 + priv->channel_info[channel].reported_duty = val; 422 + } 423 + break; 424 + case hwmon_pwm_enable: 425 + if (val < 0 || val > 2) 426 + return -EINVAL; 427 + 428 + switch (val) { 429 + case 0: 430 + /* Set channel to 100%, direct duty value */ 431 + ret = kraken3_write_fixed_duty(priv, 255, channel); 432 + if (ret < 0) 433 + return ret; 434 + 435 + /* We don't control anything anymore */ 436 + priv->channel_info[channel].mode = off; 437 + break; 438 + case 1: 439 + /* Apply the last known direct duty value */ 440 + ret = 441 + kraken3_write_fixed_duty(priv, 442 + priv->channel_info[channel].fixed_duty, 443 + channel); 444 + if (ret < 0) 445 + return ret; 446 + 447 + priv->channel_info[channel].mode = manual; 448 + break; 449 + case 2: 450 + /* Apply the curve and note as enabled */ 451 + ret = 452 + kraken3_write_curve(priv, 453 + priv->channel_info[channel].pwm_points, 454 + channel); 455 + if (ret < 0) 456 + return ret; 457 + 458 + priv->channel_info[channel].mode = curve; 459 + break; 460 + default: 461 + break; 462 + } 463 + break; 464 + default: 465 + return -EOPNOTSUPP; 466 + } 467 + break; 468 + default: 469 + return -EOPNOTSUPP; 470 + } 471 + 472 + return 0; 473 + } 474 + 475 + static ssize_t kraken3_fan_curve_pwm_store(struct device *dev, struct device_attribute *attr, 476 + const char *buf, size_t count) 477 + { 478 + struct sensor_device_attribute_2 *dev_attr = to_sensor_dev_attr_2(attr); 479 + struct kraken3_data *priv = dev_get_drvdata(dev); 480 + long val; 481 + int ret; 482 + 483 + if (kstrtol(buf, 10, &val) < 0) 484 + return -EINVAL; 485 + 486 + val = kraken3_pwm_to_percent(val, dev_attr->nr); 487 + if (val < 0) 488 + return val; 489 + 490 + priv->channel_info[dev_attr->nr].pwm_points[dev_attr->index] = val; 491 + 492 + if (priv->channel_info[dev_attr->nr].mode == curve) { 493 + /* Apply the curve */ 494 + ret = 495 + kraken3_write_curve(priv, 496 + priv->channel_info[dev_attr->nr].pwm_points, dev_attr->nr); 497 + if (ret < 0) 498 + return ret; 499 + } 500 + 501 + return count; 502 + } 503 + 504 + static umode_t kraken3_curve_props_are_visible(struct kobject *kobj, struct attribute *attr, 505 + int index) 506 + { 507 + struct device *dev = kobj_to_dev(kobj); 508 + struct kraken3_data *priv = dev_get_drvdata(dev); 509 + 510 + /* Only Z53 has the fan curve */ 511 + if (index >= CUSTOM_CURVE_POINTS && priv->kind != Z53) 512 + return 0; 513 + 514 + return attr->mode; 515 + } 516 + 517 + /* Custom pump curve from 20C to 59C (critical temp) */ 518 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point1_pwm, kraken3_fan_curve_pwm, 0, 0); 519 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point2_pwm, kraken3_fan_curve_pwm, 0, 1); 520 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point3_pwm, kraken3_fan_curve_pwm, 0, 2); 521 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point4_pwm, kraken3_fan_curve_pwm, 0, 3); 522 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point5_pwm, kraken3_fan_curve_pwm, 0, 4); 523 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point6_pwm, kraken3_fan_curve_pwm, 0, 5); 524 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point7_pwm, kraken3_fan_curve_pwm, 0, 6); 525 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point8_pwm, kraken3_fan_curve_pwm, 0, 7); 526 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point9_pwm, kraken3_fan_curve_pwm, 0, 8); 527 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point10_pwm, kraken3_fan_curve_pwm, 0, 9); 528 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point11_pwm, kraken3_fan_curve_pwm, 0, 10); 529 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point12_pwm, kraken3_fan_curve_pwm, 0, 11); 530 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point13_pwm, kraken3_fan_curve_pwm, 0, 12); 531 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point14_pwm, kraken3_fan_curve_pwm, 0, 13); 532 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point15_pwm, kraken3_fan_curve_pwm, 0, 14); 533 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point16_pwm, kraken3_fan_curve_pwm, 0, 15); 534 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point17_pwm, kraken3_fan_curve_pwm, 0, 16); 535 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point18_pwm, kraken3_fan_curve_pwm, 0, 17); 536 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point19_pwm, kraken3_fan_curve_pwm, 0, 18); 537 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point20_pwm, kraken3_fan_curve_pwm, 0, 19); 538 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point21_pwm, kraken3_fan_curve_pwm, 0, 20); 539 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point22_pwm, kraken3_fan_curve_pwm, 0, 21); 540 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point23_pwm, kraken3_fan_curve_pwm, 0, 22); 541 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point24_pwm, kraken3_fan_curve_pwm, 0, 23); 542 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point25_pwm, kraken3_fan_curve_pwm, 0, 24); 543 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point26_pwm, kraken3_fan_curve_pwm, 0, 25); 544 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point27_pwm, kraken3_fan_curve_pwm, 0, 26); 545 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point28_pwm, kraken3_fan_curve_pwm, 0, 27); 546 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point29_pwm, kraken3_fan_curve_pwm, 0, 28); 547 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point30_pwm, kraken3_fan_curve_pwm, 0, 29); 548 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point31_pwm, kraken3_fan_curve_pwm, 0, 30); 549 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point32_pwm, kraken3_fan_curve_pwm, 0, 31); 550 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point33_pwm, kraken3_fan_curve_pwm, 0, 32); 551 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point34_pwm, kraken3_fan_curve_pwm, 0, 33); 552 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point35_pwm, kraken3_fan_curve_pwm, 0, 34); 553 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point36_pwm, kraken3_fan_curve_pwm, 0, 35); 554 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point37_pwm, kraken3_fan_curve_pwm, 0, 36); 555 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point38_pwm, kraken3_fan_curve_pwm, 0, 37); 556 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point39_pwm, kraken3_fan_curve_pwm, 0, 38); 557 + static SENSOR_DEVICE_ATTR_2_WO(temp1_auto_point40_pwm, kraken3_fan_curve_pwm, 0, 39); 558 + 559 + /* Custom fan curve from 20C to 59C (critical temp) */ 560 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point1_pwm, kraken3_fan_curve_pwm, 1, 0); 561 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point2_pwm, kraken3_fan_curve_pwm, 1, 1); 562 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point3_pwm, kraken3_fan_curve_pwm, 1, 2); 563 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point4_pwm, kraken3_fan_curve_pwm, 1, 3); 564 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point5_pwm, kraken3_fan_curve_pwm, 1, 4); 565 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point6_pwm, kraken3_fan_curve_pwm, 1, 5); 566 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point7_pwm, kraken3_fan_curve_pwm, 1, 6); 567 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point8_pwm, kraken3_fan_curve_pwm, 1, 7); 568 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point9_pwm, kraken3_fan_curve_pwm, 1, 8); 569 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point10_pwm, kraken3_fan_curve_pwm, 1, 9); 570 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point11_pwm, kraken3_fan_curve_pwm, 1, 10); 571 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point12_pwm, kraken3_fan_curve_pwm, 1, 11); 572 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point13_pwm, kraken3_fan_curve_pwm, 1, 12); 573 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point14_pwm, kraken3_fan_curve_pwm, 1, 13); 574 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point15_pwm, kraken3_fan_curve_pwm, 1, 14); 575 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point16_pwm, kraken3_fan_curve_pwm, 1, 15); 576 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point17_pwm, kraken3_fan_curve_pwm, 1, 16); 577 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point18_pwm, kraken3_fan_curve_pwm, 1, 17); 578 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point19_pwm, kraken3_fan_curve_pwm, 1, 18); 579 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point20_pwm, kraken3_fan_curve_pwm, 1, 19); 580 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point21_pwm, kraken3_fan_curve_pwm, 1, 20); 581 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point22_pwm, kraken3_fan_curve_pwm, 1, 21); 582 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point23_pwm, kraken3_fan_curve_pwm, 1, 22); 583 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point24_pwm, kraken3_fan_curve_pwm, 1, 23); 584 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point25_pwm, kraken3_fan_curve_pwm, 1, 24); 585 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point26_pwm, kraken3_fan_curve_pwm, 1, 25); 586 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point27_pwm, kraken3_fan_curve_pwm, 1, 26); 587 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point28_pwm, kraken3_fan_curve_pwm, 1, 27); 588 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point29_pwm, kraken3_fan_curve_pwm, 1, 28); 589 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point30_pwm, kraken3_fan_curve_pwm, 1, 29); 590 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point31_pwm, kraken3_fan_curve_pwm, 1, 30); 591 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point32_pwm, kraken3_fan_curve_pwm, 1, 31); 592 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point33_pwm, kraken3_fan_curve_pwm, 1, 32); 593 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point34_pwm, kraken3_fan_curve_pwm, 1, 33); 594 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point35_pwm, kraken3_fan_curve_pwm, 1, 34); 595 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point36_pwm, kraken3_fan_curve_pwm, 1, 35); 596 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point37_pwm, kraken3_fan_curve_pwm, 1, 36); 597 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point38_pwm, kraken3_fan_curve_pwm, 1, 37); 598 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point39_pwm, kraken3_fan_curve_pwm, 1, 38); 599 + static SENSOR_DEVICE_ATTR_2_WO(temp2_auto_point40_pwm, kraken3_fan_curve_pwm, 1, 39); 600 + 601 + static struct attribute *kraken3_curve_attrs[] = { 602 + /* Pump control curve */ 603 + &sensor_dev_attr_temp1_auto_point1_pwm.dev_attr.attr, 604 + &sensor_dev_attr_temp1_auto_point2_pwm.dev_attr.attr, 605 + &sensor_dev_attr_temp1_auto_point3_pwm.dev_attr.attr, 606 + &sensor_dev_attr_temp1_auto_point4_pwm.dev_attr.attr, 607 + &sensor_dev_attr_temp1_auto_point5_pwm.dev_attr.attr, 608 + &sensor_dev_attr_temp1_auto_point6_pwm.dev_attr.attr, 609 + &sensor_dev_attr_temp1_auto_point7_pwm.dev_attr.attr, 610 + &sensor_dev_attr_temp1_auto_point8_pwm.dev_attr.attr, 611 + &sensor_dev_attr_temp1_auto_point9_pwm.dev_attr.attr, 612 + &sensor_dev_attr_temp1_auto_point10_pwm.dev_attr.attr, 613 + &sensor_dev_attr_temp1_auto_point11_pwm.dev_attr.attr, 614 + &sensor_dev_attr_temp1_auto_point12_pwm.dev_attr.attr, 615 + &sensor_dev_attr_temp1_auto_point13_pwm.dev_attr.attr, 616 + &sensor_dev_attr_temp1_auto_point14_pwm.dev_attr.attr, 617 + &sensor_dev_attr_temp1_auto_point15_pwm.dev_attr.attr, 618 + &sensor_dev_attr_temp1_auto_point16_pwm.dev_attr.attr, 619 + &sensor_dev_attr_temp1_auto_point17_pwm.dev_attr.attr, 620 + &sensor_dev_attr_temp1_auto_point18_pwm.dev_attr.attr, 621 + &sensor_dev_attr_temp1_auto_point19_pwm.dev_attr.attr, 622 + &sensor_dev_attr_temp1_auto_point20_pwm.dev_attr.attr, 623 + &sensor_dev_attr_temp1_auto_point21_pwm.dev_attr.attr, 624 + &sensor_dev_attr_temp1_auto_point22_pwm.dev_attr.attr, 625 + &sensor_dev_attr_temp1_auto_point23_pwm.dev_attr.attr, 626 + &sensor_dev_attr_temp1_auto_point24_pwm.dev_attr.attr, 627 + &sensor_dev_attr_temp1_auto_point25_pwm.dev_attr.attr, 628 + &sensor_dev_attr_temp1_auto_point26_pwm.dev_attr.attr, 629 + &sensor_dev_attr_temp1_auto_point27_pwm.dev_attr.attr, 630 + &sensor_dev_attr_temp1_auto_point28_pwm.dev_attr.attr, 631 + &sensor_dev_attr_temp1_auto_point29_pwm.dev_attr.attr, 632 + &sensor_dev_attr_temp1_auto_point30_pwm.dev_attr.attr, 633 + &sensor_dev_attr_temp1_auto_point31_pwm.dev_attr.attr, 634 + &sensor_dev_attr_temp1_auto_point32_pwm.dev_attr.attr, 635 + &sensor_dev_attr_temp1_auto_point33_pwm.dev_attr.attr, 636 + &sensor_dev_attr_temp1_auto_point34_pwm.dev_attr.attr, 637 + &sensor_dev_attr_temp1_auto_point35_pwm.dev_attr.attr, 638 + &sensor_dev_attr_temp1_auto_point36_pwm.dev_attr.attr, 639 + &sensor_dev_attr_temp1_auto_point37_pwm.dev_attr.attr, 640 + &sensor_dev_attr_temp1_auto_point38_pwm.dev_attr.attr, 641 + &sensor_dev_attr_temp1_auto_point39_pwm.dev_attr.attr, 642 + &sensor_dev_attr_temp1_auto_point40_pwm.dev_attr.attr, 643 + /* Fan control curve (Z53 only) */ 644 + &sensor_dev_attr_temp2_auto_point1_pwm.dev_attr.attr, 645 + &sensor_dev_attr_temp2_auto_point2_pwm.dev_attr.attr, 646 + &sensor_dev_attr_temp2_auto_point3_pwm.dev_attr.attr, 647 + &sensor_dev_attr_temp2_auto_point4_pwm.dev_attr.attr, 648 + &sensor_dev_attr_temp2_auto_point5_pwm.dev_attr.attr, 649 + &sensor_dev_attr_temp2_auto_point6_pwm.dev_attr.attr, 650 + &sensor_dev_attr_temp2_auto_point7_pwm.dev_attr.attr, 651 + &sensor_dev_attr_temp2_auto_point8_pwm.dev_attr.attr, 652 + &sensor_dev_attr_temp2_auto_point9_pwm.dev_attr.attr, 653 + &sensor_dev_attr_temp2_auto_point10_pwm.dev_attr.attr, 654 + &sensor_dev_attr_temp2_auto_point11_pwm.dev_attr.attr, 655 + &sensor_dev_attr_temp2_auto_point12_pwm.dev_attr.attr, 656 + &sensor_dev_attr_temp2_auto_point13_pwm.dev_attr.attr, 657 + &sensor_dev_attr_temp2_auto_point14_pwm.dev_attr.attr, 658 + &sensor_dev_attr_temp2_auto_point15_pwm.dev_attr.attr, 659 + &sensor_dev_attr_temp2_auto_point16_pwm.dev_attr.attr, 660 + &sensor_dev_attr_temp2_auto_point17_pwm.dev_attr.attr, 661 + &sensor_dev_attr_temp2_auto_point18_pwm.dev_attr.attr, 662 + &sensor_dev_attr_temp2_auto_point19_pwm.dev_attr.attr, 663 + &sensor_dev_attr_temp2_auto_point20_pwm.dev_attr.attr, 664 + &sensor_dev_attr_temp2_auto_point21_pwm.dev_attr.attr, 665 + &sensor_dev_attr_temp2_auto_point22_pwm.dev_attr.attr, 666 + &sensor_dev_attr_temp2_auto_point23_pwm.dev_attr.attr, 667 + &sensor_dev_attr_temp2_auto_point24_pwm.dev_attr.attr, 668 + &sensor_dev_attr_temp2_auto_point25_pwm.dev_attr.attr, 669 + &sensor_dev_attr_temp2_auto_point26_pwm.dev_attr.attr, 670 + &sensor_dev_attr_temp2_auto_point27_pwm.dev_attr.attr, 671 + &sensor_dev_attr_temp2_auto_point28_pwm.dev_attr.attr, 672 + &sensor_dev_attr_temp2_auto_point29_pwm.dev_attr.attr, 673 + &sensor_dev_attr_temp2_auto_point30_pwm.dev_attr.attr, 674 + &sensor_dev_attr_temp2_auto_point31_pwm.dev_attr.attr, 675 + &sensor_dev_attr_temp2_auto_point32_pwm.dev_attr.attr, 676 + &sensor_dev_attr_temp2_auto_point33_pwm.dev_attr.attr, 677 + &sensor_dev_attr_temp2_auto_point34_pwm.dev_attr.attr, 678 + &sensor_dev_attr_temp2_auto_point35_pwm.dev_attr.attr, 679 + &sensor_dev_attr_temp2_auto_point36_pwm.dev_attr.attr, 680 + &sensor_dev_attr_temp2_auto_point37_pwm.dev_attr.attr, 681 + &sensor_dev_attr_temp2_auto_point38_pwm.dev_attr.attr, 682 + &sensor_dev_attr_temp2_auto_point39_pwm.dev_attr.attr, 683 + &sensor_dev_attr_temp2_auto_point40_pwm.dev_attr.attr, 684 + NULL 685 + }; 686 + 687 + static const struct attribute_group kraken3_curves_group = { 688 + .attrs = kraken3_curve_attrs, 689 + .is_visible = kraken3_curve_props_are_visible 690 + }; 691 + 692 + static const struct attribute_group *kraken3_groups[] = { 693 + &kraken3_curves_group, 694 + NULL 695 + }; 696 + 697 + static const struct hwmon_ops kraken3_hwmon_ops = { 698 + .is_visible = kraken3_is_visible, 699 + .read = kraken3_read, 700 + .read_string = kraken3_read_string, 701 + .write = kraken3_write 702 + }; 703 + 704 + static const struct hwmon_channel_info *kraken3_info[] = { 705 + HWMON_CHANNEL_INFO(temp, 706 + HWMON_T_INPUT | HWMON_T_LABEL), 707 + HWMON_CHANNEL_INFO(fan, 708 + HWMON_F_INPUT | HWMON_F_LABEL, 709 + HWMON_F_INPUT | HWMON_F_LABEL, 710 + HWMON_F_INPUT | HWMON_F_LABEL, 711 + HWMON_F_INPUT | HWMON_F_LABEL), 712 + HWMON_CHANNEL_INFO(pwm, 713 + HWMON_PWM_INPUT | HWMON_PWM_ENABLE, 714 + HWMON_PWM_INPUT | HWMON_PWM_ENABLE), 715 + NULL 716 + }; 717 + 718 + static const struct hwmon_chip_info kraken3_chip_info = { 719 + .ops = &kraken3_hwmon_ops, 720 + .info = kraken3_info, 721 + }; 722 + 723 + static int kraken3_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data, int size) 724 + { 725 + struct kraken3_data *priv = hid_get_drvdata(hdev); 726 + int i; 727 + 728 + if (size < MIN_REPORT_LENGTH) 729 + return 0; 730 + 731 + if (report->id == FIRMWARE_REPORT_ID) { 732 + /* Read firmware version */ 733 + for (i = 0; i < 3; i++) 734 + priv->firmware_version[i] = data[FIRMWARE_VERSION_OFFSET + i]; 735 + 736 + if (!completion_done(&priv->fw_version_processed)) 737 + complete_all(&priv->fw_version_processed); 738 + 739 + return 0; 740 + } 741 + 742 + if (report->id != STATUS_REPORT_ID) 743 + return 0; 744 + 745 + if (data[TEMP_SENSOR_START_OFFSET] == 0xff && data[TEMP_SENSOR_END_OFFSET] == 0xff) { 746 + hid_err_once(hdev, 747 + "firmware or device is possibly damaged (is SATA power connected?), not parsing reports\n"); 748 + 749 + /* 750 + * Mark first X-series device report as received, 751 + * as well as all for Z-series, if faulty. 752 + */ 753 + spin_lock(&priv->status_completion_lock); 754 + if (priv->kind != X53 || !completion_done(&priv->status_report_processed)) { 755 + priv->is_device_faulty = true; 756 + complete_all(&priv->status_report_processed); 757 + } 758 + spin_unlock(&priv->status_completion_lock); 759 + 760 + return 0; 761 + } 762 + 763 + /* Received normal data */ 764 + priv->is_device_faulty = false; 765 + 766 + /* Temperature and fan sensor readings */ 767 + priv->temp_input[0] = 768 + data[TEMP_SENSOR_START_OFFSET] * 1000 + data[TEMP_SENSOR_END_OFFSET] * 100; 769 + 770 + priv->fan_input[0] = get_unaligned_le16(data + PUMP_SPEED_OFFSET); 771 + priv->channel_info[0].reported_duty = kraken3_percent_to_pwm(data[PUMP_DUTY_OFFSET]); 772 + 773 + spin_lock(&priv->status_completion_lock); 774 + if (priv->kind == X53 && !completion_done(&priv->status_report_processed)) { 775 + /* Mark first X-series device report as received */ 776 + complete_all(&priv->status_report_processed); 777 + } else if (priv->kind == Z53) { 778 + /* Additional readings for Z53 */ 779 + priv->fan_input[1] = get_unaligned_le16(data + Z53_FAN_SPEED_OFFSET); 780 + priv->channel_info[1].reported_duty = 781 + kraken3_percent_to_pwm(data[Z53_FAN_DUTY_OFFSET]); 782 + 783 + if (!completion_done(&priv->status_report_processed)) 784 + complete_all(&priv->status_report_processed); 785 + } 786 + spin_unlock(&priv->status_completion_lock); 787 + 788 + priv->updated = jiffies; 789 + 790 + return 0; 791 + } 792 + 793 + static int kraken3_init_device(struct hid_device *hdev) 794 + { 795 + struct kraken3_data *priv = hid_get_drvdata(hdev); 796 + int ret; 797 + 798 + /* Set the polling interval */ 799 + ret = kraken3_write_expanded(priv, set_interval_cmd, SET_INTERVAL_CMD_LENGTH); 800 + if (ret < 0) 801 + return ret; 802 + 803 + /* Finalize the init process */ 804 + ret = kraken3_write_expanded(priv, finish_init_cmd, FINISH_INIT_CMD_LENGTH); 805 + if (ret < 0) 806 + return ret; 807 + 808 + return 0; 809 + } 810 + 811 + static int kraken3_get_fw_ver(struct hid_device *hdev) 812 + { 813 + struct kraken3_data *priv = hid_get_drvdata(hdev); 814 + int ret; 815 + 816 + ret = kraken3_write_expanded(priv, get_fw_version_cmd, GET_FW_VERSION_CMD_LENGTH); 817 + if (ret < 0) 818 + return ret; 819 + 820 + ret = wait_for_completion_interruptible_timeout(&priv->fw_version_processed, 821 + msecs_to_jiffies(STATUS_VALIDITY)); 822 + if (ret == 0) 823 + return -ETIMEDOUT; 824 + else if (ret < 0) 825 + return ret; 826 + 827 + return 0; 828 + } 829 + 830 + static int __maybe_unused kraken3_reset_resume(struct hid_device *hdev) 831 + { 832 + int ret; 833 + 834 + ret = kraken3_init_device(hdev); 835 + if (ret) 836 + hid_err(hdev, "req init (reset_resume) failed with %d\n", ret); 837 + 838 + return ret; 839 + } 840 + 841 + static int firmware_version_show(struct seq_file *seqf, void *unused) 842 + { 843 + struct kraken3_data *priv = seqf->private; 844 + 845 + seq_printf(seqf, "%u.%u.%u\n", priv->firmware_version[0], priv->firmware_version[1], 846 + priv->firmware_version[2]); 847 + 848 + return 0; 849 + } 850 + DEFINE_SHOW_ATTRIBUTE(firmware_version); 851 + 852 + static void kraken3_debugfs_init(struct kraken3_data *priv) 853 + { 854 + char name[64]; 855 + 856 + if (!priv->firmware_version[0]) 857 + return; /* Nothing to display in debugfs */ 858 + 859 + scnprintf(name, sizeof(name), "%s_%s-%s", DRIVER_NAME, kraken3_device_names[priv->kind], 860 + dev_name(&priv->hdev->dev)); 861 + 862 + priv->debugfs = debugfs_create_dir(name, NULL); 863 + debugfs_create_file("firmware_version", 0444, priv->debugfs, priv, &firmware_version_fops); 864 + } 865 + 866 + static int kraken3_probe(struct hid_device *hdev, const struct hid_device_id *id) 867 + { 868 + struct kraken3_data *priv; 869 + int ret; 870 + 871 + priv = devm_kzalloc(&hdev->dev, sizeof(*priv), GFP_KERNEL); 872 + if (!priv) 873 + return -ENOMEM; 874 + 875 + priv->hdev = hdev; 876 + hid_set_drvdata(hdev, priv); 877 + 878 + /* 879 + * Initialize ->updated to STATUS_VALIDITY seconds in the past, making 880 + * the initial empty data invalid for kraken3_read without the need for 881 + * a special case there. 882 + */ 883 + priv->updated = jiffies - msecs_to_jiffies(STATUS_VALIDITY); 884 + 885 + ret = hid_parse(hdev); 886 + if (ret) { 887 + hid_err(hdev, "hid parse failed with %d\n", ret); 888 + return ret; 889 + } 890 + 891 + /* Enable hidraw so existing user-space tools can continue to work */ 892 + ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW); 893 + if (ret) { 894 + hid_err(hdev, "hid hw start failed with %d\n", ret); 895 + return ret; 896 + } 897 + 898 + ret = hid_hw_open(hdev); 899 + if (ret) { 900 + hid_err(hdev, "hid hw open failed with %d\n", ret); 901 + goto fail_and_stop; 902 + } 903 + 904 + switch (hdev->product) { 905 + case USB_PRODUCT_ID_X53: 906 + case USB_PRODUCT_ID_X53_SECOND: 907 + priv->kind = X53; 908 + break; 909 + case USB_PRODUCT_ID_Z53: 910 + priv->kind = Z53; 911 + break; 912 + default: 913 + break; 914 + } 915 + 916 + priv->buffer = devm_kzalloc(&hdev->dev, MAX_REPORT_LENGTH, GFP_KERNEL); 917 + if (!priv->buffer) { 918 + ret = -ENOMEM; 919 + goto fail_and_close; 920 + } 921 + 922 + mutex_init(&priv->buffer_lock); 923 + mutex_init(&priv->z53_status_request_lock); 924 + init_completion(&priv->fw_version_processed); 925 + init_completion(&priv->status_report_processed); 926 + spin_lock_init(&priv->status_completion_lock); 927 + 928 + hid_device_io_start(hdev); 929 + ret = kraken3_init_device(hdev); 930 + if (ret < 0) { 931 + hid_err(hdev, "device init failed with %d\n", ret); 932 + goto fail_and_close; 933 + } 934 + 935 + ret = kraken3_get_fw_ver(hdev); 936 + if (ret < 0) 937 + hid_warn(hdev, "fw version request failed with %d\n", ret); 938 + 939 + priv->hwmon_dev = hwmon_device_register_with_info(&hdev->dev, 940 + kraken3_device_names[priv->kind], priv, 941 + &kraken3_chip_info, kraken3_groups); 942 + if (IS_ERR(priv->hwmon_dev)) { 943 + ret = PTR_ERR(priv->hwmon_dev); 944 + hid_err(hdev, "hwmon registration failed with %d\n", ret); 945 + goto fail_and_close; 946 + } 947 + 948 + kraken3_debugfs_init(priv); 949 + 950 + return 0; 951 + 952 + fail_and_close: 953 + hid_hw_close(hdev); 954 + fail_and_stop: 955 + hid_hw_stop(hdev); 956 + return ret; 957 + } 958 + 959 + static void kraken3_remove(struct hid_device *hdev) 960 + { 961 + struct kraken3_data *priv = hid_get_drvdata(hdev); 962 + 963 + debugfs_remove_recursive(priv->debugfs); 964 + hwmon_device_unregister(priv->hwmon_dev); 965 + 966 + hid_hw_close(hdev); 967 + hid_hw_stop(hdev); 968 + } 969 + 970 + static const struct hid_device_id kraken3_table[] = { 971 + /* NZXT Kraken X53/X63/X73 have two possible product IDs */ 972 + { HID_USB_DEVICE(USB_VENDOR_ID_NZXT, USB_PRODUCT_ID_X53) }, 973 + { HID_USB_DEVICE(USB_VENDOR_ID_NZXT, USB_PRODUCT_ID_X53_SECOND) }, 974 + { HID_USB_DEVICE(USB_VENDOR_ID_NZXT, USB_PRODUCT_ID_Z53) }, 975 + { } 976 + }; 977 + 978 + MODULE_DEVICE_TABLE(hid, kraken3_table); 979 + 980 + static struct hid_driver kraken3_driver = { 981 + .name = DRIVER_NAME, 982 + .id_table = kraken3_table, 983 + .probe = kraken3_probe, 984 + .remove = kraken3_remove, 985 + .raw_event = kraken3_raw_event, 986 + #ifdef CONFIG_PM 987 + .reset_resume = kraken3_reset_resume, 988 + #endif 989 + }; 990 + 991 + static int __init kraken3_init(void) 992 + { 993 + return hid_register_driver(&kraken3_driver); 994 + } 995 + 996 + static void __exit kraken3_exit(void) 997 + { 998 + hid_unregister_driver(&kraken3_driver); 999 + } 1000 + 1001 + /* When compiled into the kernel, initialize after the HID bus */ 1002 + late_initcall(kraken3_init); 1003 + module_exit(kraken3_exit); 1004 + 1005 + MODULE_LICENSE("GPL"); 1006 + MODULE_AUTHOR("Jonas Malaco <jonas@protocubo.io>"); 1007 + MODULE_AUTHOR("Aleksa Savic <savicaleksa83@gmail.com>"); 1008 + MODULE_DESCRIPTION("Hwmon driver for NZXT Kraken X53/X63/X73, Z53/Z63/Z73 coolers");
-1
drivers/hwmon/occ/p8_i2c.c
··· 241 241 MODULE_DEVICE_TABLE(of, p8_i2c_occ_of_match); 242 242 243 243 static struct i2c_driver p8_i2c_occ_driver = { 244 - .class = I2C_CLASS_HWMON, 245 244 .driver = { 246 245 .name = "occ-hwmon", 247 246 .of_match_table = p8_i2c_occ_of_match,
+10
drivers/hwmon/oxp-sensors.c
··· 43 43 aok_zoe_a1 = 1, 44 44 aya_neo_2, 45 45 aya_neo_air, 46 + aya_neo_air_plus_mendo, 46 47 aya_neo_air_pro, 47 48 aya_neo_geek, 48 49 oxp_mini_amd, ··· 98 97 DMI_EXACT_MATCH(DMI_BOARD_NAME, "AIR"), 99 98 }, 100 99 .driver_data = (void *)aya_neo_air, 100 + }, 101 + { 102 + .matches = { 103 + DMI_MATCH(DMI_BOARD_VENDOR, "AYANEO"), 104 + DMI_EXACT_MATCH(DMI_BOARD_NAME, "AB05-Mendocino"), 105 + }, 106 + .driver_data = (void *)aya_neo_air_plus_mendo, 101 107 }, 102 108 { 103 109 .matches = { ··· 340 332 switch (board) { 341 333 case aya_neo_2: 342 334 case aya_neo_air: 335 + case aya_neo_air_plus_mendo: 343 336 case aya_neo_air_pro: 344 337 case aya_neo_geek: 345 338 case oxp_mini_amd: ··· 383 374 switch (board) { 384 375 case aya_neo_2: 385 376 case aya_neo_air: 377 + case aya_neo_air_plus_mendo: 386 378 case aya_neo_air_pro: 387 379 case aya_neo_geek: 388 380 case oxp_mini_amd:
+9
drivers/hwmon/pmbus/Kconfig
··· 377 377 This driver can also be built as a module. If so, the module will 378 378 be called mpq7932. 379 379 380 + config SENSORS_MPQ8785 381 + tristate "MPS MPQ8785" 382 + help 383 + If you say yes here you get hardware monitoring functionality support 384 + for power management IC MPS MPQ8785. 385 + 386 + This driver can also be built as a module. If so, the module will 387 + be called mpq8785. 388 + 380 389 config SENSORS_PIM4328 381 390 tristate "Flex PIM4328 and compatibles" 382 391 help
+1
drivers/hwmon/pmbus/Makefile
··· 39 39 obj-$(CONFIG_SENSORS_MP5023) += mp5023.o 40 40 obj-$(CONFIG_SENSORS_MP5990) += mp5990.o 41 41 obj-$(CONFIG_SENSORS_MPQ7932) += mpq7932.o 42 + obj-$(CONFIG_SENSORS_MPQ8785) += mpq8785.o 42 43 obj-$(CONFIG_SENSORS_PLI1209BC) += pli1209bc.o 43 44 obj-$(CONFIG_SENSORS_PM6764TR) += pm6764tr.o 44 45 obj-$(CONFIG_SENSORS_PXE1610) += pxe1610.o
-1
drivers/hwmon/pmbus/ir36021.c
··· 63 63 MODULE_DEVICE_TABLE(of, ir36021_of_id); 64 64 65 65 static struct i2c_driver ir36021_driver = { 66 - .class = I2C_CLASS_HWMON, 67 66 .driver = { 68 67 .name = "ir36021", 69 68 .of_match_table = of_match_ptr(ir36021_of_id),
+1 -1
drivers/hwmon/pmbus/ir38064.c
··· 22 22 23 23 #if IS_ENABLED(CONFIG_SENSORS_IR38064_REGULATOR) 24 24 static const struct regulator_desc ir38064_reg_desc[] = { 25 - PMBUS_REGULATOR("vout", 0), 25 + PMBUS_REGULATOR_ONE("vout"), 26 26 }; 27 27 #endif /* CONFIG_SENSORS_IR38064_REGULATOR */ 28 28
+1 -1
drivers/hwmon/pmbus/lm25066.c
··· 437 437 438 438 #if IS_ENABLED(CONFIG_SENSORS_LM25066_REGULATOR) 439 439 static const struct regulator_desc lm25066_reg_desc[] = { 440 - PMBUS_REGULATOR("vout", 0), 440 + PMBUS_REGULATOR_ONE("vout"), 441 441 }; 442 442 #endif 443 443
+90
drivers/hwmon/pmbus/mpq8785.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Driver for MPS MPQ8785 Step-Down Converter 4 + */ 5 + 6 + #include <linux/i2c.h> 7 + #include <linux/module.h> 8 + #include <linux/of_device.h> 9 + #include "pmbus.h" 10 + 11 + static int mpq8785_identify(struct i2c_client *client, 12 + struct pmbus_driver_info *info) 13 + { 14 + int vout_mode; 15 + 16 + vout_mode = pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE); 17 + if (vout_mode < 0 || vout_mode == 0xff) 18 + return vout_mode < 0 ? vout_mode : -ENODEV; 19 + switch (vout_mode >> 5) { 20 + case 0: 21 + info->format[PSC_VOLTAGE_OUT] = linear; 22 + break; 23 + case 1: 24 + case 2: 25 + info->format[PSC_VOLTAGE_OUT] = direct, 26 + info->m[PSC_VOLTAGE_OUT] = 64; 27 + info->b[PSC_VOLTAGE_OUT] = 0; 28 + info->R[PSC_VOLTAGE_OUT] = 1; 29 + break; 30 + default: 31 + return -ENODEV; 32 + } 33 + 34 + return 0; 35 + }; 36 + 37 + static struct pmbus_driver_info mpq8785_info = { 38 + .pages = 1, 39 + .format[PSC_VOLTAGE_IN] = direct, 40 + .format[PSC_CURRENT_OUT] = direct, 41 + .format[PSC_TEMPERATURE] = direct, 42 + .m[PSC_VOLTAGE_IN] = 4, 43 + .b[PSC_VOLTAGE_IN] = 0, 44 + .R[PSC_VOLTAGE_IN] = 1, 45 + .m[PSC_CURRENT_OUT] = 16, 46 + .b[PSC_CURRENT_OUT] = 0, 47 + .R[PSC_CURRENT_OUT] = 0, 48 + .m[PSC_TEMPERATURE] = 1, 49 + .b[PSC_TEMPERATURE] = 0, 50 + .R[PSC_TEMPERATURE] = 0, 51 + .func[0] = 52 + PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT | 53 + PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | 54 + PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | 55 + PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 56 + .identify = mpq8785_identify, 57 + }; 58 + 59 + static int mpq8785_probe(struct i2c_client *client) 60 + { 61 + return pmbus_do_probe(client, &mpq8785_info); 62 + }; 63 + 64 + static const struct i2c_device_id mpq8785_id[] = { 65 + { "mpq8785", 0 }, 66 + { }, 67 + }; 68 + MODULE_DEVICE_TABLE(i2c, mpq8785_id); 69 + 70 + static const struct of_device_id __maybe_unused mpq8785_of_match[] = { 71 + { .compatible = "mps,mpq8785" }, 72 + {} 73 + }; 74 + MODULE_DEVICE_TABLE(of, mpq8785_of_match); 75 + 76 + static struct i2c_driver mpq8785_driver = { 77 + .driver = { 78 + .name = "mpq8785", 79 + .of_match_table = of_match_ptr(mpq8785_of_match), 80 + }, 81 + .probe = mpq8785_probe, 82 + .id_table = mpq8785_id, 83 + }; 84 + 85 + module_i2c_driver(mpq8785_driver); 86 + 87 + MODULE_AUTHOR("Charles Hsu <ythsu0511@gmail.com>"); 88 + MODULE_DESCRIPTION("PMBus driver for MPS MPQ8785"); 89 + MODULE_LICENSE("GPL"); 90 + MODULE_IMPORT_NS(PMBUS);
+1 -1
drivers/hwmon/pmbus/pmbus_core.c
··· 3188 3188 3189 3189 static int pmbus_write_smbalert_mask(struct i2c_client *client, u8 page, u8 reg, u8 val) 3190 3190 { 3191 - return pmbus_write_word_data(client, page, PMBUS_SMBALERT_MASK, reg | (val << 8)); 3191 + return _pmbus_write_word_data(client, page, PMBUS_SMBALERT_MASK, reg | (val << 8)); 3192 3192 } 3193 3193 3194 3194 static irqreturn_t pmbus_fault_handler(int irq, void *pdata)
+1 -1
drivers/hwmon/pmbus/tda38640.c
··· 15 15 #include "pmbus.h" 16 16 17 17 static const struct regulator_desc __maybe_unused tda38640_reg_desc[] = { 18 - PMBUS_REGULATOR("vout", 0), 18 + PMBUS_REGULATOR_ONE("vout"), 19 19 }; 20 20 21 21 struct tda38640_data {
-1
drivers/hwmon/powr1220.c
··· 323 323 MODULE_DEVICE_TABLE(i2c, powr1220_ids); 324 324 325 325 static struct i2c_driver powr1220_driver = { 326 - .class = I2C_CLASS_HWMON, 327 326 .driver = { 328 327 .name = "powr1220", 329 328 },
+667
drivers/hwmon/pt5161l.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + #include <linux/debugfs.h> 4 + #include <linux/delay.h> 5 + #include <linux/err.h> 6 + #include <linux/i2c.h> 7 + #include <linux/init.h> 8 + #include <linux/hwmon.h> 9 + #include <linux/module.h> 10 + #include <linux/mutex.h> 11 + 12 + /* Aries current average temp ADC code CSR */ 13 + #define ARIES_CURRENT_AVG_TEMP_ADC_CSR 0x42c 14 + 15 + /* Device Load check register */ 16 + #define ARIES_CODE_LOAD_REG 0x605 17 + /* Value indicating FW was loaded properly, [3:1] = 3'b111 */ 18 + #define ARIES_LOAD_CODE 0xe 19 + 20 + /* Main Micro Heartbeat register */ 21 + #define ARIES_MM_HEARTBEAT_ADDR 0x923 22 + 23 + /* Reg offset to specify Address for MM assisted accesses */ 24 + #define ARIES_MM_ASSIST_REG_ADDR_OFFSET 0xd99 25 + /* Reg offset to specify Command for MM assisted accesses */ 26 + #define ARIES_MM_ASSIST_CMD_OFFSET 0xd9d 27 + /* Reg offset to MM SPARE 0 used specify Address[7:0] */ 28 + #define ARIES_MM_ASSIST_SPARE_0_OFFSET 0xd9f 29 + /* Reg offset to MM SPARE 3 used specify Data Byte 0 */ 30 + #define ARIES_MM_ASSIST_SPARE_3_OFFSET 0xda2 31 + /* Wide register reads */ 32 + #define ARIES_MM_RD_WIDE_REG_2B 0x1d 33 + #define ARIES_MM_RD_WIDE_REG_3B 0x1e 34 + #define ARIES_MM_RD_WIDE_REG_4B 0x1f 35 + #define ARIES_MM_RD_WIDE_REG_5B 0x20 36 + 37 + /* Time delay between checking MM status of EEPROM write (microseconds) */ 38 + #define ARIES_MM_STATUS_TIME 5000 39 + 40 + /* AL Main SRAM DMEM offset (A0) */ 41 + #define AL_MAIN_SRAM_DMEM_OFFSET (64 * 1024) 42 + /* SRAM read command */ 43 + #define AL_TG_RD_LOC_IND_SRAM 0x16 44 + 45 + /* Offset for main micro FW info */ 46 + #define ARIES_MAIN_MICRO_FW_INFO (96 * 1024 - 128) 47 + /* FW Info (Major) offset location in struct */ 48 + #define ARIES_MM_FW_VERSION_MAJOR 0 49 + /* FW Info (Minor) offset location in struct */ 50 + #define ARIES_MM_FW_VERSION_MINOR 1 51 + /* FW Info (Build no.) offset location in struct */ 52 + #define ARIES_MM_FW_VERSION_BUILD 2 53 + 54 + #define ARIES_TEMP_CAL_CODE_DEFAULT 84 55 + 56 + /* Struct defining FW version loaded on an Aries device */ 57 + struct pt5161l_fw_ver { 58 + u8 major; 59 + u8 minor; 60 + u16 build; 61 + }; 62 + 63 + /* Each client has this additional data */ 64 + struct pt5161l_data { 65 + struct i2c_client *client; 66 + struct dentry *debugfs; 67 + struct pt5161l_fw_ver fw_ver; 68 + struct mutex lock; /* for atomic I2C transactions */ 69 + bool init_done; 70 + bool code_load_okay; /* indicate if code load reg value is expected */ 71 + bool mm_heartbeat_okay; /* indicate if Main Micro heartbeat is good */ 72 + bool mm_wide_reg_access; /* MM assisted wide register access */ 73 + }; 74 + 75 + static struct dentry *pt5161l_debugfs_dir; 76 + 77 + /* 78 + * Write multiple data bytes to Aries over I2C 79 + */ 80 + static int pt5161l_write_block_data(struct pt5161l_data *data, u32 address, 81 + u8 len, u8 *val) 82 + { 83 + struct i2c_client *client = data->client; 84 + int ret; 85 + u8 remain_len = len; 86 + u8 xfer_len, curr_len; 87 + u8 buf[16]; 88 + u8 cmd = 0x0F; /* [7]:pec_en, [4:2]:func, [1]:start, [0]:end */ 89 + u8 config = 0x40; /* [6]:cfg_type, [4:1]:burst_len, [0]:address bit16 */ 90 + 91 + while (remain_len > 0) { 92 + if (remain_len > 4) { 93 + curr_len = 4; 94 + remain_len -= 4; 95 + } else { 96 + curr_len = remain_len; 97 + remain_len = 0; 98 + } 99 + 100 + buf[0] = config | (curr_len - 1) << 1 | ((address >> 16) & 0x1); 101 + buf[1] = (address >> 8) & 0xff; 102 + buf[2] = address & 0xff; 103 + memcpy(&buf[3], val, curr_len); 104 + 105 + xfer_len = 3 + curr_len; 106 + ret = i2c_smbus_write_block_data(client, cmd, xfer_len, buf); 107 + if (ret) 108 + return ret; 109 + 110 + val += curr_len; 111 + address += curr_len; 112 + } 113 + 114 + return 0; 115 + } 116 + 117 + /* 118 + * Read multiple data bytes from Aries over I2C 119 + */ 120 + static int pt5161l_read_block_data(struct pt5161l_data *data, u32 address, 121 + u8 len, u8 *val) 122 + { 123 + struct i2c_client *client = data->client; 124 + int ret, tries; 125 + u8 remain_len = len; 126 + u8 curr_len; 127 + u8 wbuf[16], rbuf[24]; 128 + u8 cmd = 0x08; /* [7]:pec_en, [4:2]:func, [1]:start, [0]:end */ 129 + u8 config = 0x00; /* [6]:cfg_type, [4:1]:burst_len, [0]:address bit16 */ 130 + 131 + while (remain_len > 0) { 132 + if (remain_len > 16) { 133 + curr_len = 16; 134 + remain_len -= 16; 135 + } else { 136 + curr_len = remain_len; 137 + remain_len = 0; 138 + } 139 + 140 + wbuf[0] = config | (curr_len - 1) << 1 | 141 + ((address >> 16) & 0x1); 142 + wbuf[1] = (address >> 8) & 0xff; 143 + wbuf[2] = address & 0xff; 144 + 145 + for (tries = 0; tries < 3; tries++) { 146 + ret = i2c_smbus_write_block_data(client, (cmd | 0x2), 3, 147 + wbuf); 148 + if (ret) 149 + return ret; 150 + 151 + ret = i2c_smbus_read_block_data(client, (cmd | 0x1), 152 + rbuf); 153 + if (ret == curr_len) 154 + break; 155 + } 156 + if (tries >= 3) 157 + return ret; 158 + 159 + memcpy(val, rbuf, curr_len); 160 + val += curr_len; 161 + address += curr_len; 162 + } 163 + 164 + return 0; 165 + } 166 + 167 + static int pt5161l_read_wide_reg(struct pt5161l_data *data, u32 address, 168 + u8 width, u8 *val) 169 + { 170 + int ret, tries; 171 + u8 buf[8]; 172 + u8 status; 173 + 174 + /* 175 + * Safely access wide registers using mailbox method to prevent 176 + * risking conflict with Aries firmware; otherwise fallback to 177 + * legacy, less secure method. 178 + */ 179 + if (data->mm_wide_reg_access) { 180 + buf[0] = address & 0xff; 181 + buf[1] = (address >> 8) & 0xff; 182 + buf[2] = (address >> 16) & 0x1; 183 + ret = pt5161l_write_block_data(data, 184 + ARIES_MM_ASSIST_SPARE_0_OFFSET, 185 + 3, buf); 186 + if (ret) 187 + return ret; 188 + 189 + /* Set command based on width */ 190 + switch (width) { 191 + case 2: 192 + buf[0] = ARIES_MM_RD_WIDE_REG_2B; 193 + break; 194 + case 3: 195 + buf[0] = ARIES_MM_RD_WIDE_REG_3B; 196 + break; 197 + case 4: 198 + buf[0] = ARIES_MM_RD_WIDE_REG_4B; 199 + break; 200 + case 5: 201 + buf[0] = ARIES_MM_RD_WIDE_REG_5B; 202 + break; 203 + default: 204 + return -EINVAL; 205 + } 206 + ret = pt5161l_write_block_data(data, ARIES_MM_ASSIST_CMD_OFFSET, 207 + 1, buf); 208 + if (ret) 209 + return ret; 210 + 211 + status = 0xff; 212 + for (tries = 0; tries < 100; tries++) { 213 + ret = pt5161l_read_block_data(data, 214 + ARIES_MM_ASSIST_CMD_OFFSET, 215 + 1, &status); 216 + if (ret) 217 + return ret; 218 + 219 + if (status == 0) 220 + break; 221 + 222 + usleep_range(ARIES_MM_STATUS_TIME, 223 + ARIES_MM_STATUS_TIME + 1000); 224 + } 225 + if (status != 0) 226 + return -ETIMEDOUT; 227 + 228 + ret = pt5161l_read_block_data(data, 229 + ARIES_MM_ASSIST_SPARE_3_OFFSET, 230 + width, val); 231 + if (ret) 232 + return ret; 233 + } else { 234 + return pt5161l_read_block_data(data, address, width, val); 235 + } 236 + 237 + return 0; 238 + } 239 + 240 + /* 241 + * Read multiple (up to eight) data bytes from micro SRAM over I2C 242 + */ 243 + static int 244 + pt5161l_read_block_data_main_micro_indirect(struct pt5161l_data *data, 245 + u32 address, u8 len, u8 *val) 246 + { 247 + int ret, tries; 248 + u8 buf[8]; 249 + u8 i, status; 250 + u32 uind_offs = ARIES_MM_ASSIST_REG_ADDR_OFFSET; 251 + u32 eeprom_base, eeprom_addr; 252 + 253 + /* No multi-byte indirect support here. Hence read a byte at a time */ 254 + eeprom_base = address - AL_MAIN_SRAM_DMEM_OFFSET; 255 + for (i = 0; i < len; i++) { 256 + eeprom_addr = eeprom_base + i; 257 + buf[0] = eeprom_addr & 0xff; 258 + buf[1] = (eeprom_addr >> 8) & 0xff; 259 + buf[2] = (eeprom_addr >> 16) & 0xff; 260 + ret = pt5161l_write_block_data(data, uind_offs, 3, buf); 261 + if (ret) 262 + return ret; 263 + 264 + buf[0] = AL_TG_RD_LOC_IND_SRAM; 265 + ret = pt5161l_write_block_data(data, uind_offs + 4, 1, buf); 266 + if (ret) 267 + return ret; 268 + 269 + status = 0xff; 270 + for (tries = 0; tries < 255; tries++) { 271 + ret = pt5161l_read_block_data(data, uind_offs + 4, 1, 272 + &status); 273 + if (ret) 274 + return ret; 275 + 276 + if (status == 0) 277 + break; 278 + } 279 + if (status != 0) 280 + return -ETIMEDOUT; 281 + 282 + ret = pt5161l_read_block_data(data, uind_offs + 3, 1, buf); 283 + if (ret) 284 + return ret; 285 + 286 + val[i] = buf[0]; 287 + } 288 + 289 + return 0; 290 + } 291 + 292 + /* 293 + * Check firmware load status 294 + */ 295 + static int pt5161l_fw_load_check(struct pt5161l_data *data) 296 + { 297 + int ret; 298 + u8 buf[8]; 299 + 300 + ret = pt5161l_read_block_data(data, ARIES_CODE_LOAD_REG, 1, buf); 301 + if (ret) 302 + return ret; 303 + 304 + if (buf[0] < ARIES_LOAD_CODE) { 305 + dev_dbg(&data->client->dev, 306 + "Code Load reg unexpected. Not all modules are loaded %x\n", 307 + buf[0]); 308 + data->code_load_okay = false; 309 + } else { 310 + data->code_load_okay = true; 311 + } 312 + 313 + return 0; 314 + } 315 + 316 + /* 317 + * Check main micro heartbeat 318 + */ 319 + static int pt5161l_heartbeat_check(struct pt5161l_data *data) 320 + { 321 + int ret, tries; 322 + u8 buf[8]; 323 + u8 heartbeat; 324 + bool hb_changed = false; 325 + 326 + ret = pt5161l_read_block_data(data, ARIES_MM_HEARTBEAT_ADDR, 1, buf); 327 + if (ret) 328 + return ret; 329 + 330 + heartbeat = buf[0]; 331 + for (tries = 0; tries < 100; tries++) { 332 + ret = pt5161l_read_block_data(data, ARIES_MM_HEARTBEAT_ADDR, 1, 333 + buf); 334 + if (ret) 335 + return ret; 336 + 337 + if (buf[0] != heartbeat) { 338 + hb_changed = true; 339 + break; 340 + } 341 + } 342 + data->mm_heartbeat_okay = hb_changed; 343 + 344 + return 0; 345 + } 346 + 347 + /* 348 + * Check the status of firmware 349 + */ 350 + static int pt5161l_fwsts_check(struct pt5161l_data *data) 351 + { 352 + int ret; 353 + u8 buf[8]; 354 + u8 major = 0, minor = 0; 355 + u16 build = 0; 356 + 357 + ret = pt5161l_fw_load_check(data); 358 + if (ret) 359 + return ret; 360 + 361 + ret = pt5161l_heartbeat_check(data); 362 + if (ret) 363 + return ret; 364 + 365 + if (data->code_load_okay && data->mm_heartbeat_okay) { 366 + ret = pt5161l_read_block_data_main_micro_indirect(data, ARIES_MAIN_MICRO_FW_INFO + 367 + ARIES_MM_FW_VERSION_MAJOR, 368 + 1, &major); 369 + if (ret) 370 + return ret; 371 + 372 + ret = pt5161l_read_block_data_main_micro_indirect(data, ARIES_MAIN_MICRO_FW_INFO + 373 + ARIES_MM_FW_VERSION_MINOR, 374 + 1, &minor); 375 + if (ret) 376 + return ret; 377 + 378 + ret = pt5161l_read_block_data_main_micro_indirect(data, ARIES_MAIN_MICRO_FW_INFO + 379 + ARIES_MM_FW_VERSION_BUILD, 380 + 2, buf); 381 + if (ret) 382 + return ret; 383 + build = buf[1] << 8 | buf[0]; 384 + } 385 + data->fw_ver.major = major; 386 + data->fw_ver.minor = minor; 387 + data->fw_ver.build = build; 388 + 389 + return 0; 390 + } 391 + 392 + static int pt5161l_fw_is_at_least(struct pt5161l_data *data, u8 major, u8 minor, 393 + u16 build) 394 + { 395 + u32 ver = major << 24 | minor << 16 | build; 396 + u32 curr_ver = data->fw_ver.major << 24 | data->fw_ver.minor << 16 | 397 + data->fw_ver.build; 398 + 399 + if (curr_ver >= ver) 400 + return true; 401 + 402 + return false; 403 + } 404 + 405 + static int pt5161l_init_dev(struct pt5161l_data *data) 406 + { 407 + int ret; 408 + 409 + mutex_lock(&data->lock); 410 + ret = pt5161l_fwsts_check(data); 411 + mutex_unlock(&data->lock); 412 + if (ret) 413 + return ret; 414 + 415 + /* Firmware 2.2.0 enables safe access to wide registers */ 416 + if (pt5161l_fw_is_at_least(data, 2, 2, 0)) 417 + data->mm_wide_reg_access = true; 418 + 419 + data->init_done = true; 420 + 421 + return 0; 422 + } 423 + 424 + static int pt5161l_read(struct device *dev, enum hwmon_sensor_types type, 425 + u32 attr, int channel, long *val) 426 + { 427 + struct pt5161l_data *data = dev_get_drvdata(dev); 428 + int ret; 429 + u8 buf[8]; 430 + long adc_code; 431 + 432 + switch (attr) { 433 + case hwmon_temp_input: 434 + if (!data->init_done) { 435 + ret = pt5161l_init_dev(data); 436 + if (ret) 437 + return ret; 438 + } 439 + 440 + mutex_lock(&data->lock); 441 + ret = pt5161l_read_wide_reg(data, 442 + ARIES_CURRENT_AVG_TEMP_ADC_CSR, 4, 443 + buf); 444 + mutex_unlock(&data->lock); 445 + if (ret) { 446 + dev_dbg(dev, "Read adc_code failed %d\n", ret); 447 + return ret; 448 + } 449 + 450 + adc_code = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]; 451 + if (adc_code == 0 || adc_code >= 0x3ff) { 452 + dev_dbg(dev, "Invalid adc_code %lx\n", adc_code); 453 + return -EIO; 454 + } 455 + 456 + *val = 110000 + 457 + ((adc_code - (ARIES_TEMP_CAL_CODE_DEFAULT + 250)) * 458 + -320); 459 + break; 460 + default: 461 + return -EOPNOTSUPP; 462 + } 463 + 464 + return 0; 465 + } 466 + 467 + static umode_t pt5161l_is_visible(const void *data, 468 + enum hwmon_sensor_types type, u32 attr, 469 + int channel) 470 + { 471 + switch (attr) { 472 + case hwmon_temp_input: 473 + return 0444; 474 + default: 475 + break; 476 + } 477 + 478 + return 0; 479 + } 480 + 481 + static const struct hwmon_channel_info *pt5161l_info[] = { 482 + HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT), 483 + NULL 484 + }; 485 + 486 + static const struct hwmon_ops pt5161l_hwmon_ops = { 487 + .is_visible = pt5161l_is_visible, 488 + .read = pt5161l_read, 489 + }; 490 + 491 + static const struct hwmon_chip_info pt5161l_chip_info = { 492 + .ops = &pt5161l_hwmon_ops, 493 + .info = pt5161l_info, 494 + }; 495 + 496 + static ssize_t pt5161l_debugfs_read_fw_ver(struct file *file, char __user *buf, 497 + size_t count, loff_t *ppos) 498 + { 499 + struct pt5161l_data *data = file->private_data; 500 + int ret; 501 + char ver[32]; 502 + 503 + mutex_lock(&data->lock); 504 + ret = pt5161l_fwsts_check(data); 505 + mutex_unlock(&data->lock); 506 + if (ret) 507 + return ret; 508 + 509 + ret = snprintf(ver, sizeof(ver), "%u.%u.%u\n", data->fw_ver.major, 510 + data->fw_ver.minor, data->fw_ver.build); 511 + 512 + return simple_read_from_buffer(buf, count, ppos, ver, ret); 513 + } 514 + 515 + static const struct file_operations pt5161l_debugfs_ops_fw_ver = { 516 + .read = pt5161l_debugfs_read_fw_ver, 517 + .open = simple_open, 518 + }; 519 + 520 + static ssize_t pt5161l_debugfs_read_fw_load_sts(struct file *file, 521 + char __user *buf, size_t count, 522 + loff_t *ppos) 523 + { 524 + struct pt5161l_data *data = file->private_data; 525 + int ret; 526 + bool status = false; 527 + char health[16]; 528 + 529 + mutex_lock(&data->lock); 530 + ret = pt5161l_fw_load_check(data); 531 + mutex_unlock(&data->lock); 532 + if (ret == 0) 533 + status = data->code_load_okay; 534 + 535 + ret = snprintf(health, sizeof(health), "%s\n", 536 + status ? "normal" : "abnormal"); 537 + 538 + return simple_read_from_buffer(buf, count, ppos, health, ret); 539 + } 540 + 541 + static const struct file_operations pt5161l_debugfs_ops_fw_load_sts = { 542 + .read = pt5161l_debugfs_read_fw_load_sts, 543 + .open = simple_open, 544 + }; 545 + 546 + static ssize_t pt5161l_debugfs_read_hb_sts(struct file *file, char __user *buf, 547 + size_t count, loff_t *ppos) 548 + { 549 + struct pt5161l_data *data = file->private_data; 550 + int ret; 551 + bool status = false; 552 + char health[16]; 553 + 554 + mutex_lock(&data->lock); 555 + ret = pt5161l_heartbeat_check(data); 556 + mutex_unlock(&data->lock); 557 + if (ret == 0) 558 + status = data->mm_heartbeat_okay; 559 + 560 + ret = snprintf(health, sizeof(health), "%s\n", 561 + status ? "normal" : "abnormal"); 562 + 563 + return simple_read_from_buffer(buf, count, ppos, health, ret); 564 + } 565 + 566 + static const struct file_operations pt5161l_debugfs_ops_hb_sts = { 567 + .read = pt5161l_debugfs_read_hb_sts, 568 + .open = simple_open, 569 + }; 570 + 571 + static int pt5161l_init_debugfs(struct pt5161l_data *data) 572 + { 573 + data->debugfs = debugfs_create_dir(dev_name(&data->client->dev), 574 + pt5161l_debugfs_dir); 575 + 576 + debugfs_create_file("fw_ver", 0444, data->debugfs, data, 577 + &pt5161l_debugfs_ops_fw_ver); 578 + 579 + debugfs_create_file("fw_load_status", 0444, data->debugfs, data, 580 + &pt5161l_debugfs_ops_fw_load_sts); 581 + 582 + debugfs_create_file("heartbeat_status", 0444, data->debugfs, data, 583 + &pt5161l_debugfs_ops_hb_sts); 584 + 585 + return 0; 586 + } 587 + 588 + static int pt5161l_probe(struct i2c_client *client) 589 + { 590 + struct device *dev = &client->dev; 591 + struct device *hwmon_dev; 592 + struct pt5161l_data *data; 593 + 594 + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 595 + if (!data) 596 + return -ENOMEM; 597 + 598 + data->client = client; 599 + mutex_init(&data->lock); 600 + pt5161l_init_dev(data); 601 + dev_set_drvdata(dev, data); 602 + 603 + hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, 604 + data, 605 + &pt5161l_chip_info, 606 + NULL); 607 + 608 + pt5161l_init_debugfs(data); 609 + 610 + return PTR_ERR_OR_ZERO(hwmon_dev); 611 + } 612 + 613 + static void pt5161l_remove(struct i2c_client *client) 614 + { 615 + struct pt5161l_data *data = i2c_get_clientdata(client); 616 + 617 + debugfs_remove_recursive(data->debugfs); 618 + } 619 + 620 + static const struct of_device_id __maybe_unused pt5161l_of_match[] = { 621 + { .compatible = "asteralabs,pt5161l" }, 622 + {}, 623 + }; 624 + MODULE_DEVICE_TABLE(of, pt5161l_of_match); 625 + 626 + static const struct acpi_device_id __maybe_unused pt5161l_acpi_match[] = { 627 + { "PT5161L", 0 }, 628 + {}, 629 + }; 630 + MODULE_DEVICE_TABLE(acpi, pt5161l_acpi_match); 631 + 632 + static const struct i2c_device_id pt5161l_id[] = { 633 + { "pt5161l", 0 }, 634 + {} 635 + }; 636 + MODULE_DEVICE_TABLE(i2c, pt5161l_id); 637 + 638 + static struct i2c_driver pt5161l_driver = { 639 + .class = I2C_CLASS_HWMON, 640 + .driver = { 641 + .name = "pt5161l", 642 + .of_match_table = of_match_ptr(pt5161l_of_match), 643 + .acpi_match_table = ACPI_PTR(pt5161l_acpi_match), 644 + }, 645 + .probe = pt5161l_probe, 646 + .remove = pt5161l_remove, 647 + .id_table = pt5161l_id, 648 + }; 649 + 650 + static int __init pt5161l_init(void) 651 + { 652 + pt5161l_debugfs_dir = debugfs_create_dir("pt5161l", NULL); 653 + return i2c_add_driver(&pt5161l_driver); 654 + } 655 + 656 + static void __exit pt5161l_exit(void) 657 + { 658 + i2c_del_driver(&pt5161l_driver); 659 + debugfs_remove_recursive(pt5161l_debugfs_dir); 660 + } 661 + 662 + module_init(pt5161l_init); 663 + module_exit(pt5161l_exit); 664 + 665 + MODULE_AUTHOR("Cosmo Chou <cosmo.chou@quantatw.com>"); 666 + MODULE_DESCRIPTION("Hwmon driver for Astera Labs Aries PCIe retimer"); 667 + MODULE_LICENSE("GPL");
-1
drivers/hwmon/sbrmi.c
··· 342 342 MODULE_DEVICE_TABLE(of, sbrmi_of_match); 343 343 344 344 static struct i2c_driver sbrmi_driver = { 345 - .class = I2C_CLASS_HWMON, 346 345 .driver = { 347 346 .name = "sbrmi", 348 347 .of_match_table = of_match_ptr(sbrmi_of_match),
-1
drivers/hwmon/sbtsi_temp.c
··· 232 232 MODULE_DEVICE_TABLE(of, sbtsi_of_match); 233 233 234 234 static struct i2c_driver sbtsi_driver = { 235 - .class = I2C_CLASS_HWMON, 236 235 .driver = { 237 236 .name = "sbtsi", 238 237 .of_match_table = of_match_ptr(sbtsi_of_match),
+1 -1
drivers/hwmon/sch5627.c
··· 116 116 .val_bits = 8, 117 117 .wr_table = &sch5627_tunables_table, 118 118 .rd_table = &sch5627_tunables_table, 119 - .cache_type = REGCACHE_RBTREE, 119 + .cache_type = REGCACHE_MAPLE, 120 120 .use_single_read = true, 121 121 .use_single_write = true, 122 122 .can_sleep = true,
+65 -1
drivers/hwmon/sht3x.c
··· 10 10 11 11 #include <asm/page.h> 12 12 #include <linux/crc8.h> 13 + #include <linux/debugfs.h> 13 14 #include <linux/delay.h> 14 15 #include <linux/err.h> 15 16 #include <linux/hwmon.h> ··· 42 41 /* other commands */ 43 42 static const unsigned char sht3x_cmd_read_status_reg[] = { 0xf3, 0x2d }; 44 43 static const unsigned char sht3x_cmd_clear_status_reg[] = { 0x30, 0x41 }; 44 + static const unsigned char sht3x_cmd_read_serial_number[] = { 0x37, 0x80 }; 45 + 46 + static struct dentry *debugfs; 45 47 46 48 /* delays for single-shot mode i2c commands, both in us */ 47 49 #define SHT3X_SINGLE_WAIT_TIME_HPM 15000 ··· 167 163 enum sht3x_chips chip_id; 168 164 struct mutex i2c_lock; /* lock for sending i2c commands */ 169 165 struct mutex data_lock; /* lock for updating driver data */ 166 + struct dentry *sensor_dir; 170 167 171 168 u8 mode; 172 169 const unsigned char *command; 173 170 u32 wait_time; /* in us*/ 174 171 unsigned long last_update; /* last update in periodic mode*/ 175 172 enum sht3x_repeatability repeatability; 173 + u32 serial_number; 176 174 177 175 /* 178 176 * cached values for temperature and humidity and limits ··· 837 831 } 838 832 } 839 833 834 + static void sht3x_debugfs_init(struct sht3x_data *data) 835 + { 836 + char name[32]; 837 + 838 + snprintf(name, sizeof(name), "i2c%u-%02x", 839 + data->client->adapter->nr, data->client->addr); 840 + data->sensor_dir = debugfs_create_dir(name, debugfs); 841 + debugfs_create_u32("serial_number", 0444, 842 + data->sensor_dir, &data->serial_number); 843 + } 844 + 845 + static void sht3x_debugfs_remove(void *sensor_dir) 846 + { 847 + debugfs_remove_recursive(sensor_dir); 848 + } 849 + 850 + static int sht3x_serial_number_read(struct sht3x_data *data) 851 + { 852 + int ret; 853 + char buffer[SHT3X_RESPONSE_LENGTH]; 854 + struct i2c_client *client = data->client; 855 + 856 + ret = sht3x_read_from_command(client, data, 857 + sht3x_cmd_read_serial_number, 858 + buffer, 859 + SHT3X_RESPONSE_LENGTH, 0); 860 + if (ret) 861 + return ret; 862 + 863 + data->serial_number = (buffer[0] << 24) | (buffer[1] << 16) | 864 + (buffer[3] << 8) | buffer[4]; 865 + return ret; 866 + } 867 + 840 868 static const struct hwmon_ops sht3x_ops = { 841 869 .is_visible = sht3x_is_visible, 842 870 .read = sht3x_read, ··· 939 899 if (ret) 940 900 return ret; 941 901 902 + ret = sht3x_serial_number_read(data); 903 + if (ret) { 904 + dev_dbg(dev, "unable to read serial number\n"); 905 + } else { 906 + sht3x_debugfs_init(data); 907 + ret = devm_add_action_or_reset(dev, 908 + sht3x_debugfs_remove, 909 + data->sensor_dir); 910 + if (ret) 911 + return ret; 912 + } 913 + 942 914 hwmon_dev = devm_hwmon_device_register_with_info(dev, 943 915 client->name, 944 916 data, ··· 969 917 .id_table = sht3x_ids, 970 918 }; 971 919 972 - module_i2c_driver(sht3x_i2c_driver); 920 + static int __init sht3x_init(void) 921 + { 922 + debugfs = debugfs_create_dir("sht3x", NULL); 923 + return i2c_add_driver(&sht3x_i2c_driver); 924 + } 925 + module_init(sht3x_init); 926 + 927 + static void __exit sht3x_cleanup(void) 928 + { 929 + debugfs_remove_recursive(debugfs); 930 + i2c_del_driver(&sht3x_i2c_driver); 931 + } 932 + module_exit(sht3x_cleanup); 973 933 974 934 MODULE_AUTHOR("David Frey <david.frey@sensirion.com>"); 975 935 MODULE_AUTHOR("Pascal Sachs <pascal.sachs@sensirion.com>");
+2 -6
drivers/hwmon/sis5595.c
··· 153 153 } 154 154 155 155 /* 156 - * FAN DIV: 1, 2, 4, or 8 (defaults to 2) 157 - * REG: 0, 1, 2, or 3 (respectively) (defaults to 1) 156 + * FAN DIV: 1, 2, 4, or 8 157 + * REG: 0, 1, 2, or 3 (respectively) 158 158 */ 159 - static inline u8 DIV_TO_REG(int val) 160 - { 161 - return val == 8 ? 3 : val == 4 ? 2 : val == 1 ? 0 : 1; 162 - } 163 159 #define DIV_FROM_REG(val) (1 << (val)) 164 160 165 161 /*
+91
drivers/hwmon/surface_fan.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Surface Fan driver for Surface System Aggregator Module. It provides access 4 + * to the fan's rpm through the hwmon system. 5 + * 6 + * Copyright (C) 2023 Ivor Wanders <ivor@iwanders.net> 7 + */ 8 + 9 + #include <linux/hwmon.h> 10 + #include <linux/kernel.h> 11 + #include <linux/module.h> 12 + #include <linux/surface_aggregator/device.h> 13 + #include <linux/types.h> 14 + 15 + // SSAM 16 + SSAM_DEFINE_SYNC_REQUEST_CL_R(__ssam_fan_rpm_get, __le16, { 17 + .target_category = SSAM_SSH_TC_FAN, 18 + .command_id = 0x01, 19 + }); 20 + 21 + // hwmon 22 + static umode_t surface_fan_hwmon_is_visible(const void *drvdata, 23 + enum hwmon_sensor_types type, u32 attr, 24 + int channel) 25 + { 26 + return 0444; 27 + } 28 + 29 + static int surface_fan_hwmon_read(struct device *dev, 30 + enum hwmon_sensor_types type, u32 attr, 31 + int channel, long *val) 32 + { 33 + struct ssam_device *sdev = dev_get_drvdata(dev); 34 + int ret; 35 + __le16 value; 36 + 37 + ret = __ssam_fan_rpm_get(sdev, &value); 38 + if (ret) 39 + return ret; 40 + 41 + *val = le16_to_cpu(value); 42 + 43 + return 0; 44 + } 45 + 46 + static const struct hwmon_channel_info *const surface_fan_info[] = { 47 + HWMON_CHANNEL_INFO(fan, HWMON_F_INPUT), 48 + NULL 49 + }; 50 + 51 + static const struct hwmon_ops surface_fan_hwmon_ops = { 52 + .is_visible = surface_fan_hwmon_is_visible, 53 + .read = surface_fan_hwmon_read, 54 + }; 55 + 56 + static const struct hwmon_chip_info surface_fan_chip_info = { 57 + .ops = &surface_fan_hwmon_ops, 58 + .info = surface_fan_info, 59 + }; 60 + 61 + static int surface_fan_probe(struct ssam_device *sdev) 62 + { 63 + struct device *hdev; 64 + 65 + hdev = devm_hwmon_device_register_with_info(&sdev->dev, 66 + "surface_fan", sdev, 67 + &surface_fan_chip_info, 68 + NULL); 69 + 70 + return PTR_ERR_OR_ZERO(hdev); 71 + } 72 + 73 + static const struct ssam_device_id ssam_fan_match[] = { 74 + { SSAM_SDEV(FAN, SAM, 0x01, 0x01) }, 75 + {}, 76 + }; 77 + MODULE_DEVICE_TABLE(ssam, ssam_fan_match); 78 + 79 + static struct ssam_device_driver surface_fan = { 80 + .probe = surface_fan_probe, 81 + .match_table = ssam_fan_match, 82 + .driver = { 83 + .name = "surface_fan", 84 + .probe_type = PROBE_PREFER_ASYNCHRONOUS, 85 + }, 86 + }; 87 + module_ssam_device_driver(surface_fan); 88 + 89 + MODULE_AUTHOR("Ivor Wanders <ivor@iwanders.net>"); 90 + MODULE_DESCRIPTION("Fan Driver for Surface System Aggregator Module"); 91 + MODULE_LICENSE("GPL");
+1 -1
drivers/hwmon/tmp401.c
··· 256 256 static const struct regmap_config tmp401_regmap_config = { 257 257 .reg_bits = 8, 258 258 .val_bits = 16, 259 - .cache_type = REGCACHE_RBTREE, 259 + .cache_type = REGCACHE_MAPLE, 260 260 .volatile_reg = tmp401_regmap_is_volatile, 261 261 .reg_read = tmp401_reg_read, 262 262 .reg_write = tmp401_reg_write,
-1
drivers/hwmon/w83773g.c
··· 290 290 } 291 291 292 292 static struct i2c_driver w83773_driver = { 293 - .class = I2C_CLASS_HWMON, 294 293 .driver = { 295 294 .name = "w83773g", 296 295 .of_match_table = of_match_ptr(w83773_of_match),
+12 -6
include/linux/hwmon.h
··· 141 141 hwmon_in_rated_min, 142 142 hwmon_in_rated_max, 143 143 hwmon_in_beep, 144 + hwmon_in_fault, 144 145 }; 145 146 146 147 #define HWMON_I_ENABLE BIT(hwmon_in_enable) ··· 163 162 #define HWMON_I_RATED_MIN BIT(hwmon_in_rated_min) 164 163 #define HWMON_I_RATED_MAX BIT(hwmon_in_rated_max) 165 164 #define HWMON_I_BEEP BIT(hwmon_in_beep) 165 + #define HWMON_I_FAULT BIT(hwmon_in_fault) 166 166 167 167 enum hwmon_curr_attributes { 168 168 hwmon_curr_enable, ··· 295 293 hwmon_humidity_fault, 296 294 hwmon_humidity_rated_min, 297 295 hwmon_humidity_rated_max, 296 + hwmon_humidity_min_alarm, 297 + hwmon_humidity_max_alarm, 298 298 }; 299 299 300 300 #define HWMON_H_ENABLE BIT(hwmon_humidity_enable) ··· 310 306 #define HWMON_H_FAULT BIT(hwmon_humidity_fault) 311 307 #define HWMON_H_RATED_MIN BIT(hwmon_humidity_rated_min) 312 308 #define HWMON_H_RATED_MAX BIT(hwmon_humidity_rated_max) 309 + #define HWMON_H_MIN_ALARM BIT(hwmon_humidity_min_alarm) 310 + #define HWMON_H_MAX_ALARM BIT(hwmon_humidity_max_alarm) 313 311 314 312 enum hwmon_fan_attributes { 315 313 hwmon_fan_enable, ··· 431 425 const u32 *config; 432 426 }; 433 427 434 - #define HWMON_CHANNEL_INFO(stype, ...) \ 435 - (&(struct hwmon_channel_info) { \ 436 - .type = hwmon_##stype, \ 437 - .config = (u32 []) { \ 438 - __VA_ARGS__, 0 \ 439 - } \ 428 + #define HWMON_CHANNEL_INFO(stype, ...) \ 429 + (&(const struct hwmon_channel_info) { \ 430 + .type = hwmon_##stype, \ 431 + .config = (const u32 []) { \ 432 + __VA_ARGS__, 0 \ 433 + } \ 440 434 }) 441 435 442 436 /**