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

Configure Feed

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

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

Pull hwmon updates from Guenter Roeck:
"New drivers:
- SB-TSI sensors
- Lineat Technology LTC2992
- Delta power supplies Q54SJ108A2
- Maxim MAX127
- Corsair PSU
- STMicroelectronics PM6764 Voltage Regulator

New chip support:
- P10 added to fsi/occ driver
- NCT6687D added to nct6883 driver
- Intel-based Xserves added to applesmc driver
- AMD family 19h model 01h added to amd_energy driver

And various minor bug fixes and improvements"

* tag 'hwmon-for-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging: (41 commits)
dt-bindings: (hwmon/sbtsi_temp) Add SB-TSI hwmon driver bindings
hwmon: (sbtsi) Add documentation
hwmon: (sbtsi) Add basic support for SB-TSI sensors
hwmon: (iio_hwmon) Drop bogus __refdata annotation
hwmon: (xgene) Drop bogus __refdata annotation
dt-bindings: hwmon: convert AD ADM1275 bindings to dt-schema
hwmon: (occ) Add new temperature sensor type
fsi: occ: Add support for P10
dt-bindings: fsi: Add P10 OCC device documentation
dt-bindings: hwmon: convert TI ADS7828 bindings to dt-schema
dt-bindings: hwmon: convert AD AD741x bindings to dt-schema
dt-bindings: hwmon: convert TI INA2xx bindings to dt-schema
hwmon: (ltc2992) Fix less than zero comparisons with an unsigned integer
hwmon: (pmbus/q54sj108a2) Correct title underline length
dt-bindings: hwmon: Add documentation for ltc2992
hwmon: (ltc2992) Add support for GPIOs.
hwmon: (ltc2992) Add support
hwmon: (pmbus) Driver for Delta power supplies Q54SJ108A2
hwmon: Add driver for STMicroelectronics PM6764 Voltage Regulator
hwmon: (nct6683) Support NCT6687D.
...

+3880 -321
+6 -6
Documentation/devicetree/bindings/fsi/ibm,p9-occ.txt
··· 1 - Device-tree bindings for FSI-attached POWER9 On-Chip Controller (OCC) 2 - --------------------------------------------------------------------- 1 + Device-tree bindings for FSI-attached POWER9/POWER10 On-Chip Controller (OCC) 2 + ----------------------------------------------------------------------------- 3 3 4 - This is the binding for the P9 On-Chip Controller accessed over FSI from a 5 - service processor. See fsi.txt for details on bindings for FSI slave and CFAM 4 + This is the binding for the P9 or P10 On-Chip Controller accessed over FSI from 5 + a service processor. See fsi.txt for details on bindings for FSI slave and CFAM 6 6 nodes. The OCC is not an FSI slave device itself, rather it is accessed 7 - through the SBE fifo. 7 + through the SBE FIFO. 8 8 9 9 Required properties: 10 - - compatible = "ibm,p9-occ" 10 + - compatible = "ibm,p9-occ" or "ibm,p10-occ" 11 11 12 12 Examples: 13 13
-15
Documentation/devicetree/bindings/hwmon/ad741x.txt
··· 1 - * AD7416/AD7417/AD7418 Temperature Sensor Device Tree Bindings 2 - 3 - Required properties: 4 - - compatible: one of 5 - "adi,ad7416" 6 - "adi,ad7417" 7 - "adi,ad7418" 8 - - reg: I2C address 9 - 10 - Example: 11 - 12 - hwmon@28 { 13 - compatible = "adi,ad7418"; 14 - reg = <0x28>; 15 - };
+39
Documentation/devicetree/bindings/hwmon/adi,ad741x.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + 5 + $id: http://devicetree.org/schemas/hwmon/adi,ad741x.yaml# 6 + $schema: http://devicetree.org/meta-schemas/core.yaml# 7 + 8 + title: Analog Devices AD7416/AD7417/AD7418 temperature sensors 9 + 10 + maintainers: 11 + - Krzysztof Kozlowski <krzk@kernel.org> 12 + 13 + properties: 14 + compatible: 15 + enum: 16 + - adi,ad7416 17 + - adi,ad7417 18 + - adi,ad7418 19 + 20 + reg: 21 + maxItems: 1 22 + 23 + required: 24 + - compatible 25 + - reg 26 + 27 + additionalProperties: false 28 + 29 + examples: 30 + - | 31 + i2c { 32 + #address-cells = <1>; 33 + #size-cells = <0>; 34 + 35 + temperature-sensor@28 { 36 + compatible = "adi,ad7418"; 37 + reg = <0x28>; 38 + }; 39 + };
+57
Documentation/devicetree/bindings/hwmon/adi,adm1275.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + 5 + $id: http://devicetree.org/schemas/hwmon/adi,adm1275.yaml# 6 + $schema: http://devicetree.org/meta-schemas/core.yaml# 7 + 8 + title: Analog Devices ADM1075/ADM127x/ADM129x digital power monitors 9 + 10 + maintainers: 11 + - Krzysztof Kozlowski <krzk@kernel.org> 12 + 13 + description: | 14 + The ADM1293 and ADM1294 are high accuracy integrated digital power monitors 15 + that offer digital current, voltage, and power monitoring using an on-chip, 16 + 12-bit analog-to-digital converter (ADC), communicated through a PMBus 17 + compliant I2C interface. 18 + 19 + Datasheets: 20 + https://www.analog.com/en/products/adm1294.html 21 + 22 + properties: 23 + compatible: 24 + enum: 25 + - adi,adm1075 26 + - adi,adm1272 27 + - adi,adm1275 28 + - adi,adm1276 29 + - adi,adm1278 30 + - adi,adm1293 31 + - adi,adm1294 32 + 33 + reg: 34 + maxItems: 1 35 + 36 + shunt-resistor-micro-ohms: 37 + description: 38 + Shunt resistor value in micro-Ohm. 39 + 40 + required: 41 + - compatible 42 + - reg 43 + 44 + additionalProperties: false 45 + 46 + examples: 47 + - | 48 + i2c { 49 + #address-cells = <1>; 50 + #size-cells = <0>; 51 + 52 + power-sensor@10 { 53 + compatible = "adi,adm1272"; 54 + reg = <0x10>; 55 + shunt-resistor-micro-ohms = <500>; 56 + }; 57 + };
+80
Documentation/devicetree/bindings/hwmon/adi,ltc2992.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,ltc2992.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Linear Technology 2992 Power Monitor 8 + 9 + maintainers: 10 + - Alexandru Tachici <alexandru.tachici@analog.com> 11 + 12 + description: | 13 + Linear Technology 2992 Dual Wide Range Power Monitor 14 + https://www.analog.com/media/en/technical-documentation/data-sheets/ltc2992.pdf 15 + 16 + properties: 17 + compatible: 18 + enum: 19 + - adi,ltc2992 20 + 21 + reg: 22 + maxItems: 1 23 + 24 + '#address-cells': 25 + const: 1 26 + 27 + '#size-cells': 28 + const: 0 29 + 30 + avcc-supply: true 31 + 32 + patternProperties: 33 + "^channel@([0-1])$": 34 + type: object 35 + description: | 36 + Represents the two supplies to be monitored. 37 + 38 + properties: 39 + reg: 40 + description: | 41 + The channel number. LTC2992 can monitor two supplies. 42 + items: 43 + minimum: 0 44 + maximum: 1 45 + 46 + shunt-resistor-micro-ohms: 47 + description: 48 + The value of curent sense resistor in microohms. 49 + 50 + required: 51 + - compatible 52 + - reg 53 + 54 + additionalProperties: false 55 + 56 + examples: 57 + - | 58 + i2c1 { 59 + #address-cells = <1>; 60 + #size-cells = <0>; 61 + 62 + ltc2992@6F { 63 + #address-cells = <1>; 64 + #size-cells = <0>; 65 + 66 + compatible = "adi,ltc2992"; 67 + reg = <0x6F>; 68 + 69 + channel@0 { 70 + reg = <0x0>; 71 + shunt-resistor-micro-ohms = <10000>; 72 + }; 73 + 74 + channel@1 { 75 + reg = <0x1>; 76 + shunt-resistor-micro-ohms = <10000>; 77 + }; 78 + }; 79 + }; 80 + ...
-25
Documentation/devicetree/bindings/hwmon/adm1275.txt
··· 1 - adm1275 properties 2 - 3 - Required properties: 4 - - compatible: Must be one of the supported compatible strings: 5 - - "adi,adm1075" for adm1075 6 - - "adi,adm1272" for adm1272 7 - - "adi,adm1275" for adm1275 8 - - "adi,adm1276" for adm1276 9 - - "adi,adm1278" for adm1278 10 - - "adi,adm1293" for adm1293 11 - - "adi,adm1294" for adm1294 12 - - reg: I2C address 13 - 14 - Optional properties: 15 - 16 - - shunt-resistor-micro-ohms 17 - Shunt resistor value in micro-Ohm 18 - 19 - Example: 20 - 21 - adm1272@10 { 22 - compatible = "adi,adm1272"; 23 - reg = <0x10>; 24 - shunt-resistor-micro-ohms = <500>; 25 - };
-25
Documentation/devicetree/bindings/hwmon/ads7828.txt
··· 1 - ads7828 properties 2 - 3 - Required properties: 4 - - compatible: Should be one of 5 - ti,ads7828 6 - ti,ads7830 7 - - reg: I2C address 8 - 9 - Optional properties: 10 - 11 - - ti,differential-input 12 - Set to use the device in differential mode. 13 - - vref-supply 14 - The external reference on the device is set to this regulators output. If it 15 - does not exists the internal reference will be used and output by the ads78xx 16 - on the "external vref" pin. 17 - 18 - Example ADS7828 node: 19 - 20 - ads7828: ads@48 { 21 - comatible = "ti,ads7828"; 22 - reg = <0x48>; 23 - vref-supply = <&vref>; 24 - ti,differential-input; 25 - };
+54
Documentation/devicetree/bindings/hwmon/amd,sbtsi.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/amd,sbtsi.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: > 8 + Sideband interface Temperature Sensor Interface (SB-TSI) compliant 9 + AMD SoC temperature device 10 + 11 + maintainers: 12 + - Kun Yi <kunyi@google.com> 13 + - Supreeth Venkatesh <supreeth.venkatesh@amd.com> 14 + 15 + description: | 16 + SB Temperature Sensor Interface (SB-TSI) is an SMBus compatible 17 + interface that reports AMD SoC's Ttcl (normalized temperature), 18 + and resembles a typical 8-pin remote temperature sensor's I2C interface 19 + to BMC. The emulated thermal sensor can report temperatures in increments 20 + of 0.125 degrees, ranging from 0 to 255.875. 21 + 22 + properties: 23 + compatible: 24 + enum: 25 + - amd,sbtsi 26 + 27 + reg: 28 + maxItems: 1 29 + description: | 30 + I2C bus address of the device as specified in Section 6.3.1 of the 31 + SoC register reference. The SB-TSI address is normally 98h for socket 32 + 0 and 90h for socket 1, but it could vary based on hardware address 33 + select pins. 34 + \[open source SoC register reference\] 35 + https://www.amd.com/system/files/TechDocs/56255_OSRR.pdf 36 + 37 + required: 38 + - compatible 39 + - reg 40 + 41 + additionalProperties: false 42 + 43 + examples: 44 + - | 45 + i2c0 { 46 + #address-cells = <1>; 47 + #size-cells = <0>; 48 + 49 + sbtsi@4c { 50 + compatible = "amd,sbtsi"; 51 + reg = <0x4c>; 52 + }; 53 + }; 54 + ...
-24
Documentation/devicetree/bindings/hwmon/ina2xx.txt
··· 1 - ina2xx properties 2 - 3 - Required properties: 4 - - compatible: Must be one of the following: 5 - - "ti,ina209" for ina209 6 - - "ti,ina219" for ina219 7 - - "ti,ina220" for ina220 8 - - "ti,ina226" for ina226 9 - - "ti,ina230" for ina230 10 - - "ti,ina231" for ina231 11 - - reg: I2C address 12 - 13 - Optional properties: 14 - 15 - - shunt-resistor 16 - Shunt resistor value in micro-Ohm 17 - 18 - Example: 19 - 20 - ina220@44 { 21 - compatible = "ti,ina220"; 22 - reg = <0x44>; 23 - shunt-resistor = <1000>; 24 - };
+19 -9
Documentation/devicetree/bindings/hwmon/pwm-fan.txt
··· 8 8 9 9 Optional properties: 10 10 - fan-supply : phandle to the regulator that provides power to the fan 11 - - interrupts : This contains a single interrupt specifier which 12 - describes the tachometer output of the fan as an 13 - interrupt source. The output signal must generate a 14 - defined number of interrupts per fan revolution, which 15 - require that it must be self resetting edge interrupts. 16 - See interrupt-controller/interrupts.txt for the format. 17 - - pulses-per-revolution : define the tachometer pulses per fan revolution as 18 - an integer (default is 2 interrupts per revolution). 19 - The value must be greater than zero. 11 + - interrupts : This contains an interrupt specifier for each fan 12 + tachometer output connected to an interrupt source. 13 + The output signal must generate a defined number of 14 + interrupts per fan revolution, which require that 15 + it must be self resetting edge interrupts. See 16 + interrupt-controller/interrupts.txt for the format. 17 + - pulses-per-revolution : define the number of pulses per fan revolution for 18 + each tachometer input as an integer (default is 2 19 + interrupts per revolution). The value must be 20 + greater than zero. 20 21 21 22 Example: 22 23 fan0: pwm-fan { ··· 55 54 interrupt-parent = <&gpio5>; 56 55 interrupts = <1 IRQ_TYPE_EDGE_FALLING>; 57 56 pulses-per-revolution = <2>; 57 + }; 58 + 59 + Example 3: 60 + fan0: pwm-fan { 61 + compatible = "pwm-fan"; 62 + pwms = <&pwm1 0 25000 0>; 63 + interrupts-extended = <&gpio1 1 IRQ_TYPE_EDGE_FALLING>, 64 + <&gpio2 5 IRQ_TYPE_EDGE_FALLING>; 65 + pulses-per-revolution = <2>, <1>; 58 66 };
+57
Documentation/devicetree/bindings/hwmon/ti,ads7828.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + 5 + $id: http://devicetree.org/schemas/hwmon/ti,ads7828.yaml# 6 + $schema: http://devicetree.org/meta-schemas/core.yaml# 7 + 8 + title: Texas Instruments ADS7828/ADS7830 Analog to Digital Converter (ADC) 9 + 10 + maintainers: 11 + - Krzysztof Kozlowski <krzk@kernel.org> 12 + 13 + description: | 14 + The ADS7828 is 12-Bit, 8-Channel Sampling Analog to Digital Converter (ADC) 15 + with an I2C interface. 16 + 17 + Datasheets: 18 + https://www.ti.com/product/ADS7828 19 + 20 + properties: 21 + compatible: 22 + enum: 23 + - ti,ads7828 24 + - ti,ads7830 25 + 26 + reg: 27 + maxItems: 1 28 + 29 + ti,differential-input: 30 + description: 31 + Set to use the device in differential mode. 32 + type: boolean 33 + 34 + vref-supply: 35 + description: 36 + The regulator to use as an external reference. If it does not exists the 37 + internal reference will be used. 38 + 39 + required: 40 + - compatible 41 + - reg 42 + 43 + additionalProperties: false 44 + 45 + examples: 46 + - | 47 + i2c { 48 + #address-cells = <1>; 49 + #size-cells = <0>; 50 + 51 + adc@48 { 52 + comatible = "ti,ads7828"; 53 + reg = <0x48>; 54 + vref-supply = <&vref>; 55 + ti,differential-input; 56 + }; 57 + };
+55
Documentation/devicetree/bindings/hwmon/ti,ina2xx.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + 5 + $id: http://devicetree.org/schemas/hwmon/ti,ina2xx.yaml# 6 + $schema: http://devicetree.org/meta-schemas/core.yaml# 7 + 8 + title: Texas Instruments INA209 family of power/voltage monitors 9 + 10 + maintainers: 11 + - Krzysztof Kozlowski <krzk@kernel.org> 12 + 13 + description: | 14 + The INA209 is a high-side current shunt and power monitor with 15 + an I2C interface. 16 + 17 + Datasheets: 18 + https://www.ti.com/product/INA209 19 + 20 + properties: 21 + compatible: 22 + enum: 23 + - ti,ina209 24 + - ti,ina219 25 + - ti,ina220 26 + - ti,ina226 27 + - ti,ina230 28 + - ti,ina231 29 + 30 + reg: 31 + maxItems: 1 32 + 33 + shunt-resistor: 34 + description: 35 + Shunt resistor value in micro-Ohm. 36 + $ref: /schemas/types.yaml#/definitions/uint32 37 + 38 + required: 39 + - compatible 40 + - reg 41 + 42 + additionalProperties: false 43 + 44 + examples: 45 + - | 46 + i2c { 47 + #address-cells = <1>; 48 + #size-cells = <0>; 49 + 50 + power-sensor@44 { 51 + compatible = "ti,ina220"; 52 + reg = <0x44>; 53 + shunt-resistor = <1000>; 54 + }; 55 + };
-4
Documentation/devicetree/bindings/trivial-devices.yaml
··· 254 254 - st,24c256 255 255 # Ambient Light Sensor with SMBUS/Two Wire Serial Interface 256 256 - taos,tsl2550 257 - # 8-Channels, 12-bit ADC 258 - - ti,ads7828 259 - # 8-Channels, 8-bit ADC 260 - - ti,ads7830 261 257 # Temperature Monitoring and Fan Control 262 258 - ti,amc6821 263 259 # Temperature and humidity sensor with i2c interface
+1 -1
Documentation/hwmon/adm1275.rst
··· 83 83 and will typically have to be scaled. 84 84 85 85 The shunt value in micro-ohms can be set via device tree at compile-time. Please 86 - refer to the Documentation/devicetree/bindings/hwmon/adm1275.txt for bindings 86 + refer to the Documentation/devicetree/bindings/hwmon/adi,adm1275.yaml for bindings 87 87 if the device tree is used. 88 88 89 89 Platform data support
+6 -1
Documentation/hwmon/amd_energy.rst
··· 5 5 6 6 Supported chips: 7 7 8 - * AMD Family 17h Processors 8 + * AMD Family 17h Processors: Model 30h 9 + 10 + * AMD Family 19h Processors: Model 01h 9 11 10 12 Prefix: 'amd_energy' 11 13 ··· 114 112 energy[N]_input EsocketX Socket Energy X = [0] to [nr_socks -1] 115 113 Measured input socket energy 116 114 =============== ======== ====================================== 115 + 116 + Note: To address CVE-2020-12912, the visibility of the energy[N]_input 117 + attributes is restricted to owner and groups only.
+82
Documentation/hwmon/corsair-psu.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + Kernel driver corsair-psu 4 + ========================= 5 + 6 + Supported devices: 7 + 8 + * Corsair Power Supplies 9 + 10 + Corsair HX550i 11 + 12 + Corsair HX650i 13 + 14 + Corsair HX750i 15 + 16 + Corsair HX850i 17 + 18 + Corsair HX1000i 19 + 20 + Corsair HX1200i 21 + 22 + Corsair RM550i 23 + 24 + Corsair RM650i 25 + 26 + Corsair RM750i 27 + 28 + Corsair RM850i 29 + 30 + Corsair RM1000i 31 + 32 + Author: Wilken Gottwalt 33 + 34 + Description 35 + ----------- 36 + 37 + This driver implements the sysfs interface for the Corsair PSUs with a HID protocol 38 + interface of the HXi and RMi series. 39 + These power supplies provide access to a micro-controller with 2 attached 40 + temperature sensors, 1 fan rpm sensor, 4 sensors for volt levels, 4 sensors for 41 + power usage and 4 sensors for current levels and addtional non-sensor information 42 + like uptimes. 43 + 44 + Sysfs entries 45 + ------------- 46 + 47 + ======================= ======================================================== 48 + curr1_input Total current usage 49 + curr2_input Current on the 12v psu rail 50 + curr3_input Current on the 5v psu rail 51 + curr4_input Current on the 3.3v psu rail 52 + fan1_input RPM of psu fan 53 + in0_input Voltage of the psu ac input 54 + in1_input Voltage of the 12v psu rail 55 + in2_input Voltage of the 5v psu rail 56 + in3_input Voltage of the 3.3 psu rail 57 + power1_input Total power usage 58 + power2_input Power usage of the 12v psu rail 59 + power3_input Power usage of the 5v psu rail 60 + power4_input Power usage of the 3.3v psu rail 61 + temp1_input Temperature of the psu vrm component 62 + temp2_input Temperature of the psu case 63 + ======================= ======================================================== 64 + 65 + Usage Notes 66 + ----------- 67 + 68 + It is an USB HID device, so it is auto-detected and supports hot-swapping. 69 + 70 + Flickering values in the rail voltage levels can be an indicator for a failing 71 + PSU. The driver also provides some additional useful values via debugfs, which 72 + do not fit into the hwmon class. 73 + 74 + Debugfs entries 75 + --------------- 76 + 77 + ======================= ======================================================== 78 + uptime Current uptime of the psu 79 + uptime_total Total uptime of the psu 80 + vendor Vendor name of the psu 81 + product Product name of the psu 82 + ======================= ========================================================
+6
Documentation/hwmon/index.rst
··· 49 49 bt1-pvt 50 50 coretemp 51 51 corsair-cpro 52 + corsair-psu 52 53 da9052 53 54 da9055 54 55 dell-smm-hwmon ··· 101 100 lm95234 102 101 lm95245 103 102 lochnagar 103 + ltc2992 104 104 ltc2945 105 105 ltc2947 106 106 ltc2978 ··· 112 110 ltc4245 113 111 ltc4260 114 112 ltc4261 113 + max127 115 114 max16064 116 115 max16065 117 116 max1619 ··· 147 144 pc87360 148 145 pc87427 149 146 pcf8591 147 + pm6764tr 150 148 pmbus 151 149 powr1220 152 150 pxe1610 153 151 pwm-fan 152 + q54sj108a2 154 153 raspberrypi-hwmon 154 + sbtsi_temp 155 155 sch5627 156 156 sch5636 157 157 scpi-hwmon
+56
Documentation/hwmon/ltc2992.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0 2 + 3 + Kernel driver ltc2992 4 + ===================== 5 + 6 + Supported chips: 7 + * Linear Technology LTC2992 8 + Prefix: 'ltc2992' 9 + Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ltc2992.pdf 10 + 11 + Author: Alexandru Tachici <alexandru.tachici@analog.com> 12 + 13 + 14 + Description 15 + ----------- 16 + 17 + This driver supports hardware monitoring for Linear Technology LTC2992 power monitor. 18 + 19 + LTC2992 is a rail-to-rail system monitor that measures current, 20 + voltage, and power of two supplies. 21 + 22 + Two ADCs simultaneously measure each supply’s current. A third ADC monitors 23 + the input voltages and four auxiliary external voltages. 24 + 25 + 26 + Sysfs entries 27 + ------------- 28 + 29 + The following attributes are supported. Limits are read-write, 30 + all other attributes are read-only. 31 + 32 + in_reset_history Reset all highest/lowest values. 33 + 34 + inX_input Measured voltage. 35 + inX_lowest Minimum measured voltage. 36 + inX_highest Maximum measured voltage. 37 + inX_min Minimum voltage allowed. 38 + inX_max Maximum voltage allowed. 39 + inX_min_alarm An undervoltage occurred. Cleared on read. 40 + inX_max_alarm An overvoltage occurred. Cleared on read. 41 + 42 + currX_input Measured current. 43 + currX_lowest Minimum measured current. 44 + currX_highest Maximum measured current. 45 + currX_min Minimum current allowed. 46 + currX_max Maximum current allowed. 47 + currX_min_alarm An undercurrent occurred. Cleared on read. 48 + currX_max_alarm An overcurrent occurred. Cleared on read. 49 + 50 + powerX_input Measured power. 51 + powerX_input_lowest Minimum measured voltage. 52 + powerX_input_highest Maximum measured voltage. 53 + powerX_min Minimum power. 54 + powerX_max Maximum power. 55 + powerX_min_alarm An underpower occurred. Cleared on read. 56 + powerX_max_alarm An overpower occurred. Cleared on read.
+45
Documentation/hwmon/max127.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + Kernel driver max127 4 + ==================== 5 + 6 + Author: 7 + 8 + * Tao Ren <rentao.bupt@gmail.com> 9 + 10 + Supported chips: 11 + 12 + * Maxim MAX127 13 + 14 + Prefix: 'max127' 15 + 16 + Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX127-MAX128.pdf 17 + 18 + Description 19 + ----------- 20 + 21 + The MAX127 is a multirange, 12-bit data acquisition system (DAS) providing 22 + 8 analog input channels that are independently software programmable for 23 + a variety of ranges. The available ranges are {0,5V}, {0,10V}, {-5,5V} 24 + and {-10,10V}. 25 + 26 + The MAX127 features a 2-wire, I2C-compatible serial interface that allows 27 + communication among multiple devices using SDA and SCL lines. 28 + 29 + Sysfs interface 30 + --------------- 31 + 32 + ============== ============================================================== 33 + in[0-7]_input The input voltage (in mV) of the corresponding channel. 34 + RO 35 + 36 + in[0-7]_min The lower input limit (in mV) for the corresponding channel. 37 + ADC range and LSB will be updated when the limit is changed. 38 + For the MAX127, it will be adjusted to -10000, -5000, or 0. 39 + RW 40 + 41 + in[0-7]_max The higher input limit (in mV) for the corresponding channel. 42 + ADC range and LSB will be updated when the limit is changed. 43 + For the MAX127, it will be adjusted to 0, 5000, or 10000. 44 + RW 45 + ============== ==============================================================
+2 -1
Documentation/hwmon/nct6683.rst
··· 3 3 4 4 Supported chips: 5 5 6 - * Nuvoton NCT6683D 6 + * Nuvoton NCT6683D/NCT6687D 7 7 8 8 Prefix: 'nct6683' 9 9 ··· 61 61 Intel DH87RL NCT6683D EC firmware version 1.0 build 04/03/13 62 62 Intel DH87MC NCT6683D EC firmware version 1.0 build 04/03/13 63 63 Intel DB85FL NCT6683D EC firmware version 1.0 build 04/03/13 64 + MSI B550 NCT6687D EC firmware version 1.0 build 05/07/20 64 65 =============== ===============================================
+32
Documentation/hwmon/pm6764tr.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0-only 2 + 3 + Kernel driver pm6764tr 4 + ====================== 5 + 6 + Supported chips: 7 + 8 + * ST PM6764TR 9 + 10 + Prefix: 'pm6764tr' 11 + 12 + Addresses scanned: - 13 + 14 + Datasheet: http://www.st.com/resource/en/data_brief/pm6764.pdf 15 + 16 + Authors: 17 + <hsu.yungteng@gmail.com> 18 + 19 + Description: 20 + ------------ 21 + 22 + This driver supports the STMicroelectronics PM6764TR chip. The PM6764TR is a high 23 + performance digital controller designed to power Intel’s VR12.5 processors and memories. 24 + 25 + The device utilizes digital technology to implement all control and power management 26 + functions to provide maximum flexibility and performance. The NVM is embedded to store 27 + custom configurations. The PM6764TR device features up to 4-phase programmable operation. 28 + 29 + The PM6764TR supports power state transitions featuring VFDE, and programmable DPM 30 + maintaining the best efficiency over all loading conditions without compromising transient 31 + response. The device assures fast and independent protection against load overcurrent, 32 + under/overvoltage and feedback disconnections.
-6
Documentation/hwmon/pmbus-core.rst
··· 279 279 280 280 :: 281 281 282 - void pmbus_do_remove(struct i2c_client *client); 283 - 284 - Execute driver remove function. Similar to standard driver remove function. 285 - 286 - :: 287 - 288 282 const struct pmbus_driver_info 289 283 *pmbus_get_driver_info(struct i2c_client *client); 290 284
-6
Documentation/hwmon/pmbus.rst
··· 148 148 return pmbus_do_probe(client, &ds1200_info); 149 149 } 150 150 151 - static int ds1200_remove(struct i2c_client *client) 152 - { 153 - return pmbus_do_remove(client); 154 - } 155 - 156 151 static const struct i2c_device_id ds1200_id[] = { 157 152 {"ds1200", 0}, 158 153 {} ··· 161 166 .name = "ds1200", 162 167 }, 163 168 .probe_new = ds1200_probe, 164 - .remove = ds1200_remove, 165 169 .id_table = ds1200_id, 166 170 }; 167 171
+54
Documentation/hwmon/q54sj108a2.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + Kernel driver q54sj108a2 4 + ======================== 5 + 6 + Supported chips: 7 + 8 + * DELTA Q54SJ108A2NCAH, Q54SJ108A2NCDH, Q54SJ108A2NCPG, Q54SJ108A2NCPH 9 + 10 + Prefix: 'q54sj108a2' 11 + 12 + Addresses scanned: - 13 + 14 + Datasheet: https://filecenter.delta-china.com.cn/products/download/01/0102/datasheet/DS_Q54SJ108A2.pdf 15 + 16 + Authors: 17 + Xiao.ma <xiao.mx.ma@deltaww.com> 18 + 19 + 20 + Description 21 + ----------- 22 + 23 + This driver implements support for DELTA Q54SJ108A2NCAH, Q54SJ108A2NCDH, 24 + Q54SJ108A2NCPG, and Q54SJ108A2NCPH 1/4 Brick DC/DC Regulated Power Module 25 + with PMBus support. 26 + 27 + The driver is a client driver to the core PMBus driver. 28 + Please see Documentation/hwmon/pmbus.rst for details on PMBus client drivers. 29 + 30 + 31 + Usage Notes 32 + ----------- 33 + 34 + This driver does not auto-detect devices. You will have to instantiate the 35 + devices explicitly. Please see Documentation/i2c/instantiating-devices.rst for 36 + details. 37 + 38 + 39 + Sysfs entries 40 + ------------- 41 + 42 + ===================== ===== ================================================== 43 + curr1_alarm RO Output current alarm 44 + curr1_input RO Output current 45 + curr1_label RO 'iout1' 46 + in1_alarm RO Input voltage alarm 47 + in1_input RO Input voltage 48 + in1_label RO 'vin' 49 + in2_alarm RO Output voltage alarm 50 + in2_input RO Output voltage 51 + in2_label RO 'vout1' 52 + temp1_alarm RO Temperature alarm 53 + temp1_input RO Chip temperature 54 + ===================== ===== ==================================================
+42
Documentation/hwmon/sbtsi_temp.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + Kernel driver sbtsi_temp 4 + ================== 5 + 6 + Supported hardware: 7 + 8 + * Sideband interface (SBI) Temperature Sensor Interface (SB-TSI) 9 + compliant AMD SoC temperature device. 10 + 11 + Prefix: 'sbtsi_temp' 12 + 13 + Addresses scanned: This driver doesn't support address scanning. 14 + 15 + To instantiate this driver on an AMD CPU with SB-TSI 16 + support, the i2c bus number would be the bus connected from the board 17 + management controller (BMC) to the CPU. The i2c address is specified in 18 + Section 6.3.1 of the SoC register reference: The SB-TSI address is normally 19 + 98h for socket 0 and 90h for socket 1, but it could vary based on hardware 20 + address select pins. 21 + 22 + Datasheet: The SB-TSI interface and protocol is available as part of 23 + the open source SoC register reference at: 24 + 25 + https://www.amd.com/system/files/TechDocs/56255_OSRR.pdf 26 + 27 + The Advanced Platform Management Link (APML) Specification is 28 + available at: 29 + 30 + http://developer.amd.com/wordpress/media/2012/10/41918.pdf 31 + 32 + Author: Kun Yi <kunyi@google.com> 33 + 34 + Description 35 + ----------- 36 + 37 + The SBI temperature sensor interface (SB-TSI) is an emulation of the software 38 + and physical interface of a typical 8-pin remote temperature sensor (RTS) on 39 + AMD SoCs. It implements one temperature sensor with readings and limit 40 + registers encode the temperature in increments of 0.125 from 0 to 255.875. 41 + Limits can be set through the writable thresholds, and if reached will trigger 42 + corresponding alert signals.
+15 -1
MAINTAINERS
··· 4513 4513 S: Maintained 4514 4514 F: drivers/hwmon/corsair-cpro.c 4515 4515 4516 + CORSAIR-PSU HARDWARE MONITOR DRIVER 4517 + M: Wilken Gottwalt <wilken.gottwalt@posteo.net> 4518 + L: linux-hwmon@vger.kernel.org 4519 + S: Maintained 4520 + F: Documentation/hwmon/corsair-psu.rst 4521 + F: drivers/hwmon/corsair-psu.c 4522 + 4516 4523 COSA/SRP SYNC SERIAL DRIVER 4517 4524 M: Jan "Yenya" Kasprzak <kas@fi.muni.cz> 4518 4525 S: Maintained ··· 8682 8675 M: Guenter Roeck <linux@roeck-us.net> 8683 8676 L: linux-hwmon@vger.kernel.org 8684 8677 S: Maintained 8685 - F: Documentation/devicetree/bindings/hwmon/ina2xx.txt 8678 + F: Documentation/devicetree/bindings/hwmon/ti,ina2xx.yaml 8686 8679 F: Documentation/hwmon/ina209.rst 8687 8680 F: drivers/hwmon/ina209.c 8688 8681 ··· 14041 14034 M: Logan Gunthorpe <logang@deltatee.com> 14042 14035 S: Maintained 14043 14036 F: drivers/dma/plx_dma.c 14037 + 14038 + PM6764TR DRIVER 14039 + M: Charles Hsu <hsu.yungteng@gmail.com> 14040 + L: linux-hwmon@vger.kernel.org 14041 + S: Maintained 14042 + F: Documentation/hwmon/pm6764tr.rst 14043 + F: drivers/hwmon/pmbus/pm6764tr.c 14044 14044 14045 14045 PM-GRAPH UTILITY 14046 14046 M: "Todd E Brandt" <todd.e.brandt@linux.intel.com>
+92 -35
drivers/fsi/fsi-occ.c
··· 14 14 #include <linux/mutex.h> 15 15 #include <linux/fsi-occ.h> 16 16 #include <linux/of.h> 17 + #include <linux/of_device.h> 17 18 #include <linux/platform_device.h> 18 19 #include <linux/sched.h> 19 20 #include <linux/slab.h> ··· 25 24 #define OCC_CMD_DATA_BYTES 4090 26 25 #define OCC_RESP_DATA_BYTES 4089 27 26 28 - #define OCC_SRAM_CMD_ADDR 0xFFFBE000 29 - #define OCC_SRAM_RSP_ADDR 0xFFFBF000 27 + #define OCC_P9_SRAM_CMD_ADDR 0xFFFBE000 28 + #define OCC_P9_SRAM_RSP_ADDR 0xFFFBF000 29 + 30 + #define OCC_P10_SRAM_CMD_ADDR 0xFFFFD000 31 + #define OCC_P10_SRAM_RSP_ADDR 0xFFFFE000 32 + 33 + #define OCC_P10_SRAM_MODE 0x58 /* Normal mode, OCB channel 2 */ 30 34 31 35 /* 32 36 * Assume we don't have much FFDC, if we do we'll overflow and ··· 43 37 #define OCC_TIMEOUT_MS 1000 44 38 #define OCC_CMD_IN_PRG_WAIT_MS 50 45 39 40 + enum versions { occ_p9, occ_p10 }; 41 + 46 42 struct occ { 47 43 struct device *dev; 48 44 struct device *sbefifo; 49 45 char name[32]; 50 46 int idx; 47 + enum versions version; 51 48 struct miscdevice mdev; 52 49 struct mutex occ_lock; 53 50 }; ··· 244 235 return 0; 245 236 } 246 237 247 - static int occ_getsram(struct occ *occ, u32 address, void *data, ssize_t len) 238 + static int occ_getsram(struct occ *occ, u32 offset, void *data, ssize_t len) 248 239 { 249 240 u32 data_len = ((len + 7) / 8) * 8; /* must be multiples of 8 B */ 250 - size_t resp_len, resp_data_len; 251 - __be32 *resp, cmd[5]; 252 - int rc; 241 + size_t cmd_len, resp_len, resp_data_len; 242 + __be32 *resp, cmd[6]; 243 + int idx = 0, rc; 253 244 254 245 /* 255 246 * Magic sequence to do SBE getsram command. SBE will fetch data from 256 247 * specified SRAM address. 257 248 */ 258 - cmd[0] = cpu_to_be32(0x5); 249 + switch (occ->version) { 250 + default: 251 + case occ_p9: 252 + cmd_len = 5; 253 + cmd[2] = cpu_to_be32(1); /* Normal mode */ 254 + cmd[3] = cpu_to_be32(OCC_P9_SRAM_RSP_ADDR + offset); 255 + break; 256 + case occ_p10: 257 + idx = 1; 258 + cmd_len = 6; 259 + cmd[2] = cpu_to_be32(OCC_P10_SRAM_MODE); 260 + cmd[3] = 0; 261 + cmd[4] = cpu_to_be32(OCC_P10_SRAM_RSP_ADDR + offset); 262 + break; 263 + } 264 + 265 + cmd[0] = cpu_to_be32(cmd_len); 259 266 cmd[1] = cpu_to_be32(SBEFIFO_CMD_GET_OCC_SRAM); 260 - cmd[2] = cpu_to_be32(1); 261 - cmd[3] = cpu_to_be32(address); 262 - cmd[4] = cpu_to_be32(data_len); 267 + cmd[4 + idx] = cpu_to_be32(data_len); 263 268 264 269 resp_len = (data_len >> 2) + OCC_SBE_STATUS_WORDS; 265 270 resp = kzalloc(resp_len << 2, GFP_KERNEL); 266 271 if (!resp) 267 272 return -ENOMEM; 268 273 269 - rc = sbefifo_submit(occ->sbefifo, cmd, 5, resp, &resp_len); 274 + rc = sbefifo_submit(occ->sbefifo, cmd, cmd_len, resp, &resp_len); 270 275 if (rc) 271 276 goto free; 272 277 ··· 310 287 return rc; 311 288 } 312 289 313 - static int occ_putsram(struct occ *occ, u32 address, const void *data, 314 - ssize_t len) 290 + static int occ_putsram(struct occ *occ, const void *data, ssize_t len) 315 291 { 316 292 size_t cmd_len, buf_len, resp_len, resp_data_len; 317 293 u32 data_len = ((len + 7) / 8) * 8; /* must be multiples of 8 B */ 318 294 __be32 *buf; 319 - int rc; 295 + int idx = 0, rc; 296 + 297 + cmd_len = (occ->version == occ_p10) ? 6 : 5; 320 298 321 299 /* 322 300 * We use the same buffer for command and response, make 323 301 * sure it's big enough 324 302 */ 325 303 resp_len = OCC_SBE_STATUS_WORDS; 326 - cmd_len = (data_len >> 2) + 5; 304 + cmd_len += data_len >> 2; 327 305 buf_len = max(cmd_len, resp_len); 328 306 buf = kzalloc(buf_len << 2, GFP_KERNEL); 329 307 if (!buf) ··· 336 312 */ 337 313 buf[0] = cpu_to_be32(cmd_len); 338 314 buf[1] = cpu_to_be32(SBEFIFO_CMD_PUT_OCC_SRAM); 339 - buf[2] = cpu_to_be32(1); 340 - buf[3] = cpu_to_be32(address); 341 - buf[4] = cpu_to_be32(data_len); 342 315 343 - memcpy(&buf[5], data, len); 316 + switch (occ->version) { 317 + default: 318 + case occ_p9: 319 + buf[2] = cpu_to_be32(1); /* Normal mode */ 320 + buf[3] = cpu_to_be32(OCC_P9_SRAM_CMD_ADDR); 321 + break; 322 + case occ_p10: 323 + idx = 1; 324 + buf[2] = cpu_to_be32(OCC_P10_SRAM_MODE); 325 + buf[3] = 0; 326 + buf[4] = cpu_to_be32(OCC_P10_SRAM_CMD_ADDR); 327 + break; 328 + } 329 + 330 + buf[4 + idx] = cpu_to_be32(data_len); 331 + memcpy(&buf[5 + idx], data, len); 344 332 345 333 rc = sbefifo_submit(occ->sbefifo, buf, cmd_len, buf, &resp_len); 346 334 if (rc) ··· 392 356 static int occ_trigger_attn(struct occ *occ) 393 357 { 394 358 __be32 buf[OCC_SBE_STATUS_WORDS]; 395 - size_t resp_len, resp_data_len; 396 - int rc; 359 + size_t cmd_len, resp_len, resp_data_len; 360 + int idx = 0, rc; 397 361 398 - BUILD_BUG_ON(OCC_SBE_STATUS_WORDS < 7); 362 + BUILD_BUG_ON(OCC_SBE_STATUS_WORDS < 8); 399 363 resp_len = OCC_SBE_STATUS_WORDS; 400 364 401 - buf[0] = cpu_to_be32(0x5 + 0x2); /* Chip-op length in words */ 402 - buf[1] = cpu_to_be32(SBEFIFO_CMD_PUT_OCC_SRAM); 403 - buf[2] = cpu_to_be32(0x3); /* Mode: Circular */ 404 - buf[3] = cpu_to_be32(0x0); /* Address: ignore in mode 3 */ 405 - buf[4] = cpu_to_be32(0x8); /* Data length in bytes */ 406 - buf[5] = cpu_to_be32(0x20010000); /* Trigger OCC attention */ 407 - buf[6] = 0; 365 + switch (occ->version) { 366 + default: 367 + case occ_p9: 368 + cmd_len = 7; 369 + buf[2] = cpu_to_be32(3); /* Circular mode */ 370 + buf[3] = 0; 371 + break; 372 + case occ_p10: 373 + idx = 1; 374 + cmd_len = 8; 375 + buf[2] = cpu_to_be32(0xd0); /* Circular mode, OCB Channel 1 */ 376 + buf[3] = 0; 377 + buf[4] = 0; 378 + break; 379 + } 408 380 409 - rc = sbefifo_submit(occ->sbefifo, buf, 7, buf, &resp_len); 381 + buf[0] = cpu_to_be32(cmd_len); /* Chip-op length in words */ 382 + buf[1] = cpu_to_be32(SBEFIFO_CMD_PUT_OCC_SRAM); 383 + buf[4 + idx] = cpu_to_be32(8); /* Data length in bytes */ 384 + buf[5 + idx] = cpu_to_be32(0x20010000); /* Trigger OCC attention */ 385 + buf[6 + idx] = 0; 386 + 387 + rc = sbefifo_submit(occ->sbefifo, buf, cmd_len, buf, &resp_len); 410 388 if (rc) 411 389 goto error; 412 390 ··· 479 429 480 430 /* Extract the seq_no from the command (first byte) */ 481 431 seq_no = *(const u8 *)request; 482 - rc = occ_putsram(occ, OCC_SRAM_CMD_ADDR, request, req_len); 432 + rc = occ_putsram(occ, request, req_len); 483 433 if (rc) 484 434 goto done; 485 435 ··· 490 440 /* Read occ response header */ 491 441 start = jiffies; 492 442 do { 493 - rc = occ_getsram(occ, OCC_SRAM_RSP_ADDR, resp, 8); 443 + rc = occ_getsram(occ, 0, resp, 8); 494 444 if (rc) 495 445 goto done; 496 446 ··· 526 476 /* Grab the rest */ 527 477 if (resp_data_length > 1) { 528 478 /* already got 3 bytes resp, also need 2 bytes checksum */ 529 - rc = occ_getsram(occ, OCC_SRAM_RSP_ADDR + 8, 530 - &resp->data[3], resp_data_length - 1); 479 + rc = occ_getsram(occ, 8, &resp->data[3], resp_data_length - 1); 531 480 if (rc) 532 481 goto done; 533 482 } ··· 566 517 if (!occ) 567 518 return -ENOMEM; 568 519 520 + occ->version = (uintptr_t)of_device_get_match_data(dev); 569 521 occ->dev = dev; 570 522 occ->sbefifo = dev->parent; 571 523 mutex_init(&occ->occ_lock); ··· 625 575 } 626 576 627 577 static const struct of_device_id occ_match[] = { 628 - { .compatible = "ibm,p9-occ" }, 578 + { 579 + .compatible = "ibm,p9-occ", 580 + .data = (void *)occ_p9 581 + }, 582 + { 583 + .compatible = "ibm,p10-occ", 584 + .data = (void *)occ_p10 585 + }, 629 586 { }, 630 587 }; 631 588
+44
drivers/hwmon/Kconfig
··· 449 449 This driver can also be built as a module. If so, the module 450 450 will be called corsair-cpro. 451 451 452 + config SENSORS_CORSAIR_PSU 453 + tristate "Corsair PSU HID controller" 454 + depends on HID 455 + help 456 + If you say yes here you get support for Corsair PSUs with a HID 457 + interface. 458 + Currently this driver supports the (RM/HX)550i, (RM/HX)650i, 459 + (RM/HX)750i, (RM/HX)850i, (RM/HX)1000i and HX1200i power supplies 460 + by Corsair. 461 + 462 + This driver can also be built as a module. If so, the module 463 + will be called corsair-psu. 464 + 452 465 config SENSORS_DRIVETEMP 453 466 tristate "Hard disk drives with temperature sensors" 454 467 depends on SCSI && ATA ··· 871 858 This driver can also be built as a module. If so, the module will 872 859 be called ltc2990. 873 860 861 + config SENSORS_LTC2992 862 + tristate "Linear Technology LTC2992" 863 + depends on I2C 864 + depends on GPIOLIB 865 + help 866 + If you say yes here you get support for Linear Technology LTC2992 867 + I2C System Monitor. The LTC2992 measures current, voltage, and 868 + power of two supplies. 869 + 870 + This driver can also be built as a module. If so, the module will 871 + be called ltc2992. 872 + 874 873 config SENSORS_LTC4151 875 874 tristate "Linear Technology LTC4151" 876 875 depends on I2C ··· 961 936 962 937 This driver can also be built as a module. If so, the module 963 938 will be called max1111. 939 + 940 + config SENSORS_MAX127 941 + tristate "Maxim MAX127 12-bit 8-channel Data Acquisition System" 942 + depends on I2C 943 + help 944 + Say y here to support Maxim's MAX127 DAS chips. 945 + 946 + This driver can also be built as a module. If so, the module 947 + will be called max127. 964 948 965 949 config SENSORS_MAX16065 966 950 tristate "Maxim MAX16065 System Manager and compatibles" ··· 1532 1498 1533 1499 This driver can also be built as a module. If so, the module 1534 1500 will be called sl28cpld-hwmon. 1501 + 1502 + config SENSORS_SBTSI 1503 + tristate "Emulated SB-TSI temperature sensor" 1504 + depends on I2C 1505 + help 1506 + If you say yes here you get support for emulated temperature 1507 + sensors on AMD SoCs with SB-TSI interface connected to a BMC device. 1508 + 1509 + This driver can also be built as a module. If so, the module will 1510 + be called sbtsi_temp. 1535 1511 1536 1512 config SENSORS_SHT15 1537 1513 tristate "Sensiron humidity and temperature sensors. SHT15 and compat."
+4
drivers/hwmon/Makefile
··· 57 57 obj-$(CONFIG_SENSORS_BT1_PVT) += bt1-pvt.o 58 58 obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o 59 59 obj-$(CONFIG_SENSORS_CORSAIR_CPRO) += corsair-cpro.o 60 + obj-$(CONFIG_SENSORS_CORSAIR_PSU) += corsair-psu.o 60 61 obj-$(CONFIG_SENSORS_DA9052_ADC)+= da9052-hwmon.o 61 62 obj-$(CONFIG_SENSORS_DA9055)+= da9055-hwmon.o 62 63 obj-$(CONFIG_SENSORS_DELL_SMM) += dell-smm-hwmon.o ··· 119 118 obj-$(CONFIG_SENSORS_LTC2947_I2C) += ltc2947-i2c.o 120 119 obj-$(CONFIG_SENSORS_LTC2947_SPI) += ltc2947-spi.o 121 120 obj-$(CONFIG_SENSORS_LTC2990) += ltc2990.o 121 + obj-$(CONFIG_SENSORS_LTC2992) += ltc2992.o 122 122 obj-$(CONFIG_SENSORS_LTC4151) += ltc4151.o 123 123 obj-$(CONFIG_SENSORS_LTC4215) += ltc4215.o 124 124 obj-$(CONFIG_SENSORS_LTC4222) += ltc4222.o ··· 128 126 obj-$(CONFIG_SENSORS_LTC4261) += ltc4261.o 129 127 obj-$(CONFIG_SENSORS_LTQ_CPUTEMP) += ltq-cputemp.o 130 128 obj-$(CONFIG_SENSORS_MAX1111) += max1111.o 129 + obj-$(CONFIG_SENSORS_MAX127) += max127.o 131 130 obj-$(CONFIG_SENSORS_MAX16065) += max16065.o 132 131 obj-$(CONFIG_SENSORS_MAX1619) += max1619.o 133 132 obj-$(CONFIG_SENSORS_MAX1668) += max1668.o ··· 161 158 obj-$(CONFIG_SENSORS_PWM_FAN) += pwm-fan.o 162 159 obj-$(CONFIG_SENSORS_RASPBERRYPI_HWMON) += raspberrypi-hwmon.o 163 160 obj-$(CONFIG_SENSORS_S3C) += s3c-hwmon.o 161 + obj-$(CONFIG_SENSORS_SBTSI) += sbtsi_temp.o 164 162 obj-$(CONFIG_SENSORS_SCH56XX_COMMON)+= sch56xx-common.o 165 163 obj-$(CONFIG_SENSORS_SCH5627) += sch5627.o 166 164 obj-$(CONFIG_SENSORS_SCH5636) += sch5636.o
+1 -1
drivers/hwmon/abx500.c
··· 263 263 static umode_t abx500_attrs_visible(struct kobject *kobj, 264 264 struct attribute *attr, int n) 265 265 { 266 - struct device *dev = container_of(kobj, struct device, kobj); 266 + struct device *dev = kobj_to_dev(kobj); 267 267 struct abx500_temp *data = dev_get_drvdata(dev); 268 268 269 269 if (data->ops.is_visible)
+4 -5
drivers/hwmon/acpi_power_meter.c
··· 725 725 int i; 726 726 727 727 str = &resource->model_number; 728 - for (i = 0; i < 3; i++, str++) 728 + for (i = 0; i < 3; i++, str++) { 729 729 kfree(*str); 730 + *str = NULL; 731 + } 730 732 } 731 733 732 734 static int read_capabilities(struct acpi_power_meter_resource *resource) ··· 803 801 dev_info(&resource->acpi_dev->dev, "Found ACPI power meter.\n"); 804 802 goto end; 805 803 error: 806 - str = &resource->model_number; 807 - for (i = 0; i < 3; i++, str++) 808 - kfree(*str); 804 + free_capabilities(resource); 809 805 end: 810 806 kfree(buffer.pointer); 811 807 return res; ··· 874 874 strcpy(acpi_device_class(device), ACPI_POWER_METER_CLASS); 875 875 device->driver_data = resource; 876 876 877 - free_capabilities(resource); 878 877 res = read_capabilities(resource); 879 878 if (res) 880 879 goto exit_free;
+5 -5
drivers/hwmon/adm1177.c
··· 25 25 26 26 /** 27 27 * struct adm1177_state - driver instance specific data 28 - * @client pointer to i2c client 29 - * @reg regulator info for the the power supply of the device 30 - * @r_sense_uohm current sense resistor value 31 - * @alert_threshold_ua current limit for shutdown 32 - * @vrange_high internal voltage divider 28 + * @client: pointer to i2c client 29 + * @reg: regulator info for the power supply of the device 30 + * @r_sense_uohm: current sense resistor value 31 + * @alert_threshold_ua: current limit for shutdown 32 + * @vrange_high: internal voltage divider 33 33 */ 34 34 struct adm1177_state { 35 35 struct i2c_client *client;
+118 -36
drivers/hwmon/adt7470.c
··· 270 270 return 0; 271 271 } 272 272 273 - static struct adt7470_data *adt7470_update_device(struct device *dev) 273 + static int adt7470_update_sensors(struct adt7470_data *data) 274 274 { 275 - struct adt7470_data *data = dev_get_drvdata(dev); 276 275 struct i2c_client *client = data->client; 277 - unsigned long local_jiffies = jiffies; 278 276 u8 cfg; 279 277 int i; 280 - int need_sensors = 1; 281 - int need_limits = 1; 282 - 283 - /* 284 - * Figure out if we need to update the shadow registers. 285 - * Lockless means that we may occasionally report out of 286 - * date data. 287 - */ 288 - if (time_before(local_jiffies, data->sensors_last_updated + 289 - SENSOR_REFRESH_INTERVAL) && 290 - data->sensors_valid) 291 - need_sensors = 0; 292 - 293 - if (time_before(local_jiffies, data->limits_last_updated + 294 - LIMIT_REFRESH_INTERVAL) && 295 - data->limits_valid) 296 - need_limits = 0; 297 - 298 - if (!need_sensors && !need_limits) 299 - return data; 300 - 301 - mutex_lock(&data->lock); 302 - if (!need_sensors) 303 - goto no_sensor_update; 304 278 305 279 if (!data->temperatures_probed) 306 280 adt7470_read_temperatures(client, data); ··· 326 352 data->alarms_mask = adt7470_read_word_data(client, 327 353 ADT7470_REG_ALARM1_MASK); 328 354 329 - data->sensors_last_updated = local_jiffies; 330 - data->sensors_valid = 1; 355 + return 0; 356 + } 331 357 332 - no_sensor_update: 333 - if (!need_limits) 334 - goto out; 358 + static int adt7470_update_limits(struct adt7470_data *data) 359 + { 360 + struct i2c_client *client = data->client; 361 + int i; 335 362 336 363 for (i = 0; i < ADT7470_TEMP_COUNT; i++) { 337 364 data->temp_min[i] = i2c_smbus_read_byte_data(client, ··· 357 382 ADT7470_REG_PWM_TMIN(i)); 358 383 } 359 384 360 - data->limits_last_updated = local_jiffies; 361 - data->limits_valid = 1; 385 + return 0; 386 + } 362 387 388 + static struct adt7470_data *adt7470_update_device(struct device *dev) 389 + { 390 + struct adt7470_data *data = dev_get_drvdata(dev); 391 + unsigned long local_jiffies = jiffies; 392 + int need_sensors = 1; 393 + int need_limits = 1; 394 + int err; 395 + 396 + /* 397 + * Figure out if we need to update the shadow registers. 398 + * Lockless means that we may occasionally report out of 399 + * date data. 400 + */ 401 + if (time_before(local_jiffies, data->sensors_last_updated + 402 + SENSOR_REFRESH_INTERVAL) && 403 + data->sensors_valid) 404 + need_sensors = 0; 405 + 406 + if (time_before(local_jiffies, data->limits_last_updated + 407 + LIMIT_REFRESH_INTERVAL) && 408 + data->limits_valid) 409 + need_limits = 0; 410 + 411 + if (!need_sensors && !need_limits) 412 + return data; 413 + 414 + mutex_lock(&data->lock); 415 + if (need_sensors) { 416 + err = adt7470_update_sensors(data); 417 + if (err < 0) 418 + goto out; 419 + data->sensors_last_updated = local_jiffies; 420 + data->sensors_valid = 1; 421 + } 422 + 423 + if (need_limits) { 424 + err = adt7470_update_limits(data); 425 + if (err < 0) 426 + goto out; 427 + data->limits_last_updated = local_jiffies; 428 + data->limits_valid = 1; 429 + } 363 430 out: 364 431 mutex_unlock(&data->lock); 365 - return data; 432 + 433 + return err < 0 ? ERR_PTR(err) : data; 366 434 } 367 435 368 436 static ssize_t auto_update_interval_show(struct device *dev, ··· 413 395 char *buf) 414 396 { 415 397 struct adt7470_data *data = adt7470_update_device(dev); 398 + 399 + if (IS_ERR(data)) 400 + return PTR_ERR(data); 401 + 416 402 return sprintf(buf, "%d\n", data->auto_update_interval); 417 403 } 418 404 ··· 444 422 char *buf) 445 423 { 446 424 struct adt7470_data *data = adt7470_update_device(dev); 425 + 426 + if (IS_ERR(data)) 427 + return PTR_ERR(data); 428 + 447 429 return sprintf(buf, "%d\n", data->num_temp_sensors); 448 430 } 449 431 ··· 477 451 { 478 452 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 479 453 struct adt7470_data *data = adt7470_update_device(dev); 454 + 455 + if (IS_ERR(data)) 456 + return PTR_ERR(data); 457 + 480 458 return sprintf(buf, "%d\n", 1000 * data->temp_min[attr->index]); 481 459 } 482 460 ··· 513 483 { 514 484 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 515 485 struct adt7470_data *data = adt7470_update_device(dev); 486 + 487 + if (IS_ERR(data)) 488 + return PTR_ERR(data); 489 + 516 490 return sprintf(buf, "%d\n", 1000 * data->temp_max[attr->index]); 517 491 } 518 492 ··· 549 515 { 550 516 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 551 517 struct adt7470_data *data = adt7470_update_device(dev); 518 + 519 + if (IS_ERR(data)) 520 + return PTR_ERR(data); 521 + 552 522 return sprintf(buf, "%d\n", 1000 * data->temp[attr->index]); 553 523 } 554 524 ··· 561 523 char *buf) 562 524 { 563 525 struct adt7470_data *data = adt7470_update_device(dev); 526 + 527 + if (IS_ERR(data)) 528 + return PTR_ERR(data); 564 529 565 530 return sprintf(buf, "%x\n", data->alarms_mask); 566 531 } ··· 594 553 { 595 554 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 596 555 struct adt7470_data *data = adt7470_update_device(dev); 556 + 557 + if (IS_ERR(data)) 558 + return PTR_ERR(data); 597 559 598 560 if (FAN_DATA_VALID(data->fan_max[attr->index])) 599 561 return sprintf(buf, "%d\n", ··· 634 590 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 635 591 struct adt7470_data *data = adt7470_update_device(dev); 636 592 593 + if (IS_ERR(data)) 594 + return PTR_ERR(data); 595 + 637 596 if (FAN_DATA_VALID(data->fan_min[attr->index])) 638 597 return sprintf(buf, "%d\n", 639 598 FAN_PERIOD_TO_RPM(data->fan_min[attr->index])); ··· 673 626 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 674 627 struct adt7470_data *data = adt7470_update_device(dev); 675 628 629 + if (IS_ERR(data)) 630 + return PTR_ERR(data); 631 + 676 632 if (FAN_DATA_VALID(data->fan[attr->index])) 677 633 return sprintf(buf, "%d\n", 678 634 FAN_PERIOD_TO_RPM(data->fan[attr->index])); ··· 687 637 struct device_attribute *devattr, char *buf) 688 638 { 689 639 struct adt7470_data *data = adt7470_update_device(dev); 640 + 641 + if (IS_ERR(data)) 642 + return PTR_ERR(data); 643 + 690 644 return sprintf(buf, "%d\n", data->force_pwm_max); 691 645 } 692 646 ··· 724 670 { 725 671 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 726 672 struct adt7470_data *data = adt7470_update_device(dev); 673 + 674 + if (IS_ERR(data)) 675 + return PTR_ERR(data); 676 + 727 677 return sprintf(buf, "%d\n", data->pwm[attr->index]); 728 678 } 729 679 ··· 821 763 { 822 764 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 823 765 struct adt7470_data *data = adt7470_update_device(dev); 766 + 767 + if (IS_ERR(data)) 768 + return PTR_ERR(data); 769 + 824 770 return sprintf(buf, "%d\n", data->pwm_max[attr->index]); 825 771 } 826 772 ··· 856 794 { 857 795 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 858 796 struct adt7470_data *data = adt7470_update_device(dev); 797 + 798 + if (IS_ERR(data)) 799 + return PTR_ERR(data); 800 + 859 801 return sprintf(buf, "%d\n", data->pwm_min[attr->index]); 860 802 } 861 803 ··· 891 825 { 892 826 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 893 827 struct adt7470_data *data = adt7470_update_device(dev); 828 + 829 + if (IS_ERR(data)) 830 + return PTR_ERR(data); 831 + 894 832 /* the datasheet says that tmax = tmin + 20C */ 895 833 return sprintf(buf, "%d\n", 1000 * (20 + data->pwm_tmin[attr->index])); 896 834 } ··· 904 834 { 905 835 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 906 836 struct adt7470_data *data = adt7470_update_device(dev); 837 + 838 + if (IS_ERR(data)) 839 + return PTR_ERR(data); 840 + 907 841 return sprintf(buf, "%d\n", 1000 * data->pwm_tmin[attr->index]); 908 842 } 909 843 ··· 940 866 { 941 867 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 942 868 struct adt7470_data *data = adt7470_update_device(dev); 869 + 870 + if (IS_ERR(data)) 871 + return PTR_ERR(data); 872 + 943 873 return sprintf(buf, "%d\n", 1 + data->pwm_automatic[attr->index]); 944 874 } 945 875 ··· 989 911 { 990 912 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 991 913 struct adt7470_data *data = adt7470_update_device(dev); 992 - u8 ctrl = data->pwm_auto_temp[attr->index]; 914 + u8 ctrl; 993 915 916 + if (IS_ERR(data)) 917 + return PTR_ERR(data); 918 + 919 + ctrl = data->pwm_auto_temp[attr->index]; 994 920 if (ctrl) 995 921 return sprintf(buf, "%d\n", 1 << (ctrl - 1)); 996 922 else
+1
drivers/hwmon/amd_energy.c
··· 331 331 332 332 static const struct x86_cpu_id cpu_ids[] __initconst = { 333 333 X86_MATCH_VENDOR_FAM_MODEL(AMD, 0x17, 0x31, NULL), 334 + X86_MATCH_VENDOR_FAM_MODEL(AMD, 0x19, 0x01, NULL), 334 335 {} 335 336 }; 336 337 MODULE_DEVICE_TABLE(x86cpu, cpu_ids);
+4
drivers/hwmon/applesmc.c
··· 1299 1299 DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), 1300 1300 DMI_MATCH(DMI_PRODUCT_NAME, "iMac") }, 1301 1301 }, 1302 + { applesmc_dmi_match, "Apple Xserve", { 1303 + DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), 1304 + DMI_MATCH(DMI_PRODUCT_NAME, "Xserve") }, 1305 + }, 1302 1306 { .ident = NULL } 1303 1307 }; 1304 1308
+600
drivers/hwmon/corsair-psu.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * corsair-psu.c - Linux driver for Corsair power supplies with HID sensors interface 4 + * Copyright (C) 2020 Wilken Gottwalt <wilken.gottwalt@posteo.net> 5 + */ 6 + 7 + #include <linux/completion.h> 8 + #include <linux/debugfs.h> 9 + #include <linux/errno.h> 10 + #include <linux/hid.h> 11 + #include <linux/hwmon.h> 12 + #include <linux/hwmon-sysfs.h> 13 + #include <linux/jiffies.h> 14 + #include <linux/kernel.h> 15 + #include <linux/module.h> 16 + #include <linux/mutex.h> 17 + #include <linux/slab.h> 18 + #include <linux/types.h> 19 + 20 + /* 21 + * Corsair protocol for PSUs 22 + * 23 + * message size = 64 bytes (request and response, little endian) 24 + * request: 25 + * [length][command][param0][param1][paramX]... 26 + * reply: 27 + * [echo of length][echo of command][data0][data1][dataX]... 28 + * 29 + * - commands are byte sized opcodes 30 + * - length is the sum of all bytes of the commands/params 31 + * - the micro-controller of most of these PSUs support concatenation in the request and reply, 32 + * but it is better to not rely on this (it is also hard to parse) 33 + * - the driver uses raw events to be accessible from userspace (though this is not really 34 + * supported, it is just there for convenience, may be removed in the future) 35 + * - a reply always start with the length and command in the same order the request used it 36 + * - length of the reply data is specific to the command used 37 + * - some of the commands work on a rail and can be switched to a specific rail (0 = 12v, 38 + * 1 = 5v, 2 = 3.3v) 39 + * - the format of the init command 0xFE is swapped length/command bytes 40 + * - parameter bytes amount and values are specific to the command (rail setting is the only 41 + * for now that uses non-zero values) 42 + * - there are much more commands, especially for configuring the device, but they are not 43 + * supported because a wrong command/length can lockup the micro-controller 44 + * - the driver supports debugfs for values not fitting into the hwmon class 45 + * - not every device class (HXi, RMi or AXi) supports all commands 46 + * - it is a pure sensors reading driver (will not support configuring) 47 + */ 48 + 49 + #define DRIVER_NAME "corsair-psu" 50 + 51 + #define REPLY_SIZE 16 /* max length of a reply to a single command */ 52 + #define CMD_BUFFER_SIZE 64 53 + #define CMD_TIMEOUT_MS 250 54 + #define SECONDS_PER_HOUR (60 * 60) 55 + #define SECONDS_PER_DAY (SECONDS_PER_HOUR * 24) 56 + 57 + #define PSU_CMD_SELECT_RAIL 0x00 /* expects length 2 */ 58 + #define PSU_CMD_IN_VOLTS 0x88 /* the rest of the commands expect length 3 */ 59 + #define PSU_CMD_IN_AMPS 0x89 60 + #define PSU_CMD_RAIL_OUT_VOLTS 0x8B 61 + #define PSU_CMD_RAIL_AMPS 0x8C 62 + #define PSU_CMD_TEMP0 0x8D 63 + #define PSU_CMD_TEMP1 0x8E 64 + #define PSU_CMD_FAN 0x90 65 + #define PSU_CMD_RAIL_WATTS 0x96 66 + #define PSU_CMD_VEND_STR 0x99 67 + #define PSU_CMD_PROD_STR 0x9A 68 + #define PSU_CMD_TOTAL_WATTS 0xEE 69 + #define PSU_CMD_TOTAL_UPTIME 0xD1 70 + #define PSU_CMD_UPTIME 0xD2 71 + #define PSU_CMD_INIT 0xFE 72 + 73 + #define L_IN_VOLTS "v_in" 74 + #define L_OUT_VOLTS_12V "v_out +12v" 75 + #define L_OUT_VOLTS_5V "v_out +5v" 76 + #define L_OUT_VOLTS_3_3V "v_out +3.3v" 77 + #define L_IN_AMPS "curr in" 78 + #define L_AMPS_12V "curr +12v" 79 + #define L_AMPS_5V "curr +5v" 80 + #define L_AMPS_3_3V "curr +3.3v" 81 + #define L_FAN "psu fan" 82 + #define L_TEMP0 "vrm temp" 83 + #define L_TEMP1 "case temp" 84 + #define L_WATTS "power total" 85 + #define L_WATTS_12V "power +12v" 86 + #define L_WATTS_5V "power +5v" 87 + #define L_WATTS_3_3V "power +3.3v" 88 + 89 + static const char *const label_watts[] = { 90 + L_WATTS, 91 + L_WATTS_12V, 92 + L_WATTS_5V, 93 + L_WATTS_3_3V 94 + }; 95 + 96 + static const char *const label_volts[] = { 97 + L_IN_VOLTS, 98 + L_OUT_VOLTS_12V, 99 + L_OUT_VOLTS_5V, 100 + L_OUT_VOLTS_3_3V 101 + }; 102 + 103 + static const char *const label_amps[] = { 104 + L_IN_AMPS, 105 + L_AMPS_12V, 106 + L_AMPS_5V, 107 + L_AMPS_3_3V 108 + }; 109 + 110 + struct corsairpsu_data { 111 + struct hid_device *hdev; 112 + struct device *hwmon_dev; 113 + struct dentry *debugfs; 114 + struct completion wait_completion; 115 + struct mutex lock; /* for locking access to cmd_buffer */ 116 + u8 *cmd_buffer; 117 + char vendor[REPLY_SIZE]; 118 + char product[REPLY_SIZE]; 119 + }; 120 + 121 + /* some values are SMBus LINEAR11 data which need a conversion */ 122 + static int corsairpsu_linear11_to_int(const int val) 123 + { 124 + int exp = (val & 0xFFFF) >> 0x0B; 125 + int mant = val & 0x7FF; 126 + int i; 127 + 128 + if (exp > 0x0F) 129 + exp -= 0x20; 130 + if (mant > 0x3FF) 131 + mant -= 0x800; 132 + if ((mant & 0x01) == 1) 133 + ++mant; 134 + if (exp < 0) { 135 + for (i = 0; i < -exp; ++i) 136 + mant /= 2; 137 + } else { 138 + for (i = 0; i < exp; ++i) 139 + mant *= 2; 140 + } 141 + 142 + return mant; 143 + } 144 + 145 + static int corsairpsu_usb_cmd(struct corsairpsu_data *priv, u8 p0, u8 p1, u8 p2, void *data) 146 + { 147 + unsigned long time; 148 + int ret; 149 + 150 + memset(priv->cmd_buffer, 0, CMD_BUFFER_SIZE); 151 + priv->cmd_buffer[0] = p0; 152 + priv->cmd_buffer[1] = p1; 153 + priv->cmd_buffer[2] = p2; 154 + 155 + reinit_completion(&priv->wait_completion); 156 + 157 + ret = hid_hw_output_report(priv->hdev, priv->cmd_buffer, CMD_BUFFER_SIZE); 158 + if (ret < 0) 159 + return ret; 160 + 161 + time = wait_for_completion_timeout(&priv->wait_completion, 162 + msecs_to_jiffies(CMD_TIMEOUT_MS)); 163 + if (!time) 164 + return -ETIMEDOUT; 165 + 166 + /* 167 + * at the start of the reply is an echo of the send command/length in the same order it 168 + * was send, not every command is supported on every device class, if a command is not 169 + * supported, the length value in the reply is okay, but the command value is set to 0 170 + */ 171 + if (p0 != priv->cmd_buffer[0] || p1 != priv->cmd_buffer[1]) 172 + return -EOPNOTSUPP; 173 + 174 + if (data) 175 + memcpy(data, priv->cmd_buffer + 2, REPLY_SIZE); 176 + 177 + return 0; 178 + } 179 + 180 + static int corsairpsu_init(struct corsairpsu_data *priv) 181 + { 182 + /* 183 + * PSU_CMD_INIT uses swapped length/command and expects 2 parameter bytes, this command 184 + * actually generates a reply, but we don't need it 185 + */ 186 + return corsairpsu_usb_cmd(priv, PSU_CMD_INIT, 3, 0, NULL); 187 + } 188 + 189 + static int corsairpsu_fwinfo(struct corsairpsu_data *priv) 190 + { 191 + int ret; 192 + 193 + ret = corsairpsu_usb_cmd(priv, 3, PSU_CMD_VEND_STR, 0, priv->vendor); 194 + if (ret < 0) 195 + return ret; 196 + 197 + ret = corsairpsu_usb_cmd(priv, 3, PSU_CMD_PROD_STR, 0, priv->product); 198 + if (ret < 0) 199 + return ret; 200 + 201 + return 0; 202 + } 203 + 204 + static int corsairpsu_request(struct corsairpsu_data *priv, u8 cmd, u8 rail, void *data) 205 + { 206 + int ret; 207 + 208 + mutex_lock(&priv->lock); 209 + switch (cmd) { 210 + case PSU_CMD_RAIL_OUT_VOLTS: 211 + case PSU_CMD_RAIL_AMPS: 212 + case PSU_CMD_RAIL_WATTS: 213 + ret = corsairpsu_usb_cmd(priv, 2, PSU_CMD_SELECT_RAIL, rail, NULL); 214 + if (ret < 0) 215 + goto cmd_fail; 216 + break; 217 + default: 218 + break; 219 + } 220 + 221 + ret = corsairpsu_usb_cmd(priv, 3, cmd, 0, data); 222 + 223 + cmd_fail: 224 + mutex_unlock(&priv->lock); 225 + return ret; 226 + } 227 + 228 + static int corsairpsu_get_value(struct corsairpsu_data *priv, u8 cmd, u8 rail, long *val) 229 + { 230 + u8 data[REPLY_SIZE]; 231 + long tmp; 232 + int ret; 233 + 234 + ret = corsairpsu_request(priv, cmd, rail, data); 235 + if (ret < 0) 236 + return ret; 237 + 238 + /* 239 + * the biggest value here comes from the uptime command and to exceed MAXINT total uptime 240 + * needs to be about 68 years, the rest are u16 values and the biggest value coming out of 241 + * the LINEAR11 conversion are the watts values which are about 1200 for the strongest psu 242 + * supported (HX1200i) 243 + */ 244 + tmp = ((long)data[3] << 24) + (data[2] << 16) + (data[1] << 8) + data[0]; 245 + switch (cmd) { 246 + case PSU_CMD_IN_VOLTS: 247 + case PSU_CMD_IN_AMPS: 248 + case PSU_CMD_RAIL_OUT_VOLTS: 249 + case PSU_CMD_RAIL_AMPS: 250 + case PSU_CMD_TEMP0: 251 + case PSU_CMD_TEMP1: 252 + *val = corsairpsu_linear11_to_int(tmp & 0xFFFF) * 1000; 253 + break; 254 + case PSU_CMD_FAN: 255 + *val = corsairpsu_linear11_to_int(tmp & 0xFFFF); 256 + break; 257 + case PSU_CMD_RAIL_WATTS: 258 + case PSU_CMD_TOTAL_WATTS: 259 + *val = corsairpsu_linear11_to_int(tmp & 0xFFFF) * 1000000; 260 + break; 261 + case PSU_CMD_TOTAL_UPTIME: 262 + case PSU_CMD_UPTIME: 263 + *val = tmp; 264 + break; 265 + default: 266 + ret = -EOPNOTSUPP; 267 + break; 268 + } 269 + 270 + return ret; 271 + } 272 + 273 + static umode_t corsairpsu_hwmon_ops_is_visible(const void *data, enum hwmon_sensor_types type, 274 + u32 attr, int channel) 275 + { 276 + if (type == hwmon_temp && (attr == hwmon_temp_input || attr == hwmon_temp_label)) 277 + return 0444; 278 + else if (type == hwmon_fan && (attr == hwmon_fan_input || attr == hwmon_fan_label)) 279 + return 0444; 280 + else if (type == hwmon_power && (attr == hwmon_power_input || attr == hwmon_power_label)) 281 + return 0444; 282 + else if (type == hwmon_in && (attr == hwmon_in_input || attr == hwmon_in_label)) 283 + return 0444; 284 + else if (type == hwmon_curr && (attr == hwmon_curr_input || attr == hwmon_curr_label)) 285 + return 0444; 286 + 287 + return 0; 288 + } 289 + 290 + static int corsairpsu_hwmon_ops_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, 291 + int channel, long *val) 292 + { 293 + struct corsairpsu_data *priv = dev_get_drvdata(dev); 294 + int ret; 295 + 296 + if (type == hwmon_temp && attr == hwmon_temp_input && channel < 2) { 297 + ret = corsairpsu_get_value(priv, channel ? PSU_CMD_TEMP1 : PSU_CMD_TEMP0, channel, 298 + val); 299 + } else if (type == hwmon_fan && attr == hwmon_fan_input) { 300 + ret = corsairpsu_get_value(priv, PSU_CMD_FAN, 0, val); 301 + } else if (type == hwmon_power && attr == hwmon_power_input) { 302 + switch (channel) { 303 + case 0: 304 + ret = corsairpsu_get_value(priv, PSU_CMD_TOTAL_WATTS, 0, val); 305 + break; 306 + case 1 ... 3: 307 + ret = corsairpsu_get_value(priv, PSU_CMD_RAIL_WATTS, channel - 1, val); 308 + break; 309 + default: 310 + return -EOPNOTSUPP; 311 + } 312 + } else if (type == hwmon_in && attr == hwmon_in_input) { 313 + switch (channel) { 314 + case 0: 315 + ret = corsairpsu_get_value(priv, PSU_CMD_IN_VOLTS, 0, val); 316 + break; 317 + case 1 ... 3: 318 + ret = corsairpsu_get_value(priv, PSU_CMD_RAIL_OUT_VOLTS, channel - 1, val); 319 + break; 320 + default: 321 + return -EOPNOTSUPP; 322 + } 323 + } else if (type == hwmon_curr && attr == hwmon_curr_input) { 324 + switch (channel) { 325 + case 0: 326 + ret = corsairpsu_get_value(priv, PSU_CMD_IN_AMPS, 0, val); 327 + break; 328 + case 1 ... 3: 329 + ret = corsairpsu_get_value(priv, PSU_CMD_RAIL_AMPS, channel - 1, val); 330 + break; 331 + default: 332 + return -EOPNOTSUPP; 333 + } 334 + } else { 335 + return -EOPNOTSUPP; 336 + } 337 + 338 + if (ret < 0) 339 + return ret; 340 + 341 + return 0; 342 + } 343 + 344 + static int corsairpsu_hwmon_ops_read_string(struct device *dev, enum hwmon_sensor_types type, 345 + u32 attr, int channel, const char **str) 346 + { 347 + if (type == hwmon_temp && attr == hwmon_temp_label) { 348 + *str = channel ? L_TEMP1 : L_TEMP0; 349 + return 0; 350 + } else if (type == hwmon_fan && attr == hwmon_fan_label) { 351 + *str = L_FAN; 352 + return 0; 353 + } else if (type == hwmon_power && attr == hwmon_power_label && channel < 4) { 354 + *str = label_watts[channel]; 355 + return 0; 356 + } else if (type == hwmon_in && attr == hwmon_in_label && channel < 4) { 357 + *str = label_volts[channel]; 358 + return 0; 359 + } else if (type == hwmon_curr && attr == hwmon_curr_label && channel < 4) { 360 + *str = label_amps[channel]; 361 + return 0; 362 + } 363 + 364 + return -EOPNOTSUPP; 365 + } 366 + 367 + static const struct hwmon_ops corsairpsu_hwmon_ops = { 368 + .is_visible = corsairpsu_hwmon_ops_is_visible, 369 + .read = corsairpsu_hwmon_ops_read, 370 + .read_string = corsairpsu_hwmon_ops_read_string, 371 + }; 372 + 373 + static const struct hwmon_channel_info *corsairpsu_info[] = { 374 + HWMON_CHANNEL_INFO(chip, 375 + HWMON_C_REGISTER_TZ), 376 + HWMON_CHANNEL_INFO(temp, 377 + HWMON_T_INPUT | HWMON_T_LABEL, 378 + HWMON_T_INPUT | HWMON_T_LABEL), 379 + HWMON_CHANNEL_INFO(fan, 380 + HWMON_F_INPUT | HWMON_F_LABEL), 381 + HWMON_CHANNEL_INFO(power, 382 + HWMON_P_INPUT | HWMON_P_LABEL, 383 + HWMON_P_INPUT | HWMON_P_LABEL, 384 + HWMON_P_INPUT | HWMON_P_LABEL, 385 + HWMON_P_INPUT | HWMON_P_LABEL), 386 + HWMON_CHANNEL_INFO(in, 387 + HWMON_I_INPUT | HWMON_I_LABEL, 388 + HWMON_I_INPUT | HWMON_I_LABEL, 389 + HWMON_I_INPUT | HWMON_I_LABEL, 390 + HWMON_I_INPUT | HWMON_I_LABEL), 391 + HWMON_CHANNEL_INFO(curr, 392 + HWMON_C_INPUT | HWMON_C_LABEL, 393 + HWMON_C_INPUT | HWMON_C_LABEL, 394 + HWMON_C_INPUT | HWMON_C_LABEL, 395 + HWMON_C_INPUT | HWMON_C_LABEL), 396 + NULL 397 + }; 398 + 399 + static const struct hwmon_chip_info corsairpsu_chip_info = { 400 + .ops = &corsairpsu_hwmon_ops, 401 + .info = corsairpsu_info, 402 + }; 403 + 404 + #ifdef CONFIG_DEBUG_FS 405 + 406 + static void print_uptime(struct seq_file *seqf, u8 cmd) 407 + { 408 + struct corsairpsu_data *priv = seqf->private; 409 + long val; 410 + int ret; 411 + 412 + ret = corsairpsu_get_value(priv, cmd, 0, &val); 413 + if (ret < 0) { 414 + seq_puts(seqf, "N/A\n"); 415 + return; 416 + } 417 + 418 + if (val > SECONDS_PER_DAY) { 419 + seq_printf(seqf, "%ld day(s), %02ld:%02ld:%02ld\n", val / SECONDS_PER_DAY, 420 + val % SECONDS_PER_DAY / SECONDS_PER_HOUR, val % SECONDS_PER_HOUR / 60, 421 + val % 60); 422 + return; 423 + } 424 + 425 + seq_printf(seqf, "%02ld:%02ld:%02ld\n", val % SECONDS_PER_DAY / SECONDS_PER_HOUR, 426 + val % SECONDS_PER_HOUR / 60, val % 60); 427 + } 428 + 429 + static int uptime_show(struct seq_file *seqf, void *unused) 430 + { 431 + print_uptime(seqf, PSU_CMD_UPTIME); 432 + 433 + return 0; 434 + } 435 + DEFINE_SHOW_ATTRIBUTE(uptime); 436 + 437 + static int uptime_total_show(struct seq_file *seqf, void *unused) 438 + { 439 + print_uptime(seqf, PSU_CMD_TOTAL_UPTIME); 440 + 441 + return 0; 442 + } 443 + DEFINE_SHOW_ATTRIBUTE(uptime_total); 444 + 445 + static int vendor_show(struct seq_file *seqf, void *unused) 446 + { 447 + struct corsairpsu_data *priv = seqf->private; 448 + 449 + seq_printf(seqf, "%s\n", priv->vendor); 450 + 451 + return 0; 452 + } 453 + DEFINE_SHOW_ATTRIBUTE(vendor); 454 + 455 + static int product_show(struct seq_file *seqf, void *unused) 456 + { 457 + struct corsairpsu_data *priv = seqf->private; 458 + 459 + seq_printf(seqf, "%s\n", priv->product); 460 + 461 + return 0; 462 + } 463 + DEFINE_SHOW_ATTRIBUTE(product); 464 + 465 + static void corsairpsu_debugfs_init(struct corsairpsu_data *priv) 466 + { 467 + char name[32]; 468 + 469 + scnprintf(name, sizeof(name), "%s-%s", DRIVER_NAME, dev_name(&priv->hdev->dev)); 470 + 471 + priv->debugfs = debugfs_create_dir(name, NULL); 472 + debugfs_create_file("uptime", 0444, priv->debugfs, priv, &uptime_fops); 473 + debugfs_create_file("uptime_total", 0444, priv->debugfs, priv, &uptime_total_fops); 474 + debugfs_create_file("vendor", 0444, priv->debugfs, priv, &vendor_fops); 475 + debugfs_create_file("product", 0444, priv->debugfs, priv, &product_fops); 476 + } 477 + 478 + #else 479 + 480 + static void corsairpsu_debugfs_init(struct corsairpsu_data *priv) 481 + { 482 + } 483 + 484 + #endif 485 + 486 + static int corsairpsu_probe(struct hid_device *hdev, const struct hid_device_id *id) 487 + { 488 + struct corsairpsu_data *priv; 489 + int ret; 490 + 491 + priv = devm_kzalloc(&hdev->dev, sizeof(struct corsairpsu_data), GFP_KERNEL); 492 + if (!priv) 493 + return -ENOMEM; 494 + 495 + priv->cmd_buffer = devm_kmalloc(&hdev->dev, CMD_BUFFER_SIZE, GFP_KERNEL); 496 + if (!priv->cmd_buffer) 497 + return -ENOMEM; 498 + 499 + ret = hid_parse(hdev); 500 + if (ret) 501 + return ret; 502 + 503 + ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW); 504 + if (ret) 505 + return ret; 506 + 507 + ret = hid_hw_open(hdev); 508 + if (ret) 509 + goto fail_and_stop; 510 + 511 + priv->hdev = hdev; 512 + hid_set_drvdata(hdev, priv); 513 + mutex_init(&priv->lock); 514 + init_completion(&priv->wait_completion); 515 + 516 + hid_device_io_start(hdev); 517 + 518 + ret = corsairpsu_init(priv); 519 + if (ret < 0) { 520 + dev_err(&hdev->dev, "unable to initialize device (%d)\n", ret); 521 + goto fail_and_stop; 522 + } 523 + 524 + ret = corsairpsu_fwinfo(priv); 525 + if (ret < 0) { 526 + dev_err(&hdev->dev, "unable to query firmware (%d)\n", ret); 527 + goto fail_and_stop; 528 + } 529 + 530 + priv->hwmon_dev = hwmon_device_register_with_info(&hdev->dev, "corsairpsu", priv, 531 + &corsairpsu_chip_info, 0); 532 + 533 + if (IS_ERR(priv->hwmon_dev)) { 534 + ret = PTR_ERR(priv->hwmon_dev); 535 + goto fail_and_close; 536 + } 537 + 538 + corsairpsu_debugfs_init(priv); 539 + 540 + return 0; 541 + 542 + fail_and_close: 543 + hid_hw_close(hdev); 544 + fail_and_stop: 545 + hid_hw_stop(hdev); 546 + return ret; 547 + } 548 + 549 + static void corsairpsu_remove(struct hid_device *hdev) 550 + { 551 + struct corsairpsu_data *priv = hid_get_drvdata(hdev); 552 + 553 + debugfs_remove_recursive(priv->debugfs); 554 + hwmon_device_unregister(priv->hwmon_dev); 555 + hid_hw_close(hdev); 556 + hid_hw_stop(hdev); 557 + } 558 + 559 + static int corsairpsu_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data, 560 + int size) 561 + { 562 + struct corsairpsu_data *priv = hid_get_drvdata(hdev); 563 + 564 + if (completion_done(&priv->wait_completion)) 565 + return 0; 566 + 567 + memcpy(priv->cmd_buffer, data, min(CMD_BUFFER_SIZE, size)); 568 + complete(&priv->wait_completion); 569 + 570 + return 0; 571 + } 572 + 573 + static const struct hid_device_id corsairpsu_idtable[] = { 574 + { HID_USB_DEVICE(0x1b1c, 0x1c03) }, /* Corsair HX550i */ 575 + { HID_USB_DEVICE(0x1b1c, 0x1c04) }, /* Corsair HX650i */ 576 + { HID_USB_DEVICE(0x1b1c, 0x1c05) }, /* Corsair HX750i */ 577 + { HID_USB_DEVICE(0x1b1c, 0x1c06) }, /* Corsair HX850i */ 578 + { HID_USB_DEVICE(0x1b1c, 0x1c07) }, /* Corsair HX1000i */ 579 + { HID_USB_DEVICE(0x1b1c, 0x1c08) }, /* Corsair HX1200i */ 580 + { HID_USB_DEVICE(0x1b1c, 0x1c09) }, /* Corsair RM550i */ 581 + { HID_USB_DEVICE(0x1b1c, 0x1c0a) }, /* Corsair RM650i */ 582 + { HID_USB_DEVICE(0x1b1c, 0x1c0b) }, /* Corsair RM750i */ 583 + { HID_USB_DEVICE(0x1b1c, 0x1c0c) }, /* Corsair RM850i */ 584 + { HID_USB_DEVICE(0x1b1c, 0x1c0d) }, /* Corsair RM1000i */ 585 + { }, 586 + }; 587 + MODULE_DEVICE_TABLE(hid, corsairpsu_idtable); 588 + 589 + static struct hid_driver corsairpsu_driver = { 590 + .name = DRIVER_NAME, 591 + .id_table = corsairpsu_idtable, 592 + .probe = corsairpsu_probe, 593 + .remove = corsairpsu_remove, 594 + .raw_event = corsairpsu_raw_event, 595 + }; 596 + module_hid_driver(corsairpsu_driver); 597 + 598 + MODULE_LICENSE("GPL"); 599 + MODULE_AUTHOR("Wilken Gottwalt <wilken.gottwalt@posteo.net>"); 600 + MODULE_DESCRIPTION("Linux driver for Corsair power supplies with HID sensors interface");
+1 -1
drivers/hwmon/drivetemp.c
··· 10 10 * hwmon: Driver for SCSI/ATA temperature sensors 11 11 * by Constantin Baranov <const@mimas.ru>, submitted September 2009 12 12 * 13 - * This drive supports reporting the temperatire of SATA drives. It can be 13 + * This drive supports reporting the temperature of SATA drives. It can be 14 14 * easily extended to report the temperature of SCSI drives. 15 15 * 16 16 * The primary means to read drive temperatures and temperature limits
+1 -1
drivers/hwmon/ibmpowernv.c
··· 240 240 if (err) 241 241 return err; 242 242 243 - strncpy(attr, dash_pos + 1, MAX_ATTR_LEN); 243 + strscpy(attr, dash_pos + 1, MAX_ATTR_LEN); 244 244 245 245 return 0; 246 246 }
+1 -1
drivers/hwmon/iio_hwmon.c
··· 169 169 }; 170 170 MODULE_DEVICE_TABLE(of, iio_hwmon_of_match); 171 171 172 - static struct platform_driver __refdata iio_hwmon_driver = { 172 + static struct platform_driver iio_hwmon_driver = { 173 173 .driver = { 174 174 .name = "iio_hwmon", 175 175 .of_match_table = iio_hwmon_of_match,
+2 -2
drivers/hwmon/ina3221.c
··· 139 139 (ina->reg_config & INA3221_CONFIG_CHx_EN(channel)); 140 140 } 141 141 142 - /** 142 + /* 143 143 * Helper function to return the resistor value for current summation. 144 144 * 145 145 * There is a condition to calculate current summation -- all the shunt ··· 489 489 490 490 /* For enabling routine, increase refcount and resume() at first */ 491 491 if (enable) { 492 - ret = pm_runtime_get_sync(ina->pm_dev); 492 + ret = pm_runtime_resume_and_get(ina->pm_dev); 493 493 if (ret < 0) { 494 494 dev_err(dev, "Failed to get PM runtime\n"); 495 495 return ret;
+971
drivers/hwmon/ltc2992.c
··· 1 + // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + /* 3 + * LTC2992 - Dual Wide Range Power Monitor 4 + * 5 + * Copyright 2020 Analog Devices Inc. 6 + */ 7 + 8 + #include <linux/bitfield.h> 9 + #include <linux/bitops.h> 10 + #include <linux/err.h> 11 + #include <linux/gpio/driver.h> 12 + #include <linux/hwmon.h> 13 + #include <linux/i2c.h> 14 + #include <linux/kernel.h> 15 + #include <linux/module.h> 16 + #include <linux/property.h> 17 + #include <linux/regmap.h> 18 + 19 + #define LTC2992_CTRLB 0x01 20 + #define LTC2992_FAULT1 0x03 21 + #define LTC2992_POWER1 0x05 22 + #define LTC2992_POWER1_MAX 0x08 23 + #define LTC2992_POWER1_MIN 0x0B 24 + #define LTC2992_POWER1_MAX_THRESH 0x0E 25 + #define LTC2992_POWER1_MIN_THRESH 0x11 26 + #define LTC2992_DSENSE1 0x14 27 + #define LTC2992_DSENSE1_MAX 0x16 28 + #define LTC2992_DSENSE1_MIN 0x18 29 + #define LTC2992_DSENSE1_MAX_THRESH 0x1A 30 + #define LTC2992_DSENSE1_MIN_THRESH 0x1C 31 + #define LTC2992_SENSE1 0x1E 32 + #define LTC2992_SENSE1_MAX 0x20 33 + #define LTC2992_SENSE1_MIN 0x22 34 + #define LTC2992_SENSE1_MAX_THRESH 0x24 35 + #define LTC2992_SENSE1_MIN_THRESH 0x26 36 + #define LTC2992_G1 0x28 37 + #define LTC2992_G1_MAX 0x2A 38 + #define LTC2992_G1_MIN 0x2C 39 + #define LTC2992_G1_MAX_THRESH 0x2E 40 + #define LTC2992_G1_MIN_THRESH 0x30 41 + #define LTC2992_FAULT2 0x35 42 + #define LTC2992_G2 0x5A 43 + #define LTC2992_G2_MAX 0x5C 44 + #define LTC2992_G2_MIN 0x5E 45 + #define LTC2992_G2_MAX_THRESH 0x60 46 + #define LTC2992_G2_MIN_THRESH 0x62 47 + #define LTC2992_G3 0x64 48 + #define LTC2992_G3_MAX 0x66 49 + #define LTC2992_G3_MIN 0x68 50 + #define LTC2992_G3_MAX_THRESH 0x6A 51 + #define LTC2992_G3_MIN_THRESH 0x6C 52 + #define LTC2992_G4 0x6E 53 + #define LTC2992_G4_MAX 0x70 54 + #define LTC2992_G4_MIN 0x72 55 + #define LTC2992_G4_MAX_THRESH 0x74 56 + #define LTC2992_G4_MIN_THRESH 0x76 57 + #define LTC2992_FAULT3 0x92 58 + #define LTC2992_GPIO_STATUS 0x95 59 + #define LTC2992_GPIO_IO_CTRL 0x96 60 + #define LTC2992_GPIO_CTRL 0x97 61 + 62 + #define LTC2992_POWER(x) (LTC2992_POWER1 + ((x) * 0x32)) 63 + #define LTC2992_POWER_MAX(x) (LTC2992_POWER1_MAX + ((x) * 0x32)) 64 + #define LTC2992_POWER_MIN(x) (LTC2992_POWER1_MIN + ((x) * 0x32)) 65 + #define LTC2992_POWER_MAX_THRESH(x) (LTC2992_POWER1_MAX_THRESH + ((x) * 0x32)) 66 + #define LTC2992_POWER_MIN_THRESH(x) (LTC2992_POWER1_MIN_THRESH + ((x) * 0x32)) 67 + #define LTC2992_DSENSE(x) (LTC2992_DSENSE1 + ((x) * 0x32)) 68 + #define LTC2992_DSENSE_MAX(x) (LTC2992_DSENSE1_MAX + ((x) * 0x32)) 69 + #define LTC2992_DSENSE_MIN(x) (LTC2992_DSENSE1_MIN + ((x) * 0x32)) 70 + #define LTC2992_DSENSE_MAX_THRESH(x) (LTC2992_DSENSE1_MAX_THRESH + ((x) * 0x32)) 71 + #define LTC2992_DSENSE_MIN_THRESH(x) (LTC2992_DSENSE1_MIN_THRESH + ((x) * 0x32)) 72 + #define LTC2992_SENSE(x) (LTC2992_SENSE1 + ((x) * 0x32)) 73 + #define LTC2992_SENSE_MAX(x) (LTC2992_SENSE1_MAX + ((x) * 0x32)) 74 + #define LTC2992_SENSE_MIN(x) (LTC2992_SENSE1_MIN + ((x) * 0x32)) 75 + #define LTC2992_SENSE_MAX_THRESH(x) (LTC2992_SENSE1_MAX_THRESH + ((x) * 0x32)) 76 + #define LTC2992_SENSE_MIN_THRESH(x) (LTC2992_SENSE1_MIN_THRESH + ((x) * 0x32)) 77 + #define LTC2992_POWER_FAULT(x) (LTC2992_FAULT1 + ((x) * 0x32)) 78 + #define LTC2992_SENSE_FAULT(x) (LTC2992_FAULT1 + ((x) * 0x32)) 79 + #define LTC2992_DSENSE_FAULT(x) (LTC2992_FAULT1 + ((x) * 0x32)) 80 + 81 + /* CTRLB register bitfields */ 82 + #define LTC2992_RESET_HISTORY BIT(3) 83 + 84 + /* FAULT1 FAULT2 registers common bitfields */ 85 + #define LTC2992_POWER_FAULT_MSK(x) (BIT(6) << (x)) 86 + #define LTC2992_DSENSE_FAULT_MSK(x) (BIT(4) << (x)) 87 + #define LTC2992_SENSE_FAULT_MSK(x) (BIT(2) << (x)) 88 + 89 + /* FAULT1 bitfields */ 90 + #define LTC2992_GPIO1_FAULT_MSK(x) (BIT(0) << (x)) 91 + 92 + /* FAULT2 bitfields */ 93 + #define LTC2992_GPIO2_FAULT_MSK(x) (BIT(0) << (x)) 94 + 95 + /* FAULT3 bitfields */ 96 + #define LTC2992_GPIO3_FAULT_MSK(x) (BIT(6) << (x)) 97 + #define LTC2992_GPIO4_FAULT_MSK(x) (BIT(4) << (x)) 98 + 99 + #define LTC2992_IADC_NANOV_LSB 12500 100 + #define LTC2992_VADC_UV_LSB 25000 101 + #define LTC2992_VADC_GPIO_UV_LSB 500 102 + 103 + #define LTC2992_GPIO_NR 4 104 + #define LTC2992_GPIO1_BIT 7 105 + #define LTC2992_GPIO2_BIT 6 106 + #define LTC2992_GPIO3_BIT 0 107 + #define LTC2992_GPIO4_BIT 6 108 + #define LTC2992_GPIO_BIT(x) (LTC2992_GPIO_NR - (x) - 1) 109 + 110 + struct ltc2992_state { 111 + struct i2c_client *client; 112 + struct gpio_chip gc; 113 + struct mutex gpio_mutex; /* lock for gpio access */ 114 + const char *gpio_names[LTC2992_GPIO_NR]; 115 + struct regmap *regmap; 116 + u32 r_sense_uohm[2]; 117 + }; 118 + 119 + struct ltc2992_gpio_regs { 120 + u8 data; 121 + u8 max; 122 + u8 min; 123 + u8 max_thresh; 124 + u8 min_thresh; 125 + u8 alarm; 126 + u8 min_alarm_msk; 127 + u8 max_alarm_msk; 128 + u8 ctrl; 129 + u8 ctrl_bit; 130 + }; 131 + 132 + static const struct ltc2992_gpio_regs ltc2992_gpio_addr_map[] = { 133 + { 134 + .data = LTC2992_G1, 135 + .max = LTC2992_G1_MAX, 136 + .min = LTC2992_G1_MIN, 137 + .max_thresh = LTC2992_G1_MAX_THRESH, 138 + .min_thresh = LTC2992_G1_MIN_THRESH, 139 + .alarm = LTC2992_FAULT1, 140 + .min_alarm_msk = LTC2992_GPIO1_FAULT_MSK(0), 141 + .max_alarm_msk = LTC2992_GPIO1_FAULT_MSK(1), 142 + .ctrl = LTC2992_GPIO_IO_CTRL, 143 + .ctrl_bit = LTC2992_GPIO1_BIT, 144 + }, 145 + { 146 + .data = LTC2992_G2, 147 + .max = LTC2992_G2_MAX, 148 + .min = LTC2992_G2_MIN, 149 + .max_thresh = LTC2992_G2_MAX_THRESH, 150 + .min_thresh = LTC2992_G2_MIN_THRESH, 151 + .alarm = LTC2992_FAULT2, 152 + .min_alarm_msk = LTC2992_GPIO2_FAULT_MSK(0), 153 + .max_alarm_msk = LTC2992_GPIO2_FAULT_MSK(1), 154 + .ctrl = LTC2992_GPIO_IO_CTRL, 155 + .ctrl_bit = LTC2992_GPIO2_BIT, 156 + }, 157 + { 158 + .data = LTC2992_G3, 159 + .max = LTC2992_G3_MAX, 160 + .min = LTC2992_G3_MIN, 161 + .max_thresh = LTC2992_G3_MAX_THRESH, 162 + .min_thresh = LTC2992_G3_MIN_THRESH, 163 + .alarm = LTC2992_FAULT3, 164 + .min_alarm_msk = LTC2992_GPIO3_FAULT_MSK(0), 165 + .max_alarm_msk = LTC2992_GPIO3_FAULT_MSK(1), 166 + .ctrl = LTC2992_GPIO_IO_CTRL, 167 + .ctrl_bit = LTC2992_GPIO3_BIT, 168 + }, 169 + { 170 + .data = LTC2992_G4, 171 + .max = LTC2992_G4_MAX, 172 + .min = LTC2992_G4_MIN, 173 + .max_thresh = LTC2992_G4_MAX_THRESH, 174 + .min_thresh = LTC2992_G4_MIN_THRESH, 175 + .alarm = LTC2992_FAULT3, 176 + .min_alarm_msk = LTC2992_GPIO4_FAULT_MSK(0), 177 + .max_alarm_msk = LTC2992_GPIO4_FAULT_MSK(1), 178 + .ctrl = LTC2992_GPIO_CTRL, 179 + .ctrl_bit = LTC2992_GPIO4_BIT, 180 + }, 181 + }; 182 + 183 + static const char *ltc2992_gpio_names[LTC2992_GPIO_NR] = { 184 + "GPIO1", "GPIO2", "GPIO3", "GPIO4", 185 + }; 186 + 187 + static int ltc2992_read_reg(struct ltc2992_state *st, u8 addr, const u8 reg_len) 188 + { 189 + u8 regvals[4]; 190 + int val; 191 + int ret; 192 + int i; 193 + 194 + ret = regmap_bulk_read(st->regmap, addr, regvals, reg_len); 195 + if (ret < 0) 196 + return ret; 197 + 198 + val = 0; 199 + for (i = 0; i < reg_len; i++) 200 + val |= regvals[reg_len - i - 1] << (i * 8); 201 + 202 + return val; 203 + } 204 + 205 + static int ltc2992_write_reg(struct ltc2992_state *st, u8 addr, const u8 reg_len, u32 val) 206 + { 207 + u8 regvals[4]; 208 + int i; 209 + 210 + for (i = 0; i < reg_len; i++) 211 + regvals[reg_len - i - 1] = (val >> (i * 8)) & 0xFF; 212 + 213 + return regmap_bulk_write(st->regmap, addr, regvals, reg_len); 214 + } 215 + 216 + static int ltc2992_gpio_get(struct gpio_chip *chip, unsigned int offset) 217 + { 218 + struct ltc2992_state *st = gpiochip_get_data(chip); 219 + unsigned long gpio_status; 220 + int reg; 221 + 222 + mutex_lock(&st->gpio_mutex); 223 + reg = ltc2992_read_reg(st, LTC2992_GPIO_STATUS, 1); 224 + mutex_unlock(&st->gpio_mutex); 225 + 226 + if (reg < 0) 227 + return reg; 228 + 229 + gpio_status = reg; 230 + 231 + return !test_bit(LTC2992_GPIO_BIT(offset), &gpio_status); 232 + } 233 + 234 + static int ltc2992_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask, 235 + unsigned long *bits) 236 + { 237 + struct ltc2992_state *st = gpiochip_get_data(chip); 238 + unsigned long gpio_status; 239 + unsigned int gpio_nr; 240 + int reg; 241 + 242 + mutex_lock(&st->gpio_mutex); 243 + reg = ltc2992_read_reg(st, LTC2992_GPIO_STATUS, 1); 244 + mutex_unlock(&st->gpio_mutex); 245 + 246 + if (reg < 0) 247 + return reg; 248 + 249 + gpio_status = reg; 250 + 251 + gpio_nr = 0; 252 + for_each_set_bit_from(gpio_nr, mask, LTC2992_GPIO_NR) { 253 + if (test_bit(LTC2992_GPIO_BIT(gpio_nr), &gpio_status)) 254 + set_bit(gpio_nr, bits); 255 + } 256 + 257 + return 0; 258 + } 259 + 260 + static void ltc2992_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) 261 + { 262 + struct ltc2992_state *st = gpiochip_get_data(chip); 263 + unsigned long gpio_ctrl; 264 + int reg; 265 + 266 + mutex_lock(&st->gpio_mutex); 267 + reg = ltc2992_read_reg(st, ltc2992_gpio_addr_map[offset].ctrl, 1); 268 + if (reg < 0) { 269 + mutex_unlock(&st->gpio_mutex); 270 + return; 271 + } 272 + 273 + gpio_ctrl = reg; 274 + assign_bit(ltc2992_gpio_addr_map[offset].ctrl_bit, &gpio_ctrl, value); 275 + 276 + ltc2992_write_reg(st, ltc2992_gpio_addr_map[offset].ctrl, 1, gpio_ctrl); 277 + mutex_unlock(&st->gpio_mutex); 278 + } 279 + 280 + static void ltc2992_gpio_set_multiple(struct gpio_chip *chip, unsigned long *mask, 281 + unsigned long *bits) 282 + { 283 + struct ltc2992_state *st = gpiochip_get_data(chip); 284 + unsigned long gpio_ctrl_io = 0; 285 + unsigned long gpio_ctrl = 0; 286 + unsigned int gpio_nr; 287 + 288 + for_each_set_bit(gpio_nr, mask, LTC2992_GPIO_NR) { 289 + if (gpio_nr < 3) 290 + assign_bit(ltc2992_gpio_addr_map[gpio_nr].ctrl_bit, &gpio_ctrl_io, true); 291 + 292 + if (gpio_nr == 3) 293 + assign_bit(ltc2992_gpio_addr_map[gpio_nr].ctrl_bit, &gpio_ctrl, true); 294 + } 295 + 296 + mutex_lock(&st->gpio_mutex); 297 + ltc2992_write_reg(st, LTC2992_GPIO_IO_CTRL, 1, gpio_ctrl_io); 298 + ltc2992_write_reg(st, LTC2992_GPIO_CTRL, 1, gpio_ctrl); 299 + mutex_unlock(&st->gpio_mutex); 300 + } 301 + 302 + static int ltc2992_config_gpio(struct ltc2992_state *st) 303 + { 304 + const char *name = dev_name(&st->client->dev); 305 + char *gpio_name; 306 + int ret; 307 + int i; 308 + 309 + ret = ltc2992_write_reg(st, LTC2992_GPIO_IO_CTRL, 1, 0); 310 + if (ret < 0) 311 + return ret; 312 + 313 + mutex_init(&st->gpio_mutex); 314 + 315 + for (i = 0; i < ARRAY_SIZE(st->gpio_names); i++) { 316 + gpio_name = devm_kasprintf(&st->client->dev, GFP_KERNEL, "ltc2992-%x-%s", 317 + st->client->addr, ltc2992_gpio_names[i]); 318 + if (!gpio_name) 319 + return -ENOMEM; 320 + 321 + st->gpio_names[i] = gpio_name; 322 + } 323 + 324 + st->gc.label = name; 325 + st->gc.parent = &st->client->dev; 326 + st->gc.owner = THIS_MODULE; 327 + st->gc.base = -1; 328 + st->gc.names = st->gpio_names; 329 + st->gc.ngpio = ARRAY_SIZE(st->gpio_names); 330 + st->gc.get = ltc2992_gpio_get; 331 + st->gc.get_multiple = ltc2992_gpio_get_multiple; 332 + st->gc.set = ltc2992_gpio_set; 333 + st->gc.set_multiple = ltc2992_gpio_set_multiple; 334 + 335 + ret = devm_gpiochip_add_data(&st->client->dev, &st->gc, st); 336 + if (ret) 337 + dev_err(&st->client->dev, "GPIO registering failed (%d)\n", ret); 338 + 339 + return ret; 340 + } 341 + 342 + static umode_t ltc2992_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr, 343 + int channel) 344 + { 345 + const struct ltc2992_state *st = data; 346 + 347 + switch (type) { 348 + case hwmon_chip: 349 + switch (attr) { 350 + case hwmon_chip_in_reset_history: 351 + return 0200; 352 + } 353 + break; 354 + case hwmon_in: 355 + switch (attr) { 356 + case hwmon_in_input: 357 + case hwmon_in_lowest: 358 + case hwmon_in_highest: 359 + case hwmon_in_min_alarm: 360 + case hwmon_in_max_alarm: 361 + return 0444; 362 + case hwmon_in_min: 363 + case hwmon_in_max: 364 + return 0644; 365 + } 366 + break; 367 + case hwmon_curr: 368 + switch (attr) { 369 + case hwmon_curr_input: 370 + case hwmon_curr_lowest: 371 + case hwmon_curr_highest: 372 + case hwmon_curr_min_alarm: 373 + case hwmon_curr_max_alarm: 374 + if (st->r_sense_uohm[channel]) 375 + return 0444; 376 + break; 377 + case hwmon_curr_min: 378 + case hwmon_curr_max: 379 + if (st->r_sense_uohm[channel]) 380 + return 0644; 381 + break; 382 + } 383 + break; 384 + case hwmon_power: 385 + switch (attr) { 386 + case hwmon_power_input: 387 + case hwmon_power_input_lowest: 388 + case hwmon_power_input_highest: 389 + case hwmon_power_min_alarm: 390 + case hwmon_power_max_alarm: 391 + if (st->r_sense_uohm[channel]) 392 + return 0444; 393 + break; 394 + case hwmon_power_min: 395 + case hwmon_power_max: 396 + if (st->r_sense_uohm[channel]) 397 + return 0644; 398 + break; 399 + } 400 + break; 401 + default: 402 + break; 403 + } 404 + 405 + return 0; 406 + } 407 + 408 + static int ltc2992_get_voltage(struct ltc2992_state *st, u32 reg, u32 scale, long *val) 409 + { 410 + int reg_val; 411 + 412 + reg_val = ltc2992_read_reg(st, reg, 2); 413 + if (reg_val < 0) 414 + return reg_val; 415 + 416 + reg_val = reg_val >> 4; 417 + *val = DIV_ROUND_CLOSEST(reg_val * scale, 1000); 418 + 419 + return 0; 420 + } 421 + 422 + static int ltc2992_set_voltage(struct ltc2992_state *st, u32 reg, u32 scale, long val) 423 + { 424 + val = DIV_ROUND_CLOSEST(val * 1000, scale); 425 + val = val << 4; 426 + 427 + return ltc2992_write_reg(st, reg, 2, val); 428 + } 429 + 430 + static int ltc2992_read_gpio_alarm(struct ltc2992_state *st, int nr_gpio, u32 attr, long *val) 431 + { 432 + int reg_val; 433 + u32 mask; 434 + 435 + if (attr == hwmon_in_max_alarm) 436 + mask = ltc2992_gpio_addr_map[nr_gpio].max_alarm_msk; 437 + else 438 + mask = ltc2992_gpio_addr_map[nr_gpio].min_alarm_msk; 439 + 440 + reg_val = ltc2992_read_reg(st, ltc2992_gpio_addr_map[nr_gpio].alarm, 1); 441 + if (reg_val < 0) 442 + return reg_val; 443 + 444 + *val = !!(reg_val & mask); 445 + reg_val &= ~mask; 446 + 447 + return ltc2992_write_reg(st, ltc2992_gpio_addr_map[nr_gpio].alarm, 1, reg_val); 448 + } 449 + 450 + static int ltc2992_read_gpios_in(struct device *dev, u32 attr, int nr_gpio, long *val) 451 + { 452 + struct ltc2992_state *st = dev_get_drvdata(dev); 453 + u32 reg; 454 + 455 + switch (attr) { 456 + case hwmon_in_input: 457 + reg = ltc2992_gpio_addr_map[nr_gpio].data; 458 + break; 459 + case hwmon_in_lowest: 460 + reg = ltc2992_gpio_addr_map[nr_gpio].min; 461 + break; 462 + case hwmon_in_highest: 463 + reg = ltc2992_gpio_addr_map[nr_gpio].max; 464 + break; 465 + case hwmon_in_min: 466 + reg = ltc2992_gpio_addr_map[nr_gpio].min_thresh; 467 + break; 468 + case hwmon_in_max: 469 + reg = ltc2992_gpio_addr_map[nr_gpio].max_thresh; 470 + break; 471 + case hwmon_in_min_alarm: 472 + case hwmon_in_max_alarm: 473 + return ltc2992_read_gpio_alarm(st, nr_gpio, attr, val); 474 + default: 475 + return -EOPNOTSUPP; 476 + } 477 + 478 + return ltc2992_get_voltage(st, reg, LTC2992_VADC_GPIO_UV_LSB, val); 479 + } 480 + 481 + static int ltc2992_read_in_alarm(struct ltc2992_state *st, int channel, long *val, u32 attr) 482 + { 483 + int reg_val; 484 + u32 mask; 485 + 486 + if (attr == hwmon_in_max_alarm) 487 + mask = LTC2992_SENSE_FAULT_MSK(1); 488 + else 489 + mask = LTC2992_SENSE_FAULT_MSK(0); 490 + 491 + reg_val = ltc2992_read_reg(st, LTC2992_SENSE_FAULT(channel), 1); 492 + if (reg_val < 0) 493 + return reg_val; 494 + 495 + *val = !!(reg_val & mask); 496 + reg_val &= ~mask; 497 + 498 + return ltc2992_write_reg(st, LTC2992_SENSE_FAULT(channel), 1, reg_val); 499 + } 500 + 501 + static int ltc2992_read_in(struct device *dev, u32 attr, int channel, long *val) 502 + { 503 + struct ltc2992_state *st = dev_get_drvdata(dev); 504 + u32 reg; 505 + 506 + if (channel > 1) 507 + return ltc2992_read_gpios_in(dev, attr, channel - 2, val); 508 + 509 + switch (attr) { 510 + case hwmon_in_input: 511 + reg = LTC2992_SENSE(channel); 512 + break; 513 + case hwmon_in_lowest: 514 + reg = LTC2992_SENSE_MIN(channel); 515 + break; 516 + case hwmon_in_highest: 517 + reg = LTC2992_SENSE_MAX(channel); 518 + break; 519 + case hwmon_in_min: 520 + reg = LTC2992_SENSE_MIN_THRESH(channel); 521 + break; 522 + case hwmon_in_max: 523 + reg = LTC2992_SENSE_MAX_THRESH(channel); 524 + break; 525 + case hwmon_in_min_alarm: 526 + case hwmon_in_max_alarm: 527 + return ltc2992_read_in_alarm(st, channel, val, attr); 528 + default: 529 + return -EOPNOTSUPP; 530 + } 531 + 532 + return ltc2992_get_voltage(st, reg, LTC2992_VADC_UV_LSB, val); 533 + } 534 + 535 + static int ltc2992_get_current(struct ltc2992_state *st, u32 reg, u32 channel, long *val) 536 + { 537 + int reg_val; 538 + 539 + reg_val = ltc2992_read_reg(st, reg, 2); 540 + if (reg_val < 0) 541 + return reg_val; 542 + 543 + reg_val = reg_val >> 4; 544 + *val = DIV_ROUND_CLOSEST(reg_val * LTC2992_IADC_NANOV_LSB, st->r_sense_uohm[channel]); 545 + 546 + return 0; 547 + } 548 + 549 + static int ltc2992_set_current(struct ltc2992_state *st, u32 reg, u32 channel, long val) 550 + { 551 + u32 reg_val; 552 + 553 + reg_val = DIV_ROUND_CLOSEST(val * st->r_sense_uohm[channel], LTC2992_IADC_NANOV_LSB); 554 + reg_val = reg_val << 4; 555 + 556 + return ltc2992_write_reg(st, reg, 2, reg_val); 557 + } 558 + 559 + static int ltc2992_read_curr_alarm(struct ltc2992_state *st, int channel, long *val, u32 attr) 560 + { 561 + int reg_val; 562 + u32 mask; 563 + 564 + if (attr == hwmon_curr_max_alarm) 565 + mask = LTC2992_DSENSE_FAULT_MSK(1); 566 + else 567 + mask = LTC2992_DSENSE_FAULT_MSK(0); 568 + 569 + reg_val = ltc2992_read_reg(st, LTC2992_DSENSE_FAULT(channel), 1); 570 + if (reg_val < 0) 571 + return reg_val; 572 + 573 + *val = !!(reg_val & mask); 574 + 575 + reg_val &= ~mask; 576 + return ltc2992_write_reg(st, LTC2992_DSENSE_FAULT(channel), 1, reg_val); 577 + } 578 + 579 + static int ltc2992_read_curr(struct device *dev, u32 attr, int channel, long *val) 580 + { 581 + struct ltc2992_state *st = dev_get_drvdata(dev); 582 + u32 reg; 583 + 584 + switch (attr) { 585 + case hwmon_curr_input: 586 + reg = LTC2992_DSENSE(channel); 587 + break; 588 + case hwmon_curr_lowest: 589 + reg = LTC2992_DSENSE_MIN(channel); 590 + break; 591 + case hwmon_curr_highest: 592 + reg = LTC2992_DSENSE_MAX(channel); 593 + break; 594 + case hwmon_curr_min: 595 + reg = LTC2992_DSENSE_MIN_THRESH(channel); 596 + break; 597 + case hwmon_curr_max: 598 + reg = LTC2992_DSENSE_MAX_THRESH(channel); 599 + break; 600 + case hwmon_curr_min_alarm: 601 + case hwmon_curr_max_alarm: 602 + return ltc2992_read_curr_alarm(st, channel, val, attr); 603 + default: 604 + return -EOPNOTSUPP; 605 + } 606 + 607 + return ltc2992_get_current(st, reg, channel, val); 608 + } 609 + 610 + static int ltc2992_get_power(struct ltc2992_state *st, u32 reg, u32 channel, long *val) 611 + { 612 + int reg_val; 613 + 614 + reg_val = ltc2992_read_reg(st, reg, 3); 615 + if (reg_val < 0) 616 + return reg_val; 617 + 618 + *val = mul_u64_u32_div(reg_val, LTC2992_VADC_UV_LSB * LTC2992_IADC_NANOV_LSB, 619 + st->r_sense_uohm[channel] * 1000); 620 + 621 + return 0; 622 + } 623 + 624 + static int ltc2992_set_power(struct ltc2992_state *st, u32 reg, u32 channel, long val) 625 + { 626 + u32 reg_val; 627 + 628 + reg_val = mul_u64_u32_div(val, st->r_sense_uohm[channel] * 1000, 629 + LTC2992_VADC_UV_LSB * LTC2992_IADC_NANOV_LSB); 630 + 631 + return ltc2992_write_reg(st, reg, 3, reg_val); 632 + } 633 + 634 + static int ltc2992_read_power_alarm(struct ltc2992_state *st, int channel, long *val, u32 attr) 635 + { 636 + int reg_val; 637 + u32 mask; 638 + 639 + if (attr == hwmon_power_max_alarm) 640 + mask = LTC2992_POWER_FAULT_MSK(1); 641 + else 642 + mask = LTC2992_POWER_FAULT_MSK(0); 643 + 644 + reg_val = ltc2992_read_reg(st, LTC2992_POWER_FAULT(channel), 1); 645 + if (reg_val < 0) 646 + return reg_val; 647 + 648 + *val = !!(reg_val & mask); 649 + reg_val &= ~mask; 650 + 651 + return ltc2992_write_reg(st, LTC2992_POWER_FAULT(channel), 1, reg_val); 652 + } 653 + 654 + static int ltc2992_read_power(struct device *dev, u32 attr, int channel, long *val) 655 + { 656 + struct ltc2992_state *st = dev_get_drvdata(dev); 657 + u32 reg; 658 + 659 + switch (attr) { 660 + case hwmon_power_input: 661 + reg = LTC2992_POWER(channel); 662 + break; 663 + case hwmon_power_input_lowest: 664 + reg = LTC2992_POWER_MIN(channel); 665 + break; 666 + case hwmon_power_input_highest: 667 + reg = LTC2992_POWER_MAX(channel); 668 + break; 669 + case hwmon_power_min: 670 + reg = LTC2992_POWER_MIN_THRESH(channel); 671 + break; 672 + case hwmon_power_max: 673 + reg = LTC2992_POWER_MAX_THRESH(channel); 674 + break; 675 + case hwmon_power_min_alarm: 676 + case hwmon_power_max_alarm: 677 + return ltc2992_read_power_alarm(st, channel, val, attr); 678 + default: 679 + return -EOPNOTSUPP; 680 + } 681 + 682 + return ltc2992_get_power(st, reg, channel, val); 683 + } 684 + 685 + static int ltc2992_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, 686 + long *val) 687 + { 688 + switch (type) { 689 + case hwmon_in: 690 + return ltc2992_read_in(dev, attr, channel, val); 691 + case hwmon_curr: 692 + return ltc2992_read_curr(dev, attr, channel, val); 693 + case hwmon_power: 694 + return ltc2992_read_power(dev, attr, channel, val); 695 + default: 696 + return -EOPNOTSUPP; 697 + } 698 + } 699 + 700 + static int ltc2992_write_curr(struct device *dev, u32 attr, int channel, long val) 701 + { 702 + struct ltc2992_state *st = dev_get_drvdata(dev); 703 + u32 reg; 704 + 705 + switch (attr) { 706 + case hwmon_curr_min: 707 + reg = LTC2992_DSENSE_MIN_THRESH(channel); 708 + break; 709 + case hwmon_curr_max: 710 + reg = LTC2992_DSENSE_MAX_THRESH(channel); 711 + break; 712 + default: 713 + return -EOPNOTSUPP; 714 + } 715 + 716 + return ltc2992_set_current(st, reg, channel, val); 717 + } 718 + 719 + static int ltc2992_write_gpios_in(struct device *dev, u32 attr, int nr_gpio, long val) 720 + { 721 + struct ltc2992_state *st = dev_get_drvdata(dev); 722 + u32 reg; 723 + 724 + switch (attr) { 725 + case hwmon_in_min: 726 + reg = ltc2992_gpio_addr_map[nr_gpio].min_thresh; 727 + break; 728 + case hwmon_in_max: 729 + reg = ltc2992_gpio_addr_map[nr_gpio].max_thresh; 730 + break; 731 + default: 732 + return -EOPNOTSUPP; 733 + } 734 + 735 + return ltc2992_set_voltage(st, reg, LTC2992_VADC_GPIO_UV_LSB, val); 736 + } 737 + 738 + static int ltc2992_write_in(struct device *dev, u32 attr, int channel, long val) 739 + { 740 + struct ltc2992_state *st = dev_get_drvdata(dev); 741 + u32 reg; 742 + 743 + if (channel > 1) 744 + return ltc2992_write_gpios_in(dev, attr, channel - 2, val); 745 + 746 + switch (attr) { 747 + case hwmon_in_min: 748 + reg = LTC2992_SENSE_MIN_THRESH(channel); 749 + break; 750 + case hwmon_in_max: 751 + reg = LTC2992_SENSE_MAX_THRESH(channel); 752 + break; 753 + default: 754 + return -EOPNOTSUPP; 755 + } 756 + 757 + return ltc2992_set_voltage(st, reg, LTC2992_VADC_UV_LSB, val); 758 + } 759 + 760 + static int ltc2992_write_power(struct device *dev, u32 attr, int channel, long val) 761 + { 762 + struct ltc2992_state *st = dev_get_drvdata(dev); 763 + u32 reg; 764 + 765 + switch (attr) { 766 + case hwmon_power_min: 767 + reg = LTC2992_POWER_MIN_THRESH(channel); 768 + break; 769 + case hwmon_power_max: 770 + reg = LTC2992_POWER_MAX_THRESH(channel); 771 + break; 772 + default: 773 + return -EOPNOTSUPP; 774 + } 775 + 776 + return ltc2992_set_power(st, reg, channel, val); 777 + } 778 + 779 + static int ltc2992_write_chip(struct device *dev, u32 attr, int channel, long val) 780 + { 781 + struct ltc2992_state *st = dev_get_drvdata(dev); 782 + 783 + switch (attr) { 784 + case hwmon_chip_in_reset_history: 785 + return regmap_update_bits(st->regmap, LTC2992_CTRLB, LTC2992_RESET_HISTORY, 786 + LTC2992_RESET_HISTORY); 787 + default: 788 + return -EOPNOTSUPP; 789 + } 790 + } 791 + 792 + static int ltc2992_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, 793 + long val) 794 + { 795 + switch (type) { 796 + case hwmon_chip: 797 + return ltc2992_write_chip(dev, attr, channel, val); 798 + case hwmon_in: 799 + return ltc2992_write_in(dev, attr, channel, val); 800 + case hwmon_curr: 801 + return ltc2992_write_curr(dev, attr, channel, val); 802 + case hwmon_power: 803 + return ltc2992_write_power(dev, attr, channel, val); 804 + default: 805 + return -EOPNOTSUPP; 806 + } 807 + } 808 + 809 + static const struct hwmon_ops ltc2992_hwmon_ops = { 810 + .is_visible = ltc2992_is_visible, 811 + .read = ltc2992_read, 812 + .write = ltc2992_write, 813 + }; 814 + 815 + static const u32 ltc2992_chip_config[] = { 816 + HWMON_C_IN_RESET_HISTORY, 817 + 0 818 + }; 819 + 820 + static const struct hwmon_channel_info ltc2992_chip = { 821 + .type = hwmon_chip, 822 + .config = ltc2992_chip_config, 823 + }; 824 + 825 + static const u32 ltc2992_in_config[] = { 826 + HWMON_I_INPUT | HWMON_I_LOWEST | HWMON_I_HIGHEST | HWMON_I_MIN | HWMON_I_MAX | 827 + HWMON_I_MIN_ALARM | HWMON_I_MAX_ALARM, 828 + HWMON_I_INPUT | HWMON_I_LOWEST | HWMON_I_HIGHEST | HWMON_I_MIN | HWMON_I_MAX | 829 + HWMON_I_MIN_ALARM | HWMON_I_MAX_ALARM, 830 + HWMON_I_INPUT | HWMON_I_LOWEST | HWMON_I_HIGHEST | HWMON_I_MIN | HWMON_I_MAX | 831 + HWMON_I_MIN_ALARM | HWMON_I_MAX_ALARM, 832 + HWMON_I_INPUT | HWMON_I_LOWEST | HWMON_I_HIGHEST | HWMON_I_MIN | HWMON_I_MAX | 833 + HWMON_I_MIN_ALARM | HWMON_I_MAX_ALARM, 834 + HWMON_I_INPUT | HWMON_I_LOWEST | HWMON_I_HIGHEST | HWMON_I_MIN | HWMON_I_MAX | 835 + HWMON_I_MIN_ALARM | HWMON_I_MAX_ALARM, 836 + HWMON_I_INPUT | HWMON_I_LOWEST | HWMON_I_HIGHEST | HWMON_I_MIN | HWMON_I_MAX | 837 + HWMON_I_MIN_ALARM | HWMON_I_MAX_ALARM, 838 + 0 839 + }; 840 + 841 + static const struct hwmon_channel_info ltc2992_in = { 842 + .type = hwmon_in, 843 + .config = ltc2992_in_config, 844 + }; 845 + 846 + static const u32 ltc2992_curr_config[] = { 847 + HWMON_C_INPUT | HWMON_C_LOWEST | HWMON_C_HIGHEST | HWMON_C_MIN | HWMON_C_MAX | 848 + HWMON_C_MIN_ALARM | HWMON_C_MAX_ALARM, 849 + HWMON_C_INPUT | HWMON_C_LOWEST | HWMON_C_HIGHEST | HWMON_C_MIN | HWMON_C_MAX | 850 + HWMON_C_MIN_ALARM | HWMON_C_MAX_ALARM, 851 + 0 852 + }; 853 + 854 + static const struct hwmon_channel_info ltc2992_curr = { 855 + .type = hwmon_curr, 856 + .config = ltc2992_curr_config, 857 + }; 858 + 859 + static const u32 ltc2992_power_config[] = { 860 + HWMON_P_INPUT | HWMON_P_INPUT_LOWEST | HWMON_P_INPUT_HIGHEST | HWMON_P_MIN | HWMON_P_MAX | 861 + HWMON_P_MIN_ALARM | HWMON_P_MAX_ALARM, 862 + HWMON_P_INPUT | HWMON_P_INPUT_LOWEST | HWMON_P_INPUT_HIGHEST | HWMON_P_MIN | HWMON_P_MAX | 863 + HWMON_P_MIN_ALARM | HWMON_P_MAX_ALARM, 864 + 0 865 + }; 866 + 867 + static const struct hwmon_channel_info ltc2992_power = { 868 + .type = hwmon_power, 869 + .config = ltc2992_power_config, 870 + }; 871 + 872 + static const struct hwmon_channel_info *ltc2992_info[] = { 873 + &ltc2992_chip, 874 + &ltc2992_in, 875 + &ltc2992_curr, 876 + &ltc2992_power, 877 + NULL 878 + }; 879 + 880 + static const struct hwmon_chip_info ltc2992_chip_info = { 881 + .ops = &ltc2992_hwmon_ops, 882 + .info = ltc2992_info, 883 + }; 884 + 885 + static const struct regmap_config ltc2992_regmap_config = { 886 + .reg_bits = 8, 887 + .val_bits = 8, 888 + .max_register = 0xE8, 889 + }; 890 + 891 + static int ltc2992_parse_dt(struct ltc2992_state *st) 892 + { 893 + struct fwnode_handle *fwnode; 894 + struct fwnode_handle *child; 895 + u32 addr; 896 + u32 val; 897 + int ret; 898 + 899 + fwnode = dev_fwnode(&st->client->dev); 900 + 901 + fwnode_for_each_available_child_node(fwnode, child) { 902 + ret = fwnode_property_read_u32(child, "reg", &addr); 903 + if (ret < 0) 904 + return ret; 905 + 906 + if (addr > 1) 907 + return -EINVAL; 908 + 909 + ret = fwnode_property_read_u32(child, "shunt-resistor-micro-ohms", &val); 910 + if (!ret) 911 + st->r_sense_uohm[addr] = val; 912 + } 913 + 914 + return 0; 915 + } 916 + 917 + static int ltc2992_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) 918 + { 919 + struct device *hwmon_dev; 920 + struct ltc2992_state *st; 921 + int ret; 922 + 923 + st = devm_kzalloc(&client->dev, sizeof(*st), GFP_KERNEL); 924 + if (!st) 925 + return -ENOMEM; 926 + 927 + st->client = client; 928 + st->regmap = devm_regmap_init_i2c(client, &ltc2992_regmap_config); 929 + if (IS_ERR(st->regmap)) 930 + return PTR_ERR(st->regmap); 931 + 932 + ret = ltc2992_parse_dt(st); 933 + if (ret < 0) 934 + return ret; 935 + 936 + ret = ltc2992_config_gpio(st); 937 + if (ret < 0) 938 + return ret; 939 + 940 + hwmon_dev = devm_hwmon_device_register_with_info(&client->dev, client->name, st, 941 + &ltc2992_chip_info, NULL); 942 + 943 + return PTR_ERR_OR_ZERO(hwmon_dev); 944 + } 945 + 946 + static const struct of_device_id ltc2992_of_match[] = { 947 + { .compatible = "adi,ltc2992" }, 948 + { } 949 + }; 950 + MODULE_DEVICE_TABLE(of, ltc2992_of_match); 951 + 952 + static const struct i2c_device_id ltc2992_i2c_id[] = { 953 + {"ltc2992", 0}, 954 + {} 955 + }; 956 + MODULE_DEVICE_TABLE(i2c, ltc2992_i2c_id); 957 + 958 + static struct i2c_driver ltc2992_i2c_driver = { 959 + .driver = { 960 + .name = "ltc2992", 961 + .of_match_table = ltc2992_of_match, 962 + }, 963 + .probe = ltc2992_i2c_probe, 964 + .id_table = ltc2992_i2c_id, 965 + }; 966 + 967 + module_i2c_driver(ltc2992_i2c_driver); 968 + 969 + MODULE_AUTHOR("Alexandru Tachici <alexandru.tachici@analog.com>"); 970 + MODULE_DESCRIPTION("Hwmon driver for Linear Technology 2992"); 971 + MODULE_LICENSE("Dual BSD/GPL");
+352
drivers/hwmon/max127.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Hardware monitoring driver for MAX127. 4 + * 5 + * Copyright (c) 2020 Facebook Inc. 6 + */ 7 + 8 + #include <linux/err.h> 9 + #include <linux/hwmon.h> 10 + #include <linux/i2c.h> 11 + #include <linux/init.h> 12 + #include <linux/module.h> 13 + 14 + /* 15 + * MAX127 Control Byte. Refer to MAX127 datasheet, Table 1 "Control-Byte 16 + * Format" for details. 17 + */ 18 + #define MAX127_CTRL_START BIT(7) 19 + #define MAX127_CTRL_SEL_SHIFT 4 20 + #define MAX127_CTRL_RNG BIT(3) 21 + #define MAX127_CTRL_BIP BIT(2) 22 + #define MAX127_CTRL_PD1 BIT(1) 23 + #define MAX127_CTRL_PD0 BIT(0) 24 + 25 + #define MAX127_NUM_CHANNELS 8 26 + #define MAX127_SET_CHANNEL(ch) (((ch) & 7) << MAX127_CTRL_SEL_SHIFT) 27 + 28 + /* 29 + * MAX127 channel input ranges. Refer to MAX127 datasheet, Table 3 "Range 30 + * and Polarity Selection" for details. 31 + */ 32 + #define MAX127_FULL_RANGE 10000 /* 10V */ 33 + #define MAX127_HALF_RANGE 5000 /* 5V */ 34 + 35 + /* 36 + * MAX127 returns 2 bytes at read: 37 + * - the first byte contains data[11:4]. 38 + * - the second byte contains data[3:0] (MSB) and 4 dummy 0s (LSB). 39 + * Refer to MAX127 datasheet, "Read a Conversion (Read Cycle)" section 40 + * for details. 41 + */ 42 + #define MAX127_DATA_LEN 2 43 + #define MAX127_DATA_SHIFT 4 44 + 45 + #define MAX127_SIGN_BIT BIT(11) 46 + 47 + struct max127_data { 48 + struct mutex lock; 49 + struct i2c_client *client; 50 + u8 ctrl_byte[MAX127_NUM_CHANNELS]; 51 + }; 52 + 53 + static int max127_select_channel(struct i2c_client *client, u8 ctrl_byte) 54 + { 55 + int status; 56 + struct i2c_msg msg = { 57 + .addr = client->addr, 58 + .flags = 0, 59 + .len = sizeof(ctrl_byte), 60 + .buf = &ctrl_byte, 61 + }; 62 + 63 + status = i2c_transfer(client->adapter, &msg, 1); 64 + if (status < 0) 65 + return status; 66 + if (status != 1) 67 + return -EIO; 68 + 69 + return 0; 70 + } 71 + 72 + static int max127_read_channel(struct i2c_client *client, long *val) 73 + { 74 + int status; 75 + u8 i2c_data[MAX127_DATA_LEN]; 76 + struct i2c_msg msg = { 77 + .addr = client->addr, 78 + .flags = I2C_M_RD, 79 + .len = sizeof(i2c_data), 80 + .buf = i2c_data, 81 + }; 82 + 83 + status = i2c_transfer(client->adapter, &msg, 1); 84 + if (status < 0) 85 + return status; 86 + if (status != 1) 87 + return -EIO; 88 + 89 + *val = (i2c_data[1] >> MAX127_DATA_SHIFT) | 90 + ((u16)i2c_data[0] << MAX127_DATA_SHIFT); 91 + return 0; 92 + } 93 + 94 + static long max127_process_raw(u8 ctrl_byte, long raw) 95 + { 96 + long scale, weight; 97 + 98 + /* 99 + * MAX127's data coding is binary in unipolar mode with 1 LSB = 100 + * (Full-Scale/4096) and two’s complement binary in bipolar mode 101 + * with 1 LSB = [(2 x |FS|)/4096]. 102 + * Refer to MAX127 datasheet, "Transfer Function" section for 103 + * details. 104 + */ 105 + scale = (ctrl_byte & MAX127_CTRL_RNG) ? MAX127_FULL_RANGE : 106 + MAX127_HALF_RANGE; 107 + if (ctrl_byte & MAX127_CTRL_BIP) { 108 + weight = (raw & MAX127_SIGN_BIT); 109 + raw &= ~MAX127_SIGN_BIT; 110 + raw -= weight; 111 + raw *= 2; 112 + } 113 + 114 + return raw * scale / 4096; 115 + } 116 + 117 + static int max127_read_input(struct max127_data *data, int channel, long *val) 118 + { 119 + long raw; 120 + int status; 121 + struct i2c_client *client = data->client; 122 + u8 ctrl_byte = data->ctrl_byte[channel]; 123 + 124 + mutex_lock(&data->lock); 125 + 126 + status = max127_select_channel(client, ctrl_byte); 127 + if (status) 128 + goto exit; 129 + 130 + status = max127_read_channel(client, &raw); 131 + if (status) 132 + goto exit; 133 + 134 + *val = max127_process_raw(ctrl_byte, raw); 135 + 136 + exit: 137 + mutex_unlock(&data->lock); 138 + return status; 139 + } 140 + 141 + static int max127_read_min(struct max127_data *data, int channel, long *val) 142 + { 143 + u8 rng_bip = (data->ctrl_byte[channel] >> 2) & 3; 144 + static const int min_input_map[4] = { 145 + 0, /* RNG=0, BIP=0 */ 146 + -MAX127_HALF_RANGE, /* RNG=0, BIP=1 */ 147 + 0, /* RNG=1, BIP=0 */ 148 + -MAX127_FULL_RANGE, /* RNG=1, BIP=1 */ 149 + }; 150 + 151 + *val = min_input_map[rng_bip]; 152 + return 0; 153 + } 154 + 155 + static int max127_read_max(struct max127_data *data, int channel, long *val) 156 + { 157 + u8 rng_bip = (data->ctrl_byte[channel] >> 2) & 3; 158 + static const int max_input_map[4] = { 159 + MAX127_HALF_RANGE, /* RNG=0, BIP=0 */ 160 + MAX127_HALF_RANGE, /* RNG=0, BIP=1 */ 161 + MAX127_FULL_RANGE, /* RNG=1, BIP=0 */ 162 + MAX127_FULL_RANGE, /* RNG=1, BIP=1 */ 163 + }; 164 + 165 + *val = max_input_map[rng_bip]; 166 + return 0; 167 + } 168 + 169 + static int max127_write_min(struct max127_data *data, int channel, long val) 170 + { 171 + u8 ctrl; 172 + 173 + mutex_lock(&data->lock); 174 + 175 + ctrl = data->ctrl_byte[channel]; 176 + if (val <= -MAX127_FULL_RANGE) { 177 + ctrl |= (MAX127_CTRL_RNG | MAX127_CTRL_BIP); 178 + } else if (val < 0) { 179 + ctrl |= MAX127_CTRL_BIP; 180 + ctrl &= ~MAX127_CTRL_RNG; 181 + } else { 182 + ctrl &= ~MAX127_CTRL_BIP; 183 + } 184 + data->ctrl_byte[channel] = ctrl; 185 + 186 + mutex_unlock(&data->lock); 187 + 188 + return 0; 189 + } 190 + 191 + static int max127_write_max(struct max127_data *data, int channel, long val) 192 + { 193 + mutex_lock(&data->lock); 194 + 195 + if (val >= MAX127_FULL_RANGE) 196 + data->ctrl_byte[channel] |= MAX127_CTRL_RNG; 197 + else 198 + data->ctrl_byte[channel] &= ~MAX127_CTRL_RNG; 199 + 200 + mutex_unlock(&data->lock); 201 + 202 + return 0; 203 + } 204 + 205 + static umode_t max127_is_visible(const void *_data, 206 + enum hwmon_sensor_types type, 207 + u32 attr, int channel) 208 + { 209 + if (type == hwmon_in) { 210 + switch (attr) { 211 + case hwmon_in_input: 212 + return 0444; 213 + 214 + case hwmon_in_min: 215 + case hwmon_in_max: 216 + return 0644; 217 + 218 + default: 219 + break; 220 + } 221 + } 222 + 223 + return 0; 224 + } 225 + 226 + static int max127_read(struct device *dev, enum hwmon_sensor_types type, 227 + u32 attr, int channel, long *val) 228 + { 229 + int status; 230 + struct max127_data *data = dev_get_drvdata(dev); 231 + 232 + if (type != hwmon_in) 233 + return -EOPNOTSUPP; 234 + 235 + switch (attr) { 236 + case hwmon_in_input: 237 + status = max127_read_input(data, channel, val); 238 + break; 239 + 240 + case hwmon_in_min: 241 + status = max127_read_min(data, channel, val); 242 + break; 243 + 244 + case hwmon_in_max: 245 + status = max127_read_max(data, channel, val); 246 + break; 247 + 248 + default: 249 + status = -EOPNOTSUPP; 250 + break; 251 + } 252 + 253 + return status; 254 + } 255 + 256 + static int max127_write(struct device *dev, enum hwmon_sensor_types type, 257 + u32 attr, int channel, long val) 258 + { 259 + int status; 260 + struct max127_data *data = dev_get_drvdata(dev); 261 + 262 + if (type != hwmon_in) 263 + return -EOPNOTSUPP; 264 + 265 + switch (attr) { 266 + case hwmon_in_min: 267 + status = max127_write_min(data, channel, val); 268 + break; 269 + 270 + case hwmon_in_max: 271 + status = max127_write_max(data, channel, val); 272 + break; 273 + 274 + default: 275 + status = -EOPNOTSUPP; 276 + break; 277 + } 278 + 279 + return status; 280 + } 281 + 282 + static const struct hwmon_ops max127_hwmon_ops = { 283 + .is_visible = max127_is_visible, 284 + .read = max127_read, 285 + .write = max127_write, 286 + }; 287 + 288 + static const struct hwmon_channel_info *max127_info[] = { 289 + HWMON_CHANNEL_INFO(in, 290 + HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX, 291 + HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX, 292 + HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX, 293 + HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX, 294 + HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX, 295 + HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX, 296 + HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX, 297 + HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX), 298 + NULL, 299 + }; 300 + 301 + static const struct hwmon_chip_info max127_chip_info = { 302 + .ops = &max127_hwmon_ops, 303 + .info = max127_info, 304 + }; 305 + 306 + static int max127_probe(struct i2c_client *client, 307 + const struct i2c_device_id *id) 308 + { 309 + int i; 310 + struct device *hwmon_dev; 311 + struct max127_data *data; 312 + struct device *dev = &client->dev; 313 + 314 + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 315 + if (!data) 316 + return -ENOMEM; 317 + 318 + data->client = client; 319 + mutex_init(&data->lock); 320 + for (i = 0; i < ARRAY_SIZE(data->ctrl_byte); i++) 321 + data->ctrl_byte[i] = (MAX127_CTRL_START | 322 + MAX127_SET_CHANNEL(i)); 323 + 324 + hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, 325 + data, 326 + &max127_chip_info, 327 + NULL); 328 + 329 + return PTR_ERR_OR_ZERO(hwmon_dev); 330 + } 331 + 332 + static const struct i2c_device_id max127_id[] = { 333 + { "max127", 0 }, 334 + { } 335 + }; 336 + MODULE_DEVICE_TABLE(i2c, max127_id); 337 + 338 + static struct i2c_driver max127_driver = { 339 + .class = I2C_CLASS_HWMON, 340 + .driver = { 341 + .name = "max127", 342 + }, 343 + .probe = max127_probe, 344 + .id_table = max127_id, 345 + }; 346 + 347 + module_i2c_driver(max127_driver); 348 + 349 + MODULE_LICENSE("GPL"); 350 + MODULE_AUTHOR("Mike Choi <mikechoi@fb.com>"); 351 + MODULE_AUTHOR("Tao Ren <rentao.bupt@gmail.com>"); 352 + MODULE_DESCRIPTION("MAX127 Hardware Monitoring driver");
+12 -2
drivers/hwmon/nct6683.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-or-later 2 2 /* 3 3 * nct6683 - Driver for the hardware monitoring functionality of 4 - * Nuvoton NCT6683D eSIO 4 + * Nuvoton NCT6683D/NCT6687D eSIO 5 5 * 6 6 * Copyright (C) 2013 Guenter Roeck <linux@roeck-us.net> 7 7 * ··· 12 12 * 13 13 * Chip #vin #fan #pwm #temp chip ID 14 14 * nct6683d 21(1) 16 8 32(1) 0xc730 15 + * nct6687d 21(1) 16 8 32(1) 0xd590 15 16 * 16 17 * Notes: 17 18 * (1) Total number of vin and temp inputs is 32. ··· 33 32 #include <linux/platform_device.h> 34 33 #include <linux/slab.h> 35 34 36 - enum kinds { nct6683 }; 35 + enum kinds { nct6683, nct6687 }; 37 36 38 37 static bool force; 39 38 module_param(force, bool, 0); ··· 41 40 42 41 static const char * const nct6683_device_names[] = { 43 42 "nct6683", 43 + "nct6687", 44 44 }; 45 45 46 46 static const char * const nct6683_chip_names[] = { 47 47 "NCT6683D", 48 + "NCT6687D", 48 49 }; 49 50 50 51 #define DRVNAME "nct6683" ··· 66 63 67 64 #define SIO_NCT6681_ID 0xb270 /* for later */ 68 65 #define SIO_NCT6683_ID 0xc730 66 + #define SIO_NCT6687_ID 0xd590 69 67 #define SIO_ID_MASK 0xFFF0 70 68 71 69 static inline void ··· 168 164 #define NCT6683_REG_CUSTOMER_ID 0x602 169 165 #define NCT6683_CUSTOMER_ID_INTEL 0x805 170 166 #define NCT6683_CUSTOMER_ID_MITAC 0xa0e 167 + #define NCT6683_CUSTOMER_ID_MSI 0x201 171 168 172 169 #define NCT6683_REG_BUILD_YEAR 0x604 173 170 #define NCT6683_REG_BUILD_MONTH 0x605 ··· 1223 1218 break; 1224 1219 case NCT6683_CUSTOMER_ID_MITAC: 1225 1220 break; 1221 + case NCT6683_CUSTOMER_ID_MSI: 1222 + break; 1226 1223 default: 1227 1224 if (!force) 1228 1225 return -ENODEV; ··· 1358 1351 switch (val & SIO_ID_MASK) { 1359 1352 case SIO_NCT6683_ID: 1360 1353 sio_data->kind = nct6683; 1354 + break; 1355 + case SIO_NCT6687_ID: 1356 + sio_data->kind = nct6687; 1361 1357 break; 1362 1358 default: 1363 1359 if (val != 0xffff)
+75
drivers/hwmon/occ/common.c
··· 41 41 u8 value; 42 42 } __packed; 43 43 44 + struct temp_sensor_10 { 45 + u32 sensor_id; 46 + u8 fru_type; 47 + u8 value; 48 + u8 throttle; 49 + u8 reserved; 50 + } __packed; 51 + 44 52 struct freq_sensor_1 { 45 53 u16 sensor_id; 46 54 u16 value; ··· 307 299 break; 308 300 case 3: 309 301 val = temp->value == OCC_TEMP_SENSOR_FAULT; 302 + break; 303 + default: 304 + return -EINVAL; 305 + } 306 + 307 + return snprintf(buf, PAGE_SIZE - 1, "%u\n", val); 308 + } 309 + 310 + static ssize_t occ_show_temp_10(struct device *dev, 311 + struct device_attribute *attr, char *buf) 312 + { 313 + int rc; 314 + u32 val = 0; 315 + struct temp_sensor_10 *temp; 316 + struct occ *occ = dev_get_drvdata(dev); 317 + struct occ_sensors *sensors = &occ->sensors; 318 + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); 319 + 320 + rc = occ_update_response(occ); 321 + if (rc) 322 + return rc; 323 + 324 + temp = ((struct temp_sensor_10 *)sensors->temp.data) + sattr->index; 325 + 326 + switch (sattr->nr) { 327 + case 0: 328 + val = get_unaligned_be32(&temp->sensor_id); 329 + break; 330 + case 1: 331 + val = temp->value; 332 + if (val == OCC_TEMP_SENSOR_FAULT) 333 + return -EREMOTEIO; 334 + 335 + /* 336 + * VRM doesn't return temperature, only alarm bit. This 337 + * attribute maps to tempX_alarm instead of tempX_input for 338 + * VRM 339 + */ 340 + if (temp->fru_type != OCC_FRU_TYPE_VRM) { 341 + /* sensor not ready */ 342 + if (val == 0) 343 + return -EAGAIN; 344 + 345 + val *= 1000; 346 + } 347 + break; 348 + case 2: 349 + val = temp->fru_type; 350 + break; 351 + case 3: 352 + val = temp->value == OCC_TEMP_SENSOR_FAULT; 353 + break; 354 + case 4: 355 + val = temp->throttle * 1000; 310 356 break; 311 357 default: 312 358 return -EINVAL; ··· 807 745 num_attrs += (sensors->temp.num_sensors * 4); 808 746 show_temp = occ_show_temp_2; 809 747 break; 748 + case 0x10: 749 + num_attrs += (sensors->temp.num_sensors * 5); 750 + show_temp = occ_show_temp_10; 751 + break; 810 752 default: 811 753 sensors->temp.num_sensors = 0; 812 754 } ··· 910 844 attr->sensor = OCC_INIT_ATTR(attr->name, 0444, 911 845 show_temp, NULL, 3, i); 912 846 attr++; 847 + 848 + if (sensors->temp.version == 0x10) { 849 + snprintf(attr->name, sizeof(attr->name), 850 + "temp%d_max", s); 851 + attr->sensor = OCC_INIT_ATTR(attr->name, 0444, 852 + show_temp, NULL, 853 + 4, i); 854 + attr++; 855 + } 913 856 } 914 857 } 915 858
+18
drivers/hwmon/pmbus/Kconfig
··· 220 220 This driver can also be built as a module. If so, the module will 221 221 be called mp2975. 222 222 223 + config SENSORS_PM6764TR 224 + tristate "ST PM6764TR" 225 + help 226 + If you say yes here you get hardware monitoring support for ST 227 + PM6764TR. 228 + 229 + This driver can also be built as a module. If so, the module will 230 + be called pm6764tr. 231 + 223 232 config SENSORS_PXE1610 224 233 tristate "Infineon PXE1610" 225 234 help ··· 237 228 238 229 This driver can also be built as a module. If so, the module will 239 230 be called pxe1610. 231 + 232 + config SENSORS_Q54SJ108A2 233 + tristate "Delta Power Supplies Q54SJ108A2" 234 + help 235 + If you say yes here you get hardware monitoring support for Delta 236 + Q54SJ108A2 series Power Supplies. 237 + 238 + This driver can also be built as a module. If so, the module will 239 + be called q54sj108a2. 240 240 241 241 config SENSORS_TPS40422 242 242 tristate "TI TPS40422"
+2
drivers/hwmon/pmbus/Makefile
··· 25 25 obj-$(CONFIG_SENSORS_MAX34440) += max34440.o 26 26 obj-$(CONFIG_SENSORS_MAX8688) += max8688.o 27 27 obj-$(CONFIG_SENSORS_MP2975) += mp2975.o 28 + obj-$(CONFIG_SENSORS_PM6764TR) += pm6764tr.o 28 29 obj-$(CONFIG_SENSORS_PXE1610) += pxe1610.o 30 + obj-$(CONFIG_SENSORS_Q54SJ108A2) += q54sj108a2.o 29 31 obj-$(CONFIG_SENSORS_TPS40422) += tps40422.o 30 32 obj-$(CONFIG_SENSORS_TPS53679) += tps53679.o 31 33 obj-$(CONFIG_SENSORS_UCD9000) += ucd9000.o
-1
drivers/hwmon/pmbus/adm1266.c
··· 502 502 .of_match_table = adm1266_of_match, 503 503 }, 504 504 .probe_new = adm1266_probe, 505 - .remove = pmbus_do_remove, 506 505 .id_table = adm1266_id, 507 506 }; 508 507
-1
drivers/hwmon/pmbus/adm1275.c
··· 797 797 .name = "adm1275", 798 798 }, 799 799 .probe_new = adm1275_probe, 800 - .remove = pmbus_do_remove, 801 800 .id_table = adm1275_id, 802 801 }; 803 802
-1
drivers/hwmon/pmbus/bel-pfe.c
··· 121 121 .name = "bel-pfe", 122 122 }, 123 123 .probe_new = pfe_pmbus_probe, 124 - .remove = pmbus_do_remove, 125 124 .id_table = pfe_device_id, 126 125 }; 127 126
-1
drivers/hwmon/pmbus/ibm-cffps.c
··· 617 617 .of_match_table = ibm_cffps_of_match, 618 618 }, 619 619 .probe_new = ibm_cffps_probe, 620 - .remove = pmbus_do_remove, 621 620 .id_table = ibm_cffps_id, 622 621 }; 623 622
-1
drivers/hwmon/pmbus/inspur-ipsps.c
··· 216 216 .of_match_table = of_match_ptr(ipsps_of_match), 217 217 }, 218 218 .probe_new = ipsps_probe, 219 - .remove = pmbus_do_remove, 220 219 .id_table = ipsps_id, 221 220 }; 222 221
-1
drivers/hwmon/pmbus/ir35221.c
··· 137 137 .name = "ir35221", 138 138 }, 139 139 .probe_new = ir35221_probe, 140 - .remove = pmbus_do_remove, 141 140 .id_table = ir35221_id, 142 141 }; 143 142
-1
drivers/hwmon/pmbus/ir38064.c
··· 53 53 .name = "ir38064", 54 54 }, 55 55 .probe_new = ir38064_probe, 56 - .remove = pmbus_do_remove, 57 56 .id_table = ir38064_id, 58 57 }; 59 58
-1
drivers/hwmon/pmbus/irps5401.c
··· 55 55 .name = "irps5401", 56 56 }, 57 57 .probe_new = irps5401_probe, 58 - .remove = pmbus_do_remove, 59 58 .id_table = irps5401_id, 60 59 }; 61 60
-1
drivers/hwmon/pmbus/isl68137.c
··· 324 324 .name = "isl68137", 325 325 }, 326 326 .probe_new = isl68137_probe, 327 - .remove = pmbus_do_remove, 328 327 .id_table = raa_dmpvr_id, 329 328 }; 330 329
-1
drivers/hwmon/pmbus/lm25066.c
··· 508 508 .name = "lm25066", 509 509 }, 510 510 .probe_new = lm25066_probe, 511 - .remove = pmbus_do_remove, 512 511 .id_table = lm25066_id, 513 512 }; 514 513
-1
drivers/hwmon/pmbus/ltc2978.c
··· 875 875 .of_match_table = of_match_ptr(ltc2978_of_match), 876 876 }, 877 877 .probe_new = ltc2978_probe, 878 - .remove = pmbus_do_remove, 879 878 .id_table = ltc2978_id, 880 879 }; 881 880
-1
drivers/hwmon/pmbus/ltc3815.c
··· 200 200 .name = "ltc3815", 201 201 }, 202 202 .probe_new = ltc3815_probe, 203 - .remove = pmbus_do_remove, 204 203 .id_table = ltc3815_id, 205 204 }; 206 205
-1
drivers/hwmon/pmbus/max16064.c
··· 103 103 .name = "max16064", 104 104 }, 105 105 .probe_new = max16064_probe, 106 - .remove = pmbus_do_remove, 107 106 .id_table = max16064_id, 108 107 }; 109 108
-1
drivers/hwmon/pmbus/max16601.c
··· 302 302 .name = "max16601", 303 303 }, 304 304 .probe_new = max16601_probe, 305 - .remove = pmbus_do_remove, 306 305 .id_table = max16601_id, 307 306 }; 308 307
-3
drivers/hwmon/pmbus/max20730.c
··· 328 328 return -ENOENT; 329 329 330 330 max20730_dir = debugfs_create_dir(client->name, debugfs); 331 - if (!max20730_dir) 332 - return -ENOENT; 333 331 334 332 for (i = 0; i < MAX20730_DEBUGFS_NUM_ENTRIES; ++i) 335 333 psu->debugfs_entries[i] = i; ··· 777 779 .of_match_table = max20730_of_match, 778 780 }, 779 781 .probe_new = max20730_probe, 780 - .remove = pmbus_do_remove, 781 782 .id_table = max20730_id, 782 783 }; 783 784
-1
drivers/hwmon/pmbus/max20751.c
··· 43 43 .name = "max20751", 44 44 }, 45 45 .probe_new = max20751_probe, 46 - .remove = pmbus_do_remove, 47 46 .id_table = max20751_id, 48 47 }; 49 48
-1
drivers/hwmon/pmbus/max31785.c
··· 390 390 .of_match_table = max31785_of_match, 391 391 }, 392 392 .probe_new = max31785_probe, 393 - .remove = pmbus_do_remove, 394 393 .id_table = max31785_id, 395 394 }; 396 395
-1
drivers/hwmon/pmbus/max34440.c
··· 521 521 .name = "max34440", 522 522 }, 523 523 .probe_new = max34440_probe, 524 - .remove = pmbus_do_remove, 525 524 .id_table = max34440_id, 526 525 }; 527 526
-1
drivers/hwmon/pmbus/max8688.c
··· 183 183 .name = "max8688", 184 184 }, 185 185 .probe_new = max8688_probe, 186 - .remove = pmbus_do_remove, 187 186 .id_table = max8688_id, 188 187 }; 189 188
-1
drivers/hwmon/pmbus/mp2975.c
··· 758 758 .of_match_table = of_match_ptr(mp2975_of_match), 759 759 }, 760 760 .probe_new = mp2975_probe, 761 - .remove = pmbus_do_remove, 762 761 .id_table = mp2975_id, 763 762 }; 764 763
+75
drivers/hwmon/pmbus/pm6764tr.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Hardware monitoring driver for STMicroelectronics digital controller PM6764TR 4 + */ 5 + 6 + #include <linux/err.h> 7 + #include <linux/i2c.h> 8 + #include <linux/init.h> 9 + #include <linux/kernel.h> 10 + #include <linux/module.h> 11 + #include <linux/pmbus.h> 12 + #include "pmbus.h" 13 + 14 + #define PM6764TR_PMBUS_READ_VOUT 0xD4 15 + 16 + static int pm6764tr_read_word_data(struct i2c_client *client, int page, int phase, int reg) 17 + { 18 + int ret; 19 + 20 + switch (reg) { 21 + case PMBUS_VIRT_READ_VMON: 22 + ret = pmbus_read_word_data(client, page, phase, PM6764TR_PMBUS_READ_VOUT); 23 + break; 24 + default: 25 + ret = -ENODATA; 26 + break; 27 + } 28 + return ret; 29 + } 30 + 31 + static struct pmbus_driver_info pm6764tr_info = { 32 + .pages = 1, 33 + .format[PSC_VOLTAGE_IN] = linear, 34 + .format[PSC_VOLTAGE_OUT] = vid, 35 + .format[PSC_TEMPERATURE] = linear, 36 + .format[PSC_CURRENT_OUT] = linear, 37 + .format[PSC_POWER] = linear, 38 + .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | 39 + PMBUS_HAVE_IOUT | PMBUS_HAVE_POUT | PMBUS_HAVE_VMON | 40 + PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_STATUS_VOUT | 41 + PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 42 + .read_word_data = pm6764tr_read_word_data, 43 + }; 44 + 45 + static int pm6764tr_probe(struct i2c_client *client) 46 + { 47 + return pmbus_do_probe(client, &pm6764tr_info); 48 + } 49 + 50 + static const struct i2c_device_id pm6764tr_id[] = { 51 + {"pm6764tr", 0}, 52 + {} 53 + }; 54 + MODULE_DEVICE_TABLE(i2c, pm6764tr_id); 55 + 56 + static const struct of_device_id __maybe_unused pm6764tr_of_match[] = { 57 + {.compatible = "st,pm6764tr"}, 58 + {} 59 + }; 60 + 61 + /* This is the driver that will be inserted */ 62 + static struct i2c_driver pm6764tr_driver = { 63 + .driver = { 64 + .name = "pm6764tr", 65 + .of_match_table = of_match_ptr(pm6764tr_of_match), 66 + }, 67 + .probe_new = pm6764tr_probe, 68 + .id_table = pm6764tr_id, 69 + }; 70 + 71 + module_i2c_driver(pm6764tr_driver); 72 + 73 + MODULE_AUTHOR("Charles Hsu"); 74 + MODULE_DESCRIPTION("PMBus driver for ST PM6764TR"); 75 + MODULE_LICENSE("GPL");
-1
drivers/hwmon/pmbus/pmbus.c
··· 238 238 .name = "pmbus", 239 239 }, 240 240 .probe_new = pmbus_probe, 241 - .remove = pmbus_do_remove, 242 241 .id_table = pmbus_id, 243 242 }; 244 243
-1
drivers/hwmon/pmbus/pmbus.h
··· 490 490 bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg); 491 491 bool pmbus_check_word_register(struct i2c_client *client, int page, int reg); 492 492 int pmbus_do_probe(struct i2c_client *client, struct pmbus_driver_info *info); 493 - int pmbus_do_remove(struct i2c_client *client); 494 493 const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client 495 494 *client); 496 495 int pmbus_get_fan_rate_device(struct i2c_client *client, int page, int id,
+9 -11
drivers/hwmon/pmbus/pmbus_core.c
··· 2395 2395 DEFINE_DEBUGFS_ATTRIBUTE(pmbus_debugfs_ops_pec, pmbus_debugfs_get_pec, 2396 2396 pmbus_debugfs_set_pec, "%llu\n"); 2397 2397 2398 + static void pmbus_remove_debugfs(void *data) 2399 + { 2400 + struct dentry *entry = data; 2401 + 2402 + debugfs_remove_recursive(entry); 2403 + } 2404 + 2398 2405 static int pmbus_init_debugfs(struct i2c_client *client, 2399 2406 struct pmbus_data *data) 2400 2407 { ··· 2537 2530 } 2538 2531 } 2539 2532 2540 - return 0; 2533 + return devm_add_action_or_reset(data->dev, 2534 + pmbus_remove_debugfs, data->debugfs); 2541 2535 } 2542 2536 #else 2543 2537 static int pmbus_init_debugfs(struct i2c_client *client, ··· 2624 2616 return 0; 2625 2617 } 2626 2618 EXPORT_SYMBOL_GPL(pmbus_do_probe); 2627 - 2628 - int pmbus_do_remove(struct i2c_client *client) 2629 - { 2630 - struct pmbus_data *data = i2c_get_clientdata(client); 2631 - 2632 - debugfs_remove_recursive(data->debugfs); 2633 - 2634 - return 0; 2635 - } 2636 - EXPORT_SYMBOL_GPL(pmbus_do_remove); 2637 2619 2638 2620 struct dentry *pmbus_get_debugfs_dir(struct i2c_client *client) 2639 2621 {
-1
drivers/hwmon/pmbus/pxe1610.c
··· 131 131 .name = "pxe1610", 132 132 }, 133 133 .probe_new = pxe1610_probe, 134 - .remove = pmbus_do_remove, 135 134 .id_table = pxe1610_id, 136 135 }; 137 136
+422
drivers/hwmon/pmbus/q54sj108a2.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Driver for Delta modules, Q54SJ108A2 series 1/4 Brick DC/DC 4 + * Regulated Power Module 5 + * 6 + * Copyright 2020 Delta LLC. 7 + */ 8 + 9 + #include <linux/debugfs.h> 10 + #include <linux/i2c.h> 11 + #include <linux/module.h> 12 + #include <linux/of_device.h> 13 + #include "pmbus.h" 14 + 15 + #define STORE_DEFAULT_ALL 0x11 16 + #define ERASE_BLACKBOX_DATA 0xD1 17 + #define READ_HISTORY_EVENT_NUMBER 0xD2 18 + #define READ_HISTORY_EVENTS 0xE0 19 + #define SET_HISTORY_EVENT_OFFSET 0xE1 20 + #define PMBUS_FLASH_KEY_WRITE 0xEC 21 + 22 + enum chips { 23 + q54sj108a2 24 + }; 25 + 26 + enum { 27 + Q54SJ108A2_DEBUGFS_OPERATION = 0, 28 + Q54SJ108A2_DEBUGFS_CLEARFAULT, 29 + Q54SJ108A2_DEBUGFS_WRITEPROTECT, 30 + Q54SJ108A2_DEBUGFS_STOREDEFAULT, 31 + Q54SJ108A2_DEBUGFS_VOOV_RESPONSE, 32 + Q54SJ108A2_DEBUGFS_IOOC_RESPONSE, 33 + Q54SJ108A2_DEBUGFS_PMBUS_VERSION, 34 + Q54SJ108A2_DEBUGFS_MFR_ID, 35 + Q54SJ108A2_DEBUGFS_MFR_MODEL, 36 + Q54SJ108A2_DEBUGFS_MFR_REVISION, 37 + Q54SJ108A2_DEBUGFS_MFR_LOCATION, 38 + Q54SJ108A2_DEBUGFS_BLACKBOX_ERASE, 39 + Q54SJ108A2_DEBUGFS_BLACKBOX_READ_OFFSET, 40 + Q54SJ108A2_DEBUGFS_BLACKBOX_SET_OFFSET, 41 + Q54SJ108A2_DEBUGFS_BLACKBOX_READ, 42 + Q54SJ108A2_DEBUGFS_FLASH_KEY, 43 + Q54SJ108A2_DEBUGFS_NUM_ENTRIES 44 + }; 45 + 46 + struct q54sj108a2_data { 47 + enum chips chip; 48 + struct i2c_client *client; 49 + 50 + int debugfs_entries[Q54SJ108A2_DEBUGFS_NUM_ENTRIES]; 51 + }; 52 + 53 + #define to_psu(x, y) container_of((x), struct q54sj108a2_data, debugfs_entries[(y)]) 54 + 55 + static struct pmbus_driver_info q54sj108a2_info[] = { 56 + [q54sj108a2] = { 57 + .pages = 1, 58 + 59 + /* Source : Delta Q54SJ108A2 */ 60 + .format[PSC_TEMPERATURE] = linear, 61 + .format[PSC_VOLTAGE_IN] = linear, 62 + .format[PSC_CURRENT_OUT] = linear, 63 + 64 + .func[0] = PMBUS_HAVE_VIN | 65 + PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | 66 + PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | 67 + PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | 68 + PMBUS_HAVE_STATUS_INPUT, 69 + }, 70 + }; 71 + 72 + static ssize_t q54sj108a2_debugfs_read(struct file *file, char __user *buf, 73 + size_t count, loff_t *ppos) 74 + { 75 + int rc; 76 + int *idxp = file->private_data; 77 + int idx = *idxp; 78 + struct q54sj108a2_data *psu = to_psu(idxp, idx); 79 + char data[I2C_SMBUS_BLOCK_MAX + 2] = { 0 }; 80 + char data_char[I2C_SMBUS_BLOCK_MAX + 2] = { 0 }; 81 + char *res; 82 + 83 + switch (idx) { 84 + case Q54SJ108A2_DEBUGFS_OPERATION: 85 + rc = i2c_smbus_read_byte_data(psu->client, PMBUS_OPERATION); 86 + if (rc < 0) 87 + return rc; 88 + 89 + rc = snprintf(data, 3, "%02x", rc); 90 + break; 91 + case Q54SJ108A2_DEBUGFS_WRITEPROTECT: 92 + rc = i2c_smbus_read_byte_data(psu->client, PMBUS_WRITE_PROTECT); 93 + if (rc < 0) 94 + return rc; 95 + 96 + rc = snprintf(data, 3, "%02x", rc); 97 + break; 98 + case Q54SJ108A2_DEBUGFS_VOOV_RESPONSE: 99 + rc = i2c_smbus_read_byte_data(psu->client, PMBUS_VOUT_OV_FAULT_RESPONSE); 100 + if (rc < 0) 101 + return rc; 102 + 103 + rc = snprintf(data, 3, "%02x", rc); 104 + break; 105 + case Q54SJ108A2_DEBUGFS_IOOC_RESPONSE: 106 + rc = i2c_smbus_read_byte_data(psu->client, PMBUS_IOUT_OC_FAULT_RESPONSE); 107 + if (rc < 0) 108 + return rc; 109 + 110 + rc = snprintf(data, 3, "%02x", rc); 111 + break; 112 + case Q54SJ108A2_DEBUGFS_PMBUS_VERSION: 113 + rc = i2c_smbus_read_byte_data(psu->client, PMBUS_REVISION); 114 + if (rc < 0) 115 + return rc; 116 + 117 + rc = snprintf(data, 3, "%02x", rc); 118 + break; 119 + case Q54SJ108A2_DEBUGFS_MFR_ID: 120 + rc = i2c_smbus_read_block_data(psu->client, PMBUS_MFR_ID, data); 121 + if (rc < 0) 122 + return rc; 123 + break; 124 + case Q54SJ108A2_DEBUGFS_MFR_MODEL: 125 + rc = i2c_smbus_read_block_data(psu->client, PMBUS_MFR_MODEL, data); 126 + if (rc < 0) 127 + return rc; 128 + break; 129 + case Q54SJ108A2_DEBUGFS_MFR_REVISION: 130 + rc = i2c_smbus_read_block_data(psu->client, PMBUS_MFR_REVISION, data); 131 + if (rc < 0) 132 + return rc; 133 + break; 134 + case Q54SJ108A2_DEBUGFS_MFR_LOCATION: 135 + rc = i2c_smbus_read_block_data(psu->client, PMBUS_MFR_LOCATION, data); 136 + if (rc < 0) 137 + return rc; 138 + break; 139 + case Q54SJ108A2_DEBUGFS_BLACKBOX_READ_OFFSET: 140 + rc = i2c_smbus_read_byte_data(psu->client, READ_HISTORY_EVENT_NUMBER); 141 + if (rc < 0) 142 + return rc; 143 + 144 + rc = snprintf(data, 3, "%02x", rc); 145 + break; 146 + case Q54SJ108A2_DEBUGFS_BLACKBOX_READ: 147 + rc = i2c_smbus_read_block_data(psu->client, READ_HISTORY_EVENTS, data); 148 + if (rc < 0) 149 + return rc; 150 + 151 + res = bin2hex(data, data_char, 32); 152 + rc = res - data; 153 + 154 + break; 155 + case Q54SJ108A2_DEBUGFS_FLASH_KEY: 156 + rc = i2c_smbus_read_block_data(psu->client, PMBUS_FLASH_KEY_WRITE, data); 157 + if (rc < 0) 158 + return rc; 159 + 160 + res = bin2hex(data, data_char, 4); 161 + rc = res - data; 162 + 163 + break; 164 + default: 165 + return -EINVAL; 166 + } 167 + 168 + data[rc] = '\n'; 169 + rc += 2; 170 + 171 + return simple_read_from_buffer(buf, count, ppos, data, rc); 172 + } 173 + 174 + static ssize_t q54sj108a2_debugfs_write(struct file *file, const char __user *buf, 175 + size_t count, loff_t *ppos) 176 + { 177 + u8 flash_key[4]; 178 + u8 dst_data; 179 + ssize_t rc; 180 + int *idxp = file->private_data; 181 + int idx = *idxp; 182 + struct q54sj108a2_data *psu = to_psu(idxp, idx); 183 + 184 + rc = i2c_smbus_write_byte_data(psu->client, PMBUS_WRITE_PROTECT, 0); 185 + if (rc) 186 + return rc; 187 + 188 + switch (idx) { 189 + case Q54SJ108A2_DEBUGFS_OPERATION: 190 + rc = kstrtou8_from_user(buf, count, 0, &dst_data); 191 + if (rc < 0) 192 + return rc; 193 + 194 + rc = i2c_smbus_write_byte_data(psu->client, PMBUS_OPERATION, dst_data); 195 + if (rc < 0) 196 + return rc; 197 + 198 + break; 199 + case Q54SJ108A2_DEBUGFS_CLEARFAULT: 200 + rc = i2c_smbus_write_byte(psu->client, PMBUS_CLEAR_FAULTS); 201 + if (rc < 0) 202 + return rc; 203 + 204 + break; 205 + case Q54SJ108A2_DEBUGFS_STOREDEFAULT: 206 + flash_key[0] = 0x7E; 207 + flash_key[1] = 0x15; 208 + flash_key[2] = 0xDC; 209 + flash_key[3] = 0x42; 210 + rc = i2c_smbus_write_block_data(psu->client, PMBUS_FLASH_KEY_WRITE, 4, flash_key); 211 + if (rc < 0) 212 + return rc; 213 + 214 + rc = i2c_smbus_write_byte(psu->client, STORE_DEFAULT_ALL); 215 + if (rc < 0) 216 + return rc; 217 + 218 + break; 219 + case Q54SJ108A2_DEBUGFS_VOOV_RESPONSE: 220 + rc = kstrtou8_from_user(buf, count, 0, &dst_data); 221 + if (rc < 0) 222 + return rc; 223 + 224 + rc = i2c_smbus_write_byte_data(psu->client, PMBUS_VOUT_OV_FAULT_RESPONSE, dst_data); 225 + if (rc < 0) 226 + return rc; 227 + 228 + break; 229 + case Q54SJ108A2_DEBUGFS_IOOC_RESPONSE: 230 + rc = kstrtou8_from_user(buf, count, 0, &dst_data); 231 + if (rc < 0) 232 + return rc; 233 + 234 + rc = i2c_smbus_write_byte_data(psu->client, PMBUS_IOUT_OC_FAULT_RESPONSE, dst_data); 235 + if (rc < 0) 236 + return rc; 237 + 238 + break; 239 + case Q54SJ108A2_DEBUGFS_BLACKBOX_ERASE: 240 + rc = i2c_smbus_write_byte(psu->client, ERASE_BLACKBOX_DATA); 241 + if (rc < 0) 242 + return rc; 243 + 244 + break; 245 + case Q54SJ108A2_DEBUGFS_BLACKBOX_SET_OFFSET: 246 + rc = kstrtou8_from_user(buf, count, 0, &dst_data); 247 + if (rc < 0) 248 + return rc; 249 + 250 + rc = i2c_smbus_write_byte_data(psu->client, SET_HISTORY_EVENT_OFFSET, dst_data); 251 + if (rc < 0) 252 + return rc; 253 + 254 + break; 255 + default: 256 + return -EINVAL; 257 + } 258 + 259 + return count; 260 + } 261 + 262 + static const struct file_operations q54sj108a2_fops = { 263 + .llseek = noop_llseek, 264 + .read = q54sj108a2_debugfs_read, 265 + .write = q54sj108a2_debugfs_write, 266 + .open = simple_open, 267 + }; 268 + 269 + static const struct i2c_device_id q54sj108a2_id[] = { 270 + { "q54sj108a2", q54sj108a2 }, 271 + { }, 272 + }; 273 + 274 + MODULE_DEVICE_TABLE(i2c, q54sj108a2_id); 275 + 276 + static int q54sj108a2_probe(struct i2c_client *client) 277 + { 278 + struct device *dev = &client->dev; 279 + u8 buf[I2C_SMBUS_BLOCK_MAX + 1]; 280 + enum chips chip_id; 281 + int ret, i; 282 + struct dentry *debugfs; 283 + struct dentry *q54sj108a2_dir; 284 + struct q54sj108a2_data *psu; 285 + 286 + if (!i2c_check_functionality(client->adapter, 287 + I2C_FUNC_SMBUS_BYTE_DATA | 288 + I2C_FUNC_SMBUS_WORD_DATA | 289 + I2C_FUNC_SMBUS_BLOCK_DATA)) 290 + return -ENODEV; 291 + 292 + if (client->dev.of_node) 293 + chip_id = (enum chips)(unsigned long)of_device_get_match_data(dev); 294 + else 295 + chip_id = i2c_match_id(q54sj108a2_id, client)->driver_data; 296 + 297 + ret = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, buf); 298 + if (ret < 0) { 299 + dev_err(&client->dev, "Failed to read Manufacturer ID\n"); 300 + return ret; 301 + } 302 + if (ret != 5 || strncmp(buf, "DELTA", 5)) { 303 + buf[ret] = '\0'; 304 + dev_err(dev, "Unsupported Manufacturer ID '%s'\n", buf); 305 + return -ENODEV; 306 + } 307 + 308 + /* 309 + * The chips support reading PMBUS_MFR_MODEL. 310 + */ 311 + ret = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf); 312 + if (ret < 0) { 313 + dev_err(dev, "Failed to read Manufacturer Model\n"); 314 + return ret; 315 + } 316 + if (ret != 14 || strncmp(buf, "Q54SJ108A2", 10)) { 317 + buf[ret] = '\0'; 318 + dev_err(dev, "Unsupported Manufacturer Model '%s'\n", buf); 319 + return -ENODEV; 320 + } 321 + 322 + ret = i2c_smbus_read_block_data(client, PMBUS_MFR_REVISION, buf); 323 + if (ret < 0) { 324 + dev_err(dev, "Failed to read Manufacturer Revision\n"); 325 + return ret; 326 + } 327 + if (ret != 4 || buf[0] != 'S') { 328 + buf[ret] = '\0'; 329 + dev_err(dev, "Unsupported Manufacturer Revision '%s'\n", buf); 330 + return -ENODEV; 331 + } 332 + 333 + ret = pmbus_do_probe(client, &q54sj108a2_info[chip_id]); 334 + if (ret) 335 + return ret; 336 + 337 + psu = devm_kzalloc(&client->dev, sizeof(*psu), GFP_KERNEL); 338 + if (!psu) 339 + return 0; 340 + 341 + psu->client = client; 342 + 343 + debugfs = pmbus_get_debugfs_dir(client); 344 + 345 + q54sj108a2_dir = debugfs_create_dir(client->name, debugfs); 346 + 347 + for (i = 0; i < Q54SJ108A2_DEBUGFS_NUM_ENTRIES; ++i) 348 + psu->debugfs_entries[i] = i; 349 + 350 + debugfs_create_file("operation", 0644, q54sj108a2_dir, 351 + &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_OPERATION], 352 + &q54sj108a2_fops); 353 + debugfs_create_file("clear_fault", 0200, q54sj108a2_dir, 354 + &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_CLEARFAULT], 355 + &q54sj108a2_fops); 356 + debugfs_create_file("write_protect", 0444, q54sj108a2_dir, 357 + &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_WRITEPROTECT], 358 + &q54sj108a2_fops); 359 + debugfs_create_file("store_default", 0200, q54sj108a2_dir, 360 + &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_STOREDEFAULT], 361 + &q54sj108a2_fops); 362 + debugfs_create_file("vo_ov_response", 0644, q54sj108a2_dir, 363 + &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_VOOV_RESPONSE], 364 + &q54sj108a2_fops); 365 + debugfs_create_file("io_oc_response", 0644, q54sj108a2_dir, 366 + &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_IOOC_RESPONSE], 367 + &q54sj108a2_fops); 368 + debugfs_create_file("pmbus_revision", 0444, q54sj108a2_dir, 369 + &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_PMBUS_VERSION], 370 + &q54sj108a2_fops); 371 + debugfs_create_file("mfr_id", 0444, q54sj108a2_dir, 372 + &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_MFR_ID], 373 + &q54sj108a2_fops); 374 + debugfs_create_file("mfr_model", 0444, q54sj108a2_dir, 375 + &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_MFR_MODEL], 376 + &q54sj108a2_fops); 377 + debugfs_create_file("mfr_revision", 0444, q54sj108a2_dir, 378 + &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_MFR_REVISION], 379 + &q54sj108a2_fops); 380 + debugfs_create_file("mfr_location", 0444, q54sj108a2_dir, 381 + &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_MFR_LOCATION], 382 + &q54sj108a2_fops); 383 + debugfs_create_file("blackbox_erase", 0200, q54sj108a2_dir, 384 + &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_BLACKBOX_ERASE], 385 + &q54sj108a2_fops); 386 + debugfs_create_file("blackbox_read_offset", 0444, q54sj108a2_dir, 387 + &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_BLACKBOX_READ_OFFSET], 388 + &q54sj108a2_fops); 389 + debugfs_create_file("blackbox_set_offset", 0200, q54sj108a2_dir, 390 + &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_BLACKBOX_SET_OFFSET], 391 + &q54sj108a2_fops); 392 + debugfs_create_file("blackbox_read", 0444, q54sj108a2_dir, 393 + &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_BLACKBOX_READ], 394 + &q54sj108a2_fops); 395 + debugfs_create_file("flash_key", 0444, q54sj108a2_dir, 396 + &psu->debugfs_entries[Q54SJ108A2_DEBUGFS_FLASH_KEY], 397 + &q54sj108a2_fops); 398 + 399 + return 0; 400 + } 401 + 402 + static const struct of_device_id q54sj108a2_of_match[] = { 403 + { .compatible = "delta,q54sj108a2", .data = (void *)q54sj108a2 }, 404 + { }, 405 + }; 406 + 407 + MODULE_DEVICE_TABLE(of, q54sj108a2_of_match); 408 + 409 + static struct i2c_driver q54sj108a2_driver = { 410 + .driver = { 411 + .name = "q54sj108a2", 412 + .of_match_table = q54sj108a2_of_match, 413 + }, 414 + .probe_new = q54sj108a2_probe, 415 + .id_table = q54sj108a2_id, 416 + }; 417 + 418 + module_i2c_driver(q54sj108a2_driver); 419 + 420 + MODULE_AUTHOR("Xiao.Ma <xiao.mx.ma@deltaww.com>"); 421 + MODULE_DESCRIPTION("PMBus driver for Delta Q54SJ108A2 series modules"); 422 + MODULE_LICENSE("GPL");
-1
drivers/hwmon/pmbus/tps40422.c
··· 43 43 .name = "tps40422", 44 44 }, 45 45 .probe_new = tps40422_probe, 46 - .remove = pmbus_do_remove, 47 46 .id_table = tps40422_id, 48 47 }; 49 48
-1
drivers/hwmon/pmbus/tps53679.c
··· 251 251 .of_match_table = of_match_ptr(tps53679_of_match), 252 252 }, 253 253 .probe_new = tps53679_probe, 254 - .remove = pmbus_do_remove, 255 254 .id_table = tps53679_id, 256 255 }; 257 256
-1
drivers/hwmon/pmbus/ucd9000.c
··· 621 621 .of_match_table = of_match_ptr(ucd9000_of_match), 622 622 }, 623 623 .probe_new = ucd9000_probe, 624 - .remove = pmbus_do_remove, 625 624 .id_table = ucd9000_id, 626 625 }; 627 626
-1
drivers/hwmon/pmbus/ucd9200.c
··· 201 201 .of_match_table = of_match_ptr(ucd9200_of_match), 202 202 }, 203 203 .probe_new = ucd9200_probe, 204 - .remove = pmbus_do_remove, 205 204 .id_table = ucd9200_id, 206 205 }; 207 206
-1
drivers/hwmon/pmbus/xdpe12284.c
··· 160 160 .of_match_table = of_match_ptr(xdpe122_of_match), 161 161 }, 162 162 .probe_new = xdpe122_probe, 163 - .remove = pmbus_do_remove, 164 163 .id_table = xdpe122_id, 165 164 }; 166 165
-1
drivers/hwmon/pmbus/zl6100.c
··· 396 396 .name = "zl6100", 397 397 }, 398 398 .probe_new = zl6100_probe, 399 - .remove = pmbus_do_remove, 400 399 .id_table = zl6100_id, 401 400 }; 402 401
+107 -65
drivers/hwmon/pwm-fan.c
··· 8 8 */ 9 9 10 10 #include <linux/hwmon.h> 11 - #include <linux/hwmon-sysfs.h> 12 11 #include <linux/interrupt.h> 13 12 #include <linux/module.h> 14 13 #include <linux/mutex.h> ··· 38 39 unsigned int pwm_fan_max_state; 39 40 unsigned int *pwm_fan_cooling_levels; 40 41 struct thermal_cooling_device *cdev; 42 + 43 + struct hwmon_chip_info info; 44 + }; 45 + 46 + static const u32 pwm_fan_channel_config_pwm[] = { 47 + HWMON_PWM_INPUT, 48 + 0 49 + }; 50 + 51 + static const struct hwmon_channel_info pwm_fan_channel_pwm = { 52 + .type = hwmon_pwm, 53 + .config = pwm_fan_channel_config_pwm, 54 + }; 55 + 56 + static const u32 pwm_fan_channel_config_fan[] = { 57 + HWMON_F_INPUT, 58 + 0 59 + }; 60 + 61 + static const struct hwmon_channel_info pwm_fan_channel_fan = { 62 + .type = hwmon_fan, 63 + .config = pwm_fan_channel_config_fan, 41 64 }; 42 65 43 66 /* This handler assumes self resetting edge triggered interrupt. */ ··· 124 103 ctx->pwm_fan_state = i; 125 104 } 126 105 127 - static ssize_t pwm_store(struct device *dev, struct device_attribute *attr, 128 - const char *buf, size_t count) 106 + static int pwm_fan_write(struct device *dev, enum hwmon_sensor_types type, 107 + u32 attr, int channel, long val) 129 108 { 130 109 struct pwm_fan_ctx *ctx = dev_get_drvdata(dev); 131 - unsigned long pwm; 132 110 int ret; 133 111 134 - if (kstrtoul(buf, 10, &pwm) || pwm > MAX_PWM) 112 + if (val < 0 || val > MAX_PWM) 135 113 return -EINVAL; 136 114 137 - ret = __set_pwm(ctx, pwm); 115 + ret = __set_pwm(ctx, val); 138 116 if (ret) 139 117 return ret; 140 118 141 - pwm_fan_update_state(ctx, pwm); 142 - return count; 119 + pwm_fan_update_state(ctx, val); 120 + return 0; 143 121 } 144 122 145 - static ssize_t pwm_show(struct device *dev, struct device_attribute *attr, 146 - char *buf) 123 + static int pwm_fan_read(struct device *dev, enum hwmon_sensor_types type, 124 + u32 attr, int channel, long *val) 147 125 { 148 126 struct pwm_fan_ctx *ctx = dev_get_drvdata(dev); 149 127 150 - return sprintf(buf, "%u\n", ctx->pwm_value); 151 - } 152 - 153 - static ssize_t rpm_show(struct device *dev, 154 - struct device_attribute *attr, char *buf) 155 - { 156 - struct pwm_fan_ctx *ctx = dev_get_drvdata(dev); 157 - 158 - return sprintf(buf, "%u\n", ctx->rpm); 159 - } 160 - 161 - static SENSOR_DEVICE_ATTR_RW(pwm1, pwm, 0); 162 - static SENSOR_DEVICE_ATTR_RO(fan1_input, rpm, 0); 163 - 164 - static struct attribute *pwm_fan_attrs[] = { 165 - &sensor_dev_attr_pwm1.dev_attr.attr, 166 - &sensor_dev_attr_fan1_input.dev_attr.attr, 167 - NULL, 168 - }; 169 - 170 - static umode_t pwm_fan_attrs_visible(struct kobject *kobj, struct attribute *a, 171 - int n) 172 - { 173 - struct device *dev = container_of(kobj, struct device, kobj); 174 - struct pwm_fan_ctx *ctx = dev_get_drvdata(dev); 175 - 176 - /* Hide fan_input in case no interrupt is available */ 177 - if (n == 1 && ctx->irq <= 0) 128 + switch (type) { 129 + case hwmon_pwm: 130 + *val = ctx->pwm_value; 178 131 return 0; 179 132 180 - return a->mode; 133 + case hwmon_fan: 134 + *val = ctx->rpm; 135 + return 0; 136 + 137 + default: 138 + return -ENOTSUPP; 139 + } 181 140 } 182 141 183 - static const struct attribute_group pwm_fan_group = { 184 - .attrs = pwm_fan_attrs, 185 - .is_visible = pwm_fan_attrs_visible, 186 - }; 142 + static umode_t pwm_fan_is_visible(const void *data, 143 + enum hwmon_sensor_types type, 144 + u32 attr, int channel) 145 + { 146 + switch (type) { 147 + case hwmon_pwm: 148 + return 0644; 187 149 188 - static const struct attribute_group *pwm_fan_groups[] = { 189 - &pwm_fan_group, 190 - NULL, 150 + case hwmon_fan: 151 + return 0444; 152 + 153 + default: 154 + return 0; 155 + } 156 + } 157 + 158 + static const struct hwmon_ops pwm_fan_hwmon_ops = { 159 + .is_visible = pwm_fan_is_visible, 160 + .read = pwm_fan_read, 161 + .write = pwm_fan_write, 191 162 }; 192 163 193 164 /* thermal cooling device callbacks */ ··· 299 286 struct device *hwmon; 300 287 int ret; 301 288 struct pwm_state state = { }; 302 - u32 ppr = 2; 289 + int tach_count; 290 + const struct hwmon_channel_info **channels; 303 291 304 292 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 305 293 if (!ctx) ··· 313 299 return dev_err_probe(dev, PTR_ERR(ctx->pwm), "Could not get PWM\n"); 314 300 315 301 platform_set_drvdata(pdev, ctx); 316 - 317 - ctx->irq = platform_get_irq_optional(pdev, 0); 318 - if (ctx->irq == -EPROBE_DEFER) 319 - return ctx->irq; 320 302 321 303 ctx->reg_en = devm_regulator_get_optional(dev, "fan"); 322 304 if (IS_ERR(ctx->reg_en)) { ··· 349 339 if (ret) 350 340 return ret; 351 341 352 - of_property_read_u32(dev->of_node, "pulses-per-revolution", &ppr); 353 - ctx->pulses_per_revolution = ppr; 354 - if (!ctx->pulses_per_revolution) { 355 - dev_err(dev, "pulses-per-revolution can't be zero.\n"); 356 - return -EINVAL; 357 - } 342 + tach_count = platform_irq_count(pdev); 343 + if (tach_count < 0) 344 + return dev_err_probe(dev, tach_count, 345 + "Could not get number of fan tachometer inputs\n"); 358 346 359 - if (ctx->irq > 0) { 360 - ret = devm_request_irq(dev, ctx->irq, pulse_handler, 0, 361 - pdev->name, ctx); 362 - if (ret) { 363 - dev_err(dev, "Failed to request interrupt: %d\n", ret); 364 - return ret; 347 + channels = devm_kcalloc(dev, tach_count + 2, 348 + sizeof(struct hwmon_channel_info *), GFP_KERNEL); 349 + if (!channels) 350 + return -ENOMEM; 351 + 352 + channels[0] = &pwm_fan_channel_pwm; 353 + 354 + if (tach_count > 0) { 355 + u32 ppr = 2; 356 + 357 + ctx->irq = platform_get_irq(pdev, 0); 358 + if (ctx->irq == -EPROBE_DEFER) 359 + return ctx->irq; 360 + if (ctx->irq > 0) { 361 + ret = devm_request_irq(dev, ctx->irq, pulse_handler, 0, 362 + pdev->name, ctx); 363 + if (ret) { 364 + dev_err(dev, 365 + "Failed to request interrupt: %d\n", 366 + ret); 367 + return ret; 368 + } 365 369 } 370 + 371 + of_property_read_u32(dev->of_node, 372 + "pulses-per-revolution", 373 + &ppr); 374 + ctx->pulses_per_revolution = ppr; 375 + if (!ctx->pulses_per_revolution) { 376 + dev_err(dev, "pulses-per-revolution can't be zero.\n"); 377 + return -EINVAL; 378 + } 379 + 380 + dev_dbg(dev, "tach: irq=%d, pulses_per_revolution=%d\n", 381 + ctx->irq, ctx->pulses_per_revolution); 382 + 366 383 ctx->sample_start = ktime_get(); 367 384 mod_timer(&ctx->rpm_timer, jiffies + HZ); 385 + 386 + channels[1] = &pwm_fan_channel_fan; 368 387 } 369 388 370 - hwmon = devm_hwmon_device_register_with_groups(dev, "pwmfan", 371 - ctx, pwm_fan_groups); 389 + ctx->info.ops = &pwm_fan_hwmon_ops; 390 + ctx->info.info = channels; 391 + 392 + hwmon = devm_hwmon_device_register_with_info(dev, "pwmfan", 393 + ctx, &ctx->info, NULL); 372 394 if (IS_ERR(hwmon)) { 373 395 dev_err(dev, "Failed to register hwmon device\n"); 374 396 return PTR_ERR(hwmon);
+250
drivers/hwmon/sbtsi_temp.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * sbtsi_temp.c - hwmon driver for a SBI Temperature Sensor Interface (SB-TSI) 4 + * compliant AMD SoC temperature device. 5 + * 6 + * Copyright (c) 2020, Google Inc. 7 + * Copyright (c) 2020, Kun Yi <kunyi@google.com> 8 + */ 9 + 10 + #include <linux/err.h> 11 + #include <linux/i2c.h> 12 + #include <linux/init.h> 13 + #include <linux/hwmon.h> 14 + #include <linux/module.h> 15 + #include <linux/mutex.h> 16 + #include <linux/of_device.h> 17 + #include <linux/of.h> 18 + 19 + /* 20 + * SB-TSI registers only support SMBus byte data access. "_INT" registers are 21 + * the integer part of a temperature value or limit, and "_DEC" registers are 22 + * corresponding decimal parts. 23 + */ 24 + #define SBTSI_REG_TEMP_INT 0x01 /* RO */ 25 + #define SBTSI_REG_STATUS 0x02 /* RO */ 26 + #define SBTSI_REG_CONFIG 0x03 /* RO */ 27 + #define SBTSI_REG_TEMP_HIGH_INT 0x07 /* RW */ 28 + #define SBTSI_REG_TEMP_LOW_INT 0x08 /* RW */ 29 + #define SBTSI_REG_TEMP_DEC 0x10 /* RW */ 30 + #define SBTSI_REG_TEMP_HIGH_DEC 0x13 /* RW */ 31 + #define SBTSI_REG_TEMP_LOW_DEC 0x14 /* RW */ 32 + 33 + #define SBTSI_CONFIG_READ_ORDER_SHIFT 5 34 + 35 + #define SBTSI_TEMP_MIN 0 36 + #define SBTSI_TEMP_MAX 255875 37 + 38 + /* Each client has this additional data */ 39 + struct sbtsi_data { 40 + struct i2c_client *client; 41 + struct mutex lock; 42 + }; 43 + 44 + /* 45 + * From SB-TSI spec: CPU temperature readings and limit registers encode the 46 + * temperature in increments of 0.125 from 0 to 255.875. The "high byte" 47 + * register encodes the base-2 of the integer portion, and the upper 3 bits of 48 + * the "low byte" encode in base-2 the decimal portion. 49 + * 50 + * e.g. INT=0x19, DEC=0x20 represents 25.125 degrees Celsius 51 + * 52 + * Therefore temperature in millidegree Celsius = 53 + * (INT + DEC / 256) * 1000 = (INT * 8 + DEC / 32) * 125 54 + */ 55 + static inline int sbtsi_reg_to_mc(s32 integer, s32 decimal) 56 + { 57 + return ((integer << 3) + (decimal >> 5)) * 125; 58 + } 59 + 60 + /* 61 + * Inversely, given temperature in millidegree Celsius 62 + * INT = (TEMP / 125) / 8 63 + * DEC = ((TEMP / 125) % 8) * 32 64 + * Caller have to make sure temp doesn't exceed 255875, the max valid value. 65 + */ 66 + static inline void sbtsi_mc_to_reg(s32 temp, u8 *integer, u8 *decimal) 67 + { 68 + temp /= 125; 69 + *integer = temp >> 3; 70 + *decimal = (temp & 0x7) << 5; 71 + } 72 + 73 + static int sbtsi_read(struct device *dev, enum hwmon_sensor_types type, 74 + u32 attr, int channel, long *val) 75 + { 76 + struct sbtsi_data *data = dev_get_drvdata(dev); 77 + s32 temp_int, temp_dec; 78 + int err; 79 + 80 + switch (attr) { 81 + case hwmon_temp_input: 82 + /* 83 + * ReadOrder bit specifies the reading order of integer and 84 + * decimal part of CPU temp for atomic reads. If bit == 0, 85 + * reading integer part triggers latching of the decimal part, 86 + * so integer part should be read first. If bit == 1, read 87 + * order should be reversed. 88 + */ 89 + err = i2c_smbus_read_byte_data(data->client, SBTSI_REG_CONFIG); 90 + if (err < 0) 91 + return err; 92 + 93 + mutex_lock(&data->lock); 94 + if (err & BIT(SBTSI_CONFIG_READ_ORDER_SHIFT)) { 95 + temp_dec = i2c_smbus_read_byte_data(data->client, SBTSI_REG_TEMP_DEC); 96 + temp_int = i2c_smbus_read_byte_data(data->client, SBTSI_REG_TEMP_INT); 97 + } else { 98 + temp_int = i2c_smbus_read_byte_data(data->client, SBTSI_REG_TEMP_INT); 99 + temp_dec = i2c_smbus_read_byte_data(data->client, SBTSI_REG_TEMP_DEC); 100 + } 101 + mutex_unlock(&data->lock); 102 + break; 103 + case hwmon_temp_max: 104 + mutex_lock(&data->lock); 105 + temp_int = i2c_smbus_read_byte_data(data->client, SBTSI_REG_TEMP_HIGH_INT); 106 + temp_dec = i2c_smbus_read_byte_data(data->client, SBTSI_REG_TEMP_HIGH_DEC); 107 + mutex_unlock(&data->lock); 108 + break; 109 + case hwmon_temp_min: 110 + mutex_lock(&data->lock); 111 + temp_int = i2c_smbus_read_byte_data(data->client, SBTSI_REG_TEMP_LOW_INT); 112 + temp_dec = i2c_smbus_read_byte_data(data->client, SBTSI_REG_TEMP_LOW_DEC); 113 + mutex_unlock(&data->lock); 114 + break; 115 + default: 116 + return -EINVAL; 117 + } 118 + 119 + 120 + if (temp_int < 0) 121 + return temp_int; 122 + if (temp_dec < 0) 123 + return temp_dec; 124 + 125 + *val = sbtsi_reg_to_mc(temp_int, temp_dec); 126 + 127 + return 0; 128 + } 129 + 130 + static int sbtsi_write(struct device *dev, enum hwmon_sensor_types type, 131 + u32 attr, int channel, long val) 132 + { 133 + struct sbtsi_data *data = dev_get_drvdata(dev); 134 + int reg_int, reg_dec, err; 135 + u8 temp_int, temp_dec; 136 + 137 + switch (attr) { 138 + case hwmon_temp_max: 139 + reg_int = SBTSI_REG_TEMP_HIGH_INT; 140 + reg_dec = SBTSI_REG_TEMP_HIGH_DEC; 141 + break; 142 + case hwmon_temp_min: 143 + reg_int = SBTSI_REG_TEMP_LOW_INT; 144 + reg_dec = SBTSI_REG_TEMP_LOW_DEC; 145 + break; 146 + default: 147 + return -EINVAL; 148 + } 149 + 150 + val = clamp_val(val, SBTSI_TEMP_MIN, SBTSI_TEMP_MAX); 151 + sbtsi_mc_to_reg(val, &temp_int, &temp_dec); 152 + 153 + mutex_lock(&data->lock); 154 + err = i2c_smbus_write_byte_data(data->client, reg_int, temp_int); 155 + if (err) 156 + goto exit; 157 + 158 + err = i2c_smbus_write_byte_data(data->client, reg_dec, temp_dec); 159 + exit: 160 + mutex_unlock(&data->lock); 161 + return err; 162 + } 163 + 164 + static umode_t sbtsi_is_visible(const void *data, 165 + enum hwmon_sensor_types type, 166 + u32 attr, int channel) 167 + { 168 + switch (type) { 169 + case hwmon_temp: 170 + switch (attr) { 171 + case hwmon_temp_input: 172 + return 0444; 173 + case hwmon_temp_min: 174 + return 0644; 175 + case hwmon_temp_max: 176 + return 0644; 177 + } 178 + break; 179 + default: 180 + break; 181 + } 182 + return 0; 183 + } 184 + 185 + static const struct hwmon_channel_info *sbtsi_info[] = { 186 + HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ), 187 + HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX), 188 + NULL 189 + }; 190 + 191 + static const struct hwmon_ops sbtsi_hwmon_ops = { 192 + .is_visible = sbtsi_is_visible, 193 + .read = sbtsi_read, 194 + .write = sbtsi_write, 195 + }; 196 + 197 + static const struct hwmon_chip_info sbtsi_chip_info = { 198 + .ops = &sbtsi_hwmon_ops, 199 + .info = sbtsi_info, 200 + }; 201 + 202 + static int sbtsi_probe(struct i2c_client *client, 203 + const struct i2c_device_id *id) 204 + { 205 + struct device *dev = &client->dev; 206 + struct device *hwmon_dev; 207 + struct sbtsi_data *data; 208 + 209 + data = devm_kzalloc(dev, sizeof(struct sbtsi_data), GFP_KERNEL); 210 + if (!data) 211 + return -ENOMEM; 212 + 213 + data->client = client; 214 + mutex_init(&data->lock); 215 + 216 + hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data, &sbtsi_chip_info, 217 + NULL); 218 + 219 + return PTR_ERR_OR_ZERO(hwmon_dev); 220 + } 221 + 222 + static const struct i2c_device_id sbtsi_id[] = { 223 + {"sbtsi", 0}, 224 + {} 225 + }; 226 + MODULE_DEVICE_TABLE(i2c, sbtsi_id); 227 + 228 + static const struct of_device_id __maybe_unused sbtsi_of_match[] = { 229 + { 230 + .compatible = "amd,sbtsi", 231 + }, 232 + { }, 233 + }; 234 + MODULE_DEVICE_TABLE(of, sbtsi_of_match); 235 + 236 + static struct i2c_driver sbtsi_driver = { 237 + .class = I2C_CLASS_HWMON, 238 + .driver = { 239 + .name = "sbtsi", 240 + .of_match_table = of_match_ptr(sbtsi_of_match), 241 + }, 242 + .probe = sbtsi_probe, 243 + .id_table = sbtsi_id, 244 + }; 245 + 246 + module_i2c_driver(sbtsi_driver); 247 + 248 + MODULE_AUTHOR("Kun Yi <kunyi@google.com>"); 249 + MODULE_DESCRIPTION("Hwmon driver for AMD SB-TSI emulated sensor"); 250 + MODULE_LICENSE("GPL");
+1 -1
drivers/hwmon/xgene-hwmon.c
··· 784 784 }; 785 785 MODULE_DEVICE_TABLE(of, xgene_hwmon_of_match); 786 786 787 - static struct platform_driver xgene_hwmon_driver __refdata = { 787 + static struct platform_driver xgene_hwmon_driver = { 788 788 .probe = xgene_hwmon_probe, 789 789 .remove = xgene_hwmon_remove, 790 790 .driver = {